diff --git a/DEPS b/DEPS
index 33fe59b..e997af6 100644
--- a/DEPS
+++ b/DEPS
@@ -314,7 +314,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'src_internal_revision': 'ad00a6b3a52005a50d149f0a84a8fc4b216e9839',
+  'src_internal_revision': '74f00236c1468c95c957abbe7ee5801388cf6529',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
@@ -322,7 +322,7 @@
   # 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': 'cb7e3eb9cb05d2f42d99a8e6fef4df6f81263d53',
+  'v8_revision': 'efc281b337f79ca57ff0097300905a2c39a5a321',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
@@ -389,7 +389,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '95899ca94864dd5d811a9935e30d0174095eb7aa',
+  'catapult_revision': '92eef236f6cfab3f1c24a65ac265fdd6de917553',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling chromium_variations
   # and whatever else without interference from each other.
@@ -409,7 +409,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': 'e4590077122a04c3ab18c08a87bb6eff665fe2a8',
+  'devtools_frontend_revision': 'c8b83c57ef4546aba4d1010b6af459b6813691d9',
   # 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.
@@ -449,7 +449,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'bf0426a4388288ef406a5e1c7f9f4109db7d2de9',
+  'dawn_revision': '0e1f8d431a4dac84d2681b3e01f10036b900b0ae',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -469,7 +469,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libavif
   # and whatever else without interference from each other.
-  'libavif_revision': '676aded3501ff453c88a6d9ed1e5b4f33b458f3e',
+  'libavif_revision': '5e7a1778f1199b4cb96f25f64a1dc050d7e15ee9',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libavif
   # and whatever else without interference from each other.
@@ -849,12 +849,12 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '53a7e81a8728e0b93c34a1a7d162c4b75e960f6d',
+    '1958ab73e7ce5784e7e9337dff79971786d35506',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + '49c12aba2275832dc5d645c12defc3e41f076392',
+    'url': Var('chromium_git') + '/website.git' + '@' + 'fcd9e704410cd8801f923e24aa9cbbd9cb5ed58a',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -1299,13 +1299,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c7aca34c8e5fff27dd8424b55ef520de960d0bff',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'bb14391a5092f01557cf1fedfa3f7fe3afdbd1fb',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '2c6423900dc9b550cba8f3954b60104f3fc433c8',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '95908e63edbfd2f41e38749c175a30a61a5941f3',
     'condition': 'checkout_src_internal',
   },
 
@@ -1777,7 +1777,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '1d0ca0005e4681498030fc4c1015abbec4a2077c',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '49e44b0a869219ed1acc1a55bb0a1a60bc9bf037',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1962,7 +1962,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '2ee990a4cb91b41491f83b52c9520476b18a9fd8',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '92fe5c4db3bf97b559640b196d8c40a7b3e10a78',
+    Var('webrtc_git') + '/src.git' + '@' + '4d25a77fd32fade871cba7d93a7d5716180e2307',
 
   # 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.
@@ -2085,7 +2085,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': '27JGhK2P3PGzvgCv-4VBPkVt3Wo3P6r7J8zkeC98qfgC',
+        'version': 'z_UPTWEuJx1avun9jp8L2LzuiwIoG7OOtAK9J3icFG4C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4251,7 +4251,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '90b6ca5bc5942ca1b25e4504339f80716d2dadbe',
+        'cbf06b1a54baf999a39e40de680dba54cba14166',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
index a1969528..51fd960 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java
@@ -11,7 +11,6 @@
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.android_webview.common.Lifetime;
-import org.chromium.android_webview.common.PlatformServiceBridge;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.StrictModeContext;
 import org.chromium.base.annotations.CalledByNative;
@@ -72,8 +71,6 @@
             migrateGeolocationPreferences();
         }
 
-        PlatformServiceBridge.getInstance().setSafeBrowsingHandler();
-
         // Register MemoryPressureMonitor callbacks and make sure it polls only if there is at
         // least one WebView around.
         MemoryPressureMonitor.INSTANCE.registerComponentCallbacks();
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
index e199627..2bc0a1d0 100644
--- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
+++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
@@ -192,6 +192,7 @@
                 }
 
                 PowerMonitor.create();
+                PlatformServiceBridge.getInstance().setSafeBrowsingHandler();
             });
         }
     }
diff --git a/ash/accessibility/magnifier/docked_magnifier_controller_unittest.cc b/ash/accessibility/magnifier/docked_magnifier_controller_unittest.cc
index fb00a37..d97fe33 100644
--- a/ash/accessibility/magnifier/docked_magnifier_controller_unittest.cc
+++ b/ash/accessibility/magnifier/docked_magnifier_controller_unittest.cc
@@ -539,15 +539,10 @@
   // Tab once. The viewport should be centered on the beginning of the overview
   // item's title.
   SendKey(ui::VKEY_TAB);
-  OverviewItem* item = GetOverviewItemForWindow(window.get());
+  auto* item = GetOverviewItemForWindow(window.get());
   ASSERT_TRUE(item);
-  const auto label_bounds_in_screen = item->overview_item_view()
-                                          ->header_view()
-                                          ->title_label()
-                                          ->GetBoundsInScreen();
-  const gfx::Point expected_point_of_interest(
-      label_bounds_in_screen.x(), label_bounds_in_screen.CenterPoint().y());
-  TestMagnifierLayerTransform(expected_point_of_interest, root_window);
+  TestMagnifierLayerTransform(item->GetMagnifierFocusPointInScreen(),
+                              root_window);
 
   // Tab one more time. The viewport should be centered on the center of the
   // default desk button in the zero state desks bar.
diff --git a/ash/capture_mode/capture_mode_unittests.cc b/ash/capture_mode/capture_mode_unittests.cc
index e77d2c2..dd21fbe3 100644
--- a/ash/capture_mode/capture_mode_unittests.cc
+++ b/ash/capture_mode/capture_mode_unittests.cc
@@ -2597,7 +2597,7 @@
   auto* overview_controller = Shell::Get()->overview_controller();
   overview_controller->StartOverview(OverviewStartAction::kTests);
   ASSERT_TRUE(overview_controller->InOverviewSession());
-  OverviewItem* overview_item =
+  auto* overview_item =
       overview_controller->overview_session()->GetOverviewItemForWindow(
           window.get());
   const auto target_bounds = overview_item->target_bounds();
diff --git a/ash/glanceables/tasks/fake_glanceables_tasks_client.cc b/ash/glanceables/tasks/fake_glanceables_tasks_client.cc
index 841de4c6..54a246f 100644
--- a/ash/glanceables/tasks/fake_glanceables_tasks_client.cc
+++ b/ash/glanceables/tasks/fake_glanceables_tasks_client.cc
@@ -25,7 +25,16 @@
 FakeGlanceablesTasksClient::~FakeGlanceablesTasksClient() = default;
 
 void FakeGlanceablesTasksClient::GetTaskLists(GetTaskListsCallback callback) {
-  std::move(callback).Run(task_lists_.get());
+  if (!paused_) {
+    std::move(callback).Run(task_lists_.get());
+  } else {
+    pending_get_task_lists_callbacks_.push_back(base::BindOnce(
+        [](ui::ListModel<ash::GlanceablesTaskList>* task_lists,
+           GetTaskListsCallback callback) {
+          std::move(callback).Run(task_lists);
+        },
+        task_lists_.get(), std::move(callback)));
+  }
 }
 
 void FakeGlanceablesTasksClient::GetTasks(const std::string& task_list_id,
@@ -53,6 +62,8 @@
 
 void FakeGlanceablesTasksClient::OnGlanceablesBubbleClosed() {
   ++bubble_closed_count_;
+  RunPendingGetTaskListsCallbacks();
+  RunPendingGetTasksCallbacks();
 }
 
 int FakeGlanceablesTasksClient::GetAndResetBubbleClosedCount() {
@@ -70,6 +81,15 @@
   return callbacks.size();
 }
 
+size_t FakeGlanceablesTasksClient::RunPendingGetTaskListsCallbacks() {
+  std::list<base::OnceClosure> callbacks;
+  pending_get_task_lists_callbacks_.swap(callbacks);
+  for (auto& callback : callbacks) {
+    std::move(callback).Run();
+  }
+  return callbacks.size();
+}
+
 void FakeGlanceablesTasksClient::PopulateTasks(base::Time tasks_due_time) {
   task_lists_ = std::make_unique<ui::ListModel<GlanceablesTaskList>>();
 
diff --git a/ash/glanceables/tasks/fake_glanceables_tasks_client.h b/ash/glanceables/tasks/fake_glanceables_tasks_client.h
index 87364a4..7f1ab3c 100644
--- a/ash/glanceables/tasks/fake_glanceables_tasks_client.h
+++ b/ash/glanceables/tasks/fake_glanceables_tasks_client.h
@@ -51,6 +51,9 @@
   // Runs `pending_get_tasks_callbacks_` and returns their number.
   size_t RunPendingGetTasksCallbacks();
 
+  // Runs `pending_get_task_lists_callbacks_` and returns their number.
+  size_t RunPendingGetTaskListsCallbacks();
+
   void set_paused(bool paused) { paused_ = paused; }
 
  private:
@@ -75,6 +78,7 @@
   // `RunPending**Callbacks()` is called.
   bool paused_ = false;
   std::list<base::OnceClosure> pending_get_tasks_callbacks_;
+  std::list<base::OnceClosure> pending_get_task_lists_callbacks_;
 };
 
 }  // namespace ash
diff --git a/ash/shelf/drag_window_from_shelf_controller_unittest.cc b/ash/shelf/drag_window_from_shelf_controller_unittest.cc
index 3e6004a..3400a0f 100644
--- a/ash/shelf/drag_window_from_shelf_controller_unittest.cc
+++ b/ash/shelf/drag_window_from_shelf_controller_unittest.cc
@@ -640,7 +640,7 @@
   OverviewGrid* current_grid =
       overview_controller->overview_session()->GetGridWithRootWindow(
           window1->GetRootWindow());
-  OverviewItem* drop_target_item = current_grid->GetDropTarget();
+  auto* drop_target_item = current_grid->GetDropTarget();
   EXPECT_TRUE(drop_target_item);
   EXPECT_EQ(drop_target_item->GetWindow()->layer()->GetTargetOpacity(), 1.f);
 
@@ -1213,7 +1213,7 @@
   // Get the bounds and transform of the item associated with |item2|.
   OverviewController* overview_controller = Shell::Get()->overview_controller();
   ASSERT_TRUE(overview_controller->InOverviewSession());
-  OverviewItem* item = GetOverviewItemForWindow(window2.get());
+  auto* item = GetOverviewItemForWindow(window2.get());
   ASSERT_TRUE(item);
   aura::Window* item_window = item->item_widget()->GetNativeWindow();
   const gfx::Rect pre_exit_bounds = item_window->bounds();
@@ -1328,7 +1328,7 @@
   EXPECT_TRUE(overview_grid);
   ASSERT_EQ(1u, overview_grid->window_list().size());
 
-  OverviewItem* overview_item = overview_grid->window_list()[0].get();
+  auto* overview_item = overview_grid->window_list()[0].get();
 
   // Press on `overview_item` to exit overview mode and show windows.
   auto* event_generator = GetEventGenerator();
diff --git a/ash/system/holding_space/holding_space_tray_unittest.cc b/ash/system/holding_space/holding_space_tray_unittest.cc
index 646281a..424ec311 100644
--- a/ash/system/holding_space/holding_space_tray_unittest.cc
+++ b/ash/system/holding_space/holding_space_tray_unittest.cc
@@ -2309,11 +2309,14 @@
 
   // Tap the test window preview within the overview UI, and tap it to exit
   // overview.
-  OverviewItem* overview_item =
-      Shell::Get()
-          ->overview_controller()
-          ->overview_session()
-          ->GetOverviewItemForWindow(widget->GetNativeWindow());
+  auto* overview_session =
+      Shell::Get()->overview_controller()->overview_session();
+  ASSERT_TRUE(overview_session);
+  auto* window = widget->GetNativeWindow();
+  auto* overview_item =
+      overview_session->GetOverviewItemForWindow(window)->GetLeafItemForWindow(
+          window);
+
   GetEventGenerator()->GestureTapAt(overview_item->overview_item_view()
                                         ->preview_view()
                                         ->GetBoundsInScreen()
diff --git a/ash/system/privacy_hub/camera_privacy_switch_controller_unittest.cc b/ash/system/privacy_hub/camera_privacy_switch_controller_unittest.cc
index 3a268bc..c8c696b 100644
--- a/ash/system/privacy_hub/camera_privacy_switch_controller_unittest.cc
+++ b/ash/system/privacy_hub/camera_privacy_switch_controller_unittest.cc
@@ -114,15 +114,43 @@
 
 }  // namespace
 
-class PrivacyHubCameraControllerTestBase : public AshTestBase {
+class PrivacyHubCameraTestBase
+    : public AshTestBase,
+      public testing::WithParamInterface<std::tuple<bool, bool, bool>> {
  public:
-  PrivacyHubCameraControllerTestBase()
+  PrivacyHubCameraTestBase()
       : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
-    scoped_feature_list_.InitAndEnableFeature(ash::features::kCrosPrivacyHub);
+    std::vector<base::test::FeatureRef> enabled_features;
+    std::vector<base::test::FeatureRef> disabled_features;
+    if (IsPrivacyHubEnabled()) {
+      enabled_features.push_back(ash::features::kCrosPrivacyHub);
+    } else {
+      disabled_features.push_back(ash::features::kCrosPrivacyHub);
+    }
+    if (IsPrivacyIndicatorsEnabled()) {
+      enabled_features.push_back(features::kPrivacyIndicators);
+    } else {
+      disabled_features.push_back(features::kPrivacyIndicators);
+    }
+    if (IsVideoConferenceEnabled()) {
+      fake_video_conference_tray_controller_ =
+          std::make_unique<FakeVideoConferenceTrayController>();
+      enabled_features.push_back(features::kVideoConference);
+      enabled_features.push_back(features::kCameraEffectsSupportedByHardware);
+    } else {
+      disabled_features.push_back(features::kVideoConference);
+      disabled_features.push_back(features::kCameraEffectsSupportedByHardware);
+    }
+    scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
   }
 
-  ~PrivacyHubCameraControllerTestBase() override = default;
+  ~PrivacyHubCameraTestBase() override {
+    fake_video_conference_tray_controller_.reset();
+  }
 
+  CameraPrivacySwitchSynchronizer* Synchronizer() {
+    return PrivacyHubController::Get()->CameraSynchronizerForTest();
+  }
   // AshTestBase:
   void SetUp() override {
     AshTestBase::SetUp();
@@ -130,13 +158,15 @@
     auto mock_switch = std::make_unique<::testing::NiceMock<MockSwitchAPI>>();
     mock_switch_ = mock_switch.get();
 
-    controller_ = CameraPrivacySwitchController::Get();
-    controller_->SetCameraPrivacySwitchAPIForTest(std::move(mock_switch));
+    Synchronizer()->SetCameraPrivacySwitchAPIForTest(std::move(mock_switch));
 
-    // Set up the fake `SensorDisabledNotificationDelegate`.
-    scoped_delegate_ =
-        std::make_unique<ScopedSensorDisabledNotificationDelegateForTest>(
-            std::make_unique<FakeSensorDisabledNotificationDelegate>());
+    if (IsPrivacyHubEnabled()) {
+      // Set up the fake `SensorDisabledNotificationDelegate`.
+      // In production it is set only if Privacy Hub is enabled.
+      scoped_delegate_ =
+          std::make_unique<ScopedSensorDisabledNotificationDelegateForTest>(
+              std::make_unique<FakeSensorDisabledNotificationDelegate>());
+    }
   }
 
   void TearDown() override {
@@ -145,6 +175,10 @@
     AshTestBase::TearDown();
   }
 
+  bool IsPrivacyIndicatorsEnabled() { return std::get<0>(GetParam()); }
+  bool IsVideoConferenceEnabled() { return std::get<1>(GetParam()); }
+  bool IsPrivacyHubEnabled() { return std::get<2>(GetParam()); }
+
   void SetUserPref(bool allowed) {
     Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean(
         prefs::kUserCameraAllowed, allowed);
@@ -157,6 +191,113 @@
         ->GetBoolean(prefs::kUserCameraAllowed);
   }
 
+ protected:
+  raw_ptr<::testing::NiceMock<MockSwitchAPI>,
+          DanglingUntriaged | ExperimentalAsh>
+      mock_switch_;
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+  std::unique_ptr<ScopedSensorDisabledNotificationDelegateForTest>
+      scoped_delegate_;
+
+  std::unique_ptr<FakeVideoConferenceTrayController>
+      fake_video_conference_tray_controller_;
+};
+
+using PrivacyHubCameraSynchronizerTest = PrivacyHubCameraTestBase;
+
+// Test reaction on user pref change (e.g. in UI).
+TEST_P(PrivacyHubCameraSynchronizerTest, UserPrefChange) {
+  const std::vector<bool> user_pref_sequence{false, true, true, false, true};
+  const int number_of_changes = [&]() {
+    int cnt = 0;
+    bool current_val = true;  // default value for camera-enabled is true
+    for (const bool pref_val : user_pref_sequence) {
+      if (pref_val != current_val) {
+        ++cnt;
+        current_val = pref_val;
+      }
+    }
+    return cnt;
+  }();
+
+  CameraSWPrivacySwitchSetting captured_val;
+  EXPECT_CALL(*mock_switch_, SetCameraSWPrivacySwitch(_))
+      .Times(number_of_changes)
+      .WillRepeatedly(testing::SaveArg<0>(&captured_val));
+
+  for (const bool pref_val : user_pref_sequence) {
+    SetUserPref(pref_val);
+    // User toggle ON means the camera is DISABLED.
+    CameraSWPrivacySwitchSetting expected_val =
+        pref_val ? CameraSWPrivacySwitchSetting::kEnabled
+                 : CameraSWPrivacySwitchSetting::kDisabled;
+    if (!IsPrivacyHubEnabled() && !IsVideoConferenceEnabled()) {
+      // If both VC and PrivacyHub features are off, the camera will always be
+      // re-enabled
+      expected_val = CameraSWPrivacySwitchSetting::kEnabled;
+    }
+    EXPECT_EQ(captured_val, expected_val);
+  }
+}
+
+TEST_P(PrivacyHubCameraSynchronizerTest, OnCameraSoftwarePrivacySwitchChanged) {
+  // When `prefs::kUserCameraAllowed` is true and CrOS Camera Service
+  // communicates the SW privacy switch state as UNKNOWN or ON, the states
+  // mismatch and `SetCameraSWPrivacySwitch(kEnabled)` should be called to
+  // correct the mismatch.
+  EXPECT_CALL(*mock_switch_,
+              SetCameraSWPrivacySwitch(CameraSWPrivacySwitchSetting::kEnabled))
+      .Times(::testing::Exactly(3));
+  SetUserPref(true);
+  Synchronizer()->OnCameraSWPrivacySwitchStateChanged(
+      cros::mojom::CameraPrivacySwitchState::UNKNOWN);
+  Synchronizer()->OnCameraSWPrivacySwitchStateChanged(
+      cros::mojom::CameraPrivacySwitchState::ON);
+
+  if (IsPrivacyHubEnabled() || IsVideoConferenceEnabled()) {
+    // When `prefs::kUserCameraAllowed` is false and CrOS Camera Service
+    // communicates the SW privacy switch state as UNKNOWN or OFF, the states
+    // mismatch and `SetCameraSWPrivacySwitch(kDisabled)` should be called to
+    // correct the mismatch.
+    EXPECT_CALL(*mock_switch_, SetCameraSWPrivacySwitch(
+                                   CameraSWPrivacySwitchSetting::kDisabled))
+        .Times(::testing::Exactly(3));
+    SetUserPref(false);
+    Synchronizer()->OnCameraSWPrivacySwitchStateChanged(
+        cros::mojom::CameraPrivacySwitchState::UNKNOWN);
+    Synchronizer()->OnCameraSWPrivacySwitchStateChanged(
+        cros::mojom::CameraPrivacySwitchState::OFF);
+
+    // When the SW privacy switch states match in Privacy Hub and CrOS Camera
+    // Service, `SetCameraSWPrivacySwitch()` should not be called.
+    EXPECT_CALL(*mock_switch_, SetCameraSWPrivacySwitch(_))
+        .Times(::testing::Exactly(2));
+
+    // When `prefs::kUserCameraAllowed` is true and CrOS Camera Service
+    // communicates the SW privacy switch state as OFF, the states match and
+    // `SetCameraSWPrivacySwitch()` should not be called.
+    SetUserPref(true);
+    Synchronizer()->OnCameraSWPrivacySwitchStateChanged(
+        cros::mojom::CameraPrivacySwitchState::OFF);
+
+    // When `prefs::kUserCameraAllowed` is false and CrOS Camera Service
+    // communicates the SW privacy switch state as ON, the states match and
+    // `SetCameraSWPrivacySwitch()` should not be called.
+    SetUserPref(false);
+    Synchronizer()->OnCameraSWPrivacySwitchStateChanged(
+        cros::mojom::CameraPrivacySwitchState::ON);
+  }
+}
+
+class NotificationTestBase : public PrivacyHubCameraTestBase {
+ public:
+  void SetUp() override {
+    PrivacyHubCameraTestBase::SetUp();
+    controller_ = CameraPrivacySwitchController::Get();
+  }
+
   void LaunchAppAccessingCamera(const std::u16string& app_name) {
     delegate()->LaunchAppAccessingCamera(app_name);
     controller_->ActiveApplicationsChanged(/*application_added=*/true);
@@ -178,130 +319,12 @@
             ->sensor_disabled_notification_delegate());
   }
 
-  raw_ptr<::testing::NiceMock<MockSwitchAPI>,
-          DanglingUntriaged | ExperimentalAsh>
-      mock_switch_;
-
   raw_ptr<CameraPrivacySwitchController, DanglingUntriaged | ExperimentalAsh>
       controller_;
-  base::test::ScopedFeatureList scoped_feature_list_;
   const base::HistogramTester histogram_tester_;
-  std::unique_ptr<ScopedSensorDisabledNotificationDelegateForTest>
-      scoped_delegate_;
 };
 
-class PrivacyHubCameraControllerTest
-    : public PrivacyHubCameraControllerTestBase,
-      public testing::WithParamInterface<std::tuple<bool, bool>> {
- protected:
-  PrivacyHubCameraControllerTest() {
-    std::vector<base::test::FeatureRef> enabled_features{};
-    if (IsPrivacyIndicatorsEnabled()) {
-      enabled_features.push_back(features::kPrivacyIndicators);
-    }
-    if (IsVideoConferenceEnabled()) {
-      fake_video_conference_tray_controller_ =
-          std::make_unique<FakeVideoConferenceTrayController>();
-      enabled_features.push_back(features::kVideoConference);
-      enabled_features.push_back(features::kCameraEffectsSupportedByHardware);
-    }
-    scoped_feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
-    scoped_feature_list_->InitWithFeatures(enabled_features, {});
-  }
-
-  ~PrivacyHubCameraControllerTest() override {
-    fake_video_conference_tray_controller_.reset();
-  }
-
-  bool IsPrivacyIndicatorsEnabled() { return std::get<0>(GetParam()); }
-
-  bool IsVideoConferenceEnabled() { return std::get<1>(GetParam()); }
-
-  std::unique_ptr<FakeVideoConferenceTrayController>
-      fake_video_conference_tray_controller_;
-
-  std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
-};
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         PrivacyHubCameraControllerTest,
-                         testing::Combine(testing::Bool(), testing::Bool()));
-// Test reaction on UI action.
-TEST_P(PrivacyHubCameraControllerTest, UIAction) {
-  const std::vector<bool> user_pref_sequence{false, true, true, false, true};
-  const int number_of_changes = [&]() {
-    int cnt = 0;
-    bool current_val = true;  // default value for camera-enabled is true
-    for (const bool pref_val : user_pref_sequence) {
-      if (pref_val != current_val) {
-        ++cnt;
-        current_val = pref_val;
-      }
-    }
-    return cnt;
-  }();
-
-  CameraSWPrivacySwitchSetting captured_val;
-  EXPECT_CALL(*mock_switch_, SetCameraSWPrivacySwitch(_))
-      .Times(number_of_changes)
-      .WillRepeatedly(testing::SaveArg<0>(&captured_val));
-
-  for (const bool pref_val : user_pref_sequence) {
-    SetUserPref(pref_val);
-    // User toggle ON means the camera is DISABLED.
-    const CameraSWPrivacySwitchSetting expected_val =
-        pref_val ? CameraSWPrivacySwitchSetting::kEnabled
-                 : CameraSWPrivacySwitchSetting::kDisabled;
-    EXPECT_EQ(captured_val, expected_val);
-  }
-}
-
-TEST_P(PrivacyHubCameraControllerTest, OnCameraSoftwarePrivacySwitchChanged) {
-  // When |prefs::kUserCameraAllowed| is true and CrOS Camera Service
-  // communicates the SW privacy switch state as UNKNOWN or ON, the states
-  // mismatch and SetCameraSWPrivacySwitch(kEnabled) should be called to correct
-  // the mismatch.
-  EXPECT_CALL(*mock_switch_,
-              SetCameraSWPrivacySwitch(CameraSWPrivacySwitchSetting::kEnabled))
-      .Times(::testing::Exactly(3));
-  SetUserPref(true);
-  controller_->OnCameraSWPrivacySwitchStateChanged(
-      cros::mojom::CameraPrivacySwitchState::UNKNOWN);
-  controller_->OnCameraSWPrivacySwitchStateChanged(
-      cros::mojom::CameraPrivacySwitchState::ON);
-
-  // When |prefs::kUserCameraAllowed| is false and CrOS Camera Service
-  // communicates the SW privacy switch state as UNKNOWN or OFF, the states
-  // mismatch and SetCameraSWPrivacySwitch(kDisabled) should be called to
-  // correct the mismatch.
-  EXPECT_CALL(*mock_switch_,
-              SetCameraSWPrivacySwitch(CameraSWPrivacySwitchSetting::kDisabled))
-      .Times(::testing::Exactly(3));
-  SetUserPref(false);
-  controller_->OnCameraSWPrivacySwitchStateChanged(
-      cros::mojom::CameraPrivacySwitchState::UNKNOWN);
-  controller_->OnCameraSWPrivacySwitchStateChanged(
-      cros::mojom::CameraPrivacySwitchState::OFF);
-
-  // When the SW privacy switch states match in Privacy Hub and CrOS Camera
-  // Service, SetCameraSWPrivacySwitch() should not be called.
-  EXPECT_CALL(*mock_switch_, SetCameraSWPrivacySwitch(_))
-      .Times(::testing::Exactly(2));
-
-  // When |prefs::kUserCameraAllowed| is true and CrOS Camera Service
-  // communicates the SW privacy switch state as OFF, the states match and
-  // SetCameraSWPrivacySwitch() should not be called.
-  SetUserPref(true);
-  controller_->OnCameraSWPrivacySwitchStateChanged(
-      cros::mojom::CameraPrivacySwitchState::OFF);
-
-  // When |prefs::kUserCameraAllowed| is false and CrOS Camera Service
-  // communicates the SW privacy switch state as ON, the states match and
-  // SetCameraSWPrivacySwitch() should not be called.
-  SetUserPref(false);
-  controller_->OnCameraSWPrivacySwitchStateChanged(
-      cros::mojom::CameraPrivacySwitchState::ON);
-}
+class PrivacyHubCameraControllerTest : public NotificationTestBase {};
 
 TEST_P(PrivacyHubCameraControllerTest,
        OnCameraHardwarePrivacySwitchChangedMultipleCameras) {
@@ -705,39 +728,7 @@
 }
 
 class PrivacyIndicatorAndVideoConferenceCameraControllerTest
-    : public PrivacyHubCameraControllerTestBase,
-      public testing::WithParamInterface<std::tuple<bool, bool>> {
- public:
-  PrivacyIndicatorAndVideoConferenceCameraControllerTest() {
-    std::vector<base::test::FeatureRef> enabled_features{
-        ash::features::kCrosPrivacyHub};
-    if (IsPrivacyIndicatorsEnabled()) {
-      enabled_features.push_back(features::kPrivacyIndicators);
-    }
-    if (IsVideoConferenceEnabled()) {
-      fake_video_conference_tray_controller_ =
-          std::make_unique<FakeVideoConferenceTrayController>();
-      enabled_features.push_back(features::kVideoConference);
-      enabled_features.push_back(features::kCameraEffectsSupportedByHardware);
-    }
-    scoped_feature_list_.InitWithFeatures(enabled_features, {});
-  }
-  ~PrivacyIndicatorAndVideoConferenceCameraControllerTest() override {
-    fake_video_conference_tray_controller_.reset();
-  }
-
-  bool IsPrivacyIndicatorsEnabled() { return std::get<0>(GetParam()); }
-
-  bool IsVideoConferenceEnabled() { return std::get<1>(GetParam()); }
-
-  std::unique_ptr<FakeVideoConferenceTrayController>
-      fake_video_conference_tray_controller_;
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-INSTANTIATE_TEST_SUITE_P(All,
-                         PrivacyIndicatorAndVideoConferenceCameraControllerTest,
-                         testing::Combine(testing::Bool(), testing::Bool()));
+    : public NotificationTestBase {};
 
 // With VcControls or Privacy Indicators enabled, tests that no notification
 // shows up if the switches are toggled when the number of capturing apps does
@@ -904,4 +895,25 @@
   }
 }
 
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    PrivacyHubCameraSynchronizerTest,
+    testing::Combine(/*IsPrivacyIndicatorsEnabled=*/testing::Bool(),
+                     /*IsVideoConferenceEnabled=*/testing::Bool(),
+                     /*IsPrivacyHubEnabled()=*/testing::Bool()));
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    PrivacyHubCameraControllerTest,
+    testing::Combine(/*IsPrivacyIndicatorsEnabled=*/testing::Bool(),
+                     /*IsVideoConferenceEnabled=*/testing::Bool(),
+                     /*IsPrivacyHubEnabled()=*/testing::Values(true)));
+
+INSTANTIATE_TEST_SUITE_P(
+    All,
+    PrivacyIndicatorAndVideoConferenceCameraControllerTest,
+    testing::Combine(/*IsPrivacyIndicatorsEnabled=*/testing::Bool(),
+                     /*IsVideoConferenceEnabled=*/testing::Bool(),
+                     /*IsPrivacyHubEnabled()=*/testing::Values(true)));
+
 }  // namespace ash
diff --git a/ash/system/privacy_hub/privacy_hub_controller.cc b/ash/system/privacy_hub/privacy_hub_controller.cc
index 89a5fef..3d70bfa 100644
--- a/ash/system/privacy_hub/privacy_hub_controller.cc
+++ b/ash/system/privacy_hub/privacy_hub_controller.cc
@@ -140,6 +140,14 @@
   return (file_size != 0ll);
 }
 
+CameraPrivacySwitchSynchronizer*
+PrivacyHubController::CameraSynchronizerForTest() {
+  return camera_controller() ? static_cast<CameraPrivacySwitchSynchronizer*>(
+                                   camera_controller())
+                             : static_cast<CameraPrivacySwitchSynchronizer*>(
+                                   camera_disabled_.get());
+}
+
 ScopedLedFallbackForTesting::ScopedLedFallbackForTesting(bool value)
     : value(value) {
   CHECK(!g_scoped_led_fallback_for_testing);
diff --git a/ash/system/privacy_hub/privacy_hub_controller.h b/ash/system/privacy_hub/privacy_hub_controller.h
index 5f2c528d..28de19cc 100644
--- a/ash/system/privacy_hub/privacy_hub_controller.h
+++ b/ash/system/privacy_hub/privacy_hub_controller.h
@@ -77,6 +77,8 @@
   // Gets the geolocation controller if available.
   GeolocationPrivacySwitchController* geolocation_controller();
 
+  CameraPrivacySwitchSynchronizer* CameraSynchronizerForTest();
+
   static void RegisterLocalStatePrefs(PrefRegistrySimple* registry);
   static void RegisterProfilePrefs(PrefRegistrySimple* registry);
 
diff --git a/ash/system/time/calendar_event_list_view.cc b/ash/system/time/calendar_event_list_view.cc
index 1066db4..2792d08 100644
--- a/ash/system/time/calendar_event_list_view.cc
+++ b/ash/system/time/calendar_event_list_view.cc
@@ -153,13 +153,13 @@
       features::IsCalendarJellyEnabled() ? kCloseButtonContainerInsetsJelly
                                          : kCloseButtonContainerInsets));
 
-  auto* close_button =
-      new IconButton(views::Button::PressedCallback(base::BindRepeating(
-                         &CalendarViewController::CloseEventListView,
-                         base::Unretained(calendar_view_controller))),
-                     IconButton::Type::kMediumFloating, &views::kIcCloseIcon,
-                     IDS_ASH_CLOSE_BUTTON_ACCESSIBLE_DESCRIPTION);
-  close_button_container_->AddChildView(close_button);
+  close_button_ =
+      close_button_container_->AddChildView(std::make_unique<IconButton>(
+          views::Button::PressedCallback(
+              base::BindRepeating(&CalendarViewController::CloseEventListView,
+                                  base::Unretained(calendar_view_controller))),
+          IconButton::Type::kMediumFloating, &views::kIcCloseIcon,
+          IDS_ASH_CLOSE_BUTTON_ACCESSIBLE_DESCRIPTION));
 
   scroll_view_->SetAllowKeyboardScrolling(false);
   scroll_view_->SetBackgroundColor(absl::nullopt);
@@ -215,6 +215,10 @@
   }
 }
 
+void CalendarEventListView::RequestCloseButtonFocus() {
+  close_button_->RequestFocus();
+}
+
 void CalendarEventListView::OnSelectedDateUpdated() {
   UpdateListItems();
 }
diff --git a/ash/system/time/calendar_event_list_view.h b/ash/system/time/calendar_event_list_view.h
index 6dfe145..91e7c89 100644
--- a/ash/system/time/calendar_event_list_view.h
+++ b/ash/system/time/calendar_event_list_view.h
@@ -15,6 +15,8 @@
 
 namespace ash {
 
+class IconButton;
+
 // This view displays a scrollable list of `CalendarEventListItemView`.
 class ASH_EXPORT CalendarEventListView
     : public CalendarModel::Observer,
@@ -29,6 +31,8 @@
   CalendarEventListView& operator=(const CalendarEventListView& other) = delete;
   ~CalendarEventListView() override;
 
+  void RequestCloseButtonFocus();
+
  private:
   friend class CalendarViewEventListViewTest;
   friend class CalendarViewTest;
@@ -60,6 +64,7 @@
 
   // Owned by `CalendarEventListView`.
   const raw_ptr<views::View, ExperimentalAsh> close_button_container_;
+  raw_ptr<IconButton, ExperimentalAsh> close_button_;
   const raw_ptr<views::ScrollView, ExperimentalAsh> scroll_view_;
 
   // Adds fade in/out gradients to `scroll_view_`.
diff --git a/ash/system/time/calendar_view.cc b/ash/system/time/calendar_view.cc
index 503c193..4ede052 100644
--- a/ash/system/time/calendar_view.cc
+++ b/ash/system/time/calendar_view.cc
@@ -1942,9 +1942,7 @@
 
 void CalendarView::RequestFocusForEventListCloseButton() {
   DCHECK(event_list_view_);
-  auto* focus_manager = GetFocusManager();
-  event_list_view_->RequestFocus();
-  focus_manager->AdvanceFocus(/*reverse=*/false);
+  event_list_view_->RequestCloseButtonFocus();
   current_month_->DisableFocus();
   previous_month_->DisableFocus();
   next_month_->DisableFocus();
diff --git a/ash/system/time/calendar_view_unittest.cc b/ash/system/time/calendar_view_unittest.cc
index f1cc37a..3073d2ee 100644
--- a/ash/system/time/calendar_view_unittest.cc
+++ b/ash/system/time/calendar_view_unittest.cc
@@ -2784,6 +2784,33 @@
   EXPECT_EQ(focus_manager->GetFocusedView(), close_button());
 }
 
+TEST_F(CalendarViewWithJellyEnabledTest,
+       ShouldFocusEventListCloseButton_WhenFocusMovedFromTodayButton) {
+  base::Time date;
+  ASSERT_TRUE(base::Time::FromString("18 Nov 2021 10:00 GMT", &date));
+  // Set time override.
+  SetFakeNow(date);
+  base::subtle::ScopedTimeClockOverrides time_override(
+      &CalendarViewTest::FakeTimeNow, /*time_ticks_override=*/nullptr,
+      /*thread_ticks_override=*/nullptr);
+
+  CreateCalendarView();
+  MockEventsFetched(calendar_utils::GetStartOfMonthUTC(date),
+                    CreateMockEventListWithEventStartTimeTenMinsAway());
+
+  // When fetched events are in the next 10 mins, then up next should have been
+  // created.
+  ASSERT_TRUE(up_next_view());
+
+  auto* focus_manager = calendar_view()->GetFocusManager();
+  reset_to_today_button()->RequestFocus();
+  ASSERT_EQ(reset_to_today_button(), focus_manager->GetFocusedView());
+  GestureTapOn(up_next_todays_events_button());
+
+  ASSERT_TRUE(event_list_view());
+  EXPECT_EQ(focus_manager->GetFocusedView(), close_button());
+}
+
 TEST_F(CalendarViewWithJellyEnabledTest, RecordEventsDisplayedToUserOnce) {
   base::HistogramTester histogram_tester;
   base::Time now;
diff --git a/ash/system/unified/classroom_bubble_base_view.cc b/ash/system/unified/classroom_bubble_base_view.cc
index 9e346dbc..3faf9d9 100644
--- a/ash/system/unified/classroom_bubble_base_view.cc
+++ b/ash/system/unified/classroom_bubble_base_view.cc
@@ -127,6 +127,10 @@
   AnnounceListStateOnComboBoxAccessibility();
 }
 
+void ClassroomBubbleBaseView::CancelUpdates() {
+  weak_ptr_factory_.InvalidateWeakPtrs();
+}
+
 void ClassroomBubbleBaseView::AboutToRequestAssignments() {
   progress_bar_->UpdateProgressBarVisibility(/*visible=*/true);
   combo_box_view_->SetAccessibleDescription(u"");
diff --git a/ash/system/unified/classroom_bubble_base_view.h b/ash/system/unified/classroom_bubble_base_view.h
index 6e1de480..8b27af32 100644
--- a/ash/system/unified/classroom_bubble_base_view.h
+++ b/ash/system/unified/classroom_bubble_base_view.h
@@ -43,6 +43,10 @@
   // views::ViewObserver:
   void OnViewFocused(views::View* view) override;
 
+  // Invalidates any pending assignments requests. Called when the
+  // glanceables bubble widget starts closing to avoid unnecessary UI updates.
+  void CancelUpdates();
+
  protected:
   // Handles press on the "See all" button in `GlanceablesListFooterView`. Opens
   // classroom web UI based on the selected menu option.
diff --git a/ash/system/unified/date_tray_unittest.cc b/ash/system/unified/date_tray_unittest.cc
index 0a67634b..c02d61ab 100644
--- a/ash/system/unified/date_tray_unittest.cc
+++ b/ash/system/unified/date_tray_unittest.cc
@@ -517,6 +517,7 @@
   EXPECT_FALSE(IsBubbleShown());
   EXPECT_FALSE(GetUnifiedSystemTray()->is_active());
   EXPECT_FALSE(GetDateTray()->is_active());
+  base::RunLoop().RunUntilIdle();
   if (AreGlanceablesV2Enabled()) {
     EXPECT_EQ(1,
               fake_glanceables_tasks_client()->GetAndResetBubbleClosedCount());
@@ -530,6 +531,7 @@
   EXPECT_FALSE(IsBubbleShown());
   EXPECT_FALSE(GetUnifiedSystemTray()->is_active());
   EXPECT_FALSE(GetDateTray()->is_active());
+  base::RunLoop().RunUntilIdle();
   if (AreGlanceablesV2Enabled()) {
     EXPECT_EQ(0,
               fake_glanceables_tasks_client()->GetAndResetBubbleClosedCount());
@@ -925,4 +927,70 @@
             new_work_area.height() - new_view_bounds.bottom());
 }
 
+TEST_P(GlanceablesDateTrayTest,
+       BubbleClosedUsingTrayButtonWithPendingTasksRequests) {
+  fake_glanceables_tasks_client()->set_paused(true);
+
+  LeftClickOn(GetDateTray());
+  ASSERT_TRUE(IsBubbleShown());
+  ASSERT_TRUE(GetGlanceableTrayBubble());
+
+  EXPECT_EQ(1u,
+            fake_glanceables_tasks_client()->RunPendingGetTaskListsCallbacks());
+
+  LeftClickOn(GetDateTray());
+
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(IsBubbleShown());
+}
+
+TEST_P(GlanceablesDateTrayTest, TasksListFetchedWhileBubbleClosing) {
+  fake_glanceables_tasks_client()->set_paused(true);
+
+  LeftClickOn(GetDateTray());
+  ASSERT_TRUE(IsBubbleShown());
+  ASSERT_TRUE(GetGlanceableTrayBubble());
+
+  EXPECT_EQ(1u,
+            fake_glanceables_tasks_client()->RunPendingGetTaskListsCallbacks());
+
+  GetGlanceableTrayBubble()->GetBubbleWidget()->Close();
+  EXPECT_EQ(1u, fake_glanceables_tasks_client()->RunPendingGetTasksCallbacks());
+
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(IsBubbleShown());
+}
+
+TEST_P(GlanceablesDateTrayTest, TaskListsFetchedWhileBubbleClosing) {
+  fake_glanceables_tasks_client()->set_paused(true);
+
+  LeftClickOn(GetDateTray());
+  ASSERT_TRUE(IsBubbleShown());
+  ASSERT_TRUE(GetGlanceableTrayBubble());
+
+  GetGlanceableTrayBubble()->GetBubbleWidget()->Close();
+  EXPECT_EQ(1u,
+            fake_glanceables_tasks_client()->RunPendingGetTaskListsCallbacks());
+
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(IsBubbleShown());
+}
+
+TEST_P(GlanceablesDateTrayTest, AssignmentListFetchedWhileBubbleClosing) {
+  LeftClickOn(GetDateTray());
+  ASSERT_TRUE(IsBubbleShown());
+  ASSERT_TRUE(GetGlanceableTrayBubble());
+
+  glanceables_classroom_client()->RespondToPendingIsStudentRoleEnabledCallbacks(
+      /*is_active=*/true);
+
+  GetGlanceableTrayBubble()->GetBubbleWidget()->Close();
+  ASSERT_TRUE(glanceables_classroom_client()
+                  ->RespondToNextPendingStudentAssignmentsCallback(
+                      CreateAssignmentsForTeachers(/*count=*/1)));
+
+  base::RunLoop().RunUntilIdle();
+  EXPECT_FALSE(IsBubbleShown());
+}
+
 }  // namespace ash
diff --git a/ash/system/unified/glanceable_tray_bubble.cc b/ash/system/unified/glanceable_tray_bubble.cc
index 3e2cbbbf..83c3cbd 100644
--- a/ash/system/unified/glanceable_tray_bubble.cc
+++ b/ash/system/unified/glanceable_tray_bubble.cc
@@ -4,9 +4,7 @@
 
 #include "ash/system/unified/glanceable_tray_bubble.h"
 
-#include "ash/glanceables/glanceables_v2_controller.h"
 #include "ash/shelf/shelf.h"
-#include "ash/shell.h"
 #include "ash/system/tray/tray_constants.h"
 #include "ash/system/tray/tray_event_filter.h"
 #include "ash/system/tray/tray_utils.h"
@@ -48,8 +46,6 @@
     bubble_widget_->RemoveObserver(this);
     bubble_widget_->Close();
   }
-
-  Shell::Get()->glanceables_v2_controller()->NotifyGlanceablesBubbleClosed();
 }
 
 void GlanceableTrayBubble::OnWidgetDestroying(views::Widget* widget) {
diff --git a/ash/system/unified/glanceable_tray_bubble_view.cc b/ash/system/unified/glanceable_tray_bubble_view.cc
index 490ed56..2cf10cd 100644
--- a/ash/system/unified/glanceable_tray_bubble_view.cc
+++ b/ash/system/unified/glanceable_tray_bubble_view.cc
@@ -99,7 +99,9 @@
           std::make_unique<DetailedViewDelegate>(/*tray_controller=*/nullptr)) {
 }
 
-GlanceableTrayBubbleView::~GlanceableTrayBubbleView() = default;
+GlanceableTrayBubbleView::~GlanceableTrayBubbleView() {
+  Shell::Get()->glanceables_v2_controller()->NotifyGlanceablesBubbleClosed();
+}
 
 void GlanceableTrayBubbleView::InitializeContents() {
   scroll_view_ = AddChildView(std::make_unique<views::ScrollView>(
@@ -190,6 +192,20 @@
   return true;
 }
 
+void GlanceableTrayBubbleView::OnWidgetClosing(views::Widget* widget) {
+  if (tasks_bubble_view_) {
+    tasks_bubble_view_->CancelUpdates();
+  }
+  if (classroom_bubble_teacher_view_) {
+    classroom_bubble_teacher_view_->CancelUpdates();
+  }
+  if (classroom_bubble_student_view_) {
+    classroom_bubble_student_view_->CancelUpdates();
+  }
+
+  TrayBubbleView::OnWidgetClosing(widget);
+}
+
 void GlanceableTrayBubbleView::OnDisplayConfigurationChanged() {
   int max_height = CalculateMaxTrayBubbleHeight(shelf_->GetWindow());
   SetMaxHeight(max_height);
@@ -220,7 +236,7 @@
 
 void GlanceableTrayBubbleView::OnGlanceablesContainerHeightChanged(
     int height_delta) {
-  if (!IsDrawn()) {
+  if (!IsDrawn() || !GetWidget() || GetWidget()->IsClosed()) {
     return;
   }
 
diff --git a/ash/system/unified/glanceable_tray_bubble_view.h b/ash/system/unified/glanceable_tray_bubble_view.h
index b34048f..81221d5 100644
--- a/ash/system/unified/glanceable_tray_bubble_view.h
+++ b/ash/system/unified/glanceable_tray_bubble_view.h
@@ -40,6 +40,7 @@
 
   // TrayBubbleView:
   bool CanActivate() const override;
+  void OnWidgetClosing(views::Widget* widget) override;
 
   // ScreenLayoutObserver:
   void OnDisplayConfigurationChanged() override;
diff --git a/ash/system/unified/tasks_bubble_view.cc b/ash/system/unified/tasks_bubble_view.cc
index 6e90be8c..b59c7ae 100644
--- a/ash/system/unified/tasks_bubble_view.cc
+++ b/ash/system/unified/tasks_bubble_view.cc
@@ -69,6 +69,10 @@
   AnnounceListStateOnComboBoxAccessibility();
 }
 
+void TasksBubbleView::CancelUpdates() {
+  weak_ptr_factory_.InvalidateWeakPtrs();
+}
+
 void TasksBubbleView::InitViews(ui::ListModel<GlanceablesTaskList>* task_list) {
   // TODO(b:277268122): Implement empty tasks glanceable state.
   if (task_list->item_count() == 0) {
diff --git a/ash/system/unified/tasks_bubble_view.h b/ash/system/unified/tasks_bubble_view.h
index 928eb09..0888af54 100644
--- a/ash/system/unified/tasks_bubble_view.h
+++ b/ash/system/unified/tasks_bubble_view.h
@@ -81,6 +81,10 @@
   // views::ViewObserver:
   void OnViewFocused(views::View* view) override;
 
+  // Invalidates any pending tasks, or tasks lists requests. Called when the
+  // glanceables bubble widget starts closing to avoid unnecessary UI updates.
+  void CancelUpdates();
+
  private:
   // Setup child views.
   void InitViews(ui::ListModel<GlanceablesTaskList>* task_list);
diff --git a/ash/utility/haptics_util_unittest.cc b/ash/utility/haptics_util_unittest.cc
index 2ddb7dc..f6be85a 100644
--- a/ash/utility/haptics_util_unittest.cc
+++ b/ash/utility/haptics_util_unittest.cc
@@ -143,7 +143,7 @@
   for (size_t i = 0; i < test_cases.size(); i++) {
     std::pair<gfx::Point, gfx::Rect> test_case = test_cases[i];
     EnterOverview();
-    OverviewItem* overview_item =
+    auto* overview_item =
         overview_controller->overview_session()->GetOverviewItemForWindow(
             window.get());
 
@@ -164,7 +164,7 @@
   for (size_t i = 0; i < test_cases.size(); i++) {
     std::pair<gfx::Point, gfx::Rect> test_case = test_cases[i];
     EnterOverview();
-    OverviewItem* overview_item =
+    auto* overview_item =
         overview_controller->overview_session()->GetOverviewItemForWindow(
             window.get());
 
@@ -300,7 +300,7 @@
 
   // Drag a window in overview. Test that kTick feedback is sent.
   EnterOverview();
-  OverviewItem* overview_item =
+  auto* overview_item =
       overview_controller->overview_session()->GetOverviewItemForWindow(
           window.get());
   const gfx::RectF bounds_f = overview_item->target_bounds();
diff --git a/ash/wallpaper/wallpaper_metrics_manager.cc b/ash/wallpaper/wallpaper_metrics_manager.cc
index 0a0d641..1049368 100644
--- a/ash/wallpaper/wallpaper_metrics_manager.cc
+++ b/ash/wallpaper/wallpaper_metrics_manager.cc
@@ -57,6 +57,8 @@
     const std::string& collection_id = params.collection_id;
     DCHECK(!collection_id.empty());
     const int collection_id_hash = base::PersistentHash(collection_id);
+    DVLOG(3) << __PRETTY_FUNCTION__ << " collection_id=" << collection_id
+             << " hash=" << collection_id_hash;
     base::UmaHistogramSparse("Ash.Wallpaper.Collection", collection_id_hash);
   }
 }
diff --git a/ash/webui/common/resources/post_message_api/post_message_api_request_handler.d.ts b/ash/webui/common/resources/post_message_api/post_message_api_request_handler.d.ts
index 4b3326f..cc35662a3 100644
--- a/ash/webui/common/resources/post_message_api/post_message_api_request_handler.d.ts
+++ b/ash/webui/common/resources/post_message_api/post_message_api_request_handler.d.ts
@@ -10,7 +10,8 @@
 /** Handler for requests that come to the window containing the contents. */
 export class RequestHandler {
   constructor(
-      clientElement: Element, messageOriginUrlFilter: string, targetUrl: URL);
+      clientElement: Element, messageOriginUrlFilter: string,
+      targetUrl: string);
 
   /** Returns the target url that this request handler is communicating with. */
   targetUrl(): URL;
diff --git a/ash/webui/common/resources/post_message_api/post_message_api_server.d.ts b/ash/webui/common/resources/post_message_api/post_message_api_server.d.ts
index 98ba096..fc2b883c 100644
--- a/ash/webui/common/resources/post_message_api/post_message_api_server.d.ts
+++ b/ash/webui/common/resources/post_message_api/post_message_api_server.d.ts
@@ -16,7 +16,8 @@
  */
 export class PostMessageApiServer extends RequestHandler {
   constructor(
-      clientElement: Element, targetUrl: URL, messageOriginUrlFilter: string);
+      clientElement: Element, targetUrl: string,
+      messageOriginUrlFilter: string);
 
   /** Send initialization message to client element. */
   initialize(): void;
diff --git a/ash/webui/shortcut_customization_ui/backend/search/fake_search_data.cc b/ash/webui/shortcut_customization_ui/backend/search/fake_search_data.cc
index ad6d0efc..d6ba706 100644
--- a/ash/webui/shortcut_customization_ui/backend/search/fake_search_data.cc
+++ b/ash/webui/shortcut_customization_ui/backend/search/fake_search_data.cc
@@ -13,10 +13,11 @@
 
 namespace ash::shortcut_ui::fake_search_data {
 
-ash::mojom::AcceleratorInfoPtr CreateFakeStandardAcceleratorInfo() {
+ash::mojom::AcceleratorInfoPtr CreateFakeStandardAcceleratorInfo(
+    ash::mojom::AcceleratorState state) {
   return ash::mojom::AcceleratorInfo::New(
       /*type=*/ash::mojom::AcceleratorType::kDefault,
-      /*state=*/ash::mojom::AcceleratorState::kEnabled,
+      /*state=*/state,
       /*locked=*/true,
       /*layout_properties=*/
       ash::mojom::LayoutStyleProperties::NewStandardAccelerator(
@@ -24,9 +25,10 @@
               ui::Accelerator(), u"FakeKey", absl::nullopt)));
 }
 
-std::vector<ash::mojom::AcceleratorInfoPtr> CreateFakeAcceleratorInfoList() {
+std::vector<ash::mojom::AcceleratorInfoPtr> CreateFakeAcceleratorInfoList(
+    ash::mojom::AcceleratorState state) {
   std::vector<ash::mojom::AcceleratorInfoPtr> accelerator_info_list;
-  accelerator_info_list.push_back(CreateFakeStandardAcceleratorInfo());
+  accelerator_info_list.push_back(CreateFakeStandardAcceleratorInfo(state));
   return accelerator_info_list;
 }
 
diff --git a/ash/webui/shortcut_customization_ui/backend/search/fake_search_data.h b/ash/webui/shortcut_customization_ui/backend/search/fake_search_data.h
index 122fe6a..0fa82387 100644
--- a/ash/webui/shortcut_customization_ui/backend/search/fake_search_data.h
+++ b/ash/webui/shortcut_customization_ui/backend/search/fake_search_data.h
@@ -16,9 +16,13 @@
 
 enum FakeActionIds { kAction1 = 1, kAction2 = 2, kAction3 = 3, kAction4 = 4 };
 
-ash::mojom::AcceleratorInfoPtr CreateFakeStandardAcceleratorInfo();
+ash::mojom::AcceleratorInfoPtr CreateFakeStandardAcceleratorInfo(
+    ash::mojom::AcceleratorState state);
 
-std::vector<ash::mojom::AcceleratorInfoPtr> CreateFakeAcceleratorInfoList();
+// Default state is kEnabled.
+std::vector<ash::mojom::AcceleratorInfoPtr> CreateFakeAcceleratorInfoList(
+    ash::mojom::AcceleratorState state =
+        ash::mojom::AcceleratorState::kEnabled);
 
 ash::mojom::AcceleratorLayoutInfoPtr CreateFakeAcceleratorLayoutInfo(
     const std::u16string& description,
diff --git a/ash/webui/shortcut_customization_ui/shortcuts_app_manager.cc b/ash/webui/shortcut_customization_ui/shortcuts_app_manager.cc
index c53f5bc..f5b97237 100644
--- a/ash/webui/shortcut_customization_ui/shortcuts_app_manager.cc
+++ b/ash/webui/shortcut_customization_ui/shortcuts_app_manager.cc
@@ -80,8 +80,20 @@
       if (const auto& map_iterator =
               config_iterator->second.find(layout_info->action);
           map_iterator != config_iterator->second.end()) {
-        search_concepts.emplace_back(std::move(layout_info),
-                                     std::move(map_iterator->second));
+        // Filter accelerators that state is 'kDisabledByUser' from
+        // map_iterator->second
+        auto& accelerators = map_iterator->second;
+        accelerators.erase(
+            std::remove_if(accelerators.begin(), accelerators.end(),
+                           [](const auto& accel_ptr) {
+                             return accel_ptr->state ==
+                                    mojom::AcceleratorState::kDisabledByUser;
+                           }),
+            accelerators.end());
+        if (!accelerators.empty()) {
+          search_concepts.emplace_back(std::move(layout_info),
+                                       std::move(accelerators));
+        }
       }
     }
   }
diff --git a/ash/webui/shortcut_customization_ui/shortcuts_app_manager_unittest.cc b/ash/webui/shortcut_customization_ui/shortcuts_app_manager_unittest.cc
index c45d970..c7d50e7 100644
--- a/ash/webui/shortcut_customization_ui/shortcuts_app_manager_unittest.cc
+++ b/ash/webui/shortcut_customization_ui/shortcuts_app_manager_unittest.cc
@@ -84,13 +84,16 @@
   AcceleratorConfigurationProvider::ActionIdToAcceleratorsInfoMap ash_info_map;
   ash_info_map.insert({fake_search_data::FakeActionIds::kAction1,
                        fake_search_data::CreateFakeAcceleratorInfoList()});
+  ash_info_map.insert({fake_search_data::FakeActionIds::kAction2,
+                       fake_search_data::CreateFakeAcceleratorInfoList(
+                           ash::mojom::AcceleratorState::kDisabledByUser)});
 
   AcceleratorConfigurationProvider::ActionIdToAcceleratorsInfoMap
       browser_info_map;
-  browser_info_map.insert({fake_search_data::FakeActionIds::kAction2,
-                           fake_search_data::CreateFakeAcceleratorInfoList()});
   browser_info_map.insert({fake_search_data::FakeActionIds::kAction3,
                            fake_search_data::CreateFakeAcceleratorInfoList()});
+  browser_info_map.insert({fake_search_data::FakeActionIds::kAction4,
+                           fake_search_data::CreateFakeAcceleratorInfoList()});
 
   // Create the fake config.
   shortcut_ui::AcceleratorConfigurationProvider::AcceleratorConfigurationMap
@@ -106,13 +109,17 @@
       fake_search_data::FakeActionIds::kAction1,
       ash::mojom::AcceleratorLayoutStyle::kDefault));
   fake_layout_infos.push_back(fake_search_data::CreateFakeAcceleratorLayoutInfo(
-      u"Open new tab", ash::mojom::AcceleratorSource::kBrowser,
+      u"Open/close calendar", ash::mojom::AcceleratorSource::kAsh,
       fake_search_data::FakeActionIds::kAction2,
       ash::mojom::AcceleratorLayoutStyle::kDefault));
   fake_layout_infos.push_back(fake_search_data::CreateFakeAcceleratorLayoutInfo(
-      u"Close tab", ash::mojom::AcceleratorSource::kBrowser,
+      u"Open new tab", ash::mojom::AcceleratorSource::kBrowser,
       fake_search_data::FakeActionIds::kAction3,
       ash::mojom::AcceleratorLayoutStyle::kDefault));
+  fake_layout_infos.push_back(fake_search_data::CreateFakeAcceleratorLayoutInfo(
+      u"Close tab", ash::mojom::AcceleratorSource::kBrowser,
+      fake_search_data::FakeActionIds::kAction4,
+      ash::mojom::AcceleratorLayoutStyle::kDefault));
 
   auto& registry_search_concepts =
       manager_->search_concept_registry_.get()->result_id_to_search_concept_;
@@ -127,7 +134,10 @@
                               std::move(fake_layout_infos));
   base::RunLoop().RunUntilIdle();
 
+  // Test that disabled accelerator info are filtered out.
   EXPECT_EQ(registry_search_concepts.size(), 3u);
+  EXPECT_FALSE(registry_search_concepts.contains("0-2"));
+
   // Test that the expected search concepts are present and check a few
   // attributes to be sure.
   ValidateSearchConceptById(/*search_concepts_map=*/registry_search_concepts,
@@ -136,14 +146,14 @@
                             /*expected_action=*/fake_search_data::kAction1);
   ValidateSearchConceptById(
       /*search_concepts_map=*/registry_search_concepts,
-      /*search_concept_id=*/"2-2",
-      /*expected_source=*/mojom::AcceleratorSource::kBrowser,
-      /*expected_action=*/fake_search_data::kAction2);
-  ValidateSearchConceptById(
-      /*search_concepts_map=*/registry_search_concepts,
       /*search_concept_id=*/"2-3",
       /*expected_source=*/mojom::AcceleratorSource::kBrowser,
       /*expected_action=*/fake_search_data::kAction3);
+  ValidateSearchConceptById(
+      /*search_concepts_map=*/registry_search_concepts,
+      /*search_concept_id=*/"2-4",
+      /*expected_source=*/mojom::AcceleratorSource::kBrowser,
+      /*expected_action=*/fake_search_data::kAction4);
 }
 
 }  // namespace ash::shortcut_ui
diff --git a/ash/wm/desks/desk_mini_view_animations.cc b/ash/wm/desks/desk_mini_view_animations.cc
index d553446..19618e5e 100644
--- a/ash/wm/desks/desk_mini_view_animations.cc
+++ b/ash/wm/desks/desk_mini_view_animations.cc
@@ -662,10 +662,10 @@
   OverviewGrid* grid = bar_view->overview_grid();
   CHECK(grid);
 
-  base::flat_set<OverviewItem*> ignored_items;
+  base::flat_set<OverviewItemBase*> ignored_items;
   if (auto* drag_controller =
           grid->overview_session()->window_drag_controller()) {
-    OverviewItem* dragged_item = drag_controller->item();
+    auto* dragged_item = drag_controller->item();
     if (dragged_item && dragged_item->overview_grid() == grid) {
       ignored_items.insert(dragged_item);
     }
diff --git a/ash/wm/desks/desks_controller.cc b/ash/wm/desks/desks_controller.cc
index aef3fda..64c6ef6c 100644
--- a/ash/wm/desks/desks_controller.cc
+++ b/ash/wm/desks/desks_controller.cc
@@ -172,7 +172,7 @@
       Shell::Get()->overview_controller()->overview_session();
   for (const auto& grid : overview_session->grid_list()) {
     while (!grid->empty()) {
-      OverviewItem* overview_item = grid->window_list()[0].get();
+      OverviewItemBase* overview_item = grid->window_list()[0].get();
 
       // We want to restore the window here primarily because when we are
       // undoing the removal of an active desk outside of overview, we do not
@@ -933,7 +933,7 @@
     auto* item = overview_session->GetOverviewItemForWindow(window);
     // `item` can be null when we are switching users.
     if (item) {
-      item->OnMovingWindowToAnotherDesk();
+      item->OnMovingItemToAnotherDesk();
       // The item no longer needs to be in the overview grid.
       overview_session->RemoveItem(item);
     } else if (visible_on_all_desks) {
diff --git a/ash/wm/desks/templates/saved_desk_unittest.cc b/ash/wm/desks/templates/saved_desk_unittest.cc
index a345e2b..bfb1422 100644
--- a/ash/wm/desks/templates/saved_desk_unittest.cc
+++ b/ash/wm/desks/templates/saved_desk_unittest.cc
@@ -681,9 +681,8 @@
 
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
-  OverviewItem* snappable_overview_item =
-      GetOverviewItemForWindow(test_window.get());
-  OverviewItem* unsnappable_overview_item =
+  auto* snappable_overview_item = GetOverviewItemForWindow(test_window.get());
+  auto* unsnappable_overview_item =
       GetOverviewItemForWindow(unsnappable_window.get());
 
   // Note: Cannot snap widget will be created on demand.
@@ -991,7 +990,7 @@
   // https://crbug.com/1289020.
 
   // Delete an overview item and verify.
-  OverviewItem* item = GetOverviewItemForWindow(test_widget->GetNativeWindow());
+  auto* item = GetOverviewItemForWindow(test_widget->GetNativeWindow());
   item->CloseWindow();
 
   // `NativeWidgetAura::Close()` fires a post task.
@@ -3440,7 +3439,7 @@
   RemoveDesk(desks_controller->active_desk());
 
   OverviewGrid* overview_grid = GetOverviewGridList()[0].get();
-  OverviewItem* overview_item =
+  auto* overview_item =
       overview_grid->GetOverviewItemContaining(test_window.get());
   ASSERT_TRUE(overview_item);
   ui::Layer* item_widget_layer = overview_item->item_widget()->GetLayer();
@@ -3676,8 +3675,7 @@
   EXPECT_EQ(0, GetOverviewGridList()[0]->num_incognito_windows());
   EXPECT_EQ(1, GetOverviewGridList()[0]->num_unsupported_windows());
 
-  OverviewItem* snappable_overview_item =
-      GetOverviewItemForWindow(app_window.get());
+  auto* snappable_overview_item = GetOverviewItemForWindow(app_window.get());
 
   EXPECT_FALSE(GetCannotSnapWidget(snappable_overview_item));
 
@@ -4121,7 +4119,7 @@
 
   ToggleOverview();
 
-  OverviewItem* item1 = GetOverviewItemForWindow(widget1->GetNativeWindow());
+  auto* item1 = GetOverviewItemForWindow(widget1->GetNativeWindow());
   ASSERT_TRUE(item1);
 
   // Swipe down on `item1` to close it.
@@ -4137,7 +4135,7 @@
 
   // Tests that the save desk as template button and the remaining overview item
   // bounds do not intersect (they are both fully visible).
-  OverviewItem* item2 = GetOverviewItemForWindow(widget2->GetNativeWindow());
+  auto* item2 = GetOverviewItemForWindow(widget2->GetNativeWindow());
   ASSERT_TRUE(item2);
   SavedDeskSaveDeskButtonContainer* save_desk_button_container =
       GetSaveDeskButtonContainerForRoot(Shell::GetPrimaryRootWindow());
@@ -4517,7 +4515,7 @@
 
   // Verify the overview item window for all desk window is not visible since
   // it's still in the library view.
-  OverviewItem* all_desk_window_overview_item =
+  auto* all_desk_window_overview_item =
       GetOverviewItemForWindow(tracker.windows().front());
   EXPECT_FALSE(all_desk_window_overview_item->item_widget()->IsVisible());
 }
diff --git a/ash/wm/float/float_controller_unittest.cc b/ash/wm/float/float_controller_unittest.cc
index 5f838c92..cc01aad2 100644
--- a/ash/wm/float/float_controller_unittest.cc
+++ b/ash/wm/float/float_controller_unittest.cc
@@ -855,7 +855,7 @@
   RemoveDesk(desk_1, DeskCloseType::kCombineDesks);
   ASSERT_EQ(desks_controller->desks().size(), 1u);
   // Floated window should be appended to overview items.
-  const std::vector<std::unique_ptr<OverviewItem>>& overview_items =
+  const std::vector<std::unique_ptr<OverviewItemBase>>& overview_items =
       GetOverviewItemsForRoot(0);
   ASSERT_EQ(overview_items.size(), 1u);
   EXPECT_EQ(window.get(), overview_items[0]->GetWindow());
diff --git a/ash/wm/overview/overview_controller_unittest.cc b/ash/wm/overview/overview_controller_unittest.cc
index 8b324164..fccbd22 100644
--- a/ash/wm/overview/overview_controller_unittest.cc
+++ b/ash/wm/overview/overview_controller_unittest.cc
@@ -26,13 +26,11 @@
 #include "ash/wm/overview/overview_observer.h"
 #include "ash/wm/overview/overview_session.h"
 #include "ash/wm/overview/overview_test_util.h"
-#include "ash/wm/overview/overview_wallpaper_controller.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
 #include "ash/wm/window_resizer.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
 #include "base/command_line.h"
-#include "base/feature_list.h"
 #include "base/run_loop.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "ui/aura/client/aura_constants.h"
diff --git a/ash/wm/overview/overview_grid.cc b/ash/wm/overview/overview_grid.cc
index d17f739..2675e33 100644
--- a/ash/wm/overview/overview_grid.cc
+++ b/ash/wm/overview/overview_grid.cc
@@ -5,7 +5,6 @@
 #include "ash/wm/overview/overview_grid.h"
 
 #include <algorithm>
-#include <functional>
 #include <memory>
 #include <utility>
 
@@ -47,6 +46,7 @@
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/overview/overview_grid_event_handler.h"
 #include "ash/wm/overview/overview_highlight_controller.h"
+#include "ash/wm/overview/overview_highlightable_view.h"
 #include "ash/wm/overview/overview_item.h"
 #include "ash/wm/overview/overview_item_view.h"
 #include "ash/wm/overview/overview_types.h"
@@ -400,8 +400,8 @@
 }
 
 bool ShouldExcludeItemFromGridLayout(
-    OverviewItem* item,
-    const base::flat_set<OverviewItem*>& ignored_items) {
+    OverviewItemBase* item,
+    const base::flat_set<OverviewItemBase*>& ignored_items) {
   return item->animating_to_close() || ignored_items.contains(item);
 }
 
@@ -447,7 +447,7 @@
     if (animator->is_animating())
       window->layer()->GetAnimator()->StopAnimating();
     window_list_.push_back(
-        std::make_unique<OverviewItem>(window, overview_session_, this));
+        OverviewItemBase::Create(window, overview_session_, this));
 
     UpdateNumSavedDeskUnsupportedWindows(window, /*increment*/ true);
   }
@@ -558,22 +558,26 @@
   // Fade in/out the minimized windows and position non-minimized windows.
   float scroll_ratio = y_offset / WmGestureHandler::kVerticalThresholdDp;
   for (size_t i = 0; i < window_list_.size(); ++i) {
-    OverviewItem* window_item = window_list_[i].get();
+    auto* window_item = window_list_[i].get();
+    // TODO(b/297427797) : We should avoid going deep into the implementation
+    // `OverviewItem` in `OverviewGrid`.
+    auto* window = window_item->GetWindow();
+    auto* window_item_leaf = window_item->GetLeafItemForWindow(window);
     gfx::RectF rect = cached_rects_[i];
     // If this is the first scroll update, position minimized windows
     // and hide the headers of non-minimized windows.
     if (first_scroll) {
-      if (WindowState::Get(window_item->GetWindow())->IsMinimized()) {
+      if (WindowState::Get(window)->IsMinimized()) {
         window_item->SetBounds(rect, OVERVIEW_ANIMATION_NONE);
       } else {
-        window_item->overview_item_view()->layer()->SetOpacity(0.0f);
+        window_item_leaf->overview_item_view()->layer()->SetOpacity(0.0f);
       }
     }
     // For all scroll updates, set the opacity of minimized windows and
     // reposition non-minimized windows.
     if (WindowState::Get(window_item->GetWindow())->IsMinimized()) {
       float opacity = std::clamp(0.01f, scroll_ratio, 1.f);
-      window_item->overview_item_view()->layer()->SetOpacity(opacity);
+      window_item_leaf->overview_item_view()->layer()->SetOpacity(opacity);
     } else {
       rect = gfx::Tween::RectFValueBetween(
           scroll_ratio, gfx::RectF(window_item->GetWindow()->bounds()), rect);
@@ -607,7 +611,7 @@
 
 void OverviewGrid::PositionWindows(
     bool animate,
-    const base::flat_set<OverviewItem*>& ignored_items,
+    const base::flat_set<OverviewItemBase*>& ignored_items,
     OverviewTransition transition) {
   if (!overview_session_ || suspend_reposition_ || window_list_.empty())
     return;
@@ -655,7 +659,7 @@
       animate && transition == OverviewTransition::kInOverview;
 
   for (size_t i = 0; i < window_list_.size(); ++i) {
-    OverviewItem* window_item = window_list_[i].get();
+    OverviewItemBase* window_item = window_list_[i].get();
     if (ShouldExcludeItemFromGridLayout(window_item, ignored_items)) {
       rects[i].SetRect(0, 0, 0, 0);
       continue;
@@ -699,7 +703,7 @@
   for (size_t i = 0; i < window_list_.size(); ++i) {
     if (rects[i].IsEmpty())
       continue;
-    OverviewItem* window_item = window_list_[i].get();
+    OverviewItemBase* window_item = window_list_[i].get();
     window_item->SetBounds(rects[i], animation_types[i]);
   }
 
@@ -711,7 +715,7 @@
   cached_rects_.clear();
 }
 
-OverviewItem* OverviewGrid::GetOverviewItemContaining(
+OverviewItemBase* OverviewGrid::GetOverviewItemContaining(
     const aura::Window* window) const {
   for (const auto& window_item : window_list_) {
     if (window_item && window_item->Contains(window))
@@ -720,13 +724,14 @@
   return nullptr;
 }
 
-void OverviewGrid::AddItem(aura::Window* window,
-                           bool reposition,
-                           bool animate,
-                           const base::flat_set<OverviewItem*>& ignored_items,
-                           size_t index,
-                           bool use_spawn_animation,
-                           bool restack) {
+void OverviewGrid::AddItem(
+    aura::Window* window,
+    bool reposition,
+    bool animate,
+    const base::flat_set<OverviewItemBase*>& ignored_items,
+    size_t index,
+    bool use_spawn_animation,
+    bool restack) {
   DCHECK(!GetOverviewItemContaining(window));
   DCHECK_LE(index, window_list_.size());
 
@@ -787,14 +792,14 @@
           FindInsertionIndex(window), use_spawn_animation, restack);
 }
 
-void OverviewGrid::RemoveItem(OverviewItem* overview_item,
+void OverviewGrid::RemoveItem(OverviewItemBase* overview_item,
                               bool item_destroying,
                               bool reposition) {
   EndNudge();
 
   // Use reverse iterator to be efficient when removing all.
   auto iter = base::ranges::find(base::Reversed(window_list_), overview_item,
-                                 &std::unique_ptr<OverviewItem>::get);
+                                 &std::unique_ptr<OverviewItemBase>::get);
   DCHECK(iter != window_list_.rend());
 
   UpdateNumSavedDeskUnsupportedWindows(overview_item->GetWindow(),
@@ -804,14 +809,15 @@
   // be cleaning up and its associated view may be nullptr. |overview_item|
   // needs to still be in |window_list_| so we can compute what the deleted
   // index is.
-  if (overview_session_ && (*iter)->overview_item_view()) {
+  OverviewHighlightableView* focusable_view = (*iter)->GetFocusableView();
+  if (overview_session_ && focusable_view) {
     overview_session_->highlight_controller()->OnViewDestroyingOrDisabling(
-        (*iter)->overview_item_view());
+        focusable_view);
   }
 
   // Erase from the list first because deleting OverviewItem can lead to
   // iterating through the |window_list_|.
-  std::unique_ptr<OverviewItem> tmp = std::move(*iter);
+  std::unique_ptr<OverviewItemBase> tmp = std::move(*iter);
   window_list_.erase(std::next(iter).base());
   tmp.reset();
 
@@ -834,8 +840,8 @@
     // currently overview dragged window, if there is one. Note: this does not
     // update the grid bounds if the window being dragged from the top or shelf,
     // the former being handled in TabletModeWindowDragDelegate's destructor.
-    base::flat_set<OverviewItem*> ignored_items;
-    OverviewItem* dragged_item =
+    base::flat_set<OverviewItemBase*> ignored_items;
+    OverviewItemBase* dragged_item =
         overview_session_->GetCurrentDraggedOverviewItem();
     if (dragged_item)
       ignored_items.insert(dragged_item);
@@ -870,7 +876,7 @@
 }
 
 void OverviewGrid::AddDropTargetForDraggingFromThisGrid(
-    OverviewItem* dragged_item) {
+    OverviewItemBase* dragged_item) {
   DCHECK(!drop_target_widget_);
   drop_target_widget_ =
       CreateDropTargetWidget(root_window_, dragged_item->GetWindow());
@@ -903,14 +909,14 @@
 
 void OverviewGrid::RemoveDropTarget() {
   DCHECK(drop_target_widget_);
-  OverviewItem* drop_target = GetDropTarget();
+  OverviewItemBase* drop_target = GetDropTarget();
   overview_session_->RemoveItem(drop_target);
   drop_target_widget_.reset();
 }
 
 void OverviewGrid::SetBoundsAndUpdatePositions(
     const gfx::Rect& bounds_in_screen,
-    const base::flat_set<OverviewItem*>& ignored_items,
+    const base::flat_set<OverviewItemBase*>& ignored_items,
     bool animate) {
   const bool bounds_updated = bounds_in_screen != bounds_;
   bounds_ = bounds_in_screen;
@@ -922,9 +928,9 @@
 }
 
 void OverviewGrid::RearrangeDuringDrag(
-    OverviewItem* dragged_item,
+    OverviewItemBase* dragged_item,
     SplitViewDragIndicators::WindowDraggingState window_dragging_state) {
-  OverviewItem* drop_target = GetDropTarget();
+  OverviewItemBase* drop_target = GetDropTarget();
 
   // Update the drop target visibility according to |window_dragging_state|.
   if (drop_target) {
@@ -939,7 +945,7 @@
       root_window_, absl::make_optional(window_dragging_state),
       /*divider_changed=*/false, /*account_for_hotseat=*/true);
   if (bounds_ != wanted_grid_bounds) {
-    base::flat_set<OverviewItem*> ignored_items;
+    base::flat_set<OverviewItemBase*> ignored_items;
     if (dragged_item)
       ignored_items.insert(dragged_item);
     SetBoundsAndUpdatePositions(wanted_grid_bounds, ignored_items,
@@ -983,7 +989,7 @@
 }
 
 void OverviewGrid::UpdateDropTargetBackgroundVisibility(
-    OverviewItem* dragged_item,
+    OverviewItemBase* dragged_item,
     const gfx::PointF& location_in_screen) {
   DCHECK(drop_target_widget_);
   aura::Window* target_window =
@@ -995,15 +1001,15 @@
       target_window && IsDropTargetWindow(target_window));
 }
 
-void OverviewGrid::OnSelectorItemDragStarted(OverviewItem* item) {
+void OverviewGrid::OnOverviewItemDragStarted(OverviewItemBase* item) {
   CommitNameChanges();
   for (auto& overview_mode_item : window_list_)
-    overview_mode_item->OnSelectorItemDragStarted(item);
+    overview_mode_item->OnOverviewItemDragStarted(item);
 }
 
-void OverviewGrid::OnSelectorItemDragEnded(bool snap) {
+void OverviewGrid::OnOverviewItemDragEnded(bool snap) {
   for (auto& overview_mode_item : window_list_)
-    overview_mode_item->OnSelectorItemDragEnded(snap);
+    overview_mode_item->OnOverviewItemDragEnded(snap);
 }
 
 void OverviewGrid::OnWindowDragStarted(aura::Window* dragged_window,
@@ -1013,7 +1019,7 @@
   // Stack the |dragged_window| at top during drag.
   dragged_window->parent()->StackChildAtTop(dragged_window);
   // Called to set caption and title visibility during dragging.
-  OnSelectorItemDragStarted(/*item=*/nullptr);
+  OnOverviewItemDragStarted(/*item=*/nullptr);
 }
 
 void OverviewGrid::OnWindowDragContinued(
@@ -1045,7 +1051,7 @@
   RemoveDropTarget();
 
   // Called to reset caption and title visibility after dragging.
-  OnSelectorItemDragEnded(snap);
+  OnOverviewItemDragEnded(snap);
 
   // Update the grid bounds and reposition windows. Since the grid bounds might
   // be updated based on the preview area during drag, but the window finally
@@ -1064,8 +1070,9 @@
 }
 
 void OverviewGrid::SetVisibleDuringWindowDragging(bool visible, bool animate) {
-  for (const auto& window_item : window_list_)
-    window_item->SetVisibleDuringWindowDragging(visible, animate);
+  for (const auto& window_item : window_list_) {
+    window_item->SetVisibleDuringItemDragging(visible, animate);
+  }
 
   // Update |desks_widget_|.
   if (desks_widget_) {
@@ -1090,7 +1097,7 @@
          drop_target_widget_->GetNativeWindow() == window;
 }
 
-OverviewItem* OverviewGrid::GetDropTarget() {
+OverviewItemBase* OverviewGrid::GetDropTarget() {
   return drop_target_widget_
              ? GetOverviewItemContaining(drop_target_widget_->GetNativeWindow())
              : nullptr;
@@ -1133,7 +1140,7 @@
 }
 
 void OverviewGrid::CalculateWindowListAnimationStates(
-    OverviewItem* selected_item,
+    OverviewItemBase* selected_item,
     OverviewTransition transition,
     const std::vector<gfx::RectF>& target_bounds) {
   using OverviewTransition = OverviewTransition;
@@ -1152,7 +1159,7 @@
 
   // On top items are items that are higher up on the z-order, or in the always
   // on top or float containers.
-  auto is_on_top_item = [](OverviewItem* item) -> bool {
+  auto is_on_top_item = [](OverviewItemBase* item) -> bool {
     DCHECK(item);
     if (item->GetWindow()->GetProperty(aura::client::kZOrderingKey) !=
         ui::ZOrderLevel::kNormal) {
@@ -1167,11 +1174,11 @@
 
   // Create a copy of `window_list_` which has the selected item and on top
   // windows in the front.
-  std::vector<OverviewItem*> on_top_items;
-  std::vector<OverviewItem*> regular_items;
-  for (const std::unique_ptr<OverviewItem>& item : window_list_) {
-    OverviewItem* item_ptr = item.get();
-    DCHECK(item_ptr);
+  std::vector<OverviewItemBase*> on_top_items;
+  std::vector<OverviewItemBase*> regular_items;
+  for (const std::unique_ptr<OverviewItemBase>& item : window_list_) {
+    OverviewItemBase* item_ptr = item.get();
+    CHECK(item_ptr);
     // Skip the selected item, it will be inserted into the front.
     if (item_ptr == selected_item)
       continue;
@@ -1188,7 +1195,7 @@
   //   3) Selected window which is not on top.
   //   4) Regular window.
   // Windows in the same group maintain their ordering from `window_list`.
-  std::vector<OverviewItem*> items;
+  std::vector<OverviewItemBase*> items;
   if (selected_item && is_on_top_item(selected_item))
     items.insert(items.begin(), selected_item);
   items.insert(items.end(), on_top_items.begin(), on_top_items.end());
@@ -1288,7 +1295,7 @@
     item->set_should_animate_when_exiting(false);
 }
 
-void OverviewGrid::StartNudge(OverviewItem* item) {
+void OverviewGrid::StartNudge(OverviewItemBase* item) {
   // When there is one window left, there is no need to nudge.
   if (window_list_.size() <= 1) {
     nudge_data_.clear();
@@ -1418,11 +1425,11 @@
   }
 }
 
-void OverviewGrid::UpdateNudge(OverviewItem* item, double value) {
+void OverviewGrid::UpdateNudge(OverviewItemBase* item, double value) {
   for (const auto& data : nudge_data_) {
     DCHECK_LT(data.index, window_list_.size());
 
-    OverviewItem* nudged_item = window_list_[data.index].get();
+    OverviewItemBase* nudged_item = window_list_[data.index].get();
     double nudge_param = value * value / 30.0;
     nudge_param = std::clamp(nudge_param, 0.0, 1.0);
     gfx::RectF bounds =
@@ -1437,8 +1444,8 @@
 
 aura::Window* OverviewGrid::GetTargetWindowOnLocation(
     const gfx::PointF& location_in_screen,
-    OverviewItem* ignored_item) {
-  for (std::unique_ptr<OverviewItem>& item : window_list_) {
+    OverviewItemBase* ignored_item) {
+  for (std::unique_ptr<OverviewItemBase>& item : window_list_) {
     if (item.get() == ignored_item)
       continue;
     if (item->target_bounds().Contains(location_in_screen))
@@ -1490,7 +1497,7 @@
 
 bool OverviewGrid::MaybeDropItemOnDeskMiniViewOrNewDeskButton(
     const gfx::Point& screen_location,
-    OverviewItem* drag_item) {
+    OverviewItemBase* drag_item) {
   DCHECK(desks_util::ShouldDesksBarBeCreated());
 
   aura::Window* const dragged_window = drag_item->GetWindow();
@@ -1683,8 +1690,9 @@
     PositionWindows(/*animate=*/false);
 }
 
-int OverviewGrid::CalculateWidthAndMaybeSetUnclippedBounds(OverviewItem* item,
-                                                           int height) {
+int OverviewGrid::CalculateWidthAndMaybeSetUnclippedBounds(
+    OverviewItemBase* item,
+    int height) {
   const gfx::Size item_size(0, height);
   gfx::SizeF target_size = item->GetTargetBoundsInScreen().size();
   float scale = item->GetItemScale(item_size);
@@ -1695,7 +1703,7 @@
   // the scale from the window it was meant to be a placeholder for.
   if (IsDropTargetWindow(item->GetWindow())) {
     aura::Window* dragged_window = nullptr;
-    OverviewItem* grid_dragged_item =
+    OverviewItemBase* grid_dragged_item =
         overview_session_->window_drag_controller()
             ? overview_session_->window_drag_controller()->item()
             : nullptr;
@@ -2321,7 +2329,7 @@
 }
 
 std::vector<gfx::RectF> OverviewGrid::GetWindowRects(
-    const base::flat_set<OverviewItem*>& ignored_items) {
+    const base::flat_set<OverviewItemBase*>& ignored_items) {
   gfx::Rect total_bounds = GetGridEffectiveBounds();
 
   // Windows occupy vertically centered area with additional vertical insets.
@@ -2437,14 +2445,14 @@
 }
 
 std::vector<gfx::RectF> OverviewGrid::GetWindowRectsForScrollingLayout(
-    const base::flat_set<OverviewItem*>& ignored_items) {
+    const base::flat_set<OverviewItemBase*>& ignored_items) {
   return ShouldUseTabletModeGridLayout()
              ? GetRectsForTabletScroll(ignored_items)
              : GetRectsForClamshellScroll(ignored_items);
 }
 
 std::vector<gfx::RectF> OverviewGrid::GetRectsForClamshellScroll(
-    const base::flat_set<OverviewItem*>& ignored_items) {
+    const base::flat_set<OverviewItemBase*>& ignored_items) {
   gfx::Rect total_bounds = GetGridEffectiveBounds();
   // Windows occupy vertically centered area with additional vertical insets.
   total_bounds.Inset(GetGridInsetsImpl(total_bounds));
@@ -2497,7 +2505,7 @@
                      kClamshellScrollRow;
   std::vector<gfx::RectF> rects;
   for (const auto& window : window_list_) {
-    OverviewItem* item = window.get();
+    OverviewItemBase* item = window.get();
     if (ShouldExcludeItemFromGridLayout(item, ignored_items)) {
       rects.emplace_back();
       continue;
@@ -2526,7 +2534,7 @@
 }
 
 std::vector<gfx::RectF> OverviewGrid::GetRectsForTabletScroll(
-    const base::flat_set<OverviewItem*>& ignored_items) {
+    const base::flat_set<OverviewItemBase*>& ignored_items) {
   gfx::Rect total_bounds = GetGridEffectiveBounds();
   // Windows occupy vertically centered area with additional vertical insets.
   total_bounds.Inset(GetGridInsetsImpl(total_bounds));
@@ -2574,7 +2582,7 @@
   int window_position = 0;
   std::vector<gfx::RectF> rects;
   for (const auto& window : window_list_) {
-    OverviewItem* item = window.get();
+    OverviewItemBase* item = window.get();
     if (ShouldExcludeItemFromGridLayout(item, ignored_items)) {
       rects.emplace_back();
       continue;
@@ -2605,7 +2613,7 @@
 bool OverviewGrid::FitWindowRectsInBounds(
     const gfx::Rect& bounds,
     int height,
-    const base::flat_set<OverviewItem*>& ignored_items,
+    const base::flat_set<OverviewItemBase*>& ignored_items,
     std::vector<gfx::RectF>* out_rects,
     int* out_max_bottom,
     int* out_min_right,
@@ -2670,9 +2678,9 @@
   return true;
 }
 
-size_t OverviewGrid::GetOverviewItemIndex(OverviewItem* item) const {
+size_t OverviewGrid::GetOverviewItemIndex(OverviewItemBase* item) const {
   auto iter = base::ranges::find(window_list_, item,
-                                 &std::unique_ptr<OverviewItem>::get);
+                                 &std::unique_ptr<OverviewItemBase>::get);
   DCHECK(iter != window_list_.end());
   return iter - window_list_.begin();
 }
diff --git a/ash/wm/overview/overview_grid.h b/ash/wm/overview/overview_grid.h
index a80c7ba..8f2d8f93 100644
--- a/ash/wm/overview/overview_grid.h
+++ b/ash/wm/overview/overview_grid.h
@@ -14,32 +14,39 @@
 #include "ash/rotator/screen_rotation_animator_observer.h"
 #include "ash/style/rounded_label_widget.h"
 #include "ash/wm/desks/templates/saved_desk_save_desk_button_container.h"
-#include "ash/wm/overview/overview_session.h"
-#include "ash/wm/splitview/split_view_controller.h"
+#include "ash/wm/overview/overview_observer.h"
+#include "ash/wm/overview/overview_types.h"
 #include "ash/wm/splitview/split_view_drag_indicators.h"
 #include "ash/wm/splitview/split_view_observer.h"
 #include "base/containers/flat_set.h"
 #include "base/memory/raw_ptr.h"
-#include "ui/aura/window.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
+
+namespace aura {
+class Window;
+}  // namespace aura
+
+namespace gfx {
+class Rect;
+class RectF;
+}  // namespace gfx
 
 namespace views {
 class Widget;
-}
+}  // namespace views
 
 namespace ui {
 class PresentationTimeRecorder;
-}
+}  // namespace ui
 
 namespace ash {
 
 class LegacyDeskBarView;
 class OverviewGridEventHandler;
-class OverviewItem;
+class OverviewItemBase;
+class OverviewSession;
 class SavedDeskSaveDeskButton;
-class SavedDeskSaveDeskButtonContainer;
 class SavedDeskLibraryView;
+class SplitViewController;
 
 // Manages and positions the overview UI on a per root window basis. Overview UI
 // elements include:
@@ -82,7 +89,7 @@
   // called. Updates the save desk template button if necessary.
   void PositionWindows(
       bool animate,
-      const base::flat_set<OverviewItem*>& ignored_items = {},
+      const base::flat_set<OverviewItemBase*>& ignored_items = {},
       OverviewTransition transition = OverviewTransition::kInOverview);
 
   // Used when feature ContinuousOverviewScrollAnimation is enabled. Positions
@@ -92,10 +99,10 @@
   // offset.
   void PositionWindowsContinuously(float y_offset);
 
-  // Returns the OverviewItem if a window is contained in any of the
+  // Returns the `OverviewItemBase` if a window is contained in any of the
   // OverviewItems this grid owns. Returns nullptr if no such a OverviewItem
   // exist.
-  OverviewItem* GetOverviewItemContaining(const aura::Window* window) const;
+  OverviewItemBase* GetOverviewItemContaining(const aura::Window* window) const;
 
   // TODO(b/285408040): Handle two finger scroll and make it smooth.
   void HandleMouseWheelScrollEvent(int scroll_offset);
@@ -124,7 +131,7 @@
   void AddItem(aura::Window* window,
                bool reposition,
                bool animate,
-               const base::flat_set<OverviewItem*>& ignored_items,
+               const base::flat_set<OverviewItemBase*>& ignored_items,
                size_t index,
                bool use_spawn_animation,
                bool restack);
@@ -148,7 +155,7 @@
   // |overview_session_| that this grid has become empty. If |item_destroying|
   // and |reposition| are both true, all items are repositioned with animation.
   // |reposition| has no effect if |item_destroying| is false.
-  void RemoveItem(OverviewItem* overview_item,
+  void RemoveItem(OverviewItemBase* overview_item,
                   bool item_destroying,
                   bool reposition);
 
@@ -163,7 +170,7 @@
   // drop target takes the place of |dragged_item|. Does not animate the
   // repositioning or fade in the drop target. The visual effect is that the
   // drop target was already present but was covered by |dragged_item|.
-  void AddDropTargetForDraggingFromThisGrid(OverviewItem* dragged_item);
+  void AddDropTargetForDraggingFromThisGrid(OverviewItemBase* dragged_item);
 
   // Adds a drop target for |dragged_window|. Used for dragging from another
   // grid, from the top in tablet mode, or from the shelf in tablet mode.
@@ -177,14 +184,14 @@
   // except windows in |ignored_items|.
   void SetBoundsAndUpdatePositions(
       const gfx::Rect& bounds_in_screen,
-      const base::flat_set<OverviewItem*>& ignored_items,
+      const base::flat_set<OverviewItemBase*>& ignored_items,
       bool animate);
 
   // Updates overview bounds and hides the drop target when a preview area is
   // shown or the drag is currently outside of |root_window_|. For dragging from
   // the top or from the shelf, pass null for |dragged_item|.
   void RearrangeDuringDrag(
-      OverviewItem* dragged_item,
+      OverviewItemBase* dragged_item,
       SplitViewDragIndicators::WindowDraggingState window_dragging_state);
 
   // Sets the dragged window on |split_view_drag_indicators_|.
@@ -202,13 +209,13 @@
   // dragged window is being dragged over it. For dragging from the top or from
   // the shelf, pass null for |dragged_item|.
   void UpdateDropTargetBackgroundVisibility(
-      OverviewItem* dragged_item,
+      OverviewItemBase* dragged_item,
       const gfx::PointF& location_in_screen);
 
   // Called when any OverviewItem on any OverviewGrid has started/ended being
   // dragged.
-  void OnSelectorItemDragStarted(OverviewItem* item);
-  void OnSelectorItemDragEnded(bool snap);
+  void OnOverviewItemDragStarted(OverviewItemBase* item);
+  void OnOverviewItemDragEnded(bool snap);
 
   // Called when a window (either it's browser window or an app window)
   // start/continue/end being dragged in tablet mode.
@@ -234,7 +241,7 @@
 
   // Returns the overview item that accociates with |drop_target_widget_|.
   // Returns nullptr if overview does not have the drop target.
-  OverviewItem* GetDropTarget();
+  OverviewItemBase* GetDropTarget();
 
   // Called by |OverviewSession::OnDisplayMetricsChanged|, only for the display
   // with this grid.
@@ -254,7 +261,7 @@
   // be in overview. If |tranisition| is exit, |target_bounds| should be empty
   // and the overview bounds should be queried from |window_list_|.
   void CalculateWindowListAnimationStates(
-      OverviewItem* selected_item,
+      OverviewItemBase* selected_item,
       OverviewTransition transition,
       const std::vector<gfx::RectF>& target_bounds);
 
@@ -269,11 +276,11 @@
   // Starts a nudge, with |item| being the item that may be deleted. This method
   // calculates which items in |window_list_| are to be updated, and their
   // destination bounds and fills |nudge_data_| accordingly.
-  void StartNudge(OverviewItem* item);
+  void StartNudge(OverviewItemBase* item);
 
   // Moves items in |nudge_data_| towards their destination bounds based on
   // |value|, which must be between 0.0 and 1.0.
-  void UpdateNudge(OverviewItem* item, double value);
+  void UpdateNudge(OverviewItemBase* item, double value);
 
   // Clears |nudge_data_|.
   void EndNudge();
@@ -282,7 +289,7 @@
   // |ignored_item| is excluded from consideration. Overview items covered by
   // |ignored_item| are eligible.
   aura::Window* GetTargetWindowOnLocation(const gfx::PointF& location_in_screen,
-                                          OverviewItem* ignored_item);
+                                          OverviewItemBase* ignored_item);
 
   // Returns true when the desks bar view is showing desks mini views (or will
   // show them once it is created).
@@ -315,7 +322,7 @@
   // another desk.
   bool MaybeDropItemOnDeskMiniViewOrNewDeskButton(
       const gfx::Point& screen_location,
-      OverviewItem* drag_item);
+      OverviewItemBase* drag_item);
 
   // Transforms `desks_bar_view_` from zero state to expanded state. Called when
   // a normal drag starts to enable user dragging a window and dropping it to
@@ -342,7 +349,8 @@
   // the same aspect ratio as the original window, but may be modified if the
   // bounds of the window are considered extreme, or if the window is in
   // splitview or entering splitview.
-  int CalculateWidthAndMaybeSetUnclippedBounds(OverviewItem* item, int height);
+  int CalculateWidthAndMaybeSetUnclippedBounds(OverviewItemBase* item,
+                                               int height);
 
   // Returns true if any desk name is being modified in its mini view on this
   // grid.
@@ -424,7 +432,7 @@
 
   OverviewSession* overview_session() { return overview_session_; }
 
-  const std::vector<std::unique_ptr<OverviewItem>>& window_list() const {
+  const std::vector<std::unique_ptr<OverviewItemBase>>& window_list() const {
     return window_list_;
   }
 
@@ -498,7 +506,7 @@
   // row height which is equivalent assuming fixed height), balanced rows and
   // minimal wasted space.
   std::vector<gfx::RectF> GetWindowRects(
-      const base::flat_set<OverviewItem*>& ignored_items);
+      const base::flat_set<OverviewItemBase*>& ignored_items);
 
   // Gets the layout of the overview items. Positions up to six windows into
   // two rows of equal height, scaling each window to fit that height.
@@ -509,13 +517,13 @@
   // TODO(b/286869951): Reduce duplication once clamshell scrolling is
   // finalized.
   std::vector<gfx::RectF> GetWindowRectsForScrollingLayout(
-      const base::flat_set<OverviewItem*>& ignored_items);
+      const base::flat_set<OverviewItemBase*>& ignored_items);
 
   std::vector<gfx::RectF> GetRectsForClamshellScroll(
-      const base::flat_set<OverviewItem*>& ignored_items);
+      const base::flat_set<OverviewItemBase*>& ignored_items);
 
   std::vector<gfx::RectF> GetRectsForTabletScroll(
-      const base::flat_set<OverviewItem*>& ignored_items);
+      const base::flat_set<OverviewItemBase*>& ignored_items);
 
   // Attempts to fit all `out_rects` inside `bounds`. The method ensures that
   // the `out_rects` vector has appropriate size and populates it with the
@@ -530,14 +538,14 @@
   bool FitWindowRectsInBounds(
       const gfx::Rect& bounds,
       int height,
-      const base::flat_set<OverviewItem*>& ignored_items,
+      const base::flat_set<OverviewItemBase*>& ignored_items,
       std::vector<gfx::RectF>* out_rects,
       int* out_max_bottom,
       int* out_min_right,
       int* out_max_right);
 
   // Returns the index of |item| in |window_list_|.
-  size_t GetOverviewItemIndex(OverviewItem* item) const;
+  size_t GetOverviewItemIndex(OverviewItemBase* item) const;
 
   // Returns the index where |window| can be inserted into |window_list_| based
   // on MRU order.
@@ -583,7 +591,7 @@
   raw_ptr<OverviewSession, ExperimentalAsh> overview_session_;
 
   // Vector containing all the windows in this grid.
-  std::vector<std::unique_ptr<OverviewItem>> window_list_;
+  std::vector<std::unique_ptr<OverviewItemBase>> window_list_;
 
   // A widget that is shown if we entered overview without any windows opened.
   std::unique_ptr<RoundedLabelWidget> no_windows_widget_;
diff --git a/ash/wm/overview/overview_grid_unittest.cc b/ash/wm/overview/overview_grid_unittest.cc
index 2387f648..ccea95f 100644
--- a/ash/wm/overview/overview_grid_unittest.cc
+++ b/ash/wm/overview/overview_grid_unittest.cc
@@ -7,7 +7,6 @@
 #include "ash/screen_util.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
-#include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/overview/overview_item.h"
 #include "ash/wm/overview/overview_test_util.h"
 #include "ash/wm/splitview/split_view_controller.h"
@@ -19,7 +18,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/aura/window.h"
-#include "ui/display/display.h"
 #include "ui/display/manager/display_manager.h"
 #include "ui/display/screen.h"
 #include "ui/gfx/geometry/rect.h"
@@ -69,9 +67,11 @@
                 grid_->window_list()[i]->should_animate_when_entering());
     }
 
-    for (size_t i = 0; i < grid_->window_list().size(); ++i)
+    for (size_t i = 0; i < grid_->window_list().size(); ++i) {
       grid_->window_list()[i]->set_target_bounds_for_testing(target_bounds[i]);
-    OverviewItem* selected_item =
+    }
+
+    auto* selected_item =
         selected_window_index
             ? grid_->window_list()[*selected_window_index].get()
             : nullptr;
@@ -306,8 +306,8 @@
   // Tests that |window3| is not animated even though its bounds are larger than
   // |window2| because it is fully occluded by |window1| + |window2| and the
   // split view divider.
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
-  OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get());
   EXPECT_TRUE(item2->should_animate_when_entering());
   EXPECT_FALSE(item3->should_animate_when_entering());
 }
diff --git a/ash/wm/overview/overview_highlight_controller.cc b/ash/wm/overview/overview_highlight_controller.cc
index bc6f356..1f88094 100644
--- a/ash/wm/overview/overview_highlight_controller.cc
+++ b/ash/wm/overview/overview_highlight_controller.cc
@@ -5,18 +5,14 @@
 #include "ash/wm/overview/overview_highlight_controller.h"
 
 #include "ash/accessibility/magnifier/docked_magnifier_controller.h"
-#include "ash/accessibility/magnifier/fullscreen_magnifier_controller.h"
 #include "ash/accessibility/magnifier/magnifier_utils.h"
 #include "ash/accessibility/scoped_a11y_override_window_setter.h"
-#include "ash/constants/ash_features.h"
 #include "ash/shell.h"
-#include "ash/wm/desks/cros_next_default_desk_button.h"
 #include "ash/wm/desks/cros_next_desk_icon_button.h"
 #include "ash/wm/desks/desk_mini_view.h"
 #include "ash/wm/desks/desk_name_view.h"
 #include "ash/wm/desks/desk_preview_view.h"
 #include "ash/wm/desks/desks_controller.h"
-#include "ash/wm/desks/desks_util.h"
 #include "ash/wm/desks/expanded_desks_bar_button.h"
 #include "ash/wm/desks/legacy_desk_bar_view.h"
 #include "ash/wm/desks/templates/saved_desk_grid_view.h"
@@ -33,7 +29,6 @@
 #include "base/containers/contains.h"
 #include "base/ranges/algorithm.h"
 #include "chromeos/constants/chromeos_features.h"
-#include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/views/view.h"
 
 namespace ash {
@@ -253,14 +248,15 @@
              overview_session_);
 }
 
-OverviewItem* OverviewHighlightController::GetHighlightedItem() const {
+OverviewItemBase* OverviewHighlightController::GetHighlightedItem() const {
   if (!highlighted_view_)
     return nullptr;
 
   for (auto& grid : overview_session_->grid_list()) {
     for (auto& item : grid->window_list()) {
-      if (highlighted_view_->GetView() == item->overview_item_view())
+      if (highlighted_view_->GetView() == item->GetFocusableView()->GetView()) {
         return item.get();
+      }
     }
   }
 
@@ -303,7 +299,7 @@
       }
     } else {
       for (auto& item : grid->window_list())
-        traversable_views.push_back(item->overview_item_view());
+        traversable_views.push_back(item->GetFocusableView());
     }
 
     AddDesksBarTraversableViews(grid.get(), traversable_views);
diff --git a/ash/wm/overview/overview_highlight_controller.h b/ash/wm/overview/overview_highlight_controller.h
index 85f05d3..dff7bf9 100644
--- a/ash/wm/overview/overview_highlight_controller.h
+++ b/ash/wm/overview/overview_highlight_controller.h
@@ -14,7 +14,7 @@
 
 namespace ash {
 class OverviewHighlightableView;
-class OverviewItem;
+class OverviewItemBase;
 class OverviewSession;
 class ScopedA11yOverrideWindowSetter;
 
@@ -94,7 +94,7 @@
 
   // Tries to get the item that is currently highlighted. Returns null if there
   // is no highlight, or if the highlight is on a desk view.
-  OverviewItem* GetHighlightedItem() const;
+  OverviewItemBase* GetHighlightedItem() const;
 
   // If `highlighted_view_` is not null, remove the highlight. The next tab will
   // start at the beginning of the tab order. This can be used when a lot of
diff --git a/ash/wm/overview/overview_highlight_controller_unittest.cc b/ash/wm/overview/overview_highlight_controller_unittest.cc
index 7ee29061..3691ada 100644
--- a/ash/wm/overview/overview_highlight_controller_unittest.cc
+++ b/ash/wm/overview/overview_highlight_controller_unittest.cc
@@ -17,8 +17,6 @@
 #include "ash/wm/desks/expanded_desks_bar_button.h"
 #include "ash/wm/desks/legacy_desk_bar_view.h"
 #include "ash/wm/desks/templates/saved_desk_util.h"
-#include "ash/wm/desks/zero_state_button.h"
-#include "ash/wm/overview/overview_constants.h"
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/overview/overview_grid.h"
 #include "ash/wm/overview/overview_highlightable_view.h"
@@ -29,7 +27,6 @@
 #include "ash/wm/overview/scoped_overview_transform_window.h"
 #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
 #include "ash/wm/window_util.h"
-#include "base/feature_list.h"
 #include "base/test/scoped_feature_list.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "ui/aura/window.h"
@@ -97,7 +94,7 @@
   std::unique_ptr<aura::Window> window1(CreateTestWindow());
 
   ToggleOverview();
-  const std::vector<std::unique_ptr<OverviewItem>>& overview_windows =
+  const std::vector<std::unique_ptr<OverviewItemBase>>& overview_windows =
       GetOverviewItemsForRoot(0);
   SendKeyUntilOverviewItemIsHighlighted(ui::VKEY_TAB);
   EXPECT_EQ(overview_windows[0]->GetWindow(), GetOverviewHighlightedWindow());
@@ -119,7 +116,7 @@
 
   TabletModeControllerTestApi().EnterTabletMode();
   ToggleOverview();
-  const std::vector<std::unique_ptr<OverviewItem>>& overview_windows =
+  const std::vector<std::unique_ptr<OverviewItemBase>>& overview_windows =
       GetOverviewItemsForRoot(0);
   SendKeyUntilOverviewItemIsHighlighted(ui::VKEY_TAB);
   EXPECT_EQ(overview_windows[0]->GetWindow(), GetOverviewHighlightedWindow());
@@ -166,7 +163,7 @@
 
   for (size_t key_index = 0; key_index < std::size(arrow_keys); ++key_index) {
     ToggleOverview();
-    const std::vector<std::unique_ptr<OverviewItem>>& overview_windows =
+    const std::vector<std::unique_ptr<OverviewItemBase>>& overview_windows =
         GetOverviewItemsForRoot(0);
     for (size_t i = 0; i < test_windows + 1; ++i) {
       SendKeyUntilOverviewItemIsHighlighted(arrow_keys[key_index]);
@@ -217,9 +214,9 @@
 
   ToggleOverview();
 
-  const std::vector<std::unique_ptr<OverviewItem>>& overview_root1 =
+  const std::vector<std::unique_ptr<OverviewItemBase>>& overview_root1 =
       GetOverviewItemsForRoot(0);
-  const std::vector<std::unique_ptr<OverviewItem>>& overview_root2 =
+  const std::vector<std::unique_ptr<OverviewItemBase>>& overview_root2 =
       GetOverviewItemsForRoot(1);
   SendKeyUntilOverviewItemIsHighlighted(ui::VKEY_RIGHT);
   EXPECT_EQ(GetOverviewHighlightedWindow(), overview_root1[0]->GetWindow());
@@ -337,7 +334,7 @@
   // Tab once to show the highlight.
   SendKeyUntilOverviewItemIsHighlighted(ui::VKEY_TAB);
   EXPECT_EQ(window3.get(), GetOverviewHighlightedWindow());
-  OverviewItem* item = GetOverviewItemForWindow(window3.get());
+  auto* item = GetOverviewItemForWindow(window3.get());
 
   // Tests that while dragging an item, tabbing does not change which item the
   // highlight is hovered over, but the highlight is hidden. Drag the item in a
@@ -431,7 +428,8 @@
 
   // Tests that the overview item gets highlighted first.
   SendKey(ui::VKEY_TAB);
-  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get())
+                    ->GetLeafItemForWindow(window2.get());
   EXPECT_EQ(item2->overview_item_view(), GetHighlightedView());
   CheckDeskBarViewSize(desk_bar_view, "overview item");
 
@@ -536,7 +534,8 @@
   // Tests that the next highlighted item when reversing is the last overview
   // item.
   SendKey(ui::VKEY_TAB, ui::EF_SHIFT_DOWN);
-  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get())
+                    ->GetLeafItemForWindow(window1.get());
   EXPECT_EQ(item1->overview_item_view(), GetHighlightedView());
 
   // Tests that the next highlighted item when reversing is the save desk for
@@ -616,10 +615,12 @@
   // Tests that tabbing initially will go through the two overview items on the
   // first display.
   SendKey(ui::VKEY_TAB);
-  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get())
+                    ->GetLeafItemForWindow(window2.get());
   EXPECT_EQ(item2->overview_item_view(), GetHighlightedView());
   SendKey(ui::VKEY_TAB);
-  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get())
+                    ->GetLeafItemForWindow(window1.get());
   EXPECT_EQ(item1->overview_item_view(), GetHighlightedView());
 
   // Tests that further tabbing will go through the desk preview views,  desk
@@ -658,7 +659,8 @@
   // Tests that the next tab will bring us to the first overview item on the
   // second display.
   SendKey(ui::VKEY_TAB);
-  auto* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get())
+                    ->GetLeafItemForWindow(window3.get());
   EXPECT_EQ(item3->overview_item_view(), GetHighlightedView());
 
   SendKey(ui::VKEY_TAB);
@@ -689,7 +691,8 @@
   // Tests that after tabbing through the items on the second display, the
   // next tab will bring us to the first overview item on the third display.
   SendKey(ui::VKEY_TAB);
-  auto* item4 = GetOverviewItemForWindow(window4.get());
+  auto* item4 = GetOverviewItemForWindow(window4.get())
+                    ->GetLeafItemForWindow(window4.get());
   EXPECT_EQ(item4->overview_item_view(), GetHighlightedView());
 
   SendKey(ui::VKEY_TAB);
diff --git a/ash/wm/overview/overview_item.cc b/ash/wm/overview/overview_item.cc
index a774f0aa..126403a 100644
--- a/ash/wm/overview/overview_item.cc
+++ b/ash/wm/overview/overview_item.cc
@@ -4,12 +4,10 @@
 
 #include "ash/wm/overview/overview_item.h"
 
-#include <algorithm>
 #include <utility>
 #include <vector>
 
 #include "ash/accessibility/accessibility_controller_impl.h"
-#include "ash/public/cpp/shell_window_ids.h"
 #include "ash/public/cpp/window_properties.h"
 #include "ash/shell.h"
 #include "ash/strings/grit/ash_strings.h"
@@ -25,6 +23,7 @@
 #include "ash/wm/overview/overview_grid.h"
 #include "ash/wm/overview/overview_grid_event_handler.h"
 #include "ash/wm/overview/overview_highlight_controller.h"
+#include "ash/wm/overview/overview_item_base.h"
 #include "ash/wm/overview/overview_item_view.h"
 #include "ash/wm/overview/overview_types.h"
 #include "ash/wm/overview/overview_utils.h"
@@ -40,28 +39,23 @@
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_transient_descendant_iterator.h"
 #include "ash/wm/window_util.h"
-#include "ash/wm/wm_event.h"
 #include "base/auto_reset.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/metrics/user_metrics.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/ui/base/window_state_type.h"
-#include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/layer_animation_observer.h"
 #include "ui/compositor/layer_animation_sequence.h"
-#include "ui/compositor/scoped_animation_duration_scale_mode.h"
 #include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/compositor_extra/shadow.h"
 #include "ui/gfx/geometry/size_conversions.h"
 #include "ui/gfx/geometry/transform_util.h"
-#include "ui/views/controls/button/image_button.h"
 #include "ui/views/widget/widget.h"
 #include "ui/wm/core/coordinate_conversion.h"
-#include "ui/wm/core/shadow_types.h"
 #include "ui/wm/core/window_util.h"
 
 namespace ash {
@@ -170,10 +164,11 @@
 OverviewItem::OverviewItem(aura::Window* window,
                            OverviewSession* overview_session,
                            OverviewGrid* overview_grid)
-    : root_window_(window->GetRootWindow()),
+    : OverviewItemBase(overview_session,
+                       overview_grid,
+                       window->GetRootWindow()),
+      root_window_(window->GetRootWindow()),
       transform_window_(this, window),
-      overview_session_(overview_session),
-      overview_grid_(overview_grid),
       animation_disabler_(window) {
   CreateItemWidget();
   window->AddObserver(this);
@@ -186,157 +181,96 @@
   window->RemoveObserver(this);
 }
 
+void OverviewItem::UpdateItemContentViewForMinimizedWindow() {
+  overview_item_view_->RefreshPreviewView();
+}
+
+OverviewAnimationType OverviewItem::GetExitOverviewAnimationType() const {
+  if (overview_session_->enter_exit_overview_type() ==
+      OverviewEnterExitType::kImmediateExit) {
+    return OVERVIEW_ANIMATION_NONE;
+  }
+
+  return should_animate_when_exiting_
+             ? OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT
+             : OVERVIEW_ANIMATION_NONE;
+}
+
+OverviewAnimationType OverviewItem::GetExitTransformAnimationType() const {
+  if (is_moving_to_another_desk_ ||
+      overview_session_->enter_exit_overview_type() ==
+          OverviewEnterExitType::kImmediateExit) {
+    return OVERVIEW_ANIMATION_NONE;
+  }
+
+  return should_animate_when_exiting_ ? OVERVIEW_ANIMATION_RESTORE_WINDOW
+                                      : OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO;
+}
+
+void OverviewItem::HandleGestureEventForTabletModeLayout(
+    ui::GestureEvent* event) {
+  const gfx::PointF location = event->details().bounding_box_f().CenterPoint();
+  switch (event->type()) {
+    case ui::ET_SCROLL_FLING_START:
+      if (IsDragItem()) {
+        HandleFlingStartEvent(location, event->details().velocity_x(),
+                              event->details().velocity_y());
+      } else {
+        overview_grid()->grid_event_handler()->OnGestureEvent(event);
+      }
+      break;
+    case ui::ET_GESTURE_SCROLL_BEGIN:
+      if (std::abs(event->details().scroll_y_hint()) >
+          std::abs(event->details().scroll_x_hint())) {
+        HandlePressEvent(location, /*from_touch_gesture=*/true);
+      } else {
+        overview_grid()->grid_event_handler()->OnGestureEvent(event);
+      }
+      break;
+    case ui::ET_GESTURE_SCROLL_UPDATE:
+      if (IsDragItem()) {
+        HandleDragEvent(location);
+      } else {
+        overview_grid()->grid_event_handler()->OnGestureEvent(event);
+      }
+      break;
+    case ui::ET_GESTURE_SCROLL_END:
+      if (IsDragItem()) {
+        HandleReleaseEvent(location);
+      } else {
+        overview_grid()->grid_event_handler()->OnGestureEvent(event);
+      }
+      break;
+    case ui::ET_GESTURE_LONG_PRESS:
+      HandlePressEvent(location, /*from_touch_gesture=*/true);
+      HandleLongPressEvent(location);
+      break;
+    case ui::ET_GESTURE_TAP:
+      overview_session_->SelectWindow(this);
+      break;
+    case ui::ET_GESTURE_END:
+      HandleGestureEndEvent();
+      break;
+    default:
+      overview_grid()->grid_event_handler()->OnGestureEvent(event);
+      break;
+  }
+}
+
 aura::Window* OverviewItem::GetWindow() {
   return transform_window_.window();
 }
 
+std::vector<aura::Window*> OverviewItem::GetWindows() {
+  return {transform_window_.window()};
+}
+
 bool OverviewItem::Contains(const aura::Window* target) const {
   return transform_window_.Contains(target);
 }
 
-void OverviewItem::HideForSavedDeskLibrary(bool animate) {
-  // To hide the window, we will set its layer opacity to 0. This would normally
-  // also hide the window from the mini view, which we don't want. By setting a
-  // property on the window, we can force it to stay visible.
-  GetWindow()->SetProperty(kForceVisibleInMiniViewKey, true);
-
-  // Temporarily hide this window in overview, so that dark/light theme change
-  // does not reset the layer visible. If `animate` is false, the callback will
-  // not run in `PerformFadeOutLayer`. Thus, here we make sure the window is
-  // also hidden in that case.
-  DCHECK(item_widget_);
-  hide_window_in_overview_callback_.Reset(base::BindOnce(
-      &OverviewItem::HideWindowInOverview, weak_ptr_factory_.GetWeakPtr()));
-  PerformFadeOutLayer(item_widget_->GetLayer(), animate,
-                      hide_window_in_overview_callback_.callback());
-  if (!animate) {
-    // Cancel the callback if we are going to run it directly.
-    hide_window_in_overview_callback_.Cancel();
-    HideWindowInOverview();
-  }
-
-  for (aura::Window* transient_child : GetTransientTreeIterator(GetWindow())) {
-    transient_child->SetProperty(kForceVisibleInMiniViewKey, true);
-    PerformFadeOutLayer(transient_child->layer(), animate, base::DoNothing());
-  }
-
-  item_widget_event_blocker_ =
-      std::make_unique<aura::ScopedWindowEventTargetingBlocker>(
-          item_widget_->GetNativeWindow());
-
-  HideCannotSnapWarning(animate);
-}
-
-void OverviewItem::RevertHideForSavedDeskLibrary(bool animate) {
-  // This might run before `HideForSavedDeskLibrary()`, thus cancel the
-  // callback to prevent such case.
-  hide_window_in_overview_callback_.Cancel();
-
-  // Restore and show the window back to overview.
-  ShowWindowInOverview();
-
-  // `item_widget_` may be null during shutdown if the window is minimized.
-  if (item_widget_) {
-    PerformFadeInLayer(item_widget_->GetLayer(), animate);
-  }
-
-  for (aura::Window* transient_child :
-       GetTransientTreeIterator(transform_window_.window())) {
-    PerformFadeInLayer(transient_child->layer(), animate);
-  }
-
-  item_widget_event_blocker_.reset();
-
-  UpdateCannotSnapWarningVisibility(animate);
-}
-
-void OverviewItem::OnMovingWindowToAnotherDesk() {
-  is_moving_to_another_desk_ = true;
-  // Restore the dragged item window, so that its transform is reset to
-  // identity.
-  RestoreWindow(/*reset_transform=*/true, /*animate=*/true);
-}
-
-void OverviewItem::RestoreWindow(bool reset_transform, bool animate) {
-  // TODO(oshima): SplitViewController has its own logic to adjust the
-  // target state in |SplitViewController::OnOverviewModeEnding|.
-  // Unify the mechanism to control it and remove ifs.
-  if (Shell::Get()->tablet_mode_controller()->InTabletMode() &&
-      !SplitViewController::Get(root_window_)->InSplitViewMode() &&
-      reset_transform) {
-    MaximizeIfSnapped(GetWindow());
-  }
-
-  GetWindow()->ClearProperty(kForceVisibleInMiniViewKey);
-  for (aura::Window* transient_child : GetTransientTreeIterator(GetWindow()))
-    transient_child->ClearProperty(kForceVisibleInMiniViewKey);
-
-  overview_item_view_->OnOverviewItemWindowRestoring();
-  transform_window_.RestoreWindow(reset_transform, animate);
-
-  if (!transform_window_.IsMinimized())
-    return;
-
-  const auto enter_exit_type = overview_session_->enter_exit_overview_type();
-  if (is_moving_to_another_desk_ ||
-      enter_exit_type == OverviewEnterExitType::kImmediateExit) {
-    overview_session_->highlight_controller()->OnViewDestroyingOrDisabling(
-        overview_item_view_);
-    ImmediatelyCloseWidgetOnExit(std::move(item_widget_));
-    overview_item_view_ = nullptr;
-    return;
-  }
-
-  OverviewAnimationType animation_type =
-      GetExitOverviewAnimationTypeForMinimizedWindow(enter_exit_type);
-  FadeOutWidgetFromOverview(std::move(item_widget_), animation_type);
-}
-
-void OverviewItem::EnsureVisible() {
-  transform_window_.EnsureVisible();
-}
-
-void OverviewItem::Shutdown() {
-  TRACE_EVENT0("ui", "OverviewItem::Shutdown");
-  // If `hide_windows` still manages the visibility of this overview item
-  // window, remove it from the list without showing.
-  ScopedOverviewHideWindows* hide_windows =
-      overview_session_->hide_windows_for_saved_desks_grid();
-  if (item_widget_ && hide_windows &&
-      hide_windows->HasWindow(item_widget_->GetNativeWindow())) {
-    hide_windows->RemoveWindow(item_widget_->GetNativeWindow(),
-                               /*show_window=*/false);
-  }
-
-  DestroyMirrorsForDragging();
-  item_widget_.reset();
-  overview_item_view_ = nullptr;
-}
-
-void OverviewItem::PrepareForOverview() {
-  transform_window_.PrepareForOverview();
-  prepared_for_overview_ = true;
-}
-
-float OverviewItem::GetItemScale(const gfx::Size& size) {
-  gfx::SizeF inset_size(size.width(), size.height());
-  return ScopedOverviewTransformWindow::GetItemScale(
-      GetTargetBoundsInScreen().size(), inset_size,
-      transform_window_.GetTopInset(), kHeaderHeightDp);
-}
-
-gfx::RectF OverviewItem::GetTransformedBounds() const {
-  return transform_window_.GetTransformedBounds();
-}
-
-gfx::RectF OverviewItem::GetTargetBoundsInScreen() const {
-  return ::ash::GetTargetBoundsInScreen(transform_window_.window());
-}
-
-gfx::RectF OverviewItem::GetWindowTargetBoundsWithInsets() const {
-  gfx::RectF window_target_bounds = target_bounds_;
-  window_target_bounds.Inset(gfx::InsetsF::TLBR(kHeaderHeightDp, 0, 0, 0));
-  return window_target_bounds;
+OverviewItem* OverviewItem::GetLeafItemForWindow(aura::Window* window) {
+  return window == GetWindow() ? this : nullptr;
 }
 
 void OverviewItem::SetBounds(const gfx::RectF& target_bounds,
@@ -455,8 +389,9 @@
     preview_layer->SetTransform(gfx::Transform());
   }
 
-  if (!is_first_update)
+  if (!is_first_update) {
     return;
+  }
 
   // On the first update show `item_widget_`. It's created on creation of
   // `this`, and needs to be shown as soon as its bounds have been determined
@@ -475,8 +410,9 @@
 
   // If entering from home launcher, use the home specific (fade) animation.
   OverviewAnimationType fade_animation = animation_type;
-  if (fade_animation != OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER)
+  if (fade_animation != OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER) {
     fade_animation = OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN;
+  }
 
   FadeInWidgetToOverview(item_widget_.get(), fade_animation,
                          /*observe=*/true);
@@ -495,168 +431,62 @@
   }
 }
 
-void OverviewItem::SendAccessibleSelectionEvent() {
-  overview_item_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection,
-                                                true);
-}
+void OverviewItem::RestoreWindow(bool reset_transform, bool animate) {
+  // TODO(oshima): SplitViewController has its own logic to adjust the
+  // target state in `SplitViewController::OnOverviewModeEnding`.
+  // Unify the mechanism to control it and remove ifs.
+  if (Shell::Get()->tablet_mode_controller()->InTabletMode() &&
+      !SplitViewController::Get(root_window_)->InSplitViewMode() &&
+      reset_transform) {
+    MaximizeIfSnapped(GetWindow());
+  }
 
-void OverviewItem::AnimateAndCloseWindow(bool up) {
-  base::RecordAction(base::UserMetricsAction("WindowSelector_SwipeToClose"));
+  GetWindow()->ClearProperty(kForceVisibleInMiniViewKey);
+  for (aura::Window* transient_child : GetTransientTreeIterator(GetWindow())) {
+    transient_child->ClearProperty(kForceVisibleInMiniViewKey);
+  }
 
-  animating_to_close_ = true;
-  overview_session_->PositionWindows(/*animate=*/true);
   overview_item_view_->OnOverviewItemWindowRestoring();
+  transform_window_.RestoreWindow(reset_transform, animate);
 
-  int translation_y = kSwipeToCloseCloseTranslationDp * (up ? -1 : 1);
-  gfx::Transform transform;
-  transform.Translate(gfx::Vector2d(0, translation_y));
-
-  auto animate_window = [this](aura::Window* window,
-                               const gfx::Transform& transform, bool observe) {
-    ScopedOverviewAnimationSettings settings(
-        OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM, window);
-    gfx::Transform original_transform = window->transform();
-    original_transform.PostConcat(transform);
-    window->SetTransform(original_transform);
-    if (observe) {
-      settings.AddObserver(new AnimationObserver{
-          base::BindOnce(&OverviewItem::OnWindowCloseAnimationCompleted,
-                         weak_ptr_factory_.GetWeakPtr())});
-    }
-  };
-
-  AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM);
-  if (cannot_snap_widget_)
-    animate_window(cannot_snap_widget_->GetNativeWindow(), transform, false);
-  if (!transform_window_.IsMinimized())
-    animate_window(GetWindow(), transform, false);
-  animate_window(item_widget_->GetNativeWindow(), transform, true);
-}
-
-void OverviewItem::CloseWindow() {
-  SetShadowBounds(absl::nullopt);
-
-  gfx::RectF inset_bounds(target_bounds_);
-  inset_bounds.Inset(gfx::InsetsF::VH(target_bounds_.height() * kPreCloseScale,
-                                      target_bounds_.width() * kPreCloseScale));
-  // Scale down both the window and label.
-  SetBounds(inset_bounds, OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM);
-  // First animate opacity to an intermediate value concurrently with the
-  // scaling animation.
-  AnimateOpacity(kClosingItemOpacity, OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM);
-
-  // Fade out the window and the label, effectively hiding them.
-  AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM);
-
-  // |transform_window_| will delete |this| by deleting the widget associated
-  // with |this|.
-  transform_window_.Close();
-}
-
-void OverviewItem::UpdateCannotSnapWarningVisibility(bool animate) {
-  // Windows which can snap will never show this warning. Or if the window is
-  // the drop target window, also do not show this warning.
-  bool visible = true;
-  if (SplitViewController::Get(root_window_)
-          ->ComputeSnapRatio(GetWindow())
-          .has_value() ||
-      overview_grid_->IsDropTargetWindow(GetWindow())) {
-    visible = false;
-  } else {
-    const SplitViewController::State state =
-        SplitViewController::Get(root_window_)->state();
-    visible = state == SplitViewController::State::kPrimarySnapped ||
-              state == SplitViewController::State::kSecondarySnapped;
-  }
-
-  if (!visible && !cannot_snap_widget_)
+  if (!transform_window_.IsMinimized()) {
     return;
-
-  if (!cannot_snap_widget_) {
-    RoundedLabelWidget::InitParams params;
-    params.horizontal_padding = kSplitviewLabelHorizontalInsetDp;
-    params.vertical_padding = kSplitviewLabelVerticalInsetDp;
-    params.rounding_dp = kSplitviewLabelRoundRectRadiusDp;
-    params.preferred_height = kSplitviewLabelPreferredHeightDp;
-    params.message_id = IDS_ASH_SPLIT_VIEW_CANNOT_SNAP;
-    params.parent = GetWindow()->parent();
-    cannot_snap_widget_ = std::make_unique<RoundedLabelWidget>();
-    cannot_snap_widget_->Init(std::move(params));
-    GetWindow()->parent()->StackChildAbove(
-        cannot_snap_widget_->GetNativeWindow(), GetWindow());
   }
-  if (animate) {
-    DoSplitviewOpacityAnimation(
-        cannot_snap_widget_->GetLayer(),
-        visible ? SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN
-                : SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT);
-  } else {
-    cannot_snap_widget_->GetLayer()->SetOpacity(visible ? 1.f : 0.f);
-  }
-  const gfx::Rect bounds =
-      ToStableSizeRoundedRect(GetWindowTargetBoundsWithInsets());
-  cannot_snap_widget_->SetBoundsCenteredIn(bounds, /*animate=*/false);
-}
 
-void OverviewItem::HideCannotSnapWarning(bool animate) {
-  if (!cannot_snap_widget_)
+  const auto enter_exit_type = overview_session_->enter_exit_overview_type();
+  if (is_moving_to_another_desk_ ||
+      enter_exit_type == OverviewEnterExitType::kImmediateExit) {
+    overview_session_->highlight_controller()->OnViewDestroyingOrDisabling(
+        overview_item_view_);
+    ImmediatelyCloseWidgetOnExit(std::move(item_widget_));
+    overview_item_view_ = nullptr;
     return;
-  if (animate) {
-    DoSplitviewOpacityAnimation(cannot_snap_widget_->GetLayer(),
-                                SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT);
-  } else {
-    cannot_snap_widget_->GetLayer()->SetOpacity(0.f);
   }
+
+  OverviewAnimationType animation_type =
+      GetExitOverviewAnimationTypeForMinimizedWindow(enter_exit_type);
+  FadeOutWidgetFromOverview(std::move(item_widget_), animation_type);
 }
 
-void OverviewItem::OnSelectorItemDragStarted(OverviewItem* item) {
-  is_being_dragged_ = (item == this);
-
-  overview_item_view_->SetHeaderVisibility(
-      is_being_dragged_ && !chromeos::features::IsJellyrollEnabled()
-          ? OverviewItemView::HeaderVisibility::kInvisible
-          : OverviewItemView::HeaderVisibility::kCloseButtonInvisibleOnly,
-      /*animate=*/true);
+gfx::RectF OverviewItem::GetTargetBoundsInScreen() const {
+  return ::ash::GetTargetBoundsInScreen(transform_window_.window());
 }
 
-void OverviewItem::OnSelectorItemDragEnded(bool snap) {
-  if (snap) {
-    if (!is_being_dragged_)
-      overview_item_view_->HideCloseInstantlyAndThenShowItSlowly();
-  } else {
-    overview_item_view_->SetHeaderVisibility(
-        OverviewItemView::HeaderVisibility::kVisible, /*animate=*/true);
-  }
-  is_being_dragged_ = false;
+gfx::RectF OverviewItem::GetWindowTargetBoundsWithInsets() const {
+  gfx::RectF window_target_bounds = target_bounds_;
+  window_target_bounds.Inset(gfx::InsetsF::TLBR(kHeaderHeightDp, 0, 0, 0));
+  return window_target_bounds;
 }
 
-void OverviewItem::SetVisibleDuringWindowDragging(bool visible, bool animate) {
-  aura::Window::Windows windows = GetWindowsForHomeGesture();
-  float new_opacity = visible ? 1.f : 0.f;
-  for (auto* window : windows) {
-    ui::Layer* layer = window->layer();
-    if (layer->GetTargetOpacity() == new_opacity)
-      continue;
-
-    if (animate) {
-      ScopedOverviewAnimationSettings settings(
-          OVERVIEW_ANIMATION_OPACITY_ON_WINDOW_DRAG, window);
-      layer->SetOpacity(new_opacity);
-    } else {
-      layer->SetOpacity(new_opacity);
-    }
-  }
+gfx::RectF OverviewItem::GetTransformedBounds() const {
+  return transform_window_.GetTransformedBounds();
 }
 
-OverviewGridWindowFillMode OverviewItem::GetWindowDimensionsType() const {
-  return transform_window_.type();
-}
-
-void OverviewItem::UpdateWindowDimensionsType() {
-  transform_window_.UpdateWindowDimensionsType();
-  const bool show_backdrop =
-      GetWindowDimensionsType() != OverviewGridWindowFillMode::kNormal;
-  overview_item_view_->SetBackdropVisibility(show_backdrop);
+float OverviewItem::GetItemScale(const gfx::Size& size) {
+  gfx::SizeF inset_size(size.width(), size.height());
+  return ScopedOverviewTransformWindow::GetItemScale(
+      GetTargetBoundsInScreen().size(), inset_size,
+      transform_window_.GetTopInset(), kHeaderHeightDp);
 }
 
 void OverviewItem::ScaleUpSelectedItem(OverviewAnimationType animation_type) {
@@ -678,121 +508,16 @@
   SetBounds(scaled_bounds, animation_type);
 }
 
-void OverviewItem::UpdateItemContentViewForMinimizedWindow() {
-  overview_item_view_->RefreshPreviewView();
+void OverviewItem::EnsureVisible() {
+  transform_window_.EnsureVisible();
 }
 
-bool OverviewItem::IsDragItem() const {
-  return overview_session_->GetCurrentDraggedOverviewItem() == this;
+OverviewHighlightableView* OverviewItem::GetFocusableView() const {
+  return overview_item_view_;
 }
 
-void OverviewItem::Restack() {
-  aura::Window* window = GetWindow();
-  aura::Window* parent_window = window->parent();
-  aura::Window* stacking_target = nullptr;
-
-  // Stack |window| below the split view window if split view is active.
-  SplitViewController* split_view_controller =
-      SplitViewController::Get(root_window_);
-  if (split_view_controller->InSplitViewMode()) {
-    aura::Window* snapped_window =
-        split_view_controller->GetDefaultSnappedWindow();
-    if (snapped_window->parent() == parent_window)
-      stacking_target = snapped_window;
-  }
-  // Stack |window| below the last window in |overview_grid_| that comes before
-  // |window| and has the same parent.
-  for (const std::unique_ptr<OverviewItem>& overview_item :
-       overview_grid_->window_list()) {
-    // |Restack| is sometimes called when there is a drop target, but is never
-    // used to restack an item that comes after a drop target. In other words,
-    // |overview_grid_| might have a drop target, but we will break out of the
-    // for loop before reaching it.
-    DCHECK(!overview_grid_->IsDropTargetWindow(overview_item->GetWindow()));
-    if (overview_item.get() == this)
-      break;
-    if (overview_item->GetWindow()->parent() == parent_window)
-      stacking_target = overview_item->item_widget()->GetNativeWindow();
-  }
-
-  if (stacking_target) {
-    DCHECK_EQ(parent_window, stacking_target->parent());
-    parent_window->StackChildBelow(window, stacking_target);
-  }
-  DCHECK_EQ(parent_window, item_widget_->GetNativeWindow()->parent());
-  parent_window->StackChildBelow(item_widget_->GetNativeWindow(), window);
-  if (cannot_snap_widget_) {
-    DCHECK_EQ(parent_window, cannot_snap_widget_->GetNativeWindow()->parent());
-    parent_window->StackChildAbove(cannot_snap_widget_->GetNativeWindow(),
-                                   window);
-  }
-}
-
-void OverviewItem::UpdateMirrorsForDragging(bool is_touch_dragging) {
-  DCHECK_GT(Shell::GetAllRootWindows().size(), 1u);
-  const bool is_minimized = transform_window_.IsMinimized();
-
-  // With Jellyroll, header is visible while dragging.
-  if (is_minimized || chromeos::features::IsJellyrollEnabled()) {
-    if (!item_mirror_for_dragging_) {
-      item_mirror_for_dragging_ = std::make_unique<DragWindowController>(
-          item_widget_->GetNativeWindow(), is_touch_dragging);
-    }
-    item_mirror_for_dragging_->Update();
-  }
-
-  // Minimized windows don't need to mirror the source as its already in
-  // `item_widget_`.
-  if (is_minimized) {
-    return;
-  }
-
-  if (!window_mirror_for_dragging_) {
-    window_mirror_for_dragging_ =
-        std::make_unique<DragWindowController>(GetWindow(), is_touch_dragging);
-  }
-  window_mirror_for_dragging_->Update();
-}
-
-void OverviewItem::DestroyMirrorsForDragging() {
-  item_mirror_for_dragging_.reset();
-  window_mirror_for_dragging_.reset();
-}
-
-void OverviewItem::SetShadowBounds(
-    absl::optional<gfx::RectF> bounds_in_screen) {
-  // Shadow is normally turned off during animations and reapplied when they
-  // are finished. On destruction, |shadow_| is cleaned up before
-  // |transform_window_|, which may call this function, so early exit if
-  // |shadow_| is nullptr.
-  if (!shadow_)
-    return;
-
-  if (!bounds_in_screen) {
-    shadow_->GetLayer()->SetVisible(false);
-    return;
-  }
-
-  shadow_->GetLayer()->SetVisible(true);
-  gfx::Rect bounds_in_item =
-      gfx::Rect(item_widget_->GetNativeWindow()->GetTargetBounds().size());
-
-  const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled();
-  const bool continuous_scroll =
-      features::IsContinuousOverviewScrollAnimationEnabled() &&
-      Shell::Get()->overview_controller()->is_continuous_scroll_in_progress();
-  if (!is_jellyroll_enabled || continuous_scroll) {
-    bounds_in_item.Inset(gfx::Insets::TLBR(kHeaderHeightDp, 0, 0, 0));
-  }
-
-  bounds_in_item.ClampToCenteredSize(
-      gfx::ToRoundedSize(bounds_in_screen->size()));
-  shadow_->SetContentBounds(bounds_in_item);
-  if (continuous_scroll) {
-    shadow_->SetRoundedCornerRadius(/*radius=*/0.f);
-  } else if (is_jellyroll_enabled) {
-    shadow_->SetRoundedCornerRadius(kOverviewItemCornerRadius);
-  }
+views::View* OverviewItem::GetBackDropView() const {
+  return overview_item_view_->backdrop_view();
 }
 
 void OverviewItem::UpdateRoundedCornersAndShadow() {
@@ -868,14 +593,64 @@
   }
 }
 
-void OverviewItem::UpdateShadowTypeForDrag(bool is_dragging) {
-  shadow_->SetType(is_dragging ? kDraggedShadowType : kDefaultShadowType);
+void OverviewItem::SetShadowBounds(
+    absl::optional<gfx::RectF> bounds_in_screen) {
+  // Shadow is normally turned off during animations and reapplied when they
+  // are finished. On destruction, `shadow_` is cleaned up before
+  // `transform_window_`, which may call this function, so early exit if
+  // `shadow_` is nullptr.
+  if (!shadow_) {
+    return;
+  }
+
+  if (!bounds_in_screen) {
+    shadow_->GetLayer()->SetVisible(false);
+    return;
+  }
+
+  shadow_->GetLayer()->SetVisible(true);
+  gfx::Rect bounds_in_item =
+      gfx::Rect(item_widget_->GetNativeWindow()->GetTargetBounds().size());
+
+  const bool is_jellyroll_enabled = chromeos::features::IsJellyrollEnabled();
+  const bool continuous_scroll =
+      features::IsContinuousOverviewScrollAnimationEnabled() &&
+      Shell::Get()->overview_controller()->is_continuous_scroll_in_progress();
+  if (!is_jellyroll_enabled || continuous_scroll) {
+    bounds_in_item.Inset(gfx::Insets::TLBR(kHeaderHeightDp, 0, 0, 0));
+  }
+
+  bounds_in_item.ClampToCenteredSize(
+      gfx::ToRoundedSize(bounds_in_screen->size()));
+  shadow_->SetContentBounds(bounds_in_item);
+  if (continuous_scroll) {
+    shadow_->SetRoundedCornerRadius(/*corner_radius=*/0.f);
+  } else if (is_jellyroll_enabled) {
+    shadow_->SetRoundedCornerRadius(kOverviewItemCornerRadius);
+  }
+}
+
+void OverviewItem::SetOpacity(float opacity) {
+  item_widget_->SetOpacity(opacity);
+  transform_window_.SetOpacity(opacity);
+  if (cannot_snap_widget_) {
+    cannot_snap_widget_->SetOpacity(opacity);
+  }
+}
+
+float OverviewItem::GetOpacity() const {
+  return item_widget_->GetNativeWindow()->layer()->GetTargetOpacity();
+}
+
+void OverviewItem::PrepareForOverview() {
+  transform_window_.PrepareForOverview();
+  prepared_for_overview_ = true;
 }
 
 void OverviewItem::OnStartingAnimationComplete() {
   DCHECK(item_widget_);
   if (transform_window_.IsMinimized()) {
-    // Fade the title in if minimized. The rest of |item_widget_| should
+    // Fade the title in if minimized. The rest of `item_widget_` should
     // already be shown.
     overview_item_view_->SetHeaderVisibility(
         OverviewItemView::HeaderVisibility::kVisible, /*animate=*/true);
@@ -887,7 +662,7 @@
     if (!Shell::Get()
              ->overview_controller()
              ->is_continuous_scroll_in_progress()) {
-      overview_item_view()->layer()->SetOpacity(1.f);
+      overview_item_view_->layer()->SetOpacity(1.f);
     }
   }
   const bool show_backdrop =
@@ -896,90 +671,130 @@
   UpdateCannotSnapWarningVisibility(/*animate=*/true);
 }
 
-void OverviewItem::StopWidgetAnimation() {
-  DCHECK(item_widget_.get());
-  item_widget_->GetNativeWindow()->layer()->GetAnimator()->StopAnimating();
-}
+void OverviewItem::HideForSavedDeskLibrary(bool animate) {
+  // To hide the window, we will set its layer opacity to 0. This would normally
+  // also hide the window from the mini view, which we don't want. By setting a
+  // property on the window, we can force it to stay visible.
+  GetWindow()->SetProperty(kForceVisibleInMiniViewKey, true);
 
-void OverviewItem::SetOpacity(float opacity) {
-  item_widget_->SetOpacity(opacity);
-  transform_window_.SetOpacity(opacity);
-  if (cannot_snap_widget_)
-    cannot_snap_widget_->SetOpacity(opacity);
-}
-
-float OverviewItem::GetOpacity() {
-  return item_widget_->GetNativeWindow()->layer()->GetTargetOpacity();
-}
-
-OverviewAnimationType OverviewItem::GetExitOverviewAnimationType() const {
-  if (overview_session_->enter_exit_overview_type() ==
-      OverviewEnterExitType::kImmediateExit) {
-    return OVERVIEW_ANIMATION_NONE;
+  // Temporarily hide this window in overview, so that dark/light theme change
+  // does not reset the layer visible. If `animate` is false, the callback will
+  // not run in `PerformFadeOutLayer`. Thus, here we make sure the window is
+  // also hidden in that case.
+  DCHECK(item_widget_);
+  hide_window_in_overview_callback_.Reset(base::BindOnce(
+      &OverviewItem::HideWindowInOverview, weak_ptr_factory_.GetWeakPtr()));
+  PerformFadeOutLayer(item_widget_->GetLayer(), animate,
+                      hide_window_in_overview_callback_.callback());
+  if (!animate) {
+    // Cancel the callback if we are going to run it directly.
+    hide_window_in_overview_callback_.Cancel();
+    HideWindowInOverview();
   }
 
-  return should_animate_when_exiting_
-             ? OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT
-             : OVERVIEW_ANIMATION_NONE;
-}
-
-OverviewAnimationType OverviewItem::GetExitTransformAnimationType() const {
-  if (is_moving_to_another_desk_ ||
-      overview_session_->enter_exit_overview_type() ==
-          OverviewEnterExitType::kImmediateExit) {
-    return OVERVIEW_ANIMATION_NONE;
+  for (aura::Window* transient_child : GetTransientTreeIterator(GetWindow())) {
+    transient_child->SetProperty(kForceVisibleInMiniViewKey, true);
+    PerformFadeOutLayer(transient_child->layer(), animate, base::DoNothing());
   }
 
-  return should_animate_when_exiting_ ? OVERVIEW_ANIMATION_RESTORE_WINDOW
-                                      : OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO;
+  item_widget_event_blocker_ =
+      std::make_unique<aura::ScopedWindowEventTargetingBlocker>(
+          item_widget_->GetNativeWindow());
+
+  HideCannotSnapWarning(animate);
 }
 
-void OverviewItem::HandleGestureEventForTabletModeLayout(
-    ui::GestureEvent* event) {
-  const gfx::PointF location = event->details().bounding_box_f().CenterPoint();
-  switch (event->type()) {
-    case ui::ET_SCROLL_FLING_START:
-      if (IsDragItem()) {
-        HandleFlingStartEvent(location, event->details().velocity_x(),
-                              event->details().velocity_y());
-      } else {
-        overview_grid()->grid_event_handler()->OnGestureEvent(event);
-      }
-      break;
-    case ui::ET_GESTURE_SCROLL_BEGIN:
-      if (std::abs(event->details().scroll_y_hint()) >
-          std::abs(event->details().scroll_x_hint())) {
-        HandlePressEvent(location, /*from_touch_gesture=*/true);
-      } else {
-        overview_grid()->grid_event_handler()->OnGestureEvent(event);
-      }
-      break;
-    case ui::ET_GESTURE_SCROLL_UPDATE:
-      if (IsDragItem())
-        HandleDragEvent(location);
-      else
-        overview_grid()->grid_event_handler()->OnGestureEvent(event);
-      break;
-    case ui::ET_GESTURE_SCROLL_END:
-      if (IsDragItem())
-        HandleReleaseEvent(location);
-      else
-        overview_grid()->grid_event_handler()->OnGestureEvent(event);
-      break;
-    case ui::ET_GESTURE_LONG_PRESS:
-      HandlePressEvent(location, /*from_touch_gesture=*/true);
-      HandleLongPressEvent(location);
-      break;
-    case ui::ET_GESTURE_TAP:
-      overview_session_->SelectWindow(this);
-      break;
-    case ui::ET_GESTURE_END:
-      HandleGestureEndEvent();
-      break;
-    default:
-      overview_grid()->grid_event_handler()->OnGestureEvent(event);
-      break;
+void OverviewItem::RevertHideForSavedDeskLibrary(bool animate) {
+  // This might run before `HideForSavedDeskLibrary()`, thus cancel the
+  // callback to prevent such case.
+  hide_window_in_overview_callback_.Cancel();
+
+  // Restore and show the window back to overview.
+  ShowWindowInOverview();
+
+  // `item_widget_` may be null during shutdown if the window is minimized.
+  if (item_widget_) {
+    PerformFadeInLayer(item_widget_->GetLayer(), animate);
   }
+
+  for (aura::Window* transient_child :
+       GetTransientTreeIterator(transform_window_.window())) {
+    PerformFadeInLayer(transient_child->layer(), animate);
+  }
+
+  item_widget_event_blocker_.reset();
+
+  UpdateCannotSnapWarningVisibility(animate);
+}
+
+void OverviewItem::Restack() {
+  aura::Window* window = GetWindow();
+  aura::Window* parent_window = window->parent();
+  aura::Window* stacking_target = nullptr;
+
+  // Stack `window` below the split view window if split view is active.
+  SplitViewController* split_view_controller =
+      SplitViewController::Get(root_window_);
+  if (split_view_controller->InSplitViewMode()) {
+    aura::Window* snapped_window =
+        split_view_controller->GetDefaultSnappedWindow();
+    if (snapped_window->parent() == parent_window) {
+      stacking_target = snapped_window;
+    }
+  }
+  // Stack `window` below the last window in `overview_grid_` that comes before
+  // `window` and has the same parent.
+  for (const std::unique_ptr<OverviewItemBase>& overview_item :
+       overview_grid_->window_list()) {
+    // `Restack` is sometimes called when there is a drop target, but is never
+    // used to restack an item that comes after a drop target. In other words,
+    // `overview_grid_` might have a drop target, but we will break out of the
+    // for loop before reaching it.
+    DCHECK(!overview_grid_->IsDropTargetWindow(overview_item->GetWindow()));
+    if (overview_item.get() == this) {
+      break;
+    }
+    if (overview_item->GetWindow()->parent() == parent_window) {
+      stacking_target = overview_item->item_widget()->GetNativeWindow();
+    }
+  }
+
+  if (stacking_target) {
+    DCHECK_EQ(parent_window, stacking_target->parent());
+    parent_window->StackChildBelow(window, stacking_target);
+  }
+  DCHECK_EQ(parent_window, item_widget_->GetNativeWindow()->parent());
+  parent_window->StackChildBelow(item_widget_->GetNativeWindow(), window);
+  if (cannot_snap_widget_) {
+    DCHECK_EQ(parent_window, cannot_snap_widget_->GetNativeWindow()->parent());
+    parent_window->StackChildAbove(cannot_snap_widget_->GetNativeWindow(),
+                                   window);
+  }
+}
+
+void OverviewItem::CloseWindow() {
+  SetShadowBounds(absl::nullopt);
+
+  gfx::RectF inset_bounds(target_bounds_);
+  inset_bounds.Inset(gfx::InsetsF::VH(target_bounds_.height() * kPreCloseScale,
+                                      target_bounds_.width() * kPreCloseScale));
+  // Scale down both the window and label.
+  SetBounds(inset_bounds, OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM);
+  // First animate opacity to an intermediate value concurrently with the
+  // scaling animation.
+  AnimateOpacity(kClosingItemOpacity, OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM);
+
+  // Fade out the window and the label, effectively hiding them.
+  AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM);
+
+  // `transform_window_` will delete `this` by deleting the widget associated
+  // with `this`.
+  transform_window_.Close();
+}
+
+void OverviewItem::SendAccessibleSelectionEvent() {
+  overview_item_view_->NotifyAccessibilityEvent(ax::mojom::Event::kSelection,
+                                                true);
 }
 
 void OverviewItem::HandleMouseEvent(const ui::MouseEvent& event) {
@@ -1060,6 +875,265 @@
   overview_session_->OnHighlightedItemClosed(this);
 }
 
+bool OverviewItem::IsDragItem() const {
+  return overview_session_->GetCurrentDraggedOverviewItem() == this;
+}
+
+void OverviewItem::OnOverviewItemDragStarted(OverviewItemBase* item) {
+  is_being_dragged_ = (item == this);
+
+  overview_item_view_->SetHeaderVisibility(
+      is_being_dragged_ && !chromeos::features::IsJellyrollEnabled()
+          ? OverviewItemView::HeaderVisibility::kInvisible
+          : OverviewItemView::HeaderVisibility::kCloseButtonInvisibleOnly,
+      /*animate=*/true);
+}
+
+void OverviewItem::OnOverviewItemDragEnded(bool snap) {
+  if (snap) {
+    if (!is_being_dragged_) {
+      overview_item_view_->HideCloseInstantlyAndThenShowItSlowly();
+    }
+  } else {
+    overview_item_view_->SetHeaderVisibility(
+        OverviewItemView::HeaderVisibility::kVisible, /*animate=*/true);
+  }
+  is_being_dragged_ = false;
+}
+
+void OverviewItem::SetVisibleDuringItemDragging(bool visible, bool animate) {
+  aura::Window::Windows windows = GetWindowsForHomeGesture();
+  float new_opacity = visible ? 1.f : 0.f;
+  for (auto* window : windows) {
+    ui::Layer* layer = window->layer();
+    if (layer->GetTargetOpacity() == new_opacity) {
+      continue;
+    }
+
+    if (animate) {
+      ScopedOverviewAnimationSettings settings(
+          OVERVIEW_ANIMATION_OPACITY_ON_WINDOW_DRAG, window);
+      layer->SetOpacity(new_opacity);
+    } else {
+      layer->SetOpacity(new_opacity);
+    }
+  }
+}
+
+void OverviewItem::UpdateShadowTypeForDrag(bool is_dragging) {
+  shadow_->SetType(is_dragging ? kDraggedShadowType : kDefaultShadowType);
+}
+
+void OverviewItem::UpdateCannotSnapWarningVisibility(bool animate) {
+  // Windows which can snap will never show this warning. Or if the window is
+  // the drop target window, also do not show this warning.
+  bool visible = true;
+  if (SplitViewController::Get(root_window_)
+          ->ComputeSnapRatio(GetWindow())
+          .has_value() ||
+      overview_grid_->IsDropTargetWindow(GetWindow())) {
+    visible = false;
+  } else {
+    const SplitViewController::State state =
+        SplitViewController::Get(root_window_)->state();
+    visible = state == SplitViewController::State::kPrimarySnapped ||
+              state == SplitViewController::State::kSecondarySnapped;
+  }
+
+  if (!visible && !cannot_snap_widget_) {
+    return;
+  }
+
+  if (!cannot_snap_widget_) {
+    RoundedLabelWidget::InitParams params;
+    params.horizontal_padding = kSplitviewLabelHorizontalInsetDp;
+    params.vertical_padding = kSplitviewLabelVerticalInsetDp;
+    params.rounding_dp = kSplitviewLabelRoundRectRadiusDp;
+    params.preferred_height = kSplitviewLabelPreferredHeightDp;
+    params.message_id = IDS_ASH_SPLIT_VIEW_CANNOT_SNAP;
+    params.parent = GetWindow()->parent();
+    cannot_snap_widget_ = std::make_unique<RoundedLabelWidget>();
+    cannot_snap_widget_->Init(std::move(params));
+    GetWindow()->parent()->StackChildAbove(
+        cannot_snap_widget_->GetNativeWindow(), GetWindow());
+  }
+  if (animate) {
+    DoSplitviewOpacityAnimation(
+        cannot_snap_widget_->GetLayer(),
+        visible ? SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN
+                : SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT);
+  } else {
+    cannot_snap_widget_->GetLayer()->SetOpacity(visible ? 1.f : 0.f);
+  }
+  const gfx::Rect bounds =
+      ToStableSizeRoundedRect(GetWindowTargetBoundsWithInsets());
+  cannot_snap_widget_->SetBoundsCenteredIn(bounds, /*animate=*/false);
+}
+
+void OverviewItem::HideCannotSnapWarning(bool animate) {
+  if (!cannot_snap_widget_) {
+    return;
+  }
+  if (animate) {
+    DoSplitviewOpacityAnimation(cannot_snap_widget_->GetLayer(),
+                                SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT);
+  } else {
+    cannot_snap_widget_->GetLayer()->SetOpacity(0.f);
+  }
+}
+
+void OverviewItem::OnMovingItemToAnotherDesk() {
+  is_moving_to_another_desk_ = true;
+  // Restore the dragged item window, so that its transform is reset to
+  // identity.
+  RestoreWindow(/*reset_transform=*/true, /*animate=*/true);
+}
+
+void OverviewItem::UpdateMirrorsForDragging(bool is_touch_dragging) {
+  DCHECK_GT(Shell::GetAllRootWindows().size(), 1u);
+  const bool is_minimized = transform_window_.IsMinimized();
+
+  // With Jellyroll, header is visible while dragging.
+  if (is_minimized || chromeos::features::IsJellyrollEnabled()) {
+    if (!item_mirror_for_dragging_) {
+      item_mirror_for_dragging_ = std::make_unique<DragWindowController>(
+          item_widget_->GetNativeWindow(), is_touch_dragging);
+    }
+    item_mirror_for_dragging_->Update();
+  }
+
+  // Minimized windows don't need to mirror the source as its already in
+  // `item_widget_`.
+  if (is_minimized) {
+    return;
+  }
+
+  if (!window_mirror_for_dragging_) {
+    window_mirror_for_dragging_ =
+        std::make_unique<DragWindowController>(GetWindow(), is_touch_dragging);
+  }
+  window_mirror_for_dragging_->Update();
+}
+
+void OverviewItem::DestroyMirrorsForDragging() {
+  item_mirror_for_dragging_.reset();
+  window_mirror_for_dragging_.reset();
+}
+
+void OverviewItem::Shutdown() {
+  TRACE_EVENT0("ui", "OverviewItem::Shutdown");
+  // If `hide_windows` still manages the visibility of this overview item
+  // window, remove it from the list without showing.
+  ScopedOverviewHideWindows* hide_windows =
+      overview_session_->hide_windows_for_saved_desks_grid();
+  if (item_widget_ && hide_windows &&
+      hide_windows->HasWindow(item_widget_->GetNativeWindow())) {
+    hide_windows->RemoveWindow(item_widget_->GetNativeWindow(),
+                               /*show_window=*/false);
+  }
+
+  DestroyMirrorsForDragging();
+  item_widget_.reset();
+  overview_item_view_ = nullptr;
+}
+
+void OverviewItem::AnimateAndCloseItem(bool up) {
+  base::RecordAction(base::UserMetricsAction("WindowSelector_SwipeToClose"));
+
+  animating_to_close_ = true;
+  overview_session_->PositionWindows(/*animate=*/true);
+  overview_item_view_->OnOverviewItemWindowRestoring();
+
+  int translation_y = kSwipeToCloseCloseTranslationDp * (up ? -1 : 1);
+  gfx::Transform transform;
+  transform.Translate(gfx::Vector2d(0, translation_y));
+
+  auto animate_window = [this](aura::Window* window,
+                               const gfx::Transform& transform, bool observe) {
+    ScopedOverviewAnimationSettings settings(
+        OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM, window);
+    gfx::Transform original_transform = window->transform();
+    original_transform.PostConcat(transform);
+    window->SetTransform(original_transform);
+    if (observe) {
+      settings.AddObserver(new AnimationObserver{
+          base::BindOnce(&OverviewItem::OnWindowCloseAnimationCompleted,
+                         weak_ptr_factory_.GetWeakPtr())});
+    }
+  };
+
+  AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM);
+  if (cannot_snap_widget_) {
+    animate_window(cannot_snap_widget_->GetNativeWindow(), transform, false);
+  }
+  if (!transform_window_.IsMinimized()) {
+    animate_window(GetWindow(), transform, false);
+  }
+  animate_window(item_widget_->GetNativeWindow(), transform, true);
+}
+
+void OverviewItem::StopWidgetAnimation() {
+  CHECK(item_widget_.get());
+  item_widget_->GetNativeWindow()->layer()->GetAnimator()->StopAnimating();
+}
+
+OverviewGridWindowFillMode OverviewItem::GetWindowDimensionsType() const {
+  return transform_window_.type();
+}
+
+void OverviewItem::UpdateWindowDimensionsType() {
+  transform_window_.UpdateWindowDimensionsType();
+  const bool show_backdrop =
+      GetWindowDimensionsType() != OverviewGridWindowFillMode::kNormal;
+  overview_item_view_->SetBackdropVisibility(show_backdrop);
+}
+
+void OverviewItem::CreateItemWidget() {
+  TRACE_EVENT0("ui", "OverviewItem::CreateItemWidget");
+
+  views::Widget::InitParams params;
+  params.type = views::Widget::InitParams::TYPE_POPUP;
+  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+  params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
+  params.visible_on_all_workspaces = true;
+  params.layer_type = ui::LAYER_NOT_DRAWN;
+  params.name = "OverviewItemWidget";
+  params.activatable = views::Widget::InitParams::Activatable::kDefault;
+  params.accept_events = true;
+  params.parent = transform_window_.window()->parent();
+  params.init_properties_container.SetProperty(kHideInDeskMiniViewKey, true);
+
+  item_widget_ = std::make_unique<views::Widget>();
+  item_widget_->set_focus_on_creation(false);
+  item_widget_->Init(std::move(params));
+  aura::Window* widget_window = item_widget_->GetNativeWindow();
+  widget_window->parent()->StackChildBelow(widget_window, GetWindow());
+
+  shadow_ = SystemShadow::CreateShadowOnNinePatchLayer(kDefaultShadowType);
+  auto* shadow_layer = shadow_->GetLayer();
+  auto* widget_layer = item_widget_->GetLayer();
+  widget_layer->Add(shadow_layer);
+  widget_layer->StackAtBottom(shadow_layer);
+  shadow_->ObserveColorProviderSource(item_widget_.get());
+
+  overview_item_view_ =
+      item_widget_->SetContentsView(std::make_unique<OverviewItemView>(
+          this,
+          base::BindRepeating(&OverviewItem::CloseButtonPressed,
+                              base::Unretained(this)),
+          GetWindow(), transform_window_.IsMinimized()));
+  item_widget_->Show();
+  item_widget_->SetOpacity(
+      overview_session_ && overview_session_->ShouldEnterWithoutAnimations()
+          ? 1.f
+          : 0.f);
+  widget_layer->SetMasksToBounds(false);
+}
+
+gfx::Point OverviewItem::GetMagnifierFocusPointInScreen() const {
+  return overview_item_view_->GetMagnifierFocusPointInScreen();
+}
+
 void OverviewItem::OnWindowPropertyChanged(aura::Window* window,
                                            const void* key,
                                            intptr_t old) {
@@ -1099,7 +1173,7 @@
     return;
 
   // The drop target will get its bounds set as opposed to its transform
-  // set in |SetItemBounds| so do not position windows again when that
+  // set in `SetItemBounds` so do not position windows again when that
   // particular window has its bounds changed.
   if (overview_grid_->IsDropTargetWindow(window))
     return;
@@ -1359,48 +1433,6 @@
   transform_window_.SetClipping(clipping_data);
 }
 
-void OverviewItem::CreateItemWidget() {
-  TRACE_EVENT0("ui", "OverviewItem::CreateItemWidget");
-
-  views::Widget::InitParams params;
-  params.type = views::Widget::InitParams::TYPE_POPUP;
-  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
-  params.opacity = views::Widget::InitParams::WindowOpacity::kTranslucent;
-  params.visible_on_all_workspaces = true;
-  params.layer_type = ui::LAYER_NOT_DRAWN;
-  params.name = "OverviewItemWidget";
-  params.activatable = views::Widget::InitParams::Activatable::kDefault;
-  params.accept_events = true;
-  params.parent = transform_window_.window()->parent();
-  params.init_properties_container.SetProperty(kHideInDeskMiniViewKey, true);
-
-  item_widget_ = std::make_unique<views::Widget>();
-  item_widget_->set_focus_on_creation(false);
-  item_widget_->Init(std::move(params));
-  aura::Window* widget_window = item_widget_->GetNativeWindow();
-  widget_window->parent()->StackChildBelow(widget_window, GetWindow());
-
-  shadow_ = SystemShadow::CreateShadowOnNinePatchLayer(kDefaultShadowType);
-  auto* shadow_layer = shadow_->GetLayer();
-  auto* widget_layer = item_widget_->GetLayer();
-  widget_layer->Add(shadow_layer);
-  widget_layer->StackAtBottom(shadow_layer);
-  shadow_->ObserveColorProviderSource(item_widget_.get());
-
-  overview_item_view_ =
-      item_widget_->SetContentsView(std::make_unique<OverviewItemView>(
-          this,
-          base::BindRepeating(&OverviewItem::CloseButtonPressed,
-                              base::Unretained(this)),
-          GetWindow(), transform_window_.IsMinimized()));
-  item_widget_->Show();
-  item_widget_->SetOpacity(
-      overview_session_ && overview_session_->ShouldEnterWithoutAnimations()
-          ? 1.f
-          : 0.f);
-  widget_layer->SetMasksToBounds(false);
-}
-
 void OverviewItem::UpdateHeaderLayout(OverviewAnimationType animation_type) {
   if (chromeos::features::IsJellyrollEnabled()) {
     UpdateHeaderLayoutCrOSNext(animation_type);
diff --git a/ash/wm/overview/overview_item.h b/ash/wm/overview/overview_item.h
index fcffc178..9507793c 100644
--- a/ash/wm/overview/overview_item.h
+++ b/ash/wm/overview/overview_item.h
@@ -9,36 +9,37 @@
 
 #include "ash/ash_export.h"
 #include "ash/scoped_animation_disabler.h"
-#include "ash/wm/overview/overview_session.h"
+#include "ash/wm/overview/overview_item_base.h"
 #include "ash/wm/overview/scoped_overview_transform_window.h"
 #include "ash/wm/window_state_observer.h"
 #include "base/cancelable_callback.h"
-#include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/aura/scoped_window_event_targeting_blocker.h"
-#include "ui/aura/window.h"
 #include "ui/aura/window_observer.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/gfx/geometry/rect_f.h"
-#include "ui/views/controls/button/button.h"
 
-namespace views {
-class Widget;
-}  // namespace views
+namespace aura {
+class Window;
+}  // namespace aura
+
+namespace gfx {
+class Rect;
+class RectF;
+}  // namespace gfx
 
 namespace ash {
 class DragWindowController;
 class OverviewGrid;
 class OverviewItemView;
-class RoundedLabelWidget;
-class SystemShadow;
+class OverviewSession;
 
-// This class represents an item in overview mode. It handles placing the window
-// in the correct bounds given by `OverviewGrid`, and owns a widget which
-// contains an item's overview specific ui (title, icon, close button, etc.).
-class ASH_EXPORT OverviewItem : public aura::WindowObserver,
+// This class implements `OverviewItemBase` and represents a single window in
+// overview mode. It handles placing the window in the correct bounds given by
+// `OverviewGrid`, and owns a widget which contains an item's overview specific
+// ui (title, icon, close button, etc.).
+class ASH_EXPORT OverviewItem : public OverviewItemBase,
+                                public aura::WindowObserver,
                                 public WindowStateObserver {
  public:
   OverviewItem(aura::Window* window,
@@ -50,147 +51,11 @@
 
   ~OverviewItem() override;
 
-  aura::Window* GetWindow();
-
-  // Returns true if |target| is contained in this OverviewItem.
-  bool Contains(const aura::Window* target) const;
-
-  // This called when the window is dragged and dropped on the mini view of
-  // another desk, which prepares this item for being removed from the grid, and
-  // the window to restore its transform.
-  void OnMovingWindowToAnotherDesk();
-
-  // Restores and animates the managed window to its non overview mode state.
-  // Doesn't animate if `animate` is true. If `reset_transform` equals false,
-  // the window's transform will not be reset to identity transform when exiting
-  // overview mode. It's needed when dragging an Arc app window in overview mode
-  // to put it in split screen. In this case the restore of its transform needs
-  // to be deferred until the Arc app window is snapped successfully, otherwise
-  // the animation will look very ugly (the Arc app window enlarges itself to
-  // maximized window bounds and then shrinks to its snapped window bounds).
-  // Note if the window's transform is not reset here, it must be reset by
-  // someone else at some point.
-  void RestoreWindow(bool reset_transform, bool animate);
-
-  // Ensures that a possibly minimized window becomes visible after restore.
-  void EnsureVisible();
-
-  // Restores stacking of window captions above the windows, then fades out.
-  void Shutdown();
-
-  // Hides the overview item. This is used to hide any overview items that may
-  // be present when entering the saved desk library. Animates `item_widget_`
-  // and the windows in the transient tree to 0 opacity if `animate` is true,
-  // otherwise just sets them to 0 opacity.
-  void HideForSavedDeskLibrary(bool animate);
-
-  // This shows overview items that were hidden by the saved desk library.
-  // Called when exiting the saved desk library and going back to the overview
-  // grid. Fades the overview items in if `animate` is true, otherwise shows
-  // them immediately.
-  void RevertHideForSavedDeskLibrary(bool animate);
-
-  // Dispatched before beginning window overview. This will do any necessary
-  // one time actions such as restoring minimized windows.
-  void PrepareForOverview();
-
-  // Calculates and returns an optimal scale ratio. With MD this is only
-  // taking into account |size.height()| as the width can vary. Without MD this
-  // returns the scale that allows the item to fully fit within |size|.
-  float GetItemScale(const gfx::Size& size);
-
-  // Returns the union of the original target bounds of all transformed windows
-  // managed by |this| item, i.e. all regular (normal or panel transient
-  // descendants of the window returned by GetWindow()).
-  gfx::RectF GetTargetBoundsInScreen() const;
-
-  // Returns the transformed bound of |transform_window_|.
-  gfx::RectF GetTransformedBounds() const;
-
-  // Returns the target bounds of `window_`. Same as `target_bounds_`, with some
-  // insets.
-  gfx::RectF GetWindowTargetBoundsWithInsets() const;
-
-  // Sets the bounds of this overview item to |target_bounds| in the
-  // |root_window_| root window. The bounds change will be animated as specified
-  // by |animation_type|.
-  void SetBounds(const gfx::RectF& target_bounds,
-                 OverviewAnimationType animation_type);
-
-  // Sends an accessibility event indicating that this window became selected
-  // so that it is highlighted and announced.
-  void SendAccessibleSelectionEvent();
-
-  // Slides the item up or down and then closes the associated window. Used by
-  // overview swipe to close.
-  void AnimateAndCloseWindow(bool up);
-
-  // Closes |transform_window_|.
-  void CloseWindow();
-
-  // Shows the cannot snap warning if currently in splitview, and the associated
-  // window cannot be snapped.
-  void UpdateCannotSnapWarningVisibility(bool animate);
-
-  // Hides the cannot snap warning (if it was showing) until the next call to
-  // |UpdateCannotSnapWarningVisibility|.
-  void HideCannotSnapWarning(bool animate);
-
-  // Called when a OverviewItem on any grid is dragged. Hides the close button
-  // when a drag is started, and reshows it when a drag is finished.
-  // Additionally hides the title and window icon if |item| is this.
-  void OnSelectorItemDragStarted(OverviewItem* item);
-  void OnSelectorItemDragEnded(bool snap);
-
-  // Shows/Hides window item during window dragging. Used when swiping up a
-  // window from shelf.
-  void SetVisibleDuringWindowDragging(bool visible, bool animate);
-
-  OverviewGridWindowFillMode GetWindowDimensionsType() const;
-
-  // Recalculates the window dimensions type of |transform_window_|. Called when
-  // |window_|'s bounds change.
-  void UpdateWindowDimensionsType();
-
-  // Increases the bounds of the dragged item.
-  void ScaleUpSelectedItem(OverviewAnimationType animation_type);
+  OverviewItemView* overview_item_view() { return overview_item_view_; }
 
   // If the window item represents a minimized window, update its content view.
   void UpdateItemContentViewForMinimizedWindow();
 
-  // Checks if this item is currently being dragged.
-  bool IsDragItem() const;
-
-  // Inserts the window back to its original stacking order so that the order of
-  // windows is the same as when entering overview.
-  void Restack();
-
-  // Updates and maybe creates the mirrors needed for multi display dragging.
-  void UpdateMirrorsForDragging(bool is_touch_dragging);
-
-  void DestroyMirrorsForDragging();
-
-  // Sets the bounds of the window shadow. If |bounds_in_screen| is nullopt,
-  // the shadow is hidden.
-  void SetShadowBounds(absl::optional<gfx::RectF> bounds_in_screen);
-
-  // Updates the rounded corners and shadow on this overview window item.
-  void UpdateRoundedCornersAndShadow();
-
-  // Updates the shadow type while being dragged and dropped.
-  void UpdateShadowTypeForDrag(bool is_dragging);
-
-  // Called when the starting animation is completed, or called immediately
-  // if there was no starting animation.
-  void OnStartingAnimationComplete();
-
-  // Stops the current animation of |item_widget_|.
-  void StopWidgetAnimation();
-
-  // Changes the opacity of all the windows the item owns.
-  void SetOpacity(float opacity);
-  float GetOpacity();
-
   OverviewAnimationType GetExitOverviewAnimationType() const;
   OverviewAnimationType GetExitTransformAnimationType() const;
 
@@ -198,11 +63,54 @@
   // might want to process scroll events on the item.
   void HandleGestureEventForTabletModeLayout(ui::GestureEvent* event);
 
-  // Handles events forwarded from |overview_item_view_|.
-  void HandleMouseEvent(const ui::MouseEvent& event);
-  void HandleGestureEvent(ui::GestureEvent* event);
-  void OnHighlightedViewActivated();
-  void OnHighlightedViewClosed();
+  // OverviewItemBase:
+  aura::Window* GetWindow() override;
+  std::vector<aura::Window*> GetWindows() override;
+  bool Contains(const aura::Window* target) const override;
+  OverviewItem* GetLeafItemForWindow(aura::Window* window) override;
+  void RestoreWindow(bool reset_transform, bool animate) override;
+  void SetBounds(const gfx::RectF& target_bounds,
+                 OverviewAnimationType animation_type) override;
+  float GetItemScale(const gfx::Size& size) override;
+  void ScaleUpSelectedItem(OverviewAnimationType animation_type) override;
+  void EnsureVisible() override;
+  gfx::RectF GetTargetBoundsInScreen() const override;
+  gfx::RectF GetWindowTargetBoundsWithInsets() const override;
+  gfx::RectF GetTransformedBounds() const override;
+  OverviewHighlightableView* GetFocusableView() const override;
+  views::View* GetBackDropView() const override;
+  void UpdateRoundedCornersAndShadow() override;
+  void SetShadowBounds(absl::optional<gfx::RectF> bounds_in_screen) override;
+  void SetOpacity(float opacity) override;
+  float GetOpacity() const override;
+  void PrepareForOverview() override;
+  void OnStartingAnimationComplete() override;
+  void HideForSavedDeskLibrary(bool animate) override;
+  void RevertHideForSavedDeskLibrary(bool animate) override;
+  void Restack() override;
+  void CloseWindow() override;
+  void SendAccessibleSelectionEvent() override;
+  void HandleMouseEvent(const ui::MouseEvent& event) override;
+  void HandleGestureEvent(ui::GestureEvent* event) override;
+  void OnHighlightedViewActivated() override;
+  void OnHighlightedViewClosed() override;
+  bool IsDragItem() const override;
+  void OnOverviewItemDragStarted(OverviewItemBase* item) override;
+  void OnOverviewItemDragEnded(bool snap) override;
+  void SetVisibleDuringItemDragging(bool visible, bool animate) override;
+  void UpdateShadowTypeForDrag(bool is_dragging) override;
+  void UpdateCannotSnapWarningVisibility(bool animate) override;
+  void HideCannotSnapWarning(bool animate) override;
+  void OnMovingItemToAnotherDesk() override;
+  void UpdateMirrorsForDragging(bool is_touch_dragging) override;
+  void DestroyMirrorsForDragging() override;
+  void Shutdown() override;
+  void AnimateAndCloseItem(bool up) override;
+  void StopWidgetAnimation() override;
+  OverviewGridWindowFillMode GetWindowDimensionsType() const override;
+  void UpdateWindowDimensionsType() override;
+  void CreateItemWidget() override;
+  gfx::Point GetMagnifierFocusPointInScreen() const override;
 
   // aura::WindowObserver:
   void OnWindowPropertyChanged(aura::Window* window,
@@ -220,61 +128,6 @@
   void OnPostWindowStateTypeChange(WindowState* window_state,
                                    chromeos::WindowStateType old_type) override;
 
-  // Returns the root window on which this item is shown.
-  aura::Window* root_window() { return root_window_; }
-
-  const gfx::RectF& target_bounds() const { return target_bounds_; }
-
-  views::Widget* item_widget() { return item_widget_.get(); }
-
-  OverviewItemView* overview_item_view() { return overview_item_view_; }
-
-  OverviewGrid* overview_grid() { return overview_grid_; }
-
-  bool is_moving_to_another_desk() const { return is_moving_to_another_desk_; }
-
-  void set_should_use_spawn_animation(bool value) {
-    should_use_spawn_animation_ = value;
-  }
-  bool should_use_spawn_animation() const {
-    return should_use_spawn_animation_;
-  }
-
-  void set_should_animate_when_entering(bool should_animate) {
-    should_animate_when_entering_ = should_animate;
-  }
-  bool should_animate_when_entering() const {
-    return should_animate_when_entering_;
-  }
-
-  void set_should_animate_when_exiting(bool should_animate) {
-    should_animate_when_exiting_ = should_animate;
-  }
-  bool should_animate_when_exiting() const {
-    return should_animate_when_exiting_;
-  }
-
-  void set_should_restack_on_animation_end(bool val) {
-    should_restack_on_animation_end_ = val;
-  }
-
-  bool animating_to_close() const { return animating_to_close_; }
-
-  void set_unclipped_size(absl::optional<gfx::Size> unclipped_size) {
-    unclipped_size_ = unclipped_size;
-  }
-
-  void set_scrolling_bounds(absl::optional<gfx::RectF> scrolling_bounds) {
-    scrolling_bounds_ = scrolling_bounds;
-  }
-  absl::optional<gfx::RectF> scrolling_bounds() const {
-    return scrolling_bounds_;
-  }
-
-  void set_target_bounds_for_testing(const gfx::RectF& target_bounds) {
-    target_bounds_ = target_bounds;
-  }
-
  private:
   friend class OverviewTestBase;
   FRIEND_TEST_ALL_PREFIXES(SplitViewOverviewSessionTest, Clipping);
@@ -302,9 +155,6 @@
                      OverviewAnimationType animation_type,
                      bool is_first_update);
 
-  // Creates |item_widget_|, which holds |overview_item_view_|.
-  void CreateItemWidget();
-
   // Updates the |item_widget|'s bounds. Any change in bounds will be animated
   // from the current bounds to the new bounds as per the |animation_type|.
   void UpdateHeaderLayout(OverviewAnimationType animation_type);
@@ -362,30 +212,16 @@
   std::unique_ptr<aura::ScopedWindowEventTargetingBlocker>
       item_widget_event_blocker_;
 
-  // The target bounds this overview item is fit within. When in splitview,
-  // |item_widget_| is fit within these bounds, but the window itself is
-  // transformed to |unclipped_size_|, and then clipped.
-  gfx::RectF target_bounds_;
-
   // True if running SetItemBounds. This prevents recursive calls resulting from
   // the bounds update when calling ::wm::RecreateWindowLayers to copy
   // a window layer for display on another monitor.
   bool in_bounds_update_ = false;
 
-  // A widget stacked under the |transform_window_|. The widget has
-  // |overview_item_view_| as its contents view. The widget is backed by a
-  // NOT_DRAWN layer since most of its surface is transparent.
-  std::unique_ptr<views::Widget> item_widget_;
-
   // The view associated with |item_widget_|. Contains a title, close button and
   // maybe a backdrop. Forwards certain events to |this|.
   raw_ptr<OverviewItemView, DanglingUntriaged | ExperimentalAsh>
       overview_item_view_ = nullptr;
 
-  // A widget with text that may show up on top of |transform_window_| to notify
-  // users this window cannot be snapped.
-  std::unique_ptr<RoundedLabelWidget> cannot_snap_widget_;
-
   // Responsible for mirrors that look like the window on all displays during
   // dragging.
   // TODO(sammiequon): We need two, one for the `item_widget_` and one for the
@@ -394,35 +230,6 @@
   std::unique_ptr<DragWindowController> item_mirror_for_dragging_;
   std::unique_ptr<DragWindowController> window_mirror_for_dragging_;
 
-  // Pointer to the Overview that owns the OverviewGrid containing |this|.
-  // Guaranteed to be non-null for the lifetime of |this|.
-  raw_ptr<OverviewSession, ExperimentalAsh> overview_session_;
-
-  // Pointer to the OverviewGrid that contains |this|. Guaranteed to be non-null
-  // for the lifetime of |this|.
-  raw_ptr<OverviewGrid, ExperimentalAsh> overview_grid_;
-
-  // True when the item is dragged and dropped on another desk's mini view. This
-  // causes it to restore its transform immediately without any animations,
-  // since it is moving to an inactive desk, and therefore won't be visible.
-  bool is_moving_to_another_desk_ = false;
-
-  // True if this item should be added to an active overview session using the
-  // spawn animation on its first update. This implies an animation type of
-  // OVERVIEW_ANIMATION_SPAWN_ITEM_IN_OVERVIEW. This value will be reset to
-  // false once the spawn animation is performed.
-  bool should_use_spawn_animation_ = false;
-
-  // True if the contained window should animate during the entering animation.
-  bool should_animate_when_entering_ = true;
-
-  // True if the contained window should animate during the exiting animation.
-  bool should_animate_when_exiting_ = true;
-
-  // True if after an animation, we need to reorder the stacking order of the
-  // widgets.
-  bool should_restack_on_animation_end_ = false;
-
   // True if the windows are still alive so they can have a closing animation.
   // These windows should not be used in calculations for
   // OverviewGrid::PositionWindows.
@@ -433,24 +240,6 @@
 
   bool prepared_for_overview_ = false;
 
-  // This has a value when there is a snapped window, or a window about to be
-  // snapped (triggering a splitview preview area). This will be set when items
-  // are positioned in OverviewGrid. The bounds delivered in |SetBounds| are the
-  // true bounds of this item, but we want to maintain the aspect ratio of the
-  // window, who's bounds are not set to split view size. So in |SetItemBounds|,
-  // we transform the window not to |target_bounds_| but to this value, and then
-  // apply clipping on the window to |target_bounds_|.
-  absl::optional<gfx::Size> unclipped_size_ = absl::nullopt;
-
-  // The shadow around the overview window. Shadows the original window, not
-  // |item_widget_|. Done here instead of on the original window because of the
-  // rounded edges mask applied on entering overview window.
-  std::unique_ptr<SystemShadow> shadow_;
-
-  // Cached values of the item bounds so that they do not have to be calculated
-  // on each scroll update. Will be nullopt unless a grid scroll is underway.
-  absl::optional<gfx::RectF> scrolling_bounds_ = absl::nullopt;
-
   // Disable animations on the contained window while it is being managed by the
   // overview item.
   ScopedAnimationDisabler animation_disabler_;
diff --git a/ash/wm/overview/overview_item_base.cc b/ash/wm/overview/overview_item_base.cc
index 6ba3b2e..9314d49 100644
--- a/ash/wm/overview/overview_item_base.cc
+++ b/ash/wm/overview/overview_item_base.cc
@@ -19,4 +19,15 @@
 
 OverviewItemBase::~OverviewItemBase() = default;
 
+// static
+std::unique_ptr<OverviewItemBase> OverviewItemBase::Create(
+    aura::Window* window,
+    OverviewSession* overview_session,
+    OverviewGrid* overview_grid) {
+  // TODO(b/295067715): Use switch to build different types of overview items
+  // by checking whether the given `window` belongs to a snap group or not.
+  return std::make_unique<OverviewItem>(window, overview_session,
+                                        overview_grid);
+}
+
 }  // namespace ash
diff --git a/ash/wm/overview/overview_item_base.h b/ash/wm/overview/overview_item_base.h
index 4913cbf2..85838c1 100644
--- a/ash/wm/overview/overview_item_base.h
+++ b/ash/wm/overview/overview_item_base.h
@@ -8,8 +8,12 @@
 #include <memory>
 #include <vector>
 
+#include "ash/style/system_shadow.h"
 #include "ash/wm/overview/overview_types.h"
+#include "base/allocator/partition_allocator/pointers/raw_ptr.h"
 #include "base/memory/raw_ptr.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "ui/events/event.h"
 
 namespace aura {
 class Window;
@@ -19,6 +23,11 @@
 class RectF;
 }  // namespace gfx
 
+namespace ui {
+class GestureEvent;
+class MouseEvent;
+}  // namespace ui
+
 namespace views {
 class View;
 class Widget;
@@ -28,8 +37,10 @@
 
 class OverviewGrid;
 class OverviewHighlightableView;
+class OverviewItem;
 class OverviewSession;
 class RoundedLabelWidget;
+class SystemShadow;
 
 // Defines the interface for the overview item which will be implemented by
 // `OverviewItem` and `OverviewGroupItem`. The `OverviewGrid` owns the instance
@@ -46,23 +57,89 @@
   // Creates an instance of the `OverviewItemBase` given the overview item
   // `type`.
   static std::unique_ptr<OverviewItemBase> Create(
-      OverviewItemType type,
       aura::Window* window,
       OverviewSession* overview_session,
       OverviewGrid* overview_grid);
 
-  // Creates `item_widget_`, which holds `overview_item_view_`.
-  virtual void CreateItemWidget(OverviewItemType type) = 0;
+  void set_should_animate_when_entering(bool should_animate) {
+    should_animate_when_entering_ = should_animate;
+  }
+  bool should_animate_when_entering() const {
+    return should_animate_when_entering_;
+  }
 
-  virtual views::Widget* GetItemWidget() = 0;
+  bool should_animate_when_exiting() const {
+    return should_animate_when_exiting_;
+  }
+
+  void set_should_animate_when_exiting(bool should_animate) {
+    should_animate_when_exiting_ = should_animate;
+  }
+
+  void set_should_restack_on_animation_end(bool val) {
+    should_restack_on_animation_end_ = val;
+  }
+
+  aura::Window* root_window() { return root_window_; }
+
+  OverviewGrid* overview_grid() { return overview_grid_; }
+
+  views::Widget* item_widget() { return item_widget_.get(); }
+
+  const gfx::RectF& target_bounds() const { return target_bounds_; }
+
+  bool is_moving_to_another_desk() const { return is_moving_to_another_desk_; }
+
+  bool animating_to_close() const { return animating_to_close_; }
+
+  void set_unclipped_size(absl::optional<gfx::Size> unclipped_size) {
+    unclipped_size_ = unclipped_size;
+  }
+
+  void set_scrolling_bounds(absl::optional<gfx::RectF> scrolling_bounds) {
+    scrolling_bounds_ = scrolling_bounds;
+  }
+  absl::optional<gfx::RectF> scrolling_bounds() const {
+    return scrolling_bounds_;
+  }
+
+  void set_should_use_spawn_animation(bool value) {
+    should_use_spawn_animation_ = value;
+  }
+  bool should_use_spawn_animation() const {
+    return should_use_spawn_animation_;
+  }
+
+  // Returns the window associated with this, which can be a single window or
+  // a list of windows.
+  // TODO(michelefan): This is temporarily added to reduce the scope of the
+  // task, which will be replaced by `GetWindows()` in a follow-up cl.
+  virtual aura::Window* GetWindow() = 0;
 
   // Returns the window(s) associated with this, which can be a single window or
   // a list of windows.
   virtual std::vector<aura::Window*> GetWindows() = 0;
 
-  // Sets the bounds of this to `target_bounds` in the
-  // `root_window_`. The bounds change will be animated as specified by
-  // `animation_type`.
+  // Returns true if `target` is contained in this OverviewItem.
+  virtual bool Contains(const aura::Window* target) const = 0;
+
+  // Returns the direct `OverviewItem` that represents the given `window`.
+  virtual OverviewItem* GetLeafItemForWindow(aura::Window* window) = 0;
+
+  // Restores and animates the managed window(s) to its non overview mode state.
+  // Doesn't animate if `animate` is true. If `reset_transform` equals false,
+  // the window's transform will not be reset to identity transform when exiting
+  // overview mode. It's needed when dragging an Arc app window in overview mode
+  // to put it in split screen. In this case the restore of its transform needs
+  // to be deferred until the Arc app window is snapped successfully, otherwise
+  // the animation will look very ugly (the Arc app window enlarges itself to
+  // maximized window bounds and then shrinks to its snapped window bounds).
+  // Note if the window's transform is not reset here, it must be reset by
+  // someone else at some point.
+  virtual void RestoreWindow(bool reset_transform, bool animate) = 0;
+
+  // Sets the bounds of this to `target_bounds` in the `root_window_`. The
+  // bounds change will be animated as specified by `animation_type`.
   virtual void SetBounds(const gfx::RectF& target_bounds,
                          OverviewAnimationType animation_type) = 0;
 
@@ -71,15 +148,41 @@
   // of the window returned by `GetWindows()`).
   virtual gfx::RectF GetTargetBoundsInScreen() const = 0;
 
-  // Returns the contents view of this.
-  virtual views::View* GetView() const = 0;
+  // Returns the target bounds of `window_`. Same as `target_bounds_`, with some
+  // insets.
+  virtual gfx::RectF GetWindowTargetBoundsWithInsets() const = 0;
+
+  // Returns the transformed bound of `transform_window_`.
+  virtual gfx::RectF GetTransformedBounds() const = 0;
+
+  // Calculates and returns an optimal scale ratio. With MD this is only
+  // taking into account `size.height()` as the width can vary. Without MD this
+  // returns the scale that allows the item to fully fit within `size`.
+  virtual float GetItemScale(const gfx::Size& size) = 0;
+
+  // Increases the bounds of the dragged item.
+  virtual void ScaleUpSelectedItem(OverviewAnimationType animation_type) = 0;
+
+  // Ensures that a possibly minimized window becomes visible after restore.
+  virtual void EnsureVisible() = 0;
 
   // Returns the focusable view of this.
   virtual OverviewHighlightableView* GetFocusableView() const = 0;
 
+  // Returns the backdrop view of this.
+  virtual views::View* GetBackDropView() const = 0;
+
   // Updates the rounded corners and shadow on this.
   virtual void UpdateRoundedCornersAndShadow() = 0;
 
+  // Sets the bounds of the item shadow. If `bounds_in_screen` is nullopt, the
+  // shadow will be hidden.
+  virtual void SetShadowBounds(absl::optional<gfx::RectF> bounds_in_screen) = 0;
+
+  // Changes the opacity of all the window(s) the item owns.
+  virtual void SetOpacity(float opacity) = 0;
+  virtual float GetOpacity() const = 0;
+
   // Dispatched before entering overview.
   // TODO(b/294916205) : Remove this function for optimization.
   virtual void PrepareForOverview() = 0;
@@ -88,10 +191,40 @@
   // if there was no starting animation to do any necessary visual changes.
   virtual void OnStartingAnimationComplete() = 0;
 
+  // Hides the overview item. This is used to hide any overview items that may
+  // be present when entering the saved desk library. Animates `item_widget_`
+  // and the windows in the transient tree to 0 opacity if `animate` is true,
+  // otherwise just sets them to 0 opacity.
+  virtual void HideForSavedDeskLibrary(bool animate) = 0;
+
+  // This shows overview items that were hidden by the saved desk library.
+  // Called when exiting the saved desk library and going back to the overview
+  // grid. Fades the overview items in if `animate` is true, otherwise shows
+  // them immediately.
+  virtual void RevertHideForSavedDeskLibrary(bool animate) = 0;
+
+  // Closes `transform_window_`.
+  // TODO(michelefan): This is temporarily added to reduce the scope of the
+  // task, which will be replaced by `CloseWindows()` in a follow-up cl.
+  virtual void CloseWindow() = 0;
+
+  // Inserts the item back to its original stacking order so that the order of
+  // overview items is the same as when entering overview.
+  virtual void Restack() = 0;
+
   // Sends an accessibility event indicating that this window became selected
   // so that it is highlighted and announced.
   virtual void SendAccessibleSelectionEvent() = 0;
 
+  // Handles events forwarded from the contents view.
+  virtual void HandleMouseEvent(const ui::MouseEvent& event) = 0;
+  virtual void HandleGestureEvent(ui::GestureEvent* event) = 0;
+  virtual void OnHighlightedViewActivated() = 0;
+  virtual void OnHighlightedViewClosed() = 0;
+
+  // Checks if this item is currently being dragged.
+  virtual bool IsDragItem() const = 0;
+
   virtual void OnOverviewItemDragStarted(OverviewItemBase* item) = 0;
   virtual void OnOverviewItemDragEnded(bool snap) = 0;
 
@@ -99,13 +232,20 @@
   // window from shelf.
   virtual void SetVisibleDuringItemDragging(bool visible, bool animate) = 0;
 
+  // Updates the shadow type while being dragged and dropped.
+  virtual void UpdateShadowTypeForDrag(bool is_dragging) = 0;
+
   // Shows the cannot snap warning if currently in splitview, and the associated
   // item cannot be snapped.
   virtual void UpdateCannotSnapWarningVisibility(bool animate) = 0;
 
-  // This called when this is dragged and dropped on the mini view of
-  // another desk, which prepares this item for being removed from the grid, and
-  // the window(s) to restore its transform.
+  // Hides the cannot snap warning (if it was showing) until the next call to
+  // `UpdateCannotSnapWarningVisibility`.
+  virtual void HideCannotSnapWarning(bool animate) = 0;
+
+  // This called when this is dragged and dropped on the mini view of another
+  // desk, which prepares this item for being removed from the grid, and the
+  // window(s) to restore its transform.
   virtual void OnMovingItemToAnotherDesk() = 0;
 
   // Updates and maybe creates the mirrors needed for multi display dragging.
@@ -122,7 +262,28 @@
   // by overview swipe to close.
   virtual void AnimateAndCloseItem(bool up) = 0;
 
+  // Stops the current animation of `item_widget_`.
+  virtual void StopWidgetAnimation() = 0;
+
+  virtual OverviewGridWindowFillMode GetWindowDimensionsType() const = 0;
+
+  // Recalculates the window dimensions type of the transform window. Called on
+  // window bounds change.
+  virtual void UpdateWindowDimensionsType() = 0;
+
+  // Returns the point the accessibility magnifiers should focus when this is
+  // highlighted.
+  virtual gfx::Point GetMagnifierFocusPointInScreen() const = 0;
+
+  void set_target_bounds_for_testing(const gfx::RectF& target_bounds) {
+    target_bounds_ = target_bounds;
+  }
+
  protected:
+  // Creates `item_widget_` with `overview_item_view_` or group
+  // container view as its contents view
+  virtual void CreateItemWidget() = 0;
+
   // The root window this item is being displayed on.
   raw_ptr<aura::Window> root_window_;
 
@@ -136,6 +297,22 @@
 
   bool prepared_for_overview_ = false;
 
+  // A widget stacked under the `transform_window_`(s). The widget has
+  // `overview_item_view_` or group container view as its contents view. The
+  // widget is backed by a NOT_DRAWN layer since most of its surface is
+  // transparent.
+  std::unique_ptr<views::Widget> item_widget_;
+
+  // The target bounds this overview item is fit within. When in splitview,
+  // `item_widget_` is fit within these bounds, but the window itself is
+  // transformed to `unclipped_size_`, and then clipped.
+  gfx::RectF target_bounds_;
+
+  // The shadow around the overview window. Shadows the original window, not
+  // `item_widget_`. Done here instead of on the original window because of the
+  // rounded edges mask applied on entering overview window.
+  std::unique_ptr<SystemShadow> shadow_;
+
   // True if this overview item is currently being dragged around.
   bool is_being_dragged_ = false;
 
@@ -149,13 +326,41 @@
   // `OverviewGrid::PositionWindows()`.
   bool animating_to_close_ = false;
 
-  // True if the contained window(s) should animate during the exiting
-  // animation.
+  // True if the contained item should animate during the entering animation.
+  bool should_animate_when_entering_ = true;
+
+  // True if the contained item should animate during the exiting animation.
   bool should_animate_when_exiting_ = true;
 
+  // True if after an animation, we need to reorder the stacking order of the
+  // widgets.
+  bool should_restack_on_animation_end_ = false;
+
   // A widget with text that may show up on top of `transform_window_` to notify
-  // users the window(s) cannot be snapped.
+  // users the item cannot be snapped.
   std::unique_ptr<RoundedLabelWidget> cannot_snap_widget_;
+
+  // This has a value when there is a snapped window, or a window about to be
+  // snapped (triggering a splitview preview area). This will be set when items
+  // are positioned in OverviewGrid. The bounds delivered in `SetBounds` are the
+  // true bounds of this item, but we want to maintain the aspect ratio of the
+  // window, whose bounds are not set to split view size. So in `SetItemBounds`,
+  // we transform the window not to `target_bounds_` but to this value, and then
+  // apply clipping on the window to `target_bounds_`.
+  absl::optional<gfx::Size> unclipped_size_ = absl::nullopt;
+
+  // Cached values of the item bounds so that they do not have to be calculated
+  // on each scroll update. Will be nullopt unless a grid scroll is underway.
+  absl::optional<gfx::RectF> scrolling_bounds_ = absl::nullopt;
+
+  // True if this item should be added to an active overview session using the
+  // spawn animation on its first update. This implies an animation type of
+  // `OVERVIEW_ANIMATION_SPAWN_ITEM_IN_OVERVIEW`. This value will be reset to
+  // false once the spawn animation is performed.
+  bool should_use_spawn_animation_ = false;
+
+ private:
+  friend class OverviewTestBase;
 };
 
 }  // namespace ash
diff --git a/ash/wm/overview/overview_session.cc b/ash/wm/overview/overview_session.cc
index da0170a..53c1651 100644
--- a/ash/wm/overview/overview_session.cc
+++ b/ash/wm/overview/overview_session.cc
@@ -4,10 +4,8 @@
 
 #include "ash/wm/overview/overview_session.h"
 
-#include <functional>
 #include <utility>
 
-#include "ash/accelerators/debug_commands.h"
 #include "ash/accessibility/accessibility_controller_impl.h"
 #include "ash/app_list/app_list_controller_impl.h"
 #include "ash/frame_throttler/frame_throttling_controller.h"
@@ -19,8 +17,6 @@
 #include "ash/scoped_animation_disabler.h"
 #include "ash/screen_util.h"
 #include "ash/shell.h"
-#include "ash/strings/grit/ash_strings.h"
-#include "ash/style/ash_color_provider.h"
 #include "ash/system/message_center/ash_message_popup_collection.h"
 #include "ash/system/message_center/unified_message_center_bubble.h"
 #include "ash/system/unified/unified_system_tray.h"
@@ -56,11 +52,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/ranges/algorithm.h"
 #include "base/task/single_thread_task_runner.h"
-#include "ui/accessibility/ax_enums.mojom.h"
-#include "ui/base/hit_test.h"
-#include "ui/base/l10n/l10n_util.h"
 #include "ui/compositor/layer.h"
-#include "ui/compositor/scoped_layer_animation_settings.h"
 #include "ui/events/devices/haptic_touchpad_effects.h"
 #include "ui/events/event.h"
 #include "ui/views/accessibility/view_accessibility.h"
@@ -370,6 +362,8 @@
                                base::Time::Now() - overview_start_time_);
   }
 
+  // Explicitly clear the `selected_item_` to avoid dangling raw_ptr detection.
+  selected_item_ = nullptr;
   grid_list_.clear();
 
   // Hide the focus widget on overview session end to prevent it from retaining
@@ -401,7 +395,7 @@
   return highlight_controller_->MaybeActivateHighlightedViewOnOverviewExit();
 }
 
-void OverviewSession::SelectWindow(OverviewItem* item) {
+void OverviewSession::SelectWindow(OverviewItemBase* item) {
   aura::Window* window = item->GetWindow();
   aura::Window::Windows window_list =
       Shell::Get()->mru_window_tracker()->BuildMruWindowList(kActiveDesk);
@@ -488,7 +482,7 @@
   }
 }
 
-void OverviewSession::RearrangeDuringDrag(OverviewItem* dragged_item) {
+void OverviewSession::RearrangeDuringDrag(OverviewItemBase* dragged_item) {
   for (std::unique_ptr<OverviewGrid>& grid : grid_list_) {
     DCHECK(grid->split_view_drag_indicators());
     grid->RearrangeDuringDrag(
@@ -498,7 +492,7 @@
 }
 
 void OverviewSession::UpdateDropTargetsBackgroundVisibilities(
-    OverviewItem* dragged_item,
+    OverviewItemBase* dragged_item,
     const gfx::PointF& location_in_screen) {
   for (std::unique_ptr<OverviewGrid>& grid : grid_list_) {
     if (grid->GetDropTarget()) {
@@ -522,7 +516,7 @@
     aura::Window* window,
     bool reposition,
     bool animate,
-    const base::flat_set<OverviewItem*>& ignored_items,
+    const base::flat_set<OverviewItemBase*>& ignored_items,
     size_t index) {
   // Early exit if a grid already contains |window|.
   OverviewGrid* grid = GetGridWithRootWindow(window->GetRootWindow());
@@ -567,11 +561,11 @@
   OnItemAdded(window);
 }
 
-void OverviewSession::RemoveItem(OverviewItem* overview_item) {
+void OverviewSession::RemoveItem(OverviewItemBase* overview_item) {
   RemoveItem(overview_item, /*item_destroying=*/false, /*reposition=*/false);
 }
 
-void OverviewSession::RemoveItem(OverviewItem* overview_item,
+void OverviewSession::RemoveItem(OverviewItemBase* overview_item,
                                  bool item_destroying,
                                  bool reposition) {
   if (overview_item->GetWindow() == active_window_before_overview_) {
@@ -594,7 +588,7 @@
   }
 }
 
-void OverviewSession::InitiateDrag(OverviewItem* item,
+void OverviewSession::InitiateDrag(OverviewItemBase* item,
                                    const gfx::PointF& location_in_screen,
                                    bool is_touch_dragging) {
   if (Shell::Get()->overview_controller()->IsInStartAnimation() ||
@@ -609,7 +603,7 @@
   window_drag_controller_->InitiateDrag(location_in_screen);
 
   for (std::unique_ptr<OverviewGrid>& grid : grid_list_) {
-    grid->OnSelectorItemDragStarted(item);
+    grid->OnOverviewItemDragStarted(item);
     grid->UpdateSaveDeskButtons();
   }
 
@@ -621,14 +615,14 @@
   }
 }
 
-void OverviewSession::Drag(OverviewItem* item,
+void OverviewSession::Drag(OverviewItemBase* item,
                            const gfx::PointF& location_in_screen) {
   DCHECK(window_drag_controller_);
   DCHECK_EQ(item, window_drag_controller_->item());
   window_drag_controller_->Drag(location_in_screen);
 }
 
-void OverviewSession::CompleteDrag(OverviewItem* item,
+void OverviewSession::CompleteDrag(OverviewItemBase* item,
                                    const gfx::PointF& location_in_screen) {
   DCHECK(window_drag_controller_);
   DCHECK_EQ(item, window_drag_controller_->item());
@@ -639,7 +633,7 @@
   const bool snap = window_drag_controller_->CompleteDrag(location_in_screen) ==
                     OverviewWindowDragController::DragResult::kSnap;
   for (std::unique_ptr<OverviewGrid>& grid : grid_list_) {
-    grid->OnSelectorItemDragEnded(snap);
+    grid->OnOverviewItemDragEnded(snap);
     grid->UpdateSaveDeskButtons();
   }
 }
@@ -649,7 +643,7 @@
   window_drag_controller_->StartNormalDragMode(location_in_screen);
 }
 
-void OverviewSession::Fling(OverviewItem* item,
+void OverviewSession::Fling(OverviewItemBase* item,
                             const gfx::PointF& location_in_screen,
                             float velocity_x,
                             float velocity_y) {
@@ -662,7 +656,7 @@
                                                    velocity_x, velocity_y) ==
                     OverviewWindowDragController::DragResult::kSnap;
   for (std::unique_ptr<OverviewGrid>& grid : grid_list_) {
-    grid->OnSelectorItemDragEnded(snap);
+    grid->OnOverviewItemDragEnded(snap);
     grid->UpdateSaveDeskButtons();
   }
 }
@@ -674,7 +668,7 @@
 void OverviewSession::ResetDraggedWindowGesture() {
   window_drag_controller_->ResetGesture();
   for (std::unique_ptr<OverviewGrid>& grid : grid_list_) {
-    grid->OnSelectorItemDragEnded(/*snap=*/false);
+    grid->OnOverviewItemDragEnded(/*snap=*/false);
     grid->UpdateSaveDeskButtons();
   }
 }
@@ -739,7 +733,7 @@
 
 void OverviewSession::PositionWindows(
     bool animate,
-    const base::flat_set<OverviewItem*>& ignored_items) {
+    const base::flat_set<OverviewItemBase*>& ignored_items) {
   for (std::unique_ptr<OverviewGrid>& grid : grid_list_)
     grid->PositionWindows(animate, ignored_items);
 
@@ -754,12 +748,13 @@
   return false;
 }
 
-OverviewItem* OverviewSession::GetOverviewItemForWindow(
+OverviewItemBase* OverviewSession::GetOverviewItemForWindow(
     const aura::Window* window) {
   for (const std::unique_ptr<OverviewGrid>& grid : grid_list_) {
-    OverviewItem* item = grid->GetOverviewItemContaining(window);
-    if (item)
+    OverviewItemBase* item = grid->GetOverviewItemContaining(window);
+    if (item) {
       return item;
+    }
   }
 
   return nullptr;
@@ -916,8 +911,9 @@
 
   auto* grid = GetGridWithRootWindow(gained_active->GetRootWindow());
   DCHECK(grid);
-  if (OverviewItem* item = grid->GetOverviewItemContaining(gained_active))
+  if (OverviewItemBase* item = grid->GetOverviewItemContaining(gained_active)) {
     selected_item_ = item;
+  }
 
   // Don't restore window activation on exit if a window was just activated.
   RestoreWindowActivation(false);
@@ -950,9 +946,11 @@
 }
 
 aura::Window* OverviewSession::GetHighlightedWindow() {
-  OverviewItem* item = highlight_controller_->GetHighlightedItem();
-  if (!item)
+  OverviewItemBase* item = highlight_controller_->GetHighlightedItem();
+  if (!item) {
     return nullptr;
+  }
+
   return item->GetWindow();
 }
 
@@ -992,7 +990,7 @@
   active_window_before_overview_ = nullptr;
 }
 
-void OverviewSession::OnHighlightedItemActivated(OverviewItem* item) {
+void OverviewSession::OnHighlightedItemActivated(OverviewItemBase* item) {
   UMA_HISTOGRAM_COUNTS_100("Ash.Overview.ArrowKeyPresses", num_key_presses_);
   UMA_HISTOGRAM_CUSTOM_COUNTS("Ash.Overview.KeyPressesOverItemsRatio",
                               (num_key_presses_ * 100) / num_items_, 1, 300,
@@ -1002,7 +1000,7 @@
   SelectWindow(item);
 }
 
-void OverviewSession::OnHighlightedItemClosed(OverviewItem* item) {
+void OverviewSession::OnHighlightedItemClosed(OverviewItemBase* item) {
   base::RecordAction(
       base::UserMetricsAction("WindowSelector_OverviewCloseKey"));
   item->CloseWindow();
@@ -1015,7 +1013,7 @@
   grid_list_.erase(iter);
 }
 
-OverviewItem* OverviewSession::GetCurrentDraggedOverviewItem() const {
+OverviewItemBase* OverviewSession::GetCurrentDraggedOverviewItem() const {
   if (!window_drag_controller_)
     return nullptr;
   return window_drag_controller_->item();
@@ -1060,18 +1058,17 @@
            ->overview_controller()
            ->is_continuous_scroll_in_progress()) {
     for (std::unique_ptr<OverviewGrid>& overview_grid : grid_list_) {
-      for (size_t i = 0; i < overview_grid->window_list().size(); ++i) {
-        OverviewItem* window_item = overview_grid->window_list()[i].get();
+      for (const auto& window_item : overview_grid->window_list()) {
         // TODO(b/292125336): Animate the opacity change.
         if (WindowState::Get(window_item->GetWindow())->IsMinimized()) {
-          window_item->overview_item_view()->layer()->SetOpacity(1.f);
+          window_item->GetFocusableView()->GetView()->layer()->SetOpacity(1.f);
         } else {
           // Remove shadow bounds so that the entry animation looks smoother and
           // does not show an unnecessary shadow.
           window_item->SetShadowBounds(absl::nullopt);
         }
       }
-      overview_grid->PositionWindows(/*animate=*/true, /*ignored_item=*/{},
+      overview_grid->PositionWindows(/*animate=*/true, /*ignored_items=*/{},
                                      /*transition=*/OverviewTransition::kEnter);
 
       // Move the desk bar back to its final position.
diff --git a/ash/wm/overview/overview_session.h b/ash/wm/overview/overview_session.h
index 77bf719..356b7148 100644
--- a/ash/wm/overview/overview_session.h
+++ b/ash/wm/overview/overview_session.h
@@ -49,6 +49,7 @@
 class OverviewGrid;
 class OverviewHighlightController;
 class OverviewItem;
+class OverviewItemBase;
 class OverviewWindowDragController;
 class SavedDeskDialogController;
 class SavedDeskPresenter;
@@ -89,8 +90,8 @@
   // false otherwise.
   bool AcceptSelection();
 
-  // Activates |item's| window.
-  void SelectWindow(OverviewItem* item);
+  // Activates the window or window group associated with the `item`.
+  void SelectWindow(OverviewItemBase* item);
 
   // Sets the dragged window on the split view drag indicators.
   void SetSplitViewDragIndicatorsDraggedWindow(aura::Window* dragged_window);
@@ -108,12 +109,12 @@
   void ResetSplitViewDragIndicatorsWindowDraggingStates();
 
   // See |OverviewGrid::RearrangeDuringDrag|.
-  void RearrangeDuringDrag(OverviewItem* dragged_item);
+  void RearrangeDuringDrag(OverviewItemBase* dragged_item);
 
   // Updates the appearance of each drop target to visually indicate when the
   // dragged window is being dragged over it.
   void UpdateDropTargetsBackgroundVisibilities(
-      OverviewItem* dragged_item,
+      OverviewItemBase* dragged_item,
       const gfx::PointF& location_in_screen);
 
   // Retrieves the window grid whose root window matches |root_window|. Returns
@@ -129,7 +130,7 @@
   void AddItem(aura::Window* window,
                bool reposition,
                bool animate,
-               const base::flat_set<OverviewItem*>& ignored_items,
+               const base::flat_set<OverviewItemBase*>& ignored_items,
                size_t index);
 
   // Similar to the above function, but adds the window at the end of the grid.
@@ -149,20 +150,21 @@
                          bool use_spawn_animation);
 
   // Removes |overview_item| from the corresponding grid.
-  void RemoveItem(OverviewItem* overview_item);
-  void RemoveItem(OverviewItem* overview_item,
+  void RemoveItem(OverviewItemBase* overview_item);
+  void RemoveItem(OverviewItemBase* overview_item,
                   bool item_destroying,
                   bool reposition);
 
   void RemoveDropTargets();
 
-  void InitiateDrag(OverviewItem* item,
+  void InitiateDrag(OverviewItemBase* item,
                     const gfx::PointF& location_in_screen,
                     bool is_touch_dragging);
-  void Drag(OverviewItem* item, const gfx::PointF& location_in_screen);
-  void CompleteDrag(OverviewItem* item, const gfx::PointF& location_in_screen);
+  void Drag(OverviewItemBase* item, const gfx::PointF& location_in_screen);
+  void CompleteDrag(OverviewItemBase* item,
+                    const gfx::PointF& location_in_screen);
   void StartNormalDragMode(const gfx::PointF& location_in_screen);
-  void Fling(OverviewItem* item,
+  void Fling(OverviewItemBase* item,
              const gfx::PointF& location_in_screen,
              float velocity_x,
              float velocity_y);
@@ -196,15 +198,16 @@
   void MergeWindowIntoOverviewForWebUITabStrip(aura::Window* dragged_window);
 
   // Positions all overview items except those in |ignored_items|.
-  void PositionWindows(bool animate,
-                       const base::flat_set<OverviewItem*>& ignored_items = {});
+  void PositionWindows(
+      bool animate,
+      const base::flat_set<OverviewItemBase*>& ignored_items = {});
 
   // Returns true if |window| is currently showing in overview.
   bool IsWindowInOverview(const aura::Window* window);
 
-  // Returns the overview item for |window|, or nullptr if |window| doesn't have
-  // a corresponding item in overview mode.
-  OverviewItem* GetOverviewItemForWindow(const aura::Window* window);
+  // Returns the `OverviewItemBase` for the given `window`, or nullptr if
+  // `window` doesn't have a corresponding item in overview mode.
+  OverviewItemBase* GetOverviewItemForWindow(const aura::Window* window);
 
   // Set the window grid that's displaying in |root_window| not animate when
   // exiting overview mode, i.e., all window items in the grid will not animate
@@ -259,8 +262,8 @@
   void RestoreWindowActivation(bool restore);
 
   // Handles requests to active or close the currently highlighted |item|.
-  void OnHighlightedItemActivated(OverviewItem* item);
-  void OnHighlightedItemClosed(OverviewItem* item);
+  void OnHighlightedItemActivated(OverviewItemBase* item);
+  void OnHighlightedItemClosed(OverviewItemBase* item);
 
   // Called explicitly (with no list of observers) by the |RootWindowController|
   // of |root|, so that the associated grid is properly removed and destroyed.
@@ -273,7 +276,7 @@
   // Returns the current dragged overview item if any. Note that windows that
   // are dragged into overview from the shelf don't have an OverviewItem while
   // dragging.
-  OverviewItem* GetCurrentDraggedOverviewItem() const;
+  OverviewItemBase* GetCurrentDraggedOverviewItem() const;
 
   // Overview objects which handle events (OverviewItemView,
   // OverviewGridEventHandler) should call this function to check if they can
@@ -494,8 +497,8 @@
 
   // The selected item when exiting overview mode. nullptr if no window
   // selected.
-  raw_ptr<OverviewItem, DanglingUntriaged | ExperimentalAsh> selected_item_ =
-      nullptr;
+  raw_ptr<OverviewItemBase, DanglingUntriaged | ExperimentalAsh>
+      selected_item_ = nullptr;
 
   // The drag controller for a window in the overview mode.
   std::unique_ptr<OverviewWindowDragController> window_drag_controller_;
diff --git a/ash/wm/overview/overview_session_unittest.cc b/ash/wm/overview/overview_session_unittest.cc
index d55fbfbd..c159f008 100644
--- a/ash/wm/overview/overview_session_unittest.cc
+++ b/ash/wm/overview/overview_session_unittest.cc
@@ -20,7 +20,6 @@
 #include "ash/constants/ash_pref_names.h"
 #include "ash/display/screen_orientation_controller.h"
 #include "ash/display/screen_orientation_controller_test_api.h"
-#include "ash/drag_drop/drag_drop_controller.h"
 #include "ash/frame_throttler/frame_throttling_controller.h"
 #include "ash/frame_throttler/mock_frame_throttling_observer.h"
 #include "ash/public/cpp/shelf_config.h"
@@ -44,8 +43,6 @@
 #include "ash/wm/desks/legacy_desk_bar_view.h"
 #include "ash/wm/desks/templates/saved_desk_save_desk_button.h"
 #include "ash/wm/desks/templates/saved_desk_util.h"
-#include "ash/wm/desks/zero_state_button.h"
-#include "ash/wm/drag_window_resizer.h"
 #include "ash/wm/gestures/back_gesture/back_gesture_event_handler.h"
 #include "ash/wm/gestures/wm_gesture_handler.h"
 #include "ash/wm/mru_window_tracker.h"
@@ -55,11 +52,11 @@
 #include "ash/wm/overview/overview_grid_event_handler.h"
 #include "ash/wm/overview/overview_highlight_controller.h"
 #include "ash/wm/overview/overview_item.h"
+#include "ash/wm/overview/overview_item_base.h"
 #include "ash/wm/overview/overview_item_view.h"
 #include "ash/wm/overview/overview_test_base.h"
 #include "ash/wm/overview/overview_test_util.h"
 #include "ash/wm/overview/overview_utils.h"
-#include "ash/wm/overview/overview_wallpaper_controller.h"
 #include "ash/wm/overview/overview_window_drag_controller.h"
 #include "ash/wm/overview/scoped_overview_transform_window.h"
 #include "ash/wm/resize_shadow.h"
@@ -257,7 +254,9 @@
       const auto insets = gfx::Insets::TLBR(
           window->GetProperty(aura::client::kTopViewInset), 0, 0, 0);
       start_bounds.Inset(insets);
-      auto size = item->overview_item_view()->GetPreviewViewSize();
+      const auto size = item->GetLeafItemForWindow(window)
+                            ->overview_item_view()
+                            ->GetPreviewViewSize();
       end_bounds = gfx::RectF(gfx::Rect(size));
     }
 
@@ -309,8 +308,8 @@
   ASSERT_FALSE(widget1->IsClosed());
   ASSERT_FALSE(widget2->IsClosed());
 
-  OverviewItem* item1 = GetOverviewItemForWindow(window1);
-  OverviewItem* item2 = GetOverviewItemForWindow(window2);
+  auto* item1 = GetOverviewItemForWindow(window1);
+  auto* item2 = GetOverviewItemForWindow(window2);
 
   // Get location of close button on `window1` before drag.
   const gfx::Point item1_close_button_position =
@@ -376,8 +375,8 @@
 
   ToggleOverview();
 
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2);
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2);
 
   ASSERT_FALSE(widget2->IsClosed());
 
@@ -542,7 +541,7 @@
   // The order of windows in overview mode is MRU.
   WindowState::Get(window1.get())->Activate();
   ToggleOverview();
-  const std::vector<std::unique_ptr<OverviewItem>>& overview1 =
+  const std::vector<std::unique_ptr<OverviewItemBase>>& overview1 =
       GetOverviewItemsForRoot(0);
   EXPECT_EQ(1, overview1[0]->GetWindow()->GetId());
   EXPECT_EQ(3, overview1[1]->GetWindow()->GetId());
@@ -552,7 +551,7 @@
   // Activate the second window.
   WindowState::Get(window2.get())->Activate();
   ToggleOverview();
-  const std::vector<std::unique_ptr<OverviewItem>>& overview2 =
+  const std::vector<std::unique_ptr<OverviewItemBase>>& overview2 =
       GetOverviewItemsForRoot(0);
 
   // The order should be MRU.
@@ -824,7 +823,7 @@
   ShellTestApi().WaitForOverviewAnimationState(
       OverviewAnimationState::kEnterAnimationComplete);
   // Click the close button.
-  OverviewItem* item = GetOverviewItemForWindow(widget->GetNativeWindow());
+  auto* item = GetOverviewItemForWindow(widget->GetNativeWindow());
   const gfx::Point point =
       GetCloseButton(item)->GetBoundsInScreen().CenterPoint();
   GetEventGenerator()->set_current_screen_location(point);
@@ -891,7 +890,7 @@
 
   ToggleOverview();
   auto* generator = GetEventGenerator();
-  OverviewItem* item = GetOverviewItemForWindow(window.get());
+  auto* item = GetOverviewItemForWindow(window.get());
   generator->set_current_screen_location(
       gfx::ToRoundedPoint(item->target_bounds().CenterPoint()));
   generator->PressLeftButton();
@@ -1243,7 +1242,7 @@
   EnterTabletMode();
   std::unique_ptr<aura::Window> window(CreateTestWindow());
   ToggleOverview();
-  OverviewItem* item = GetOverviewItemForWindow(window.get());
+  auto* item = GetOverviewItemForWindow(window.get());
   gfx::PointF drag_point = item->target_bounds().CenterPoint();
   GetOverviewSession()->InitiateDrag(item, drag_point,
                                      /*is_touch_dragging=*/false);
@@ -1262,7 +1261,7 @@
   std::unique_ptr<aura::Window> window1(CreateTestWindow());
   std::unique_ptr<aura::Window> window2(CreateTestWindow());
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
+  OverviewItemBase* item1 = GetOverviewItemForWindow(window1.get());
   gfx::PointF drag_point = item1->target_bounds().CenterPoint();
   GetOverviewSession()->InitiateDrag(item1, drag_point,
                                      /*is_touch_dragging=*/false);
@@ -1283,7 +1282,7 @@
       CreateTestWindow(gfx::Rect(), aura::client::WINDOW_TYPE_POPUP));
   EXPECT_TRUE(window_util::ShouldExcludeForOverview(window2.get()));
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
   gfx::PointF drag_point = item1->target_bounds().CenterPoint();
   GetOverviewSession()->InitiateDrag(item1, drag_point,
                                      /*is_touch_dragging=*/false);
@@ -1544,9 +1543,9 @@
   ASSERT_EQ(root_windows[1], secondary_screen_window->GetRootWindow());
 
   ToggleOverview();
-  OverviewItem* primary_screen_item =
+  auto* primary_screen_item =
       GetOverviewItemForWindow(primary_screen_window.get());
-  OverviewItem* secondary_screen_item =
+  auto* secondary_screen_item =
       GetOverviewItemForWindow(secondary_screen_window.get());
 
   EXPECT_FALSE(GetDropTarget(0));
@@ -1644,7 +1643,7 @@
   const std::u16string window_title = u"My window";
   window->SetTitle(window_title);
   ToggleOverview();
-  OverviewItem* window_item = GetOverviewItemsForRoot(0).back().get();
+  auto* window_item = GetOverviewItemsForRoot(0).back().get();
   views::Label* label = GetLabelView(window_item);
   ASSERT_TRUE(label);
 
@@ -1712,7 +1711,7 @@
   ASSERT_TRUE(overview_controller->InOverviewSession());
   ASSERT_EQ(1u, GetOverviewSession()->grid_list().size());
 
-  OverviewItem* overview_item = GetOverviewItemForWindow(window.get());
+  auto* overview_item = GetOverviewItemForWindow(window.get());
   EXPECT_TRUE(overview_item);
   const auto outside_point =
       gfx::ToRoundedPoint(
@@ -1880,7 +1879,7 @@
 
   WindowState::Get(window.get())->Minimize();
   ToggleOverview();
-  OverviewItem* overview_item = GetOverviewItemForWindow(window.get());
+  auto* overview_item = GetOverviewItemForWindow(window.get());
   auto* widget = overview_item->item_widget();
 
   gfx::Rect workarea =
@@ -2003,8 +2002,8 @@
   for (auto& grid : grids)
     EXPECT_FALSE(grid->no_windows_widget());
 
-  OverviewItem* item1 = GetOverviewItemForWindow(window1);
-  OverviewItem* item2 = GetOverviewItemForWindow(window2);
+  auto* item1 = GetOverviewItemForWindow(window1);
+  auto* item2 = GetOverviewItemForWindow(window2);
   ASSERT_TRUE(item1 && item2);
 
   // Close |item2|. Verify that we are still in overview mode because |window1|
@@ -2418,7 +2417,7 @@
 
   EnterTabletMode();
   ToggleOverview();
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
   // Drag |item2| in a way so that |window2| does not get activated.
   ui::test::EventGenerator* generator = GetEventGenerator();
   generator->MoveMouseTo(
@@ -2454,8 +2453,8 @@
 
   EnterTabletMode();
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
   // Start the drag on |item1|. Verify the dragged item, |item1| has both the
   // close button and titlebar hidden. The close button opacity however is
   // opaque as its a child of the header which handles fading away the whole
@@ -2513,9 +2512,9 @@
 
   EnterTabletMode();
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(minimized.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window.get());
-  OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item1 = GetOverviewItemForWindow(minimized.get());
+  auto* item2 = GetOverviewItemForWindow(window.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get());
 
   views::Widget* widget1 = item1->item_widget();
   views::Widget* widget2 = item2->item_widget();
@@ -2614,9 +2613,9 @@
 
   ToggleOverview();
   base::RunLoop().RunUntilIdle();
-  OverviewItem* wide_item = GetOverviewItemForWindow(wide.get());
-  OverviewItem* tall_item = GetOverviewItemForWindow(tall.get());
-  OverviewItem* normal_item = GetOverviewItemForWindow(normal.get());
+  auto* wide_item = GetOverviewItemForWindow(wide.get());
+  auto* tall_item = GetOverviewItemForWindow(tall.get());
+  auto* normal_item = GetOverviewItemForWindow(normal.get());
 
   // Only very tall and very wide windows will have a backdrop. The backdrop
   // only gets created if we need it once during the overview session.
@@ -2659,8 +2658,8 @@
   // corners until the animation is complete.
   EnterTabletMode();
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
   EXPECT_FALSE(HasRoundedCorner(item1));
   EXPECT_FALSE(HasRoundedCorner(item2));
   ShellTestApi().WaitForOverviewAnimationState(
@@ -2703,8 +2702,8 @@
 
   EnterTabletMode();
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
   ui::ScopedAnimationDurationScaleMode test_duration_mode(
       ui::ScopedAnimationDurationScaleMode::NON_ZERO_DURATION);
 
@@ -2728,7 +2727,7 @@
   generator->MoveMouseTo(gfx::Point(0, start_drag.y()));
 
   // The drop target window should be created with no shadow.
-  OverviewItem* drop_target_item = GetDropTarget(0);
+  auto* drop_target_item = GetDropTarget(0);
   ASSERT_TRUE(drop_target_item);
   EXPECT_TRUE(GetShadowBounds(drop_target_item).IsEmpty());
 
@@ -2753,21 +2752,21 @@
 TEST_P(OverviewSessionTest, ShadowBounds) {
   // Helper function to check if the bounds of a shadow owned by |shadow_parent|
   // is contained within the bounds of |widget|.
-  auto contains = [&](views::Widget* widget, OverviewItem* shadow_parent) {
+  auto contains = [&](views::Widget* widget, OverviewItemBase* shadow_parent) {
     return gfx::Rect(widget->GetNativeWindow()->bounds().size())
         .Contains(GetShadowBounds(shadow_parent));
   };
 
   // Helper function which returns the ratio of the shadow owned by
   // |shadow_parent| width and height.
-  auto shadow_ratio = [&](OverviewItem* shadow_parent) {
+  auto shadow_ratio = [&](OverviewItemBase* shadow_parent) {
     gfx::RectF boundsf = gfx::RectF(GetShadowBounds(shadow_parent));
     return boundsf.width() / boundsf.height();
   };
 
   // Helper function which returns the ratio of the item width and height minus
   // the header and window margin.
-  auto item_ratio = [](OverviewItem* item) {
+  auto item_ratio = [](OverviewItemBase* item) {
     gfx::RectF boundsf = chromeos::features::IsJellyrollEnabled()
                              ? item->target_bounds()
                              : item->GetWindowTargetBoundsWithInsets();
@@ -2790,9 +2789,9 @@
 
   ToggleOverview();
   base::RunLoop().RunUntilIdle();
-  OverviewItem* wide_item = GetOverviewItemForWindow(wide.get());
-  OverviewItem* tall_item = GetOverviewItemForWindow(tall.get());
-  OverviewItem* normal_item = GetOverviewItemForWindow(normal.get());
+  auto* wide_item = GetOverviewItemForWindow(wide.get());
+  auto* tall_item = GetOverviewItemForWindow(tall.get());
+  auto* normal_item = GetOverviewItemForWindow(normal.get());
 
   views::Widget* wide_widget = wide_item->item_widget();
   views::Widget* tall_widget = tall_item->item_widget();
@@ -2839,8 +2838,8 @@
 
   EnterTabletMode();
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
 
   const gfx::RectF original_bounds1 = item1->target_bounds();
   const gfx::RectF original_bounds2 = item2->target_bounds();
@@ -2936,9 +2935,9 @@
   std::unique_ptr<aura::Window> window3(CreateTestWindow());
 
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
-  OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get());
   const gfx::RectF bounds1 = item1->target_bounds();
   const gfx::RectF bounds2 = item2->target_bounds();
   const gfx::RectF bounds3 = item3->target_bounds();
@@ -3011,7 +3010,7 @@
   std::unique_ptr<aura::Window> window(CreateTestWindow(gfx::Rect(500, 200)));
 
   ToggleOverview();
-  OverviewItem* item = GetOverviewItemForWindow(window.get());
+  auto* item = GetOverviewItemForWindow(window.get());
   ASSERT_EQ(OverviewGridWindowFillMode::kLetterBoxed,
             item->GetWindowDimensionsType());
 
@@ -3151,7 +3150,8 @@
   ToggleOverview(OverviewEnterExitType::kFadeInEnter);
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item = GetOverviewItemForWindow(window.get());
+  auto* item = GetOverviewItemForWindow(window.get())
+                   ->GetLeafItemForWindow(window.get());
 
   // Verify that the item widget's transform is not animated as part of the
   // animation.
@@ -3169,6 +3169,7 @@
   EXPECT_TRUE(GetGridBounds().Contains(bounds));
 
   // Header is expected to be shown immediately.
+  // Header is expected to be shown immediately.
   EXPECT_EQ(
       1.0f,
       item->overview_item_view()->header_view()->layer()->GetTargetOpacity());
@@ -3194,7 +3195,7 @@
   // that NON_ZERO_DURATION animation duration scale, it should be safe to
   // dereference the widget pointer immediately (synchronously) after the
   // session ends.
-  OverviewItem* item = GetOverviewItemForWindow(test_window.get());
+  auto* item = GetOverviewItemForWindow(test_window.get());
   views::Widget* grid_item_widget = item->item_widget();
   gfx::Rect item_bounds = grid_item_widget->GetWindowBoundsInScreen();
 
@@ -3362,7 +3363,7 @@
   controller->NewDesk(DesksCreationRemovalSource::kKeyboard);
   RemoveDesk(controller->active_desk(), DeskCloseType::kCombineDesks);
 
-  OverviewItem* item = GetOverviewItemForWindow(window);
+  auto* item = GetOverviewItemForWindow(window);
   ASSERT_TRUE(item);
   item->CloseWindow();
 
@@ -3424,7 +3425,7 @@
   for (int i = 0; i < window_count + 1; ++i) {
     aura::Window* window = windows[i].get();
     ids.erase(ids.begin());
-    OverviewItem* item = grid->GetOverviewItemContaining(window);
+    auto* item = grid->GetOverviewItemContaining(window);
     grid->RemoveItem(item, /*item_destroying=*/false, /*reposition=*/false);
     EXPECT_THAT(frame_throttling_controller->GetFrameSinkIdsToThrottle(),
                 testing::UnorderedElementsAreArray(ids));
@@ -3476,7 +3477,7 @@
   for (int i = 0; i < window_count + 1; ++i) {
     aura::Window* window = windows[i].get();
     ids.erase(ids.begin());
-    OverviewItem* item = grid->GetOverviewItemContaining(window);
+    auto* item = grid->GetOverviewItemContaining(window);
     grid->RemoveItem(item, /*item_destroying=*/false, /*reposition=*/false);
     EXPECT_THAT(frame_throttling_controller->GetFrameSinkIdsToThrottle(),
                 testing::UnorderedElementsAreArray(ids));
@@ -3531,7 +3532,7 @@
     if (i == 0)
       EXPECT_CALL(observer, OnThrottlingEnded());
     EXPECT_CALL(observer, OnThrottlingStarted(testing::_, testing::_)).Times(0);
-    OverviewItem* item = grid->GetOverviewItemContaining(window);
+    auto* item = grid->GetOverviewItemContaining(window);
     grid->RemoveItem(item, /*item_destroying=*/false, /*reposition=*/false);
   }
   frame_throttling_controller->RemoveArcObserver(&observer);
@@ -5286,8 +5287,8 @@
   ToggleOverview();
   ASSERT_TRUE(IsFloatContainerBelowActiveDesk());
 
-  OverviewItem* normal_item = GetOverviewItemForWindow(normal_window.get());
-  OverviewItem* floated_item = GetOverviewItemForWindow(floated_window.get());
+  auto* normal_item = GetOverviewItemForWindow(normal_window.get());
+  auto* floated_item = GetOverviewItemForWindow(floated_window.get());
 
   // Start dragging the floated window. Check that the float container gets
   // stacked above the desk container after dragging starts.
@@ -5334,7 +5335,7 @@
   ASSERT_TRUE(WindowState::Get(floated_window.get())->IsFloated());
 
   ToggleOverview();
-  OverviewItem* normal_item = GetOverviewItemForWindow(normal_window.get());
+  auto* normal_item = GetOverviewItemForWindow(normal_window.get());
   GetEventGenerator()->set_current_screen_location(
       gfx::ToRoundedPoint(normal_item->target_bounds().CenterPoint()));
   GetEventGenerator()->ClickLeftButton();
@@ -5351,7 +5352,7 @@
 
   // Enter overview and start dragging on the normal window.
   ToggleOverview();
-  OverviewItem* normal_item = GetOverviewItemForWindow(normal_window.get());
+  auto* normal_item = GetOverviewItemForWindow(normal_window.get());
   ui::test::EventGenerator* generator = GetEventGenerator();
   generator->set_current_screen_location(
       gfx::ToRoundedPoint(normal_item->target_bounds().CenterPoint()));
@@ -5403,7 +5404,7 @@
   ASSERT_TRUE(IsFloatContainerBelowActiveDesk());
 
   // Simulate a long press on the overview item of the floated window.
-  OverviewItem* float_item = GetOverviewItemForWindow(floated_window.get());
+  auto* float_item = GetOverviewItemForWindow(floated_window.get());
   ui::test::EventGenerator* generator = GetEventGenerator();
   generator->set_current_screen_location(
       gfx::ToRoundedPoint(float_item->target_bounds().CenterPoint()));
@@ -5455,10 +5456,10 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item1 = GetOverviewItemForWindow(windows[0].get());
-  OverviewItem* item2 = GetOverviewItemForWindow(windows[1].get());
-  OverviewItem* item3 = GetOverviewItemForWindow(windows[2].get());
-  OverviewItem* item4 = GetOverviewItemForWindow(windows[3].get());
+  auto* item1 = GetOverviewItemForWindow(windows[0].get());
+  auto* item2 = GetOverviewItemForWindow(windows[1].get());
+  auto* item3 = GetOverviewItemForWindow(windows[2].get());
+  auto* item4 = GetOverviewItemForWindow(windows[3].get());
 
   const gfx::RectF item1_bounds = item1->target_bounds();
   const gfx::RectF item2_bounds = item2->target_bounds();
@@ -5487,10 +5488,10 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item0 = GetOverviewItemForWindow(windows[0].get());
-  OverviewItem* item1 = GetOverviewItemForWindow(windows[1].get());
-  OverviewItem* item8 = GetOverviewItemForWindow(windows[8].get());
-  OverviewItem* item9 = GetOverviewItemForWindow(windows[9].get());
+  auto* item0 = GetOverviewItemForWindow(windows[0].get());
+  auto* item1 = GetOverviewItemForWindow(windows[1].get());
+  auto* item8 = GetOverviewItemForWindow(windows[8].get());
+  auto* item9 = GetOverviewItemForWindow(windows[9].get());
 
   const gfx::RectF screen_bounds(GetGridBounds());
   const gfx::RectF item0_bounds = item0->target_bounds();
@@ -5516,7 +5517,7 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item0 = GetOverviewItemForWindow(windows[0].get());
+  auto* item0 = GetOverviewItemForWindow(windows[0].get());
   const gfx::RectF before_shift_bounds = item0->target_bounds();
 
   GenerateScrollSequence(gfx::Point(100, 60), gfx::Point(0, 50));
@@ -5530,7 +5531,7 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item0 = GetOverviewItemForWindow(windows[0].get());
+  auto* item0 = GetOverviewItemForWindow(windows[0].get());
   const gfx::RectF before_shift_bounds = item0->target_bounds();
 
   GenerateScrollSequence(gfx::Point(100, 60), gfx::Point(0, 50));
@@ -5547,7 +5548,7 @@
   // bounds. First, align the left-most window (|windows[0]|) to the left-hand
   // bound and store the item's location. Then, scroll a far amount and check to
   // see if the item moved at all.
-  OverviewItem* leftmost_window = GetOverviewItemForWindow(windows[0].get());
+  auto* leftmost_window = GetOverviewItemForWindow(windows[0].get());
 
   GenerateScrollSequence(
       gfx::Point(BackGestureEventHandler::kStartGoingBackLeftEdgeInset + 5, 50),
@@ -5562,7 +5563,7 @@
   // bounds. First, align the right-most window (|windows[7]|) to the right-hand
   // bound and store the item's location. Then, scroll a far amount and check to
   // see if the item moved at all.
-  OverviewItem* rightmost_window = GetOverviewItemForWindow(windows[7].get());
+  auto* rightmost_window = GetOverviewItemForWindow(windows[7].get());
   GenerateScrollSequence(gfx::Point(5000, 50), gfx::Point(0, 50));
   const gfx::RectF right_bounds = rightmost_window->target_bounds();
   GenerateScrollSequence(gfx::Point(5000, 50), gfx::Point(0, 50));
@@ -5698,7 +5699,7 @@
 
   // Tests that if we long press, but cancel the event, the window stays stacked
   // under the snapped window.
-  OverviewItem* item = GetOverviewItemForWindow(window2.get());
+  auto* item = GetOverviewItemForWindow(window2.get());
   const gfx::PointF item_center = item->target_bounds().CenterPoint();
   DispatchLongPress(item);
   ui::GestureEvent gesture_end(item_center.x(), item_center.y(), 0,
@@ -5724,7 +5725,7 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* leftmost_window = GetOverviewItemForWindow(windows[0].get());
+  auto* leftmost_window = GetOverviewItemForWindow(windows[0].get());
   const gfx::Point topleft_window_center =
       gfx::ToRoundedPoint(leftmost_window->target_bounds().CenterPoint());
   const gfx::RectF left_bounds = leftmost_window->target_bounds();
@@ -5747,7 +5748,7 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item = GetOverviewItemForWindow(window.get());
+  auto* item = GetOverviewItemForWindow(window.get());
   ui::test::EventGenerator* generator = GetEventGenerator();
   generator->set_current_screen_location(
       gfx::ToRoundedPoint(item->target_bounds().CenterPoint()));
@@ -5818,9 +5819,9 @@
   // Get the final positions by toggling overview mode regularly.
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
-  OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get());
 
   const gfx::Rect final_bounds1 = gfx::ToEnclosedRect(item1->target_bounds());
   const gfx::Rect final_bounds2 = gfx::ToEnclosedRect(item2->target_bounds());
@@ -5863,6 +5864,7 @@
 
   // Confirm the opacity of minimized windows is not 100%.
   float opacity = GetOverviewItemForWindow(minimized_window.get())
+                      ->GetLeafItemForWindow(minimized_window.get())
                       ->overview_item_view()
                       ->layer()
                       ->opacity();
@@ -5883,9 +5885,8 @@
   ThreeFingerScroll(0, short_scroll, /*complete_scroll=*/false);
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* active_item = GetOverviewItemForWindow(active_window.get());
-  OverviewItem* minimized_item =
-      GetOverviewItemForWindow(minimized_window.get());
+  auto* active_item = GetOverviewItemForWindow(active_window.get());
+  auto* minimized_item = GetOverviewItemForWindow(minimized_window.get());
 
   // If a window is minimized, it should immediately show rounded corners.
   // Otherwise, retain sharp corners until the enter animation ends.
@@ -6006,10 +6007,10 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item0 = GetOverviewItemForWindow(windows[0].get());
-  OverviewItem* item1 = GetOverviewItemForWindow(windows[1].get());
-  OverviewItem* item8 = GetOverviewItemForWindow(windows[8].get());
-  OverviewItem* item9 = GetOverviewItemForWindow(windows[9].get());
+  auto* item0 = GetOverviewItemForWindow(windows[0].get());
+  auto* item1 = GetOverviewItemForWindow(windows[1].get());
+  auto* item8 = GetOverviewItemForWindow(windows[8].get());
+  auto* item9 = GetOverviewItemForWindow(windows[9].get());
 
   const gfx::RectF screen_bounds(GetGridBounds());
   const gfx::RectF item0_bounds = item0->target_bounds();
@@ -6043,10 +6044,10 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item0 = GetOverviewItemForWindow(windows[0].get());
-  OverviewItem* item1 = GetOverviewItemForWindow(windows[1].get());
-  OverviewItem* item2 = GetOverviewItemForWindow(windows[2].get());
-  OverviewItem* item3 = GetOverviewItemForWindow(windows[3].get());
+  auto* item0 = GetOverviewItemForWindow(windows[0].get());
+  auto* item1 = GetOverviewItemForWindow(windows[1].get());
+  auto* item2 = GetOverviewItemForWindow(windows[2].get());
+  auto* item3 = GetOverviewItemForWindow(windows[3].get());
 
   const gfx::RectF screen_bounds(GetGridBounds());
   const gfx::RectF item0_bounds = item0->target_bounds();
@@ -6067,7 +6068,7 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item0 = GetOverviewItemForWindow(windows[0].get());
+  auto* item0 = GetOverviewItemForWindow(windows[0].get());
   const gfx::RectF before_shift_bounds = item0->target_bounds();
 
   GetEventGenerator()->MoveMouseTo(GetGridBounds().width(),
@@ -6084,7 +6085,7 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* item0 = GetOverviewItemForWindow(windows[0].get());
+  auto* item0 = GetOverviewItemForWindow(windows[0].get());
   const gfx::RectF before_shift_bounds = item0->target_bounds();
 
   GetEventGenerator()->MoveMouseTo(GetGridBounds().width(),
@@ -6104,7 +6105,7 @@
   // bounds. First, align the top window (`windows[0]`) to the top bound
   // and store the item's location. Then, scroll a far amount and check
   // to see if the item moved at all.
-  OverviewItem* top_window = GetOverviewItemForWindow(windows[0].get());
+  auto* top_window = GetOverviewItemForWindow(windows[0].get());
 
   GetEventGenerator()->MoveMouseTo(GetGridBounds().width(),
                                    GetGridBounds().height());
@@ -6118,7 +6119,7 @@
   // bounds. First, align the bottom window (`windows[7]`) to the bottom
   // bound and store the item's location. Then, scroll a far amount and
   // check to see if the item moved at all.
-  OverviewItem* bottom_window = GetOverviewItemForWindow(windows[7].get());
+  auto* bottom_window = GetOverviewItemForWindow(windows[7].get());
   GetEventGenerator()->MoveMouseWheel(0, 500);
   const gfx::RectF bottom_bounds = bottom_window->target_bounds();
   GetEventGenerator()->MoveMouseWheel(0, 500);
@@ -6181,11 +6182,9 @@
   auto* desk_bar_view =
       GetOverviewGridForRoot(Shell::Get()->GetPrimaryRootWindow())
           ->desks_bar_view();
-  OverviewItem* floated_window_item =
-      GetOverviewItemForWindow(floated_window.get());
-  OverviewItem* active_window_item =
-      GetOverviewItemForWindow(active_window.get());
-  OverviewItem* minimized_window_item =
+  auto* floated_window_item = GetOverviewItemForWindow(floated_window.get());
+  auto* active_window_item = GetOverviewItemForWindow(active_window.get());
+  auto* minimized_window_item =
       GetOverviewItemForWindow(minimized_window.get());
 
   const gfx::RectF float_before_shift_bounds =
@@ -6261,7 +6260,7 @@
   OverviewGrid* grid = GetOverviewSession()->grid_list()[0].get();
   OverviewGridEventHandler* grid_event_handler = grid->grid_event_handler();
 
-  OverviewItem* item = GetOverviewItemForWindow(windows[2].get());
+  auto* item = GetOverviewItemForWindow(windows[2].get());
   const gfx::Point item_center =
       gfx::ToRoundedPoint(item->target_bounds().CenterPoint());
 
@@ -6307,7 +6306,7 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* leftmost_window =
+  auto* leftmost_window =
       GetOverviewItemForWindow(widgets[0]->GetNativeWindow());
   const gfx::Point topleft_window_center =
       gfx::ToRoundedPoint(leftmost_window->target_bounds().CenterPoint());
@@ -6323,7 +6322,7 @@
   ToggleOverview();
   ASSERT_TRUE(InOverviewSession());
 
-  OverviewItem* leftmost_window = GetOverviewItemForWindow(windows[0].get());
+  auto* leftmost_window = GetOverviewItemForWindow(windows[0].get());
   const gfx::RectF left_bounds = leftmost_window->target_bounds();
 
   SendKey(ui::VKEY_RIGHT, ui::EF_CONTROL_DOWN);
@@ -6366,8 +6365,8 @@
   // right edge of the grid bounds. Either of these being false would mean there
   // is a large padding which shouldn't be there.
   auto layout_valid = [&windows, this](int expected_padding) {
-    OverviewItem* first_item = GetOverviewItemForWindow(windows.front().get());
-    OverviewItem* last_item = GetOverviewItemForWindow(windows.back().get());
+    auto* first_item = GetOverviewItemForWindow(windows.front().get());
+    auto* last_item = GetOverviewItemForWindow(windows.back().get());
 
     const gfx::Rect first_bounds =
         gfx::ToEnclosedRect(first_item->target_bounds());
@@ -6421,7 +6420,7 @@
   // start dragging in SplitView. Drags |overview_item1| to the left border of
   // the screen. SplitView should trigger and upon completing drag,
   // |overview_item1| should snap to the left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   const gfx::PointF snap_left_location =
       gfx::PointF(GetGridBounds().left_center());
 
@@ -6440,7 +6439,7 @@
   // start dragging in SplitView. Drags |overview_item2| to the right border of
   // the screen. Upon completing drag, |overview_item2| should snap to the
   // right.
-  OverviewItem* overview_item2 = GetOverviewItemForWindow(window2.get());
+  auto* overview_item2 = GetOverviewItemForWindow(window2.get());
   const gfx::PointF snap_right_location =
       gfx::PointF(GetGridBounds().right_center());
 
@@ -6466,7 +6465,7 @@
   ToggleOverview();
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
-  OverviewItem* item = GetOverviewItemForWindow(widget->GetNativeWindow());
+  auto* item = GetOverviewItemForWindow(widget->GetNativeWindow());
   const gfx::PointF start = item->target_bounds().CenterPoint();
   ASSERT_TRUE(item);
 
@@ -6497,7 +6496,7 @@
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
   EXPECT_EQ(1u, GetOverviewSession()->grid_list()[0]->size());
 
-  OverviewItem* item = GetOverviewItemForWindow(widget->GetNativeWindow());
+  auto* item = GetOverviewItemForWindow(widget->GetNativeWindow());
   const gfx::PointF start = item->target_bounds().CenterPoint();
   ASSERT_TRUE(item);
 
@@ -6539,9 +6538,9 @@
   ToggleOverview();
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
-  OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get());
 
   const gfx::RectF item1_bounds = item1->target_bounds();
   const gfx::RectF item2_bounds = item2->target_bounds();
@@ -6586,10 +6585,10 @@
   ToggleOverview();
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
-  OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
-  OverviewItem* item4 = GetOverviewItemForWindow(window4.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item4 = GetOverviewItemForWindow(window4.get());
 
   const gfx::RectF item1_bounds = item1->target_bounds();
   const gfx::RectF item2_bounds = item2->target_bounds();
@@ -6624,7 +6623,7 @@
   ToggleOverview();
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
-  OverviewItem* items[kWindows];
+  OverviewItemBase* items[kWindows];
   gfx::RectF item_bounds[kWindows];
   for (int i = 0; i < kWindows; ++i) {
     items[i] = GetOverviewItemForWindow(windows[i].get());
@@ -6673,7 +6672,7 @@
   ToggleOverview();
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
-  OverviewItem* item = GetOverviewItemForWindow(window1.get());
+  auto* item = GetOverviewItemForWindow(window1.get());
   const gfx::PointF item_center = item->target_bounds().CenterPoint();
 
   // Drag |item1| vertically to start nudging.
@@ -6697,7 +6696,7 @@
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
   // Dispatches a long press event to start drag mode.
-  OverviewItem* item = GetOverviewItemForWindow(window1.get());
+  auto* item = GetOverviewItemForWindow(window1.get());
   DispatchLongPress(item);
   GetOverviewSession()->Drag(item, gfx::PointF(10.f, 500.f));
   const gfx::Rect item_bounds = item->GetWindow()->GetBoundsInScreen();
@@ -6711,7 +6710,7 @@
   EXPECT_EQ(item_bounds, item->GetWindow()->GetBoundsInScreen());
 
   // Long press on another item, the bounds of both items should be unchanged.
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
   const gfx::Rect item2_bounds = item2->GetWindow()->GetBoundsInScreen();
   DispatchLongPress(item2);
   EXPECT_EQ(item_bounds, item->GetWindow()->GetBoundsInScreen());
@@ -6862,7 +6861,7 @@
   // |long_press| is default to true. Set |long_press| to false if we do not
   // want to long press after every press, which enables dragging vertically to
   // close an item.
-  void DragWindowTo(OverviewItem* item,
+  void DragWindowTo(OverviewItemBase* item,
                     const gfx::PointF& end_location,
                     SelectorItemLocation location,
                     bool long_press = true) {
@@ -6896,7 +6895,7 @@
   }
 
   // Drags a overview item |item| from its center point to |end_location|.
-  void DragWindowTo(OverviewItem* item, const gfx::PointF& end_location) {
+  void DragWindowTo(OverviewItemBase* item, const gfx::PointF& end_location) {
     DragWindowTo(item, end_location, SelectorItemLocation::CENTER, true);
   }
 
@@ -6926,7 +6925,7 @@
   EXPECT_FALSE(split_view_controller()->InSplitViewMode());
 
   // Drag |window1| selector item to snap to left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF(0, 0));
 
   EXPECT_TRUE(split_view_controller()->InSplitViewMode());
@@ -6937,7 +6936,7 @@
   // Drag |window2| selector item to attempt to snap to left. Since there is
   // already one left snapped window |window1|, |window1| will be put in
   // overview mode.
-  OverviewItem* overview_item2 = GetOverviewItemForWindow(window2.get());
+  auto* overview_item2 = GetOverviewItemForWindow(window2.get());
   DragWindowTo(overview_item2, gfx::PointF(0, 0));
 
   EXPECT_EQ(split_view_controller()->state(),
@@ -6947,7 +6946,7 @@
       window1.get()));
 
   // Drag |window3| selector item to snap to right.
-  OverviewItem* overview_item3 = GetOverviewItemForWindow(window3.get());
+  auto* overview_item3 = GetOverviewItemForWindow(window3.get());
   const gfx::PointF end_location3(GetWorkAreaInScreen(window3.get()).width(),
                                   0.f);
   DragWindowTo(overview_item3, end_location3);
@@ -6972,8 +6971,8 @@
   ToggleOverview();
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
-  OverviewItem* window_item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* window_item2 = GetOverviewItemForWindow(window2.get());
+  auto* window_item1 = GetOverviewItemForWindow(window1.get());
+  auto* window_item2 = GetOverviewItemForWindow(window2.get());
 
   // Verify that if a drag is orginally horizontal, the drag behavior is drag to
   // snap.
@@ -7032,7 +7031,7 @@
   // Select window one and start the drag.
   const int window_width =
       Shell::Get()->GetPrimaryRootWindow()->GetBoundsInScreen().width();
-  OverviewItem* overview_item = GetOverviewItemForWindow(window1.get());
+  auto* overview_item = GetOverviewItemForWindow(window1.get());
   gfx::RectF overview_item_bounds = overview_item->target_bounds();
   gfx::PointF start_location(overview_item_bounds.CenterPoint());
   GetOverviewSession()->InitiateDrag(overview_item, start_location,
@@ -7110,8 +7109,7 @@
 
   // Verify that after dragging the unsnappable window to the left and right,
   // the window grid bounds do not change.
-  OverviewItem* overview_item =
-      GetOverviewItemForWindow(unsnappable_window.get());
+  auto* overview_item = GetOverviewItemForWindow(unsnappable_window.get());
   GetOverviewSession()->InitiateDrag(
       overview_item, overview_item->target_bounds().CenterPoint(),
       /*is_touch_dragging=*/false);
@@ -7137,7 +7135,7 @@
       snapped_window.get(), SplitViewController::SnapPosition::kPrimary);
   ASSERT_EQ(1u, GetOverviewSession()->grid_list().size());
   OverviewGrid* overview_grid = GetOverviewSession()->grid_list()[0].get();
-  OverviewItem* overview_item =
+  auto* overview_item =
       overview_grid->GetOverviewItemContaining(unsnappable_window.get());
   GetOverviewSession()->InitiateDrag(
       overview_item, overview_item->target_bounds().CenterPoint(),
@@ -7202,10 +7200,10 @@
     EXPECT_NE(clipping4, window4->layer()->clip_rect());
     const gfx::Rect overview_clipping4 = window4->layer()->clip_rect();
 
-    OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-    OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
-    OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
-    OverviewItem* item4 = GetOverviewItemForWindow(window4.get());
+    auto* item1 = GetOverviewItemForWindow(window1.get());
+    auto* item2 = GetOverviewItemForWindow(window2.get());
+    auto* item3 = GetOverviewItemForWindow(window3.get());
+    auto* item4 = GetOverviewItemForWindow(window4.get());
     GetOverviewSession()->InitiateDrag(item1,
                                        item1->target_bounds().CenterPoint(),
                                        /*is_touch_dragging=*/false);
@@ -7233,8 +7231,10 @@
     // clipped layer will be the WindowPreviewView of the associated
     // OverviewItemView.
     EXPECT_TRUE(window3->layer()->clip_rect().IsEmpty());
-    ui::Layer* preview_layer =
-        item3->overview_item_view()->preview_view()->layer();
+    ui::Layer* preview_layer = item3->GetLeafItemForWindow(window3.get())
+                                   ->overview_item_view()
+                                   ->preview_view()
+                                   ->layer();
     EXPECT_FALSE(preview_layer->clip_rect().IsEmpty());
     EXPECT_FALSE(preview_layer->transform().IsIdentity());
     // The clip rect is affected by |preview_layer|'s transform so apply it.
@@ -7321,7 +7321,7 @@
   EXPECT_EQ(clipping2, window2->layer()->clip_rect());
 
   // Drag to the edge of the screen. There should be no clipping and no crash.
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
   GetOverviewSession()->InitiateDrag(item1,
                                      item1->target_bounds().CenterPoint(),
                                      /*is_touch_dragging=*/false);
@@ -7341,7 +7341,7 @@
   EXPECT_TRUE(GetOverviewController()->InOverviewSession());
 
   // Drag |window1| selector item to snap to left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF());
 
   // Test that overview mode is active in this single window case.
@@ -7625,14 +7625,14 @@
 
   ToggleOverview();
   // Test that dragging |window1| to the left of the screen snaps it to left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF());
   EXPECT_EQ(split_view_controller()->state(),
             SplitViewController::State::kPrimarySnapped);
   EXPECT_EQ(split_view_controller()->primary_window(), window1.get());
 
   // Test that dragging |window2| to the right of the screen snaps it to right.
-  OverviewItem* overview_item2 = GetOverviewItemForWindow(window2.get());
+  auto* overview_item2 = GetOverviewItemForWindow(window2.get());
   gfx::Rect work_area_rect = GetWorkAreaInScreen(window2.get());
   gfx::PointF end_location2(work_area_rect.width(), work_area_rect.height());
   DragWindowTo(overview_item2, end_location2);
@@ -7752,7 +7752,7 @@
   ToggleOverview();
 
   // Drag |window1| selector item to snap to left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF());
 
   EXPECT_EQ(split_view_controller()->state(),
@@ -7805,8 +7805,7 @@
   ASSERT_TRUE(split_view_controller()->InSplitViewMode());
 
   // Select the unsnappable window.
-  OverviewItem* overview_item =
-      GetOverviewItemForWindow(unsnappable_window.get());
+  auto* overview_item = GetOverviewItemForWindow(unsnappable_window.get());
   ui::test::EventGenerator* generator = GetEventGenerator();
   generator->set_current_screen_location(
       gfx::ToRoundedPoint(overview_item->target_bounds().CenterPoint()));
@@ -7863,9 +7862,8 @@
   ToggleOverview();
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
-  OverviewItem* snappable_overview_item =
-      GetOverviewItemForWindow(window2.get());
-  OverviewItem* unsnappable_overview_item =
+  auto* snappable_overview_item = GetOverviewItemForWindow(window2.get());
+  auto* unsnappable_overview_item =
       GetOverviewItemForWindow(unsnappable_window.get());
 
   // Note: |cannot_snap_label_view_| and its parent will be created on demand.
@@ -7911,7 +7909,7 @@
   split_view_controller()->SnapWindow(
       snapped_window.get(), SplitViewController::SnapPosition::kPrimary);
   ASSERT_TRUE(split_view_controller()->InSplitViewMode());
-  OverviewItem* unsnappable_overview_item =
+  auto* unsnappable_overview_item =
       GetOverviewItemForWindow(unsnappable_window.get());
   views::Widget* cannot_snap_widget =
       GetCannotSnapWidget(unsnappable_overview_item);
@@ -8013,7 +8011,7 @@
   split_view_controller()->SnapWindow(
       snapped_window.get(), SplitViewController::SnapPosition::kPrimary);
   ASSERT_TRUE(split_view_controller()->InSplitViewMode());
-  OverviewItem* overview_item = GetOverviewItemForWindow(overview_window.get());
+  auto* overview_item = GetOverviewItemForWindow(overview_window.get());
   // Note: |cannot_snap_label_view_| and its parent will be created on demand.
   EXPECT_FALSE(GetCannotSnapWidget(overview_item));
 
@@ -8048,7 +8046,7 @@
   ToggleOverview();
 
   // Drag |window1| selector item to snap to left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF());
   // Test that overview mode and split view mode are both active.
   EXPECT_TRUE(split_view_controller()->InSplitViewMode());
@@ -8065,7 +8063,7 @@
   EXPECT_TRUE(Shell::Get()->overview_controller()->InOverviewSession());
 
   // Now drag |window2| selector item to snap to left.
-  OverviewItem* overview_item2 = GetOverviewItemForWindow(window2.get());
+  auto* overview_item2 = GetOverviewItemForWindow(window2.get());
   DragWindowTo(overview_item2, gfx::PointF());
   // Test that overview mode and split view mode are both active.
   EXPECT_TRUE(split_view_controller()->InSplitViewMode());
@@ -8092,7 +8090,7 @@
   ToggleOverview();
   ASSERT_TRUE(GetOverviewController()->InOverviewSession());
 
-  OverviewItem* overview_item = GetOverviewItemForWindow(window1.get());
+  auto* overview_item = GetOverviewItemForWindow(window1.get());
   gfx::PointF start_location(overview_item->target_bounds().CenterPoint());
   const gfx::RectF original_bounds(overview_item->target_bounds());
 
@@ -8130,7 +8128,7 @@
   ToggleOverview();
 
   // Drag |window1| selector item to snap to left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF());
   EXPECT_EQ(SplitViewController::State::kPrimarySnapped,
             split_view_controller()->state());
@@ -8153,7 +8151,7 @@
   EXPECT_EQ(window1->bounds().width(), screen_width);
 
   // Drag |window2| selector item to snap to right.
-  OverviewItem* overview_item2 = GetOverviewItemForWindow(window2.get());
+  auto* overview_item2 = GetOverviewItemForWindow(window2.get());
   const gfx::Rect work_area_rect = GetWorkAreaInScreen(window2.get());
   gfx::Point end_location2 =
       gfx::Point(work_area_rect.width(), work_area_rect.height());
@@ -8275,7 +8273,7 @@
   ToggleOverview();
   // Drag |window1| selector item to snap to left. There should be two items on
   // the overview grid afterwards, |window2| and |window3|.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF());
   EXPECT_EQ(SplitViewController::State::kPrimarySnapped,
             split_view_controller()->state());
@@ -8477,7 +8475,7 @@
   std::unique_ptr<aura::Window> window2(CreateWindow(bounds));
 
   ToggleOverview();
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF());
   EXPECT_EQ(split_view_controller()->state(),
             SplitViewController::State::kPrimarySnapped);
@@ -8535,12 +8533,12 @@
   EXPECT_FALSE(window1->layer()->GetTargetTransform().IsIdentity());
   EXPECT_FALSE(window2->layer()->GetTargetTransform().IsIdentity());
   EXPECT_FALSE(window3->layer()->GetTargetTransform().IsIdentity());
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF());
   EXPECT_EQ(SplitViewController::State::kPrimarySnapped,
             split_view_controller()->state());
   // Drag |window2| to snap to right.
-  OverviewItem* overview_item2 = GetOverviewItemForWindow(window2.get());
+  auto* overview_item2 = GetOverviewItemForWindow(window2.get());
   const gfx::Rect work_area_rect =
       screen_util::GetDisplayWorkAreaBoundsInScreenForActiveDeskContainer(
           window2.get());
@@ -8613,7 +8611,7 @@
   std::unique_ptr<aura::Window> window2(CreateWindow(bounds));
 
   ToggleOverview();
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF());
   EXPECT_EQ(split_view_controller()->state(),
             SplitViewController::State::kPrimarySnapped);
@@ -8669,7 +8667,7 @@
 
   ToggleOverview();
   // Drag |window1| selector item to snap to left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF(0, 0));
   EXPECT_TRUE(GetOverviewController()->InOverviewSession());
   EXPECT_TRUE(split_view_controller()->InSplitViewMode());
@@ -8704,7 +8702,7 @@
   split_view_controller()->EndResizeWithDivider(divider_drag_point);
   ASSERT_TRUE(IsDividerAnimating());
 
-  OverviewItem* overview_item = GetOverviewItemForWindow(overview_window.get());
+  auto* overview_item = GetOverviewItemForWindow(overview_window.get());
   GetOverviewSession()->InitiateDrag(
       overview_item, overview_item->target_bounds().CenterPoint(),
       /*is_touch_dragging=*/true);
@@ -8723,7 +8721,7 @@
   const gfx::Rect grid_bounds = GetGridBounds();
   // Drag the item such that the splitview preview area shows up and the grid
   // bounds shrink.
-  OverviewItem* overview_item = GetOverviewItemForWindow(window1.get());
+  auto* overview_item = GetOverviewItemForWindow(window1.get());
   GetOverviewSession()->InitiateDrag(
       overview_item, overview_item->target_bounds().CenterPoint(),
       /*is_touch_dragging=*/true);
@@ -8779,8 +8777,7 @@
             split_view_controller()->state());
 
   // Select the minimized window.
-  OverviewItem* overview_item =
-      GetOverviewItemForWindow(minimized_window.get());
+  auto* overview_item = GetOverviewItemForWindow(minimized_window.get());
   ui::test::EventGenerator* generator = GetEventGenerator();
   generator->set_current_screen_location(
       gfx::ToRoundedPoint(overview_item->target_bounds().CenterPoint()));
@@ -8923,7 +8920,7 @@
   EXPECT_TRUE(GetOverviewController()->InOverviewSession());
   EXPECT_FALSE(split_view_controller()->InSplitViewMode());
   // Drag |window1| selector item to snap to left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF(0, 0));
   // Since the only window is snapped, overview and splitview should be both
   // ended.
@@ -8957,7 +8954,7 @@
   ToggleOverview();
   overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF(0, 0));
-  OverviewItem* overview_item3 = GetOverviewItemForWindow(window3.get());
+  auto* overview_item3 = GetOverviewItemForWindow(window3.get());
   DragWindowTo(overview_item3, gfx::PointF(600, 300));
   EXPECT_EQ(window_state1->GetStateType(), WindowStateType::kPrimarySnapped);
   EXPECT_EQ(WindowState::Get(window3.get())->GetStateType(),
@@ -9097,7 +9094,7 @@
 
   ToggleOverview();
   gfx::Rect overview_full_bounds = GetGridBounds();
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF(0, 0));
   EXPECT_NE(GetGridBounds(), overview_full_bounds);
   EXPECT_EQ(GetGridBounds(), GetSplitViewRightWindowBounds());
@@ -9125,7 +9122,7 @@
   // Resize that happens on the left edge of the left snapped window will end
   // overview. The same for the resize that happens on the top or bottom edge of
   // the left snapped window.
-  OverviewItem* overview_item2 = GetOverviewItemForWindow(window2.get());
+  auto* overview_item2 = GetOverviewItemForWindow(window2.get());
   DragWindowTo(overview_item2, gfx::PointF(0, 0));
   EXPECT_TRUE(GetOverviewController()->InOverviewSession());
   EXPECT_TRUE(split_view_controller()->InSplitViewMode());
@@ -9138,7 +9135,7 @@
   EXPECT_FALSE(split_view_controller()->InSplitViewMode());
 
   ToggleOverview();
-  OverviewItem* overview_item3 = GetOverviewItemForWindow(window3.get());
+  auto* overview_item3 = GetOverviewItemForWindow(window3.get());
   DragWindowTo(overview_item3, gfx::PointF(0, 0));
   ui::test::EventGenerator generator3(Shell::GetPrimaryRootWindow(),
                                       window3.get());
@@ -9149,7 +9146,7 @@
   EXPECT_FALSE(split_view_controller()->InSplitViewMode());
 
   ToggleOverview();
-  OverviewItem* overview_item4 = GetOverviewItemForWindow(window4.get());
+  auto* overview_item4 = GetOverviewItemForWindow(window4.get());
   DragWindowTo(overview_item4, gfx::PointF(0, 0));
   ui::test::EventGenerator generator4(Shell::GetPrimaryRootWindow(),
                                       window4.get());
@@ -9320,7 +9317,7 @@
       CreateWindowWithHitTestComponent(HTCAPTION, bounds));
 
   ToggleOverview();
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF(0, 0));
   EXPECT_TRUE(GetOverviewController()->InOverviewSession());
   EXPECT_TRUE(split_view_controller()->InSplitViewMode());
@@ -9341,7 +9338,7 @@
 
   ToggleOverview();
   // Drag |window1| selector item to snap to left.
-  OverviewItem* overview_item1 = GetOverviewItemForWindow(window1.get());
+  auto* overview_item1 = GetOverviewItemForWindow(window1.get());
   DragWindowTo(overview_item1, gfx::PointF(0, 0));
   EXPECT_TRUE(GetOverviewController()->InOverviewSession());
   EXPECT_TRUE(split_view_controller()->InSplitViewMode());
@@ -9535,7 +9532,7 @@
   split_view_controller()->SnapWindow(
       snapped_window.get(), SplitViewController::SnapPosition::kPrimary);
   ASSERT_TRUE(split_view_controller()->InSplitViewMode());
-  OverviewItem* overview_item = GetOverviewItemForWindow(overview_window.get());
+  auto* overview_item = GetOverviewItemForWindow(overview_window.get());
   // Note: |cannot_snap_label_view_| and its parent will be created on demand.
   EXPECT_FALSE(GetCannotSnapWidget(overview_item));
 
@@ -9579,7 +9576,7 @@
                             display_manager()->GetDisplayForId(display_ids[0]));
 
   ToggleOverview();
-  OverviewItem* overview_item = GetOverviewItemForWindow(window.get());
+  auto* overview_item = GetOverviewItemForWindow(window.get());
   EXPECT_FALSE(GetDropTarget(0));
   EXPECT_FALSE(GetDropTarget(1));
   gfx::PointF drag_point = overview_item->target_bounds().CenterPoint();
@@ -9811,8 +9808,8 @@
   ToggleOverview();
   OverviewGrid* grid_on_root2 =
       GetOverviewSession()->GetGridWithRootWindow(root_windows[1]);
-  OverviewItem* item1 = grid_on_root2->GetOverviewItemContaining(window1.get());
-  OverviewItem* item2 = grid_on_root2->GetOverviewItemContaining(window2.get());
+  auto* item1 = grid_on_root2->GetOverviewItemContaining(window1.get());
+  auto* item2 = grid_on_root2->GetOverviewItemContaining(window2.get());
   SplitViewController* split_view_controller =
       SplitViewController::Get(root_windows[1]);
   SplitViewDragIndicators* indicators =
@@ -9882,7 +9879,7 @@
       GetOverviewSession()->GetGridWithRootWindow(root_windows[0]);
   OverviewGrid* grid_on_root2 =
       GetOverviewSession()->GetGridWithRootWindow(root_windows[1]);
-  OverviewItem* item1 = grid_on_root1->GetOverviewItemContaining(window1.get());
+  auto* item1 = grid_on_root1->GetOverviewItemContaining(window1.get());
   SplitViewDragIndicators* indicators_on_root1 =
       grid_on_root1->split_view_drag_indicators();
   SplitViewDragIndicators* indicators_on_root2 =
@@ -10030,7 +10027,7 @@
       GetOverviewSession()->GetGridWithRootWindow(root_windows[0]);
   OverviewGrid* grid2 =
       GetOverviewSession()->GetGridWithRootWindow(root_windows[1]);
-  OverviewItem* item4 = grid2->GetOverviewItemContaining(window4.get());
+  auto* item4 = grid2->GetOverviewItemContaining(window4.get());
   // Start dragging |item4| from |grid2|.
   cursor_manager->SetDisplay(display_with_root2);
   GetOverviewSession()->InitiateDrag(item4,
@@ -10059,7 +10056,7 @@
   std::unique_ptr<aura::Window> window = CreateTestWindow();
   WindowState::Get(window.get())->Maximize();
   ToggleOverview();
-  OverviewItem* item = GetOverviewItemForWindow(window.get());
+  auto* item = GetOverviewItemForWindow(window.get());
   // Verify that |item| is letter boxed. The bounds of |item|, minus the margin
   // should have an aspect ratio of 2 : 1.
   gfx::RectF item_bounds = item->target_bounds();
@@ -10074,7 +10071,7 @@
   // Drag to the middle of the secondary display to avoid triggering the drag
   // snap indicator animation.
   GetOverviewSession()->Drag(item, gfx::PointF(1200.f, 500.f));
-  OverviewItem* drop_target = GetDropTarget(1);
+  auto* drop_target = GetDropTarget(1);
   ASSERT_TRUE(drop_target);
   // Verify that |drop_target| is effectively pillar boxed. Avoid calling
   // |OverviewItem::GetWindowDimensionsType|, because it does not work for drop
@@ -10092,7 +10089,7 @@
   UpdateDisplay("600x500,1200x1000");
   // Drags |item| from the right display to the left display and back, and
   // returns the bounds of the drop target that appears on the left display.
-  const auto root1_drop_target_bounds = [this](OverviewItem* item) {
+  const auto root1_drop_target_bounds = [this](OverviewItemBase* item) {
     wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
     const gfx::PointF drag_starting_point = item->target_bounds().CenterPoint();
     display::test::DisplayManagerTestApi display_manager_test(
@@ -10125,10 +10122,10 @@
       CreateTestWindow(gfx::Rect(600, 0, 400, 1000));
 
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
-  OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
-  OverviewItem* item4 = GetOverviewItemForWindow(window4.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item4 = GetOverviewItemForWindow(window4.get());
 
   // For good test coverage in each case, the dragged window and the drop target
   // have different |OverviewGridWindowFillMode| values.
@@ -10173,7 +10170,7 @@
 
   EXPECT_EQ(root_windows[1], window->GetRootWindow());
   EXPECT_TRUE(grid1->empty());
-  OverviewItem* item = grid2->GetOverviewItemContaining(window.get());
+  auto* item = grid2->GetOverviewItemContaining(window.get());
   ASSERT_TRUE(item);
   EXPECT_EQ(root_windows[1], item->root_window());
 }
@@ -10196,9 +10193,9 @@
   ASSERT_NE(parent_on_root1, parent_on_root2);
   ASSERT_EQ(window3->parent(), parent_on_root2);
   ToggleOverview();
-  OverviewItem* item1 = GetOverviewItemForWindow(window1.get());
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
-  OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item1 = GetOverviewItemForWindow(window1.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get());
 
   ASSERT_EQ(root_windows[0], item2->root_window());
   // Verify that |item1| is stacked above |item3| (because we created |window1|
@@ -10485,10 +10482,10 @@
   std::unique_ptr<aura::Window> window6 =
       CreateUnsnappableWindow(bounds_within_root2);
   ToggleOverview();
-  OverviewItem* item2 = GetOverviewItemForWindow(window2.get());
-  OverviewItem* item3 = GetOverviewItemForWindow(window3.get());
-  OverviewItem* item5 = GetOverviewItemForWindow(window5.get());
-  OverviewItem* item6 = GetOverviewItemForWindow(window6.get());
+  auto* item2 = GetOverviewItemForWindow(window2.get());
+  auto* item3 = GetOverviewItemForWindow(window3.get());
+  auto* item5 = GetOverviewItemForWindow(window5.get());
+  auto* item6 = GetOverviewItemForWindow(window6.get());
 
   // Note: |cannot_snap_label_view_| and its parent will be created on demand.
   ASSERT_FALSE(SplitViewController::Get(root_windows[0])->InSplitViewMode());
diff --git a/ash/wm/overview/overview_test_base.cc b/ash/wm/overview/overview_test_base.cc
index e73324ab..4fa6bb3b 100644
--- a/ash/wm/overview/overview_test_base.cc
+++ b/ash/wm/overview/overview_test_base.cc
@@ -16,6 +16,7 @@
 #include "ash/wm/overview/overview_controller.h"
 #include "ash/wm/overview/overview_grid.h"
 #include "ash/wm/overview/overview_item.h"
+#include "ash/wm/overview/overview_item_base.h"
 #include "ash/wm/overview/overview_item_view.h"
 #include "ash/wm/overview/overview_utils.h"
 #include "ash/wm/overview/overview_wallpaper_controller.h"
@@ -23,7 +24,7 @@
 #include "ash/wm/tablet_mode/tablet_mode_controller_test_api.h"
 #include "ash/wm/window_mini_view_header_view.h"
 #include "ash/wm/window_preview_view.h"
-#include "components/app_constants/constants.h"
+#include "ash/wm/window_util.h"
 #include "ui/aura/client/aura_constants.h"
 #include "ui/compositor/layer.h"
 #include "ui/compositor/presentation_time_recorder.h"
@@ -49,7 +50,7 @@
   return GetOverviewController()->InOverviewSession();
 }
 
-void OverviewTestBase::DispatchLongPress(OverviewItem* item) {
+void OverviewTestBase::DispatchLongPress(OverviewItemBase* item) {
   const gfx::Point point =
       gfx::ToRoundedPoint(item->target_bounds().CenterPoint());
   ui::GestureEvent long_press(
@@ -128,27 +129,31 @@
   return transform.MapRect(gfx::Rect(window->bounds().size()));
 }
 
-OverviewItem* OverviewTestBase::GetDropTarget(int grid_index) {
+OverviewItemBase* OverviewTestBase::GetDropTarget(int grid_index) {
   return GetOverviewSession()->grid_list_[grid_index]->GetDropTarget();
 }
 
-CloseButton* OverviewTestBase::GetCloseButton(OverviewItem* item) {
-  return item->overview_item_view_->close_button();
+CloseButton* OverviewTestBase::GetCloseButton(OverviewItemBase* item) {
+  return item->GetLeafItemForWindow(item->GetWindow())
+      ->overview_item_view_->close_button();
 }
 
-views::Label* OverviewTestBase::GetLabelView(OverviewItem* item) {
-  return item->overview_item_view_->header_view()->title_label();
+views::Label* OverviewTestBase::GetLabelView(OverviewItemBase* item) {
+  return item->GetLeafItemForWindow(item->GetWindow())
+      ->overview_item_view_->header_view()
+      ->title_label();
 }
 
-views::View* OverviewTestBase::GetBackdropView(OverviewItem* item) {
-  return item->overview_item_view_->backdrop_view();
+views::View* OverviewTestBase::GetBackdropView(OverviewItemBase* item) {
+  return item->GetBackDropView();
 }
 
-WindowPreviewView* OverviewTestBase::GetPreviewView(OverviewItem* item) {
-  return item->overview_item_view_->preview_view();
+WindowPreviewView* OverviewTestBase::GetPreviewView(OverviewItemBase* item) {
+  return item->GetLeafItemForWindow(item->GetWindow())
+      ->overview_item_view_->preview_view();
 }
 
-gfx::Rect OverviewTestBase::GetShadowBounds(OverviewItem* item) const {
+gfx::Rect OverviewTestBase::GetShadowBounds(OverviewItemBase* item) const {
   SystemShadow* shadow = item->shadow_.get();
   if (!shadow || !shadow->GetLayer()->visible()) {
     return gfx::Rect();
@@ -157,37 +162,36 @@
   return shadow->GetContentBounds();
 }
 
-views::Widget* OverviewTestBase::GetCannotSnapWidget(OverviewItem* item) {
+views::Widget* OverviewTestBase::GetCannotSnapWidget(OverviewItemBase* item) {
   return item->cannot_snap_widget_.get();
 }
 
-void OverviewTestBase::SetAnimatingToClose(OverviewItem* item, bool val) {
+void OverviewTestBase::SetAnimatingToClose(OverviewItemBase* item, bool val) {
   item->animating_to_close_ = val;
 }
 
-float OverviewTestBase::GetCloseButtonOpacity(OverviewItem* item) {
+float OverviewTestBase::GetCloseButtonOpacity(OverviewItemBase* item) {
   return GetCloseButton(item)->layer()->opacity();
 }
 
-float OverviewTestBase::GetTitlebarOpacity(OverviewItem* item) {
-  return item->overview_item_view_->header_view()->layer()->opacity();
+float OverviewTestBase::GetTitlebarOpacity(OverviewItemBase* item) {
+  return item->GetLeafItemForWindow(item->GetWindow())
+      ->overview_item_view_->header_view()
+      ->layer()
+      ->opacity();
 }
 
-const ScopedOverviewTransformWindow& OverviewTestBase::GetTransformWindow(
-    OverviewItem* item) const {
-  return item->transform_window_;
-}
-
-bool OverviewTestBase::HasRoundedCorner(OverviewItem* item) {
-  const ui::Layer* layer = item->transform_window_.IsMinimized()
+bool OverviewTestBase::HasRoundedCorner(OverviewItemBase* item) {
+  aura::Window* window = item->GetWindow();
+  const ui::Layer* layer = window_util::IsMinimizedOrTucked(window)
                                ? GetPreviewView(item)->layer()
-                               : GetTransformWindow(item).window()->layer();
+                               : window->layer();
   return !layer->rounded_corner_radii().IsEmpty();
 }
 
 void OverviewTestBase::CheckWindowAndCloseButtonInScreen(
     aura::Window* window,
-    OverviewItem* window_item) {
+    OverviewItemBase* window_item) {
   const gfx::Rect screen_bounds =
       window_item->root_window()->GetBoundsInScreen();
   EXPECT_TRUE(window_item->Contains(window));
diff --git a/ash/wm/overview/overview_test_base.h b/ash/wm/overview/overview_test_base.h
index f8ca9b10..ffcec40 100644
--- a/ash/wm/overview/overview_test_base.h
+++ b/ash/wm/overview/overview_test_base.h
@@ -25,8 +25,8 @@
 class OverviewController;
 class OverviewGrid;
 class OverviewItem;
+class OverviewItemBase;
 class OverviewSession;
-class ScopedOverviewTransformWindow;
 class SplitViewController;
 class WindowPreviewView;
 
@@ -46,7 +46,7 @@
 
   bool InOverviewSession();
 
-  void DispatchLongPress(OverviewItem* item);
+  void DispatchLongPress(OverviewItemBase* item);
 
   // Creates `n` app windows. They are created in reverse order, so that the
   // first window in the vector is the MRU window.
@@ -71,33 +71,32 @@
 
   gfx::Rect GetTransformedBoundsInRootWindow(aura::Window* window);
 
-  OverviewItem* GetDropTarget(int grid_index);
+  OverviewItemBase* GetDropTarget(int grid_index);
 
-  CloseButton* GetCloseButton(OverviewItem* item);
+  CloseButton* GetCloseButton(OverviewItemBase* item);
 
-  views::Label* GetLabelView(OverviewItem* item);
+  views::Label* GetLabelView(OverviewItemBase* item);
 
-  views::View* GetBackdropView(OverviewItem* item);
+  views::View* GetBackdropView(OverviewItemBase* item);
 
-  WindowPreviewView* GetPreviewView(OverviewItem* item);
+  WindowPreviewView* GetPreviewView(OverviewItemBase* item);
 
-  gfx::Rect GetShadowBounds(OverviewItem* item) const;
+  gfx::Rect GetShadowBounds(OverviewItemBase* item) const;
 
-  views::Widget* GetCannotSnapWidget(OverviewItem* item);
+  views::Widget* GetCannotSnapWidget(OverviewItemBase* item);
 
-  void SetAnimatingToClose(OverviewItem* item, bool val);
+  void SetAnimatingToClose(OverviewItemBase* item, bool val);
 
-  float GetCloseButtonOpacity(OverviewItem* item);
+  float GetCloseButtonOpacity(OverviewItemBase* item);
 
-  float GetTitlebarOpacity(OverviewItem* item);
-  const ScopedOverviewTransformWindow& GetTransformWindow(
-      OverviewItem* item) const;
-  bool HasRoundedCorner(OverviewItem* item);
+  float GetTitlebarOpacity(OverviewItemBase* item);
+
+  bool HasRoundedCorner(OverviewItemBase* item);
 
   // Tests that a window is contained within a given OverviewItem, and that both
   // the window and its matching close button are within the same screen.
   void CheckWindowAndCloseButtonInScreen(aura::Window* window,
-                                         OverviewItem* window_item);
+                                         OverviewItemBase* window_item);
 
   void CheckOverviewEnterExitHistogram(const std::string& trace,
                                        const std::vector<int>& enter_counts,
diff --git a/ash/wm/overview/overview_test_util.cc b/ash/wm/overview/overview_test_util.cc
index e2f353d..f64db29e 100644
--- a/ash/wm/overview/overview_test_util.cc
+++ b/ash/wm/overview/overview_test_util.cc
@@ -11,6 +11,7 @@
 #include "ash/wm/overview/overview_grid.h"
 #include "ash/wm/overview/overview_highlight_controller.h"
 #include "ash/wm/overview/overview_item.h"
+#include "ash/wm/overview/overview_item_base.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
@@ -58,7 +59,7 @@
 }
 
 const aura::Window* GetOverviewHighlightedWindow() {
-  OverviewItem* item =
+  auto* item =
       GetOverviewSession()->highlight_controller()->GetHighlightedItem();
   if (!item)
     return nullptr;
@@ -97,12 +98,12 @@
   return overview_controller->overview_session()->GetGridWithRootWindow(root);
 }
 
-const std::vector<std::unique_ptr<OverviewItem>>& GetOverviewItemsForRoot(
+const std::vector<std::unique_ptr<OverviewItemBase>>& GetOverviewItemsForRoot(
     int index) {
   return GetOverviewSession()->grid_list()[index]->window_list();
 }
 
-OverviewItem* GetOverviewItemForWindow(aura::Window* window) {
+OverviewItemBase* GetOverviewItemForWindow(aura::Window* window) {
   return GetOverviewSession()->GetOverviewItemForWindow(window);
 }
 
@@ -115,7 +116,7 @@
   return new_rect;
 }
 
-void DragItemToPoint(OverviewItem* item,
+void DragItemToPoint(OverviewItemBase* item,
                      const gfx::Point& screen_location,
                      ui::test::EventGenerator* event_generator,
                      bool by_touch_gestures,
diff --git a/ash/wm/overview/overview_test_util.h b/ash/wm/overview/overview_test_util.h
index 18e0f4782..5b3eddc 100644
--- a/ash/wm/overview/overview_test_util.h
+++ b/ash/wm/overview/overview_test_util.h
@@ -8,14 +8,14 @@
 #include "ash/wm/overview/overview_session.h"
 #include "ui/events/keycodes/keyboard_codes_posix.h"
 
-namespace ui {
-namespace test {
+namespace ui::test {
 class EventGenerator;
-}  // namespace test
-}  // namespace ui
+}  // namespace ui::test
 
 namespace ash {
 
+class OverviewItemBase;
+
 void SendKey(ui::KeyboardCode key, int flags = ui::EF_NONE);
 
 // Highlights |window| in the active overview session by cycling through all
@@ -39,11 +39,11 @@
 
 OverviewGrid* GetOverviewGridForRoot(aura::Window* root);
 
-const std::vector<std::unique_ptr<OverviewItem>>& GetOverviewItemsForRoot(
+const std::vector<std::unique_ptr<OverviewItemBase>>& GetOverviewItemsForRoot(
     int index);
 
 // Returns the OverviewItem associated with |window| if it exists.
-OverviewItem* GetOverviewItemForWindow(aura::Window* window);
+OverviewItemBase* GetOverviewItemForWindow(aura::Window* window);
 
 // Returns a rect that accounts for the shelf hotseat. Used by tests which test
 // the grids' bounds in relation to work area or snapped window bounds.
@@ -51,7 +51,7 @@
 
 // If `drop` is false, the dragged `item` won't be dropped; giving the caller
 // a chance to do some validations before the item is dropped.
-void DragItemToPoint(OverviewItem* item,
+void DragItemToPoint(OverviewItemBase* item,
                      const gfx::Point& screen_location,
                      ui::test::EventGenerator* event_generator,
                      bool by_touch_gestures = false,
diff --git a/ash/wm/overview/overview_types.h b/ash/wm/overview/overview_types.h
index 47bb6987..cc70cd99 100644
--- a/ash/wm/overview/overview_types.h
+++ b/ash/wm/overview/overview_types.h
@@ -7,12 +7,6 @@
 
 namespace ash {
 
-// Defines the overview item types.
-enum class OverviewItemType {
-  kSingleItem,
-  kGroupItem,
-};
-
 // Enumeration of the different overview mode animations.
 enum OverviewAnimationType {
   OVERVIEW_ANIMATION_NONE,
diff --git a/ash/wm/overview/overview_window_drag_controller.cc b/ash/wm/overview/overview_window_drag_controller.cc
index 7e0bd46..4ac14163 100644
--- a/ash/wm/overview/overview_window_drag_controller.cc
+++ b/ash/wm/overview/overview_window_drag_controller.cc
@@ -97,13 +97,13 @@
       kOcclusionPauseDurationForDrag);
 }
 
-bool GetVirtualDesksBarEnabled(OverviewItem* item) {
+bool GetVirtualDesksBarEnabled(OverviewItemBase* item) {
   return desks_util::ShouldDesksBarBeCreated() &&
          item->overview_grid()->desks_bar_view();
 }
 
 // Returns whether |item|'s window is visible on all desks.
-bool DraggedItemIsVisibleOnAllDesks(OverviewItem* item) {
+bool DraggedItemIsVisibleOnAllDesks(OverviewItemBase* item) {
   aura::Window* const dragged_window = item->GetWindow();
   return dragged_window &&
          desks_util::IsWindowVisibleOnAllWorkspaces(dragged_window);
@@ -217,7 +217,7 @@
       session->AddItemInMruOrder(window, /*reposition=*/false,
                                  /*animate=*/false, /*restack=*/false,
                                  /*use_spawn_animation=*/false);
-      OverviewItem* item = session->GetOverviewItemForWindow(window);
+      OverviewItemBase* item = session->GetOverviewItemForWindow(window);
       DCHECK(item);
       item->SetBounds(target_item_bounds_, OVERVIEW_ANIMATION_NONE);
       item->set_should_restack_on_animation_end(true);
@@ -235,7 +235,7 @@
 
 OverviewWindowDragController::OverviewWindowDragController(
     OverviewSession* overview_session,
-    OverviewItem* item,
+    OverviewItemBase* item,
     bool is_touch_dragging)
     : overview_session_(overview_session),
       item_(item),
@@ -430,7 +430,7 @@
   if (current_drag_behavior_ == DragBehavior::kDragToClose ||
       current_drag_behavior_ == DragBehavior::kUndefined) {
     if (std::abs(velocity_y) > kFlingToCloseVelocityThreshold) {
-      item_->AnimateAndCloseWindow(
+      item_->AnimateAndCloseItem(
           (location_in_screen - initial_event_location_).y() < 0);
       did_move_ = false;
       item_ = nullptr;
@@ -489,7 +489,7 @@
   }
 
   // No need to position windows that are being destroyed.
-  base::flat_set<OverviewItem*> ignored_items;
+  base::flat_set<OverviewItemBase*> ignored_items;
   if (item_->GetWindow()->is_destroying()) {
     ignored_items.insert(item_);
   }
@@ -570,7 +570,7 @@
   overview_session_->GetGridWithRootWindow(item_->root_window())->EndNudge();
   const float y_distance = (location_in_screen - initial_event_location_).y();
   if (std::abs(y_distance) > kDragToCloseDistanceThresholdDp) {
-    item_->AnimateAndCloseWindow(/*up=*/y_distance < 0);
+    item_->AnimateAndCloseItem(/*up=*/y_distance < 0);
     RecordDragToClose(kSwipeToCloseSuccessful);
     return DragResult::kSuccessfulDragToClose;
   }
diff --git a/ash/wm/overview/overview_window_drag_controller.h b/ash/wm/overview/overview_window_drag_controller.h
index d61d8346..05387da 100644
--- a/ash/wm/overview/overview_window_drag_controller.h
+++ b/ash/wm/overview/overview_window_drag_controller.h
@@ -20,7 +20,7 @@
 namespace ash {
 
 class OverviewGrid;
-class OverviewItem;
+class OverviewItemBase;
 class OverviewSession;
 
 // These values are persisted to logs. Entries should not be renumbered and
@@ -92,7 +92,7 @@
   };
 
   OverviewWindowDragController(OverviewSession* overview_session,
-                               OverviewItem* item,
+                               OverviewItemBase* item,
                                bool is_touch_dragging);
 
   OverviewWindowDragController(const OverviewWindowDragController&) = delete;
@@ -124,7 +124,7 @@
   // after a gesture is completed if there is an animation.
   void DestroyFloatDragHelper();
 
-  OverviewItem* item() { return item_; }
+  OverviewItemBase* item() { return item_; }
 
   bool is_touch_dragging() const { return is_touch_dragging_; }
 
@@ -200,7 +200,8 @@
   raw_ptr<OverviewSession, ExperimentalAsh> overview_session_;
 
   // The drag target window in the overview mode.
-  raw_ptr<OverviewItem, DanglingUntriaged | ExperimentalAsh> item_ = nullptr;
+  raw_ptr<OverviewItemBase, DanglingUntriaged | ExperimentalAsh> item_ =
+      nullptr;
 
   DragBehavior current_drag_behavior_ = DragBehavior::kNoDrag;
 
diff --git a/ash/wm/overview/overview_window_drag_controller_unittest.cc b/ash/wm/overview/overview_window_drag_controller_unittest.cc
index 21ea697..53187f2 100644
--- a/ash/wm/overview/overview_window_drag_controller_unittest.cc
+++ b/ash/wm/overview/overview_window_drag_controller_unittest.cc
@@ -43,7 +43,7 @@
 namespace {
 
 // Drags the item by |x| and |y| and does not drop it.
-void StartDraggingItemBy(OverviewItem* item,
+void StartDraggingItemBy(OverviewItemBase* item,
                          int x,
                          int y,
                          bool by_touch_gestures,
@@ -148,7 +148,7 @@
     return overview_grid()->desks_bar_view()->GetWidget();
   }
 
-  OverviewItem* GetOverviewItemForWindow(aura::Window* window) {
+  OverviewItemBase* GetOverviewItemForWindow(aura::Window* window) {
     return overview_session()->GetOverviewItemForWindow(window);
   }
 
diff --git a/ash/wm/overview/scoped_overview_transform_window.cc b/ash/wm/overview/scoped_overview_transform_window.cc
index 7309850..b1e8e24 100644
--- a/ash/wm/overview/scoped_overview_transform_window.cc
+++ b/ash/wm/overview/scoped_overview_transform_window.cc
@@ -574,7 +574,7 @@
 
   // Depending on the size of `backdrop_view`, we might not want to round the
   // window associated with `layer`.
-  auto* backdrop_view = overview_item_->overview_item_view()->backdrop_view();
+  auto* backdrop_view = overview_item_->GetBackDropView();
   const bool has_rounding = window_util::ShouldRoundThumbnailWindow(
       backdrop_view, GetTransformedBounds());
 
diff --git a/ash/wm/snap_group/snap_group_unittest.cc b/ash/wm/snap_group/snap_group_unittest.cc
index 0fd3cc4..035b970 100644
--- a/ash/wm/snap_group/snap_group_unittest.cc
+++ b/ash/wm/snap_group/snap_group_unittest.cc
@@ -33,6 +33,7 @@
 #include "ash/wm/window_cycle/window_cycle_controller.h"
 #include "ash/wm/window_cycle/window_cycle_list.h"
 #include "ash/wm/window_cycle/window_cycle_view.h"
+#include "ash/wm/window_mini_view.h"
 #include "ash/wm/window_state.h"
 #include "ash/wm/window_util.h"
 #include "ash/wm/wm_event.h"
@@ -45,14 +46,17 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/timer/timer.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "chromeos/ui/base/window_state_type.h"
 #include "ui/aura/test/test_window_delegate.h"
 #include "ui/base/cursor/mojom/cursor_type.mojom-shared.h"
 #include "ui/base/hit_test.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/compositor/layer.h"
 #include "ui/events/keycodes/keyboard_codes_posix.h"
 #include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/rounded_corners_f.h"
 #include "ui/gfx/geometry/vector2d.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_unittest_util.h"
@@ -68,6 +72,8 @@
 
 using WindowCyclingDirection = WindowCycleController::WindowCyclingDirection;
 
+constexpr int kWindowMiniViewCornerRadius = 16;
+
 SplitViewController* split_view_controller() {
   return SplitViewController::Get(Shell::GetPrimaryRootWindow());
 }
@@ -164,8 +170,11 @@
     // TODO(michelefan@): Change it back to
     // `scoped_feature_list_.InitAndEnableFeature(features::kSnapGroup)` when
     // do the refactor work for the snap group unit tests.
-    scoped_feature_list_.InitAndEnableFeatureWithParameters(
-        features::kSnapGroup, {{"AutomaticLockGroup", "false"}});
+    scoped_feature_list_.InitWithFeaturesAndParameters(
+        {{features::kSnapGroup, {{"AutomaticLockGroup", "false"}}},
+         {chromeos::features::kJellyroll, {}},
+         {chromeos::features::kJelly, {}}},
+        {});
   }
   SnapGroupTest(const SnapGroupTest&) = delete;
   SnapGroupTest& operator=(const SnapGroupTest&) = delete;
@@ -408,7 +417,7 @@
 
     // The `window2` gets selected in the overview will be snapped to the
     // non-occupied snap position and the overview session will end.
-    OverviewItem* item2 = GetOverviewItemForWindow(window2);
+    auto* item2 = GetOverviewItemForWindow(window2);
     auto* event_generator = GetEventGenerator();
     event_generator->MoveMouseTo(
         gfx::ToRoundedPoint(item2->GetTransformedBounds().CenterPoint()));
@@ -890,7 +899,7 @@
 
   // Upon selecting another item in the overview session, a new snap group will
   // be formed.
-  OverviewItem* item3 = GetOverviewItemForWindow(w3.get());
+  auto* item3 = GetOverviewItemForWindow(w3.get());
   auto* event_generator = GetEventGenerator();
   event_generator->MoveMouseTo(
       gfx::ToRoundedPoint(item3->GetTransformedBounds().CenterPoint()));
@@ -920,7 +929,7 @@
 
   // Do another update for the snap group by selecting another candidate from
   // the overview session and verify that the snap group has been updated.
-  OverviewItem* item4 = GetOverviewItemForWindow(w4.get());
+  auto* item4 = GetOverviewItemForWindow(w4.get());
   event_generator->MoveMouseTo(
       gfx::ToRoundedPoint(item4->GetTransformedBounds().CenterPoint()));
   event_generator->ClickLeftButton();
@@ -1037,7 +1046,7 @@
             chromeos::WindowStateType::kPrimarySnapped);
   ASSERT_EQ(1u, GetOverviewSession()->grid_list().size());
 
-  OverviewItem* w2_overview_item = GetOverviewItemForWindow(w2.get());
+  auto* w2_overview_item = GetOverviewItemForWindow(w2.get());
   EXPECT_TRUE(w2_overview_item);
   const gfx::Point outside_point =
       gfx::ToRoundedPoint(
@@ -1271,6 +1280,45 @@
   EXPECT_TRUE(wm::IsActiveWindow(window2.get()));
 }
 
+// Tests that the exposed rounded corners of the cycling items are rounded
+// corners. The visuals will be refreshed on window destruction that belongs to
+// a snap group.
+TEST_F(SnapGroupEntryPointArm1Test, WindowCycleRoundedCorners) {
+  std::unique_ptr<aura::Window> window0 =
+      CreateAppWindow(gfx::Rect(100, 200), AppType::BROWSER);
+  std::unique_ptr<aura::Window> window1 =
+      CreateAppWindow(gfx::Rect(200, 300), AppType::BROWSER);
+  std::unique_ptr<aura::Window> window2 =
+      CreateAppWindow(gfx::Rect(300, 400), AppType::BROWSER);
+  SnapTwoTestWindowsInArm1(window0.get(), window1.get());
+
+  WindowCycleController* window_cycle_controller =
+      Shell::Get()->window_cycle_controller();
+  CycleWindow(WindowCyclingDirection::kForward, /*steps=*/3);
+  EXPECT_TRUE(window_cycle_controller->IsCycling());
+  const auto* window_cycle_list = window_cycle_controller->window_cycle_list();
+  const auto* cycle_view = window_cycle_list->cycle_view();
+  auto& cycle_item_views = cycle_view->cycle_views_for_testing();
+  ASSERT_EQ(cycle_item_views.size(), 2u);
+  for (auto* cycle_item_view : cycle_item_views) {
+    EXPECT_EQ(cycle_item_view->GetRoundedCorners(),
+              gfx::RoundedCornersF(kWindowMiniViewCornerRadius));
+  }
+
+  // Destroy `window0` which belongs to a snap group.
+  window0.reset();
+  auto& new_cycle_item_views = cycle_view->cycle_views_for_testing();
+  EXPECT_EQ(new_cycle_item_views.size(), 2u);
+
+  // Verify that the visuals of the cycling items will be refreshed so that the
+  // exposed corners will be rounded corners.
+  for (auto* cycle_item_view : new_cycle_item_views) {
+    EXPECT_EQ(cycle_item_view->GetRoundedCorners(),
+              gfx::RoundedCornersF(kWindowMiniViewCornerRadius));
+  }
+  CompleteWindowCycling();
+}
+
 // Tests that after creating a snap group in clamshell, transition to tablet
 // mode won't crash (b/288179725).
 TEST_F(SnapGroupEntryPointArm1Test, NoCrashWhenRemovingGroupInTabletMode) {
diff --git a/ash/wm/splitview/split_view_controller.cc b/ash/wm/splitview/split_view_controller.cc
index 836a29a0..a33ff2a 100644
--- a/ash/wm/splitview/split_view_controller.cc
+++ b/ash/wm/splitview/split_view_controller.cc
@@ -241,7 +241,7 @@
     return;
   }
 
-  OverviewItem* item = overview_session->GetOverviewItemForWindow(window);
+  OverviewItemBase* item = overview_session->GetOverviewItemForWindow(window);
   if (!item) {
     return;
   }
@@ -1129,7 +1129,7 @@
     // |OverviewItem::OnSelectorItemDragEnded| already was called on all
     // overview items and |previous_snapped_window| was not yet among them.
     overview_session->GetOverviewItemForWindow(previous_snapped_window)
-        ->OnSelectorItemDragEnded(/*snap=*/true);
+        ->OnOverviewItemDragEnded(/*snap=*/true);
   }
 
   if (split_view_type_ == SplitViewType::kTabletType) {
diff --git a/ash/wm/splitview/split_view_controller_unittest.cc b/ash/wm/splitview/split_view_controller_unittest.cc
index ec16ea9e..5fb6f4e 100644
--- a/ash/wm/splitview/split_view_controller_unittest.cc
+++ b/ash/wm/splitview/split_view_controller_unittest.cc
@@ -843,7 +843,7 @@
 
   OverviewSession* overview_session =
       Shell::Get()->overview_controller()->overview_session();
-  OverviewItem* overview_item =
+  auto* overview_item =
       overview_session->GetOverviewItemForWindow(window2.get());
   gfx::PointF drag_point = overview_item->target_bounds().CenterPoint();
   overview_session->InitiateDrag(overview_item, drag_point,
@@ -882,7 +882,7 @@
 
   OverviewSession* overview_session =
       Shell::Get()->overview_controller()->overview_session();
-  OverviewItem* overview_item =
+  auto* overview_item =
       overview_session->GetOverviewItemForWindow(window2.get());
   gfx::PointF drag_point = overview_item->target_bounds().CenterPoint();
   overview_session->InitiateDrag(overview_item, drag_point,
diff --git a/ash/wm/splitview/split_view_drag_indicators_unittest.cc b/ash/wm/splitview/split_view_drag_indicators_unittest.cc
index 5677ddf7..56a67f6 100644
--- a/ash/wm/splitview/split_view_drag_indicators_unittest.cc
+++ b/ash/wm/splitview/split_view_drag_indicators_unittest.cc
@@ -121,8 +121,8 @@
   ui::test::EventGenerator* generator = GetEventGenerator();
 
   ToggleOverview();
-  OverviewItem* left_item = GetOverviewItemForWindow(left_window.get());
-  OverviewItem* right_item = GetOverviewItemForWindow(right_window.get());
+  auto* left_item = GetOverviewItemForWindow(left_window.get());
+  auto* right_item = GetOverviewItemForWindow(right_window.get());
 
   // The inset on each side of the screen which is a snap region. Items dragged
   // to and released under this region will get snapped.
@@ -229,7 +229,7 @@
 
   // Verify the preview area is visible when |item|'s x is in the
   // range [0, edge_inset] or [screen_width - edge_inset - 1, screen_width].
-  OverviewItem* item = GetOverviewItemForWindow(window.get());
+  auto* item = GetOverviewItemForWindow(window.get());
   ASSERT_TRUE(item);
   const gfx::PointF start_location(item->target_bounds().CenterPoint());
   // Drag horizontally to avoid activating drag to close.
@@ -263,7 +263,7 @@
   std::unique_ptr<aura::Window> window(CreateUnsnappableWindow());
   ToggleOverview();
 
-  OverviewItem* item = GetOverviewItemForWindow(window.get());
+  auto* item = GetOverviewItemForWindow(window.get());
   const gfx::PointF start_location(item->target_bounds().CenterPoint());
   overview_session_->InitiateDrag(item, start_location,
                                   /*is_touch_dragging=*/false);
@@ -290,7 +290,7 @@
   ToggleOverview();
 
   // Start dragging from overview.
-  OverviewItem* item = GetOverviewItemForWindow(window1.get());
+  auto* item = GetOverviewItemForWindow(window1.get());
   gfx::PointF start_location(item->target_bounds().CenterPoint());
   overview_session_->InitiateDrag(item, start_location,
                                   /*is_touch_dragging=*/false);
@@ -341,7 +341,7 @@
   std::unique_ptr<aura::Window> unsnappable_window(CreateUnsnappableWindow());
   ToggleOverview();
 
-  OverviewItem* item = GetOverviewItemForWindow(unsnappable_window.get());
+  auto* item = GetOverviewItemForWindow(unsnappable_window.get());
   gfx::PointF start_location(item->target_bounds().CenterPoint());
   overview_session_->InitiateDrag(item, start_location,
                                   /*is_touch_dragging=*/false);
@@ -503,7 +503,7 @@
       IndicatorType::kRightText));
 
   // Start dragging from overview in the landscape display.
-  OverviewItem* item = GetOverviewItemForWindow(window1.get());
+  auto* item = GetOverviewItemForWindow(window1.get());
   gfx::PointF start_location(item->target_bounds().CenterPoint());
   overview_session_->InitiateDrag(item, start_location,
                                   /*is_touch_dragging=*/false);
diff --git a/ash/wm/window_cycle/window_cycle_item_view.cc b/ash/wm/window_cycle/window_cycle_item_view.cc
index fcad3b3..883ab7d 100644
--- a/ash/wm/window_cycle/window_cycle_item_view.cc
+++ b/ash/wm/window_cycle/window_cycle_item_view.cc
@@ -17,6 +17,7 @@
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/compositor/layer.h"
 #include "ui/gfx/geometry/insets.h"
+#include "ui/gfx/geometry/rounded_corners_f.h"
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/view.h"
 
@@ -134,10 +135,9 @@
 }
 
 void WindowCycleItemView::RefreshItemVisuals() {
-  CHECK(!preview_view());
-
   header_view()->UpdateIconView(source_window());
   SetShowPreview(/*show=*/true);
+  UpdateHeaderViewRoundedCorners();
   UpdatePreviewRoundedCorners(/*show=*/true);
 }
 
@@ -205,6 +205,8 @@
     }
   }
 
+  RefreshItemVisuals();
+
   return base::ranges::count_if(
       mini_views_ptrs,
       [](raw_ptr<WindowCycleItemView>* ptr) { return *ptr != nullptr; });
@@ -218,6 +220,32 @@
   node_data->SetName(u"Group container view");
 }
 
+gfx::RoundedCornersF GroupContainerCycleView::GetRoundedCorners() const {
+  if (!mini_view1_ && !mini_view2_) {
+    return gfx::RoundedCornersF();
+  }
+
+  // In normal use cases, the left corners (`upper_left` and `lower_left`) will
+  // depend on the primary snapped window, and likewise for the right corners.
+  // However, if one window gets destructed leaving only one mini view hosted by
+  // this. All the rounded corners have to be from the remaining mini view.
+  // TODO(b/294294344): for vertical split view, the upper corners will depend
+  // on the primary snapped window and likewise for the lower corners.
+  const float upper_left = mini_view1_
+                               ? mini_view1_->GetRoundedCorners().upper_left()
+                               : mini_view2_->GetRoundedCorners().upper_left();
+  const float upper_right =
+      mini_view2_ ? mini_view2_->GetRoundedCorners().upper_right()
+                  : mini_view1_->GetRoundedCorners().upper_right();
+  const float lower_right = mini_view2_
+                                ? mini_view2_->GetRoundedCorners().lower_right()
+                                : mini_view1_->GetRoundedCorners().lower_left();
+  const float lower_left = mini_view1_
+                               ? mini_view1_->GetRoundedCorners().lower_left()
+                               : mini_view2_->GetRoundedCorners().lower_right();
+  return gfx::RoundedCornersF(upper_left, upper_right, lower_right, lower_left);
+}
+
 BEGIN_METADATA(GroupContainerCycleView, WindowMiniViewBase)
 END_METADATA
 
diff --git a/ash/wm/window_cycle/window_cycle_item_view.h b/ash/wm/window_cycle/window_cycle_item_view.h
index d0e6558..29ea3b12 100644
--- a/ash/wm/window_cycle/window_cycle_item_view.h
+++ b/ash/wm/window_cycle/window_cycle_item_view.h
@@ -66,6 +66,7 @@
   aura::Window* GetWindowAtPoint(const gfx::Point& screen_point) const override;
   void RefreshItemVisuals() override;
   int TryRemovingChildItem(aura::Window* destroying_window) override;
+  gfx::RoundedCornersF GetRoundedCorners() const override;
 
   // views::View:
   void GetAccessibleNodeData(ui::AXNodeData* node_data) override;
diff --git a/ash/wm/window_cycle/window_cycle_view.h b/ash/wm/window_cycle/window_cycle_view.h
index c1c8178..1979507 100644
--- a/ash/wm/window_cycle/window_cycle_view.h
+++ b/ash/wm/window_cycle/window_cycle_view.h
@@ -137,6 +137,10 @@
     return mirror_container_;
   }
 
+  const std::vector<WindowMiniViewBase*>& cycle_views_for_testing() const {
+    return cycle_views_;
+  }
+
  private:
   friend class WindowCycleListTestApi;
 
diff --git a/ash/wm/window_mini_view.cc b/ash/wm/window_mini_view.cc
index 3fbc0f3d..fbabd15 100644
--- a/ash/wm/window_mini_view.cc
+++ b/ash/wm/window_mini_view.cc
@@ -198,6 +198,14 @@
   layer->SetIsFastRoundedCorner(true);
 }
 
+void WindowMiniView::UpdateHeaderViewRoundedCorners() {
+  if (!header_view_) {
+    return;
+  }
+
+  header_view_->RefreshHeaderViewRoundedCorners();
+}
+
 bool WindowMiniView::Contains(aura::Window* window) const {
   return source_window_ == window;
 }
@@ -211,6 +219,20 @@
   return 0;
 }
 
+gfx::RoundedCornersF WindowMiniView::GetRoundedCorners() const {
+  if (!header_view_ || !preview_view_) {
+    return gfx::RoundedCornersF();
+  }
+
+  auto header_rounded_corners =
+      header_view_->GetHeaderRoundedCorners(source_window_);
+  auto preview_rounded_corners = preview_view_->layer()->rounded_corner_radii();
+  return gfx::RoundedCornersF(header_rounded_corners.upper_left(),
+                              header_rounded_corners.upper_right(),
+                              preview_rounded_corners.lower_right(),
+                              preview_rounded_corners.lower_left());
+}
+
 gfx::Rect WindowMiniView::GetHeaderBounds() const {
   gfx::Rect header_bounds = GetContentsBounds();
   header_bounds.set_height(kHeaderHeightDp);
diff --git a/ash/wm/window_mini_view.h b/ash/wm/window_mini_view.h
index fa80e122..61366887 100644
--- a/ash/wm/window_mini_view.h
+++ b/ash/wm/window_mini_view.h
@@ -8,13 +8,17 @@
 #include "ash/ash_export.h"
 #include "base/memory/raw_ptr.h"
 #include "base/scoped_observation.h"
-#include "ui/aura/window.h"
 #include "ui/aura/window_observer.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/view.h"
 
+namespace aura {
+class Window;
+}  // namespace aura
+
 namespace gfx {
 class Point;
+class RoundedCornersF;
 }  // namespace gfx
 
 namespace views {
@@ -36,6 +40,9 @@
   WindowMiniViewBase& operator=(const WindowMiniViewBase&) = delete;
   ~WindowMiniViewBase() override;
 
+  // Shows or hides a focus ring around this.
+  void UpdateFocusState(bool focus);
+
   // Returns true if a preview of the given `window` is contained in `this`.
   virtual bool Contains(aura::Window* window) const = 0;
 
@@ -55,8 +62,8 @@
   // rather than a child item.
   virtual int TryRemovingChildItem(aura::Window* destroying_window) = 0;
 
-  // Shows or hides a focus ring around this.
-  void UpdateFocusState(bool focus);
+  // Returns the exposed rounded corners.
+  virtual gfx::RoundedCornersF GetRoundedCorners() const = 0;
 
  protected:
   WindowMiniViewBase();
@@ -106,13 +113,17 @@
   // Creates or deletes |preview_view_| as needed.
   void SetShowPreview(bool show);
 
-  // Sets or hides rounded corners on |preview_view_|, if it exists.
+  // Sets or hides rounded corners on `preview_view_`, if it exists.
   void UpdatePreviewRoundedCorners(bool show);
 
+  // Updates the rounded corners on `header_view_`, if it exists.
+  void UpdateHeaderViewRoundedCorners();
+
   // WindowMiniViewBase:
   bool Contains(aura::Window* window) const override;
   aura::Window* GetWindowAtPoint(const gfx::Point& screen_point) const override;
   int TryRemovingChildItem(aura::Window* destroying_window) override;
+  gfx::RoundedCornersF GetRoundedCorners() const override;
 
  protected:
   explicit WindowMiniView(aura::Window* source_window);
diff --git a/ash/wm/window_mini_view_header_view.cc b/ash/wm/window_mini_view_header_view.cc
index 18a2d64..163e1112 100644
--- a/ash/wm/window_mini_view_header_view.cc
+++ b/ash/wm/window_mini_view_header_view.cc
@@ -53,29 +53,6 @@
              : transient_root->GetTitle();
 }
 
-gfx::RoundedCornersF GetHeaderRoundedCorners(aura::Window* window) {
-  const float scale = window->layer()->GetTargetTransform().To2dScale().x();
-  const float scaled_corner_radius = kHeaderTopCornerRadius / scale;
-  SnapGroupController* snap_group_controller =
-      Shell::Get()->snap_group_controller();
-  if (snap_group_controller) {
-    SnapGroup* snap_group =
-        snap_group_controller->GetSnapGroupForGivenWindow(window);
-    if (snap_group) {
-      auto* window1 = snap_group->window1();
-      auto* window2 = snap_group->window2();
-      CHECK(window == window1 || window == window2);
-      // `window1` is guaranteed to be the primary snapped window in a snap
-      // group and `window2` is guaranteed to be the secondary snapped window in
-      // a snap group.
-      return window == window1
-                 ? gfx::RoundedCornersF(scaled_corner_radius, 0, 0, 0)
-                 : gfx::RoundedCornersF(0, scaled_corner_radius, 0, 0);
-    }
-  }
-  return gfx::RoundedCornersF(scaled_corner_radius, scaled_corner_radius, 0, 0);
-}
-
 }  // namespace
 
 WindowMiniViewHeaderView::~WindowMiniViewHeaderView() = default;
@@ -108,12 +85,7 @@
   icon_label_view_->SetFlexForView(title_label_, 1);
 
   if (is_jellyroll_enabled) {
-    SetBackground(views::CreateThemedRoundedRectBackground(
-        chromeos::features::IsJellyrollEnabled()
-            ? cros_tokens::kCrosSysHeader
-            : static_cast<ui::ColorId>(kColorAshShieldAndBase80),
-        GetHeaderRoundedCorners(window_mini_view_->source_window()),
-        /*for_border_thickness=*/0));
+    RefreshHeaderViewRoundedCorners();
 
     views::Separator* separator =
         AddChildView(std::make_unique<views::Separator>());
@@ -147,6 +119,39 @@
   title_label_->SetText(GetWindowTitle(window));
 }
 
+void WindowMiniViewHeaderView::RefreshHeaderViewRoundedCorners() {
+  SetBackground(views::CreateThemedRoundedRectBackground(
+      chromeos::features::IsJellyrollEnabled()
+          ? cros_tokens::kCrosSysHeader
+          : static_cast<ui::ColorId>(kColorAshShieldAndBase80),
+      GetHeaderRoundedCorners(window_mini_view_->source_window()),
+      /*for_border_thickness=*/0));
+}
+
+gfx::RoundedCornersF WindowMiniViewHeaderView::GetHeaderRoundedCorners(
+    aura::Window* window) const {
+  const float scale = window->layer()->GetTargetTransform().To2dScale().x();
+  const float scaled_corner_radius = kHeaderTopCornerRadius / scale;
+  SnapGroupController* snap_group_controller =
+      Shell::Get()->snap_group_controller();
+  if (snap_group_controller) {
+    SnapGroup* snap_group =
+        snap_group_controller->GetSnapGroupForGivenWindow(window);
+    if (snap_group) {
+      auto* window1 = snap_group->window1();
+      auto* window2 = snap_group->window2();
+      CHECK(window == window1 || window == window2);
+      // `window1` is guaranteed to be the primary snapped window in a snap
+      // group and `window2` is guaranteed to be the secondary snapped window in
+      // a snap group.
+      return window == window1
+                 ? gfx::RoundedCornersF(scaled_corner_radius, 0, 0, 0)
+                 : gfx::RoundedCornersF(0, scaled_corner_radius, 0, 0);
+    }
+  }
+  return gfx::RoundedCornersF(scaled_corner_radius, scaled_corner_radius, 0, 0);
+}
+
 BEGIN_METADATA(WindowMiniViewHeaderView, views::View)
 END_METADATA
 
diff --git a/ash/wm/window_mini_view_header_view.h b/ash/wm/window_mini_view_header_view.h
index 3b94b2f..58824741e 100644
--- a/ash/wm/window_mini_view_header_view.h
+++ b/ash/wm/window_mini_view_header_view.h
@@ -6,20 +6,28 @@
 #define ASH_WM_WINDOW_MINI_VIEW_HEADER_VIEW_H_
 
 #include "ash/ash_export.h"
-#include "ash/wm/window_mini_view.h"
 #include "base/memory/raw_ptr.h"
-#include "ui/aura/window.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/views/layout/box_layout_view.h"
-#include "ui/views/view.h"
+
+namespace aura {
+class Window;
+}  // namespace aura
+
+namespace gfx {
+class RoundedCornersF;
+}  // namespace gfx
 
 namespace views {
-class Label;
 class ImageView;
+class Label;
+class View;
 }  // namespace views
 
 namespace ash {
 
+class WindowMiniView;
+
 // A view that represents the header for the window mini view. It contains an
 // icon and a title label from the source window of the `window_mini_view_` and
 // has a stroke at the bottom of it.
@@ -38,6 +46,15 @@
   void UpdateIconView(aura::Window* window);
   void UpdateTitleLabel(aura::Window* window);
 
+  // Refreshes the rounded corners on `this` by recreating the background view.
+  // Please note that there might be minor pixel difference if the rounded
+  // corner is set on the layer of this since the way to draw the rounded
+  // corners is different which may fail the pixel test
+  // (WmPixelDiffTest.WindowCycleBasic).
+  void RefreshHeaderViewRoundedCorners();
+
+  gfx::RoundedCornersF GetHeaderRoundedCorners(aura::Window* window) const;
+
  private:
   // The parent view of `this`, which is guaranteed not null during the lifetime
   // of `this`.
diff --git a/ash/wm/window_util.h b/ash/wm/window_util.h
index 0a34c891..aef2867 100644
--- a/ash/wm/window_util.h
+++ b/ash/wm/window_util.h
@@ -142,7 +142,7 @@
 
 // Returns true if `window` is in minimized state, or is in floated state and
 // tucked to the side in tablet mode.
-bool IsMinimizedOrTucked(aura::Window* window);
+ASH_EXPORT bool IsMinimizedOrTucked(aura::Window* window);
 
 // Sends |ui::VKEY_BROWSER_BACK| key press and key release event to the
 // WindowTreeHost associated with |root_window|.
diff --git a/base/profiler/native_unwinder_android_unittest.cc b/base/profiler/native_unwinder_android_unittest.cc
index 29124ae..553d77c9 100644
--- a/base/profiler/native_unwinder_android_unittest.cc
+++ b/base/profiler/native_unwinder_android_unittest.cc
@@ -365,13 +365,15 @@
 }
 
 // Checks that java frames can be unwound through.
-// Disabled, see: https://crbug.com/1076997
-TEST(NativeUnwinderAndroidTest, DISABLED_JavaFunction) {
+TEST(NativeUnwinderAndroidTest, JavaFunction) {
   auto* build_info = base::android::BuildInfo::GetInstance();
-  // Due to varying availability of compiled java unwind tables, unwinding is
-  // only expected to succeed on > SDK_VERSION_MARSHMALLOW.
-  bool can_always_unwind =
-      build_info->sdk_int() > base::android::SDK_VERSION_MARSHMALLOW;
+  const auto sdk_version = build_info->sdk_int();
+
+  // Skip this test on anything Android O or earlier, because Java unwinding
+  // fails on these.
+  if (sdk_version <= base::android::SDK_VERSION_OREO) {
+    GTEST_SKIP();
+  }
 
   UnwindScenario scenario(base::BindRepeating(callWithJavaFunction));
 
@@ -389,8 +391,7 @@
                         ASSERT_TRUE(unwinder->CanUnwindFrom(sample->back()));
                         UnwindResult result = unwinder->TryUnwind(
                             thread_context, stack_top, sample);
-                        if (can_always_unwind)
-                          EXPECT_EQ(UnwindResult::kCompleted, result);
+                        EXPECT_EQ(UnwindResult::kCompleted, result);
                       }));
 
   // Check that all the modules are valid.
@@ -398,11 +399,9 @@
     EXPECT_NE(nullptr, frame.module);
 
   // The stack should contain a full unwind.
-  if (can_always_unwind) {
-    ExpectStackContains(sample, {scenario.GetWaitForSampleAddressRange(),
-                                 scenario.GetSetupFunctionAddressRange(),
-                                 scenario.GetOuterFunctionAddressRange()});
-  }
+  ExpectStackContains(sample, {scenario.GetWaitForSampleAddressRange(),
+                               scenario.GetSetupFunctionAddressRange(),
+                               scenario.GetOuterFunctionAddressRange()});
 }
 
 TEST(NativeUnwinderAndroidTest, UnwindStackMemoryTest) {
diff --git a/build/nocompile.gni b/build/nocompile.gni
index 1b0f455..dafc9f4 100644
--- a/build/nocompile.gni
+++ b/build/nocompile.gni
@@ -193,6 +193,7 @@
     test(target_name) {
       deps = invoker.deps + [ ":$nocompile_target" ]
       sources = get_target_outputs(":$nocompile_target")
+      forward_variables_from(invoker, [ "bundle_deps" ])
     }
   }
 }
diff --git a/build/rust/std/BUILD.gn b/build/rust/std/BUILD.gn
index 3a93214..b0f3134 100644
--- a/build/rust/std/BUILD.gn
+++ b/build/rust/std/BUILD.gn
@@ -34,6 +34,12 @@
   # Equivalent of allocator symbols injected by rustc.
   source_set("remap_alloc") {
     sources = [
+      # `alias.*`, `compiler_specific.h`, and `immediate_crash.*` have been
+      # copied from `//base`.
+      # TODO(https://crbug.com/1475734): Avoid duplication / reuse code.
+      "alias.cc",
+      "alias.h",
+      "compiler_specific.h",
       "immediate_crash.h",
       "remap_alloc.cc",
     ]
diff --git a/build/rust/std/alias.cc b/build/rust/std/alias.cc
new file mode 100644
index 0000000..f0ea0311
--- /dev/null
+++ b/build/rust/std/alias.cc
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file has been copied from //base/debug/alias.cc ( additionally the APIs
+// were moved into the `build_rust_std` namespace).
+//
+// TODO(https://crbug.com/1475734): Avoid code duplication / reuse code.
+
+#include "build/rust/std/alias.h"
+
+#include "build/rust/std/compiler_specific.h"
+
+namespace build_rust_std {
+namespace debug {
+
+// This file/function should be excluded from LTO/LTCG to ensure that the
+// compiler can't see this function's implementation when compiling calls to it.
+NOINLINE void Alias(const void* var) {}
+
+}  // namespace debug
+}  // namespace build_rust_std
diff --git a/build/rust/std/alias.h b/build/rust/std/alias.h
new file mode 100644
index 0000000..068e440b
--- /dev/null
+++ b/build/rust/std/alias.h
@@ -0,0 +1,37 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file has been copied from //base/debug/alias.h (and then trimmed to just
+// the APIs / macros needed by //build/rust/std;  additionally the APIs were
+// moved into the `build_rust_std` namespace).
+//
+// TODO(https://crbug.com/1475734): Avoid code duplication / reuse code.
+
+#ifndef BUILD_RUST_STD_ALIAS_H_
+#define BUILD_RUST_STD_ALIAS_H_
+
+#include <stddef.h>
+
+namespace build_rust_std {
+namespace debug {
+
+// Make the optimizer think that |var| is aliased. This can be used to prevent a
+// local variable from being optimized out (which is something that
+// `NO_CODE_FOLDING` macro definition below depends on).  See
+// //base/debug/alias.h for more details.
+void Alias(const void* var);
+
+}  // namespace debug
+
+}  // namespace build_rust_std
+
+// Prevent code folding (where a linker identifies functions that are
+// bit-identical and overlays them, which saves space but it leads to confusing
+// call stacks because multiple symbols are at the same address).  See
+// //base/debug/alias.h for more details.
+#define NO_CODE_FOLDING()           \
+  const int line_number = __LINE__; \
+  build_rust_std::debug::Alias(&line_number)
+
+#endif  // BUILD_RUST_STD_ALIAS_H_
diff --git a/build/rust/std/compiler_specific.h b/build/rust/std/compiler_specific.h
new file mode 100644
index 0000000..47c3e29
--- /dev/null
+++ b/build/rust/std/compiler_specific.h
@@ -0,0 +1,38 @@
+// 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.
+
+// This file has been copied from //base/compiler_specific.h (and then
+// significantly trimmed to just the APIs / macros needed by //build/rust/std).
+//
+// TODO(https://crbug.com/1475734): Avoid code duplication / reuse code.
+
+#ifndef BUILD_RUST_STD_COMPILER_SPECIFIC_H_
+#define BUILD_RUST_STD_COMPILER_SPECIFIC_H_
+
+#include "build/build_config.h"
+
+#if defined(COMPILER_MSVC) && !defined(__clang__)
+#error "Only clang-cl is supported on Windows, see https://crbug.com/988071"
+#endif
+
+#if defined(__has_attribute)
+#define HAS_ATTRIBUTE(x) __has_attribute(x)
+#else
+#define HAS_ATTRIBUTE(x) 0
+#endif
+
+// Annotate a function indicating it should not be inlined.
+// Use like:
+//   NOINLINE void DoStuff() { ... }
+#if defined(__clang__) && HAS_ATTRIBUTE(noinline)
+#define NOINLINE [[clang::noinline]]
+#elif defined(COMPILER_GCC) && HAS_ATTRIBUTE(noinline)
+#define NOINLINE __attribute__((noinline))
+#elif defined(COMPILER_MSVC)
+#define NOINLINE __declspec(noinline)
+#else
+#define NOINLINE
+#endif
+
+#endif  // BUILD_RUST_STD_COMPILER_SPECIFIC_H_
diff --git a/build/rust/std/immediate_crash.h b/build/rust/std/immediate_crash.h
index bc27350..7c13eb6ae 100644
--- a/build/rust/std/immediate_crash.h
+++ b/build/rust/std/immediate_crash.h
@@ -2,7 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// This file is copied from //base/immediate_crash.h.
+// This file has been copied from //base/immediate_crash.h.
+// TODO(https://crbug.com/1475734): Avoid code duplication / reuse code.
 
 #ifndef BUILD_RUST_STD_IMMEDIATE_CRASH_H_
 #define BUILD_RUST_STD_IMMEDIATE_CRASH_H_
diff --git a/build/rust/std/remap_alloc.cc b/build/rust/std/remap_alloc.cc
index 6d010b61..bfd39b7 100644
--- a/build/rust/std/remap_alloc.cc
+++ b/build/rust/std/remap_alloc.cc
@@ -8,6 +8,7 @@
 #include <cstring>
 
 #include "build/build_config.h"
+#include "build/rust/std/alias.h"
 #include "build/rust/std/immediate_crash.h"
 
 #if BUILDFLAG(IS_ANDROID)
@@ -157,6 +158,7 @@
 
 REMAP_ALLOC_ATTRIBUTES void __rust_alloc_error_handler(size_t size,
                                                        size_t align) {
+  NO_CODE_FOLDING();
   IMMEDIATE_CRASH();
 }
 
diff --git a/build/util/android_chrome_version.py b/build/util/android_chrome_version.py
index 41b22a0d..16cf8d0 100755
--- a/build/util/android_chrome_version.py
+++ b/build/util/android_chrome_version.py
@@ -115,6 +115,7 @@
         ('TRICHROME_64_32_HIGH', 'TRICHROME', '64_32_high'),
         ('TRICHROME_64', 'TRICHROME', '64'),
         ('TRICHROME_AUTO_64_32', 'TRICHROME_AUTO', '64_32'),
+        ('TRICHROME_AUTO_64_32_HIGH', 'TRICHROME_AUTO', '64_32_high'),
         ('TRICHROME_BETA', 'TRICHROME_BETA', '32_64'),
         ('TRICHROME_32_BETA', 'TRICHROME_BETA', '32'),
         ('TRICHROME_32_64_BETA', 'TRICHROME_BETA', '32_64'),
diff --git a/build/util/android_chrome_version_test.py b/build/util/android_chrome_version_test.py
index 4aff033..a28e5c6 100644
--- a/build/util/android_chrome_version_test.py
+++ b/build/util/android_chrome_version_test.py
@@ -505,6 +505,8 @@
     arch_trichrome_64_version_code = output['TRICHROME_64_VERSION_CODE']
     arch_trichrome_auto_64_32_version_code = output[
         'TRICHROME_AUTO_64_32_VERSION_CODE']
+    arch_trichrome_auto_64_32_high_version_code = output[
+        'TRICHROME_AUTO_64_32_HIGH_VERSION_CODE']
 
     self.assertEqual(arch_monochrome_32_version_code, '575000020')
     self.assertEqual(arch_monochrome_32_64_version_code, '575000021')
@@ -518,6 +520,7 @@
     self.assertEqual(arch_trichrome_64_32_high_version_code, '575000033')
     self.assertEqual(arch_trichrome_64_version_code, '575000034')
     self.assertEqual(arch_trichrome_auto_64_32_version_code, '575000052')
+    self.assertEqual(arch_trichrome_auto_64_32_high_version_code, '575000053')
 
   def testGenerateVersionCodesAndroidArchX64(self):
     """Assert it handles different architectures correctly.
@@ -831,6 +834,17 @@
     self.assertEqual(abi, 'arm_64_32')
     self.assertEqual(is_next_build, False)
 
+
+  def testArm_Auto_64_32HighTranslate(self):
+    """Test for an auto build with Trichrome and arm_64_32_high."""
+    build, patch, package, abi, is_next_build = TranslateVersionCode(
+        '584500053')
+    self.assertEqual(build, 5845)
+    self.assertEqual(patch, 0)
+    self.assertEqual(package, 'TRICHROME_AUTO')
+    self.assertEqual(abi, 'arm_64_32_high')
+    self.assertEqual(is_next_build, False)
+
   def testArm_64_32HighTranslate(self):
     """Test for a build with Trichrome and arm_64_32_high."""
     build, patch, package, abi, is_next_build = TranslateVersionCode(
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn
index 94614f6..4f234c3 100644
--- a/chrome/android/BUILD.gn
+++ b/chrome/android/BUILD.gn
@@ -1029,6 +1029,7 @@
       "//chrome/browser/ui/android/edge_to_edge/internal:junit",
       "//chrome/browser/ui/android/fast_checkout/internal:junit",
       "//chrome/browser/ui/android/favicon:java",
+      "//chrome/browser/ui/android/hats:junit",
       "//chrome/browser/ui/android/hats/internal:controller_java",
       "//chrome/browser/ui/android/hats/internal:junit",
       "//chrome/browser/ui/android/layouts:java",
@@ -3353,6 +3354,7 @@
     "java/src/org/chromium/chrome/browser/WebContentsFactory.java",
     "java/src/org/chromium/chrome/browser/about_settings/AboutSettingsBridge.java",
     "java/src/org/chromium/chrome/browser/announcement/AnnouncementNotificationManager.java",
+    "java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java",
     "java/src/org/chromium/chrome/browser/app/send_tab_to_self/SendTabToSelfNotificationReceiver.java",
     "java/src/org/chromium/chrome/browser/app/tab_activity_glue/ReparentingTask.java",
     "java/src/org/chromium/chrome/browser/autofill/AutofillAccessibilityUtils.java",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index fb08854..625d447 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -1054,7 +1054,6 @@
   "java/src/org/chromium/chrome/browser/suggestions/tile/TopSitesTileView.java",
   "java/src/org/chromium/chrome/browser/supervised_user/ChildAccountService.java",
   "java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java",
-  "java/src/org/chromium/chrome/browser/survey/SurveyThrottler.java",
   "java/src/org/chromium/chrome/browser/sync/SyncErrorNotifier.java",
   "java/src/org/chromium/chrome/browser/sync/TrustedVaultClient.java",
   "java/src/org/chromium/chrome/browser/sync/settings/AccountManagementFragment.java",
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
index b50b0c35..40b0018615 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlags.java
@@ -6,6 +6,12 @@
 
 import android.text.TextUtils;
 
+import androidx.annotation.AnyThread;
+
+import org.chromium.base.ApplicationStatus;
+import org.chromium.base.FieldTrialList;
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.build.BuildConfig;
 import org.chromium.chrome.browser.WarmupManager;
 import org.chromium.chrome.browser.app.ChromeActivity;
@@ -18,11 +24,15 @@
 import org.chromium.chrome.browser.firstrun.FirstRunUtils;
 import org.chromium.chrome.browser.flags.CachedFeatureFlags;
 import org.chromium.chrome.browser.flags.CachedFieldTrialParameter;
+import org.chromium.chrome.browser.flags.CachedFlag;
+import org.chromium.chrome.browser.flags.CachedFlagsSafeMode;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.notifications.chime.ChimeFeatures;
 import org.chromium.chrome.browser.omaha.VersionNumberGetter;
 import org.chromium.chrome.browser.omnibox.OmniboxFeatures;
 import org.chromium.chrome.browser.optimization_guide.OptimizationGuidePushNotificationManager;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.recent_tabs.RestoreTabsFeatureHelper;
 import org.chromium.chrome.browser.tab.state.FilePersistedTabDataStorage;
 import org.chromium.chrome.browser.tabmodel.TabPersistentStore;
@@ -37,9 +47,11 @@
  * Caches the flags that Chrome might require before native is loaded in a later next run.
  */
 public class ChromeCachedFlags {
+    private static final ChromeCachedFlags INSTANCE = new ChromeCachedFlags();
+
     private boolean mIsFinishedCachingNativeFlags;
 
-    private static final ChromeCachedFlags INSTANCE = new ChromeCachedFlags();
+    private static String sReachedCodeProfilerTrialGroup;
 
     /**
      * A list of field trial parameters that will be cached when starting minimal browser mode. See
@@ -67,7 +79,7 @@
         FirstRunUtils.cacheFirstRunPrefs();
 
         CachedFeatureFlags.cacheNativeFlags(ChromeFeatureList.sFlagsCachedFullBrowser);
-        CachedFeatureFlags.cacheAdditionalNativeFlags();
+        cacheAdditionalNativeFlags();
 
         //clang-format off
         List<CachedFieldTrialParameter> fieldTrialsToCache = List.of(
@@ -154,4 +166,66 @@
         CachedFeatureFlags.cacheNativeFlags(ChromeFeatureList.sFlagsCachedInMinimalBrowser);
         CachedFeatureFlags.cacheFieldTrialParameters(MINIMAL_BROWSER_FIELD_TRIALS);
     }
+
+    /**
+     * Caches a predetermined list of flags that must take effect on startup but are set via native
+     * code.
+     *
+     * Do not add new simple boolean flags here, add them to {@link #cacheNativeFlags} instead.
+     */
+    public static void cacheAdditionalNativeFlags() {
+        CachedFlagsSafeMode.cacheSafeModeForCachedFlagsEnabled();
+        cacheReachedCodeProfilerTrialGroup();
+
+        // Propagate REACHED_CODE_PROFILER feature value to LibraryLoader. This can't be done in
+        // LibraryLoader itself because it lives in //base and can't depend on ChromeFeatureList.
+        LibraryLoader.setReachedCodeProfilerEnabledOnNextRuns(
+                ChromeFeatureList.isEnabled(ChromeFeatureList.REACHED_CODE_PROFILER),
+                ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
+                        ChromeFeatureList.REACHED_CODE_PROFILER, "sampling_interval_us", 0));
+
+        // Similarly, propagate the BACKGROUND_THREAD_POOL feature value to LibraryLoader.
+        LibraryLoader.setBackgroundThreadPoolEnabledOnNextRuns(
+                ChromeFeatureList.isEnabled(ChromeFeatureList.BACKGROUND_THREAD_POOL));
+
+        // Propagate the CACHE_ACTIVITY_TASKID feature value to ApplicationStatus.
+        ApplicationStatus.setCachingEnabled(
+                ChromeFeatureList.isEnabled(ChromeFeatureList.CACHE_ACTIVITY_TASKID));
+    }
+
+    /**
+     * Caches the trial group of the reached code profiler feature to be using on next startup.
+     */
+    private static void cacheReachedCodeProfilerTrialGroup() {
+        // Make sure that the existing value is saved in a static variable before overwriting it.
+        if (sReachedCodeProfilerTrialGroup == null) {
+            getReachedCodeProfilerTrialGroup();
+        }
+
+        SharedPreferencesManager.getInstance().writeString(
+                ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP,
+                FieldTrialList.findFullName(ChromeFeatureList.REACHED_CODE_PROFILER));
+    }
+
+    /**
+     * @return The trial group of the reached code profiler.
+     */
+    @CalledByNative
+    public static String getReachedCodeProfilerTrialGroup() {
+        if (sReachedCodeProfilerTrialGroup == null) {
+            sReachedCodeProfilerTrialGroup = SharedPreferencesManager.getInstance().readString(
+                    ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP, "");
+        }
+
+        return sReachedCodeProfilerTrialGroup;
+    }
+
+    @CalledByNative
+    @AnyThread
+    static boolean isEnabled(String featureName) {
+        CachedFlag cachedFlag = ChromeFeatureList.sAllCachedFlags.get(featureName);
+        assert cachedFlag != null;
+
+        return cachedFlag.isEnabled();
+    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
index e24c63c..4d98427 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabRootUiCoordinator.java
@@ -200,13 +200,13 @@
         if (intentDataProvider.get().getActivityType() == ActivityType.CUSTOM_TAB
                 && !intentDataProvider.get().isOpenedByChrome()
                 && !intentDataProvider.get().isIncognito()) {
-            String packageName = mIntentDataProvider.get().getClientPackageName();
-            if (TextUtils.isEmpty(packageName)) {
-                packageName = CustomTabIntentDataProvider.getReferrerPackageName(activity);
+            String appId = mIntentDataProvider.get().getClientPackageName();
+            if (TextUtils.isEmpty(appId)) {
+                appId = CustomTabIntentDataProvider.getAppIdFromReferrer(activity);
             }
-            String appName = activity.getResources().getString(R.string.app_name);
+            String browserName = activity.getResources().getString(R.string.app_name);
             mBrandingController = new BrandingController(
-                    activity, packageName, appName, new ChromePureJavaExceptionReporter());
+                    activity, appId, browserName, new ChromePureJavaExceptionReporter());
         }
         mTabController = tabController;
         mPageInsightsToken = TokenHolder.INVALID_TOKEN;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
index 6b61529..97efb754 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java
@@ -503,19 +503,24 @@
     }
 
     /**
-     * Get the package name from {@link #getReferrerUriString(Activity)}. If the referrer format
-     * is invalid, return an empty string.
+     * Extracts the name that identifies the embedding app from the referrer.
+     * @return Host name as an id if the referrer is of a well-formed URI with app intent scheme.
+     *    If not, just the whole referrer string.
      * TODO(https://crbug.com/1350252): Move this to IntentHandler.
-     * */
-    static String getReferrerPackageName(Activity activity) {
+     */
+    static String getAppIdFromReferrer(Activity activity) {
         String referrer =
                 CustomTabActivityLifecycleUmaTracker.getReferrerUriString(activity).toLowerCase(
                         Locale.US);
         if (TextUtils.isEmpty(referrer)) return "";
 
         Uri uri = Uri.parse(referrer);
-        return TextUtils.equals(UrlConstants.APP_INTENT_SCHEME, uri.getScheme()) ? uri.getHost()
-                                                                                 : "";
+        boolean isUrl = TextUtils.equals(UrlConstants.APP_INTENT_SCHEME, uri.getScheme());
+        if (isUrl) {
+            String host = uri.getHost();
+            if (!TextUtils.isEmpty(host)) return host;
+        }
+        return referrer;
     }
 
     /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
index f056c248..9b4a286 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java
@@ -10,7 +10,6 @@
 import android.os.Handler;
 import android.text.TextUtils;
 
-import androidx.annotation.IntDef;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
@@ -19,15 +18,12 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.ResettersForTesting;
-import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.AsyncTask;
 import org.chromium.chrome.R;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
 import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver;
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 import org.chromium.chrome.browser.privacy.settings.PrivacyPreferencesManagerImpl;
 import org.chromium.chrome.browser.tab.EmptyTabObserver;
 import org.chromium.chrome.browser.tab.Tab;
@@ -37,6 +33,7 @@
 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
 import org.chromium.chrome.browser.ui.hats.SurveyController;
 import org.chromium.chrome.browser.ui.hats.SurveyControllerProvider;
+import org.chromium.chrome.browser.ui.hats.SurveyThrottler;
 import org.chromium.components.messages.DismissReason;
 import org.chromium.components.messages.MessageBannerProperties;
 import org.chromium.components.messages.MessageDispatcher;
@@ -45,9 +42,6 @@
 import org.chromium.ui.modelutil.PropertyModel;
 import org.chromium.url.GURL;
 
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
 /**
  * Class that controls if and when to show surveys. One instance of this class is associated with
  * one trigger ID, which is used to fetch a survey, at the time it is created.
@@ -56,7 +50,6 @@
  */
 public class ChromeSurveyController {
     private static final String TAG = "ChromeSurveyCtrler";
-    private static final int DOWNLOAD_ATTEMPTS_HIST_NUM_BUCKETS = 20;
     @VisibleForTesting
     public static final String COMMAND_LINE_PARAM_NAME = "survey_override_site_id";
     @VisibleForTesting
@@ -70,41 +63,17 @@
     private static boolean sForceUmaEnabledForTesting;
     private static boolean sMessageShown;
 
-    /**
-     * Reasons that the user was rejected from being selected for a survey
-     * Note: these values cannot change and must match the SurveyFilteringResult enum in enums.xml
-     * because they're written to logs.
-     */
-    @IntDef({FilteringResult.SURVEY_PROMPT_ALREADY_DISPLAYED,
-            FilteringResult.FORCE_SURVEY_ON_COMMAND_PRESENT,
-            FilteringResult.USER_ALREADY_SAMPLED_TODAY, FilteringResult.MAX_NUMBER_MISSING,
-            FilteringResult.ROLLED_NON_ZERO_NUMBER, FilteringResult.USER_SELECTED_FOR_SURVEY,
-            FilteringResult.FIRST_TIME_USER, FilteringResult.NUM_ENTRIES})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface FilteringResult {
-        int SURVEY_PROMPT_ALREADY_DISPLAYED = 0;
-        int FORCE_SURVEY_ON_COMMAND_PRESENT = 2;
-        int USER_ALREADY_SAMPLED_TODAY = 3;
-        int MAX_NUMBER_MISSING = 4;
-        int ROLLED_NON_ZERO_NUMBER = 5;
-        int USER_SELECTED_FOR_SURVEY = 6;
-        int FIRST_TIME_USER = 8;
-        // Number of entries
-        int NUM_ENTRIES = 9;
-    }
-
     private TabModelSelector mTabModelSelector;
     private Handler mLoggingHandler;
     private Tab mSurveyPromptTab;
     private TabModelSelectorObserver mTabModelObserver;
 
     private final String mTriggerId;
-    private final String mPrefKeyPromptDisplayed;
-    private final String mPrefKeyDownloadAttempts;
     private final @Nullable ActivityLifecycleDispatcher mLifecycleDispatcher;
     private final Activity mActivity;
     private final MessageDispatcher mMessageDispatcher;
     private SurveyController mSurveyController;
+    private SurveyThrottler mSurveyThrottler;
     private @Nullable TabObserver mTabObserver;
     private @Nullable PauseResumeWithNativeObserver mLifecycleObserver;
 
@@ -113,13 +82,11 @@
             @Nullable ActivityLifecycleDispatcher lifecycleDispatcher, Activity activity,
             MessageDispatcher messageDispatcher) {
         mTriggerId = triggerId;
-        mPrefKeyPromptDisplayed =
-                ChromePreferenceKeys.CHROME_SURVEY_PROMPT_DISPLAYED_TIMESTAMP.createKey(mTriggerId);
-        mPrefKeyDownloadAttempts =
-                ChromePreferenceKeys.CHROME_SURVEY_DOWNLOAD_ATTEMPTS.createKey(mTriggerId);
         mLifecycleDispatcher = lifecycleDispatcher;
         mActivity = activity;
         mMessageDispatcher = messageDispatcher;
+        mSurveyThrottler = new SurveyThrottler(triggerId, 1f / getMaxNumber(),
+                ChromeSurveyController::isUMAEnabled, getMaxDownloadAttempt());
     }
 
     /**
@@ -148,6 +115,7 @@
      *                         shown.
      */
     private void startDownload(Context context, TabModelSelector tabModelSelector) {
+        mSurveyThrottler.recordDownloadAttempted();
         mLoggingHandler = new Handler();
         mTabModelSelector = tabModelSelector;
 
@@ -311,7 +279,7 @@
             recordSurveyPromptDisplayed();
         } else if (dismissReason == DismissReason.PRIMARY_ACTION) {
             recordSurveyPromptDisplayed();
-            recordSurveyAccepted();
+            mSurveyThrottler.recordSurveyAccepted();
         }
     }
 
@@ -339,6 +307,10 @@
         };
     }
 
+    private SurveyThrottler getThrottler() {
+        return mSurveyThrottler;
+    }
+
     /**
      * Shows the prompt if the passed in tab is fully loaded and interactable.
      * @param tab The tab to attach the survey info bar.
@@ -354,32 +326,6 @@
         tab.removeObserver(observer);
     }
 
-    /** @return If the survey info bar for this survey was logged as seen before. */
-    @VisibleForTesting
-    boolean hasPromptBeenDisplayed() {
-        SharedPreferencesManager preferences = SharedPreferencesManager.getInstance();
-
-        // TODO(https://crbug.com/1195928): Get an expiration date from feature flag.
-        if (preferences.readLong(mPrefKeyPromptDisplayed, -1L) != -1L) {
-            recordSurveyFilteringResult(FilteringResult.SURVEY_PROMPT_ALREADY_DISPLAYED);
-            return true;
-        }
-        return false;
-    }
-
-    private void recordDownloadAttempted() {
-        SharedPreferencesManager.getInstance().incrementInt(mPrefKeyDownloadAttempts);
-    }
-
-    /** Return whether the number of download attempts falls within the max cap. */
-    private boolean isDownloadAttemptAllowed() {
-        int maxDownloadAttempts = ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                ChromeFeatureList.CHROME_SURVEY_NEXT_ANDROID, MAX_DOWNLOAD_ATTEMPTS, 0);
-        int downloadAttemptsMade =
-                SharedPreferencesManager.getInstance().readInt(mPrefKeyDownloadAttempts, 0);
-        return maxDownloadAttempts <= 0 || downloadAttemptsMade < maxDownloadAttempts;
-    }
-
     /**
      * Checks if the tab is valid for a survey (i.e. not null, no null webcontents & not incognito).
      * @param tab The tab to be checked.
@@ -399,8 +345,7 @@
 
         mLoggingHandler.removeCallbacksAndMessages(null);
 
-        SharedPreferencesManager preferences = SharedPreferencesManager.getInstance();
-        preferences.writeLong(mPrefKeyPromptDisplayed, System.currentTimeMillis());
+        mSurveyThrottler.recordSurveyPromptDisplayed();
         mSurveyPromptTab = null;
     }
 
@@ -409,19 +354,6 @@
         mTabModelSelector = tabModelSelector;
     }
 
-    private void recordSurveyFilteringResult(@FilteringResult int value) {
-        RecordHistogram.recordEnumeratedHistogram(
-                "Android.Survey.SurveyFilteringResults", value, FilteringResult.NUM_ENTRIES);
-    }
-
-    private void recordSurveyAccepted() {
-        int downloadAttemptsMade =
-                SharedPreferencesManager.getInstance().readInt(mPrefKeyDownloadAttempts, 0);
-        RecordHistogram.recordLinearCountHistogram("Android.Survey.DownloadAttemptsBeforeAccepted",
-                downloadAttemptsMade, 1, DOWNLOAD_ATTEMPTS_HIST_NUM_BUCKETS,
-                DOWNLOAD_ATTEMPTS_HIST_NUM_BUCKETS + 1);
-    }
-
     static class StartDownloadIfEligibleTask extends AsyncTask<Boolean> {
         ChromeSurveyController mController;
         final TabModelSelector mSelector;
@@ -434,22 +366,13 @@
 
         @Override
         protected Boolean doInBackground() {
-            if (!isUMAEnabled()) return false;
-
-            if (isSurveyForceEnabled()) {
-                mController.recordSurveyFilteringResult(
-                        FilteringResult.FORCE_SURVEY_ON_COMMAND_PRESENT);
-                return true;
-            }
-            return !mController.hasPromptBeenDisplayed() && mController.isDownloadAttemptAllowed()
-                    && new SurveyThrottler(getMaxNumber()).isRandomlySelectedForSurvey();
+            return mController.getThrottler().canShowSurvey();
         }
 
         @Override
         protected void onPostExecute(Boolean result) {
             if (result) {
                 mController.startDownload(ContextUtils.getApplicationContext(), mSelector);
-                mController.recordDownloadAttempted();
             }
         }
     }
@@ -490,6 +413,11 @@
                 ChromeFeatureList.CHROME_SURVEY_NEXT_ANDROID, MAX_NUMBER, -1);
     }
 
+    private static int getMaxDownloadAttempt() {
+        return ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
+                ChromeFeatureList.CHROME_SURVEY_NEXT_ANDROID, MAX_DOWNLOAD_ATTEMPTS, 0);
+    }
+
     /** @return Whether the message has been previously shown to the client. */
     @VisibleForTesting
     public static boolean isMessageShown() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/survey/SurveyThrottler.java b/chrome/android/java/src/org/chromium/chrome/browser/survey/SurveyThrottler.java
deleted file mode 100644
index 1704cbb6..0000000
--- a/chrome/android/java/src/org/chromium/chrome/browser/survey/SurveyThrottler.java
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.chrome.browser.survey;
-
-import androidx.annotation.VisibleForTesting;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.metrics.RecordHistogram;
-import org.chromium.chrome.browser.firstrun.FirstRunStatus;
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.browser.survey.ChromeSurveyController.FilteringResult;
-
-import java.util.Calendar;
-import java.util.Random;
-
-public class SurveyThrottler {
-    private final int mMaxNumber;
-
-    /**
-     * @param maxNumber The max number that used to control the rate limit.
-     */
-    SurveyThrottler(int maxNumber) {
-        mMaxNumber = maxNumber;
-    }
-
-    /**
-     * Rolls a random number to see if the user was eligible for the survey. The user will skip the
-     * roll if:
-     *  1. User is a first time user
-     *  2. User as performed the roll today
-     *  3. Max number is not setup correctly
-     *
-     * @return Whether the user is eligible (i.e. the random number rolled was 0).
-     */
-    boolean isRandomlySelectedForSurvey() {
-        if (FirstRunStatus.isFirstRunTriggered()) {
-            recordSurveyFilteringResult(FilteringResult.FIRST_TIME_USER);
-            return false;
-        }
-
-        SharedPreferencesManager preferences = SharedPreferencesManager.getInstance();
-        int lastDate = preferences.readInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, -1);
-        int today = getDayOfYear();
-        if (lastDate == today) {
-            recordSurveyFilteringResult(FilteringResult.USER_ALREADY_SAMPLED_TODAY);
-            return false;
-        }
-
-        if (mMaxNumber <= 0) {
-            recordSurveyFilteringResult(FilteringResult.MAX_NUMBER_MISSING);
-            return false;
-        }
-
-        preferences.writeInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, today);
-        if (getRandomNumberUpTo(mMaxNumber) == 0) {
-            recordSurveyFilteringResult(FilteringResult.USER_SELECTED_FOR_SURVEY);
-            return true;
-        } else {
-            recordSurveyFilteringResult(FilteringResult.ROLLED_NON_ZERO_NUMBER);
-            return false;
-        }
-    }
-
-    /**
-     * @param max The max threshold for the random number generator.
-     * @return A random number from 0 (inclusive) to the max number (exclusive).
-     */
-    @VisibleForTesting
-    int getRandomNumberUpTo(int max) {
-        return new Random().nextInt(max);
-    }
-
-    /** @return The day of the year for today. */
-    @VisibleForTesting
-    int getDayOfYear() {
-        ThreadUtils.assertOnBackgroundThread();
-        return Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
-    }
-
-    static void recordSurveyFilteringResult(@FilteringResult int value) {
-        RecordHistogram.recordEnumeratedHistogram(
-                "Android.Survey.SurveyFilteringResults", value, FilteringResult.NUM_ENTRIES);
-    }
-}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManagerTest.java
index d04cb65..9ca114e 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManagerTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManagerTest.java
@@ -22,7 +22,7 @@
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.base.test.util.DisabledTest;
+import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.Feature;
 import org.chromium.chrome.browser.compositor.CompositorView;
 import org.chromium.chrome.browser.compositor.CompositorViewHolder;
@@ -34,7 +34,6 @@
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.chrome.test.R;
 import org.chromium.chrome.test.batch.BlankCTATabInitialStateRule;
-import org.chromium.chrome.test.util.browser.Features.DisableFeatures;
 import org.chromium.chrome.test.util.browser.Features.EnableFeatures;
 import org.chromium.content_public.browser.test.util.TestThreadUtils;
 import org.chromium.ui.test.util.RenderTestRule;
@@ -74,7 +73,6 @@
     @Test
     @MediumTest
     @Feature({"RenderTest"})
-    @DisabledTest(message = "https://crbug.com/1455878")
     public void testLiveLayerDraws() throws Exception {
         final String testHttpsUrl1 =
                 sActivityTestRule.getTestServer().getURL("/chrome/test/data/android/test.html");
@@ -89,14 +87,15 @@
 
     @Test
     @MediumTest
-    @DisabledTest(message = "https://crbug.com/1454653")
-    // Disable "AImageReader" as a workaround for https://crbug.com/1454914
-    @DisableFeatures("AImageReader")
     public void testJpegRefetch() throws Exception {
         final String testHttpsUrl1 =
-                sActivityTestRule.getTestServer().getURL("/chrome/test/data/android/test.html");
+                sActivityTestRule.getTestServer().getURL("/chrome/test/data/android/google.html");
         sActivityTestRule.loadUrlInNewTab(testHttpsUrl1);
 
+        // Sometimes loadUrlInNewTab returns before the tab is actually loaded. Confirm again.
+        final Tab currentTab = sActivityTestRule.getActivity().getActivityTab();
+        CriteriaHelper.pollUiThread(() -> !currentTab.isLoading());
+
         final CallbackHelper helper = new CallbackHelper();
         final Bitmap[] bitmapHolder = new Bitmap[1];
         Callback<Bitmap> bitmapCallback = (bitmap) -> {
@@ -105,7 +104,6 @@
         };
 
         TestThreadUtils.runOnUiThreadBlocking(() -> {
-            final Tab currentTab = sActivityTestRule.getActivity().getActivityTab();
             final TabContentManager tabContentManager =
                     sActivityTestRule.getActivity().getTabContentManagerSupplier().get();
             final int height = 100;
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/PasswordSavingIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/PasswordSavingIntegrationTest.java
index 2a87ded7c1..27fb869 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/PasswordSavingIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/password_manager/PasswordSavingIntegrationTest.java
@@ -23,7 +23,6 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
-import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Matchers;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
@@ -121,7 +120,6 @@
 
     @Test
     @MediumTest
-    @DisabledTest(message = "https://crbug.com/1468472")
     public void testSavingNewPassword() throws InterruptedException, TimeoutException {
         mActivityTestRule.loadUrl(mActivityTestRule.getTestServer().getURL(SIGNIN_FORM_URL));
 
@@ -147,7 +145,6 @@
 
     @Test
     @MediumTest
-    @DisabledTest(message = "https://crbug.com/1468903")
     public void testUpdatingPassword() throws InterruptedException, TimeoutException {
         // Store the test credential.
         PasswordStoreCredential testCredential = new PasswordStoreCredential(
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
index 925e708..490baecc 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProviderTest.java
@@ -33,7 +33,6 @@
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.os.Bundle;
-import android.text.TextUtils;
 import android.view.ContextThemeWrapper;
 
 import androidx.browser.customtabs.CustomTabColorSchemeParams;
@@ -458,18 +457,18 @@
     }
 
     @Test
-    public void testGetReferrerPackageName() {
+    public void testGetAppIdFromReferrer() {
         assertEquals("extra.activity.referrer",
-                CustomTabIntentDataProvider.getReferrerPackageName(
+                CustomTabIntentDataProvider.getAppIdFromReferrer(
                         buildMockActivity("android-app://extra.activity.referrer")));
         assertEquals("co.abc.xyz",
-                CustomTabIntentDataProvider.getReferrerPackageName(
+                CustomTabIntentDataProvider.getAppIdFromReferrer(
                         buildMockActivity("android-app://co.abc.xyz")));
 
-        assertReferrerInvalid("");
-        assertReferrerInvalid("invalid");
-        assertReferrerInvalid("android-app://");
-        assertReferrerInvalid(Uri.parse("https://www.one.com").toString());
+        assertNonPackageUriReferrer("");
+        assertNonPackageUriReferrer("invalid");
+        assertNonPackageUriReferrer("android-app://"); // empty host name is invalid.
+        assertNonPackageUriReferrer(Uri.parse("https://www.one.com").toString());
     }
 
     @Test
@@ -785,10 +784,9 @@
         return Uri.parse("https://www.example.com/");
     }
 
-    private void assertReferrerInvalid(String referrerStr) {
-        assertTrue("Referrer should be invalid for the input: " + referrerStr,
-                TextUtils.isEmpty(CustomTabIntentDataProvider.getReferrerPackageName(
-                        buildMockActivity(referrerStr))));
+    private void assertNonPackageUriReferrer(String referrerStr) {
+        assertEquals(referrerStr,
+                CustomTabIntentDataProvider.getAppIdFromReferrer(buildMockActivity(referrerStr)));
     }
 
     private Activity buildMockActivity(String referrer) {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java
index 7ce65de..a5ec5e72 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/survey/ChromeSurveyControllerTest.java
@@ -25,15 +25,11 @@
 import org.mockito.junit.MockitoRule;
 import org.robolectric.annotation.Config;
 
-import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.chrome.browser.firstrun.FirstRunStatus;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
-import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
-import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
-import org.chromium.chrome.browser.survey.ChromeSurveyController.FilteringResult;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.chrome.browser.ui.hats.SurveyThrottler;
 import org.chromium.chrome.test.util.browser.Features;
 import org.chromium.components.messages.MessageDispatcher;
 import org.chromium.content_public.browser.WebContents;
@@ -47,8 +43,6 @@
     private static final String TEST_SURVEY_TRIGGER_ID = "foobar";
 
     private TestChromeSurveyController mTestController;
-    private RiggedSurveyThrottler mRiggedThrottler;
-    private SharedPreferencesManager mSharedPreferences;
 
     @Rule
     public TestRule mFeaturesProcessorRule = new Features.JUnitProcessor();
@@ -74,49 +68,10 @@
         mTestController = new TestChromeSurveyController(TEST_SURVEY_TRIGGER_ID,
                 mActivityLifecycleDispatcher, mActivity, mMessageDispatcher);
         mTestController.setTabModelSelector(mSelector);
-        mSharedPreferences = SharedPreferencesManager.getInstance();
         Assert.assertNull("Tab should be null", mTestController.getLastTabPromptShown());
     }
 
     @Test
-    public void testPromptDisplayedBefore() {
-        final String triggerId1 = "triggerId1";
-        final String triggerId2 = "triggerId2";
-
-        TestChromeSurveyController controller1 = new TestChromeSurveyController(
-                triggerId1, mActivityLifecycleDispatcher, mActivity, mMessageDispatcher);
-        TestChromeSurveyController controller2 = new TestChromeSurveyController(
-                triggerId2, mActivityLifecycleDispatcher, mActivity, mMessageDispatcher);
-
-        String prefKey1 =
-                ChromePreferenceKeys.CHROME_SURVEY_PROMPT_DISPLAYED_TIMESTAMP.createKey(triggerId1);
-        String prefKey2 =
-                ChromePreferenceKeys.CHROME_SURVEY_PROMPT_DISPLAYED_TIMESTAMP.createKey(triggerId2);
-
-        // The new survey should not have been presented before.
-        Assert.assertFalse("SharedPref for triggerId1 should not be recorded.",
-                mSharedPreferences.contains(prefKey1));
-        Assert.assertFalse("SharedPref for triggerId2 should not be recorded.",
-                mSharedPreferences.contains(prefKey2));
-        Assert.assertFalse(
-                "Prompt for triggerId1 is marked displayed.", controller1.hasPromptBeenDisplayed());
-        Assert.assertFalse(
-                "Prompt for triggerId2 is marked displayed.", controller2.hasPromptBeenDisplayed());
-
-        mSharedPreferences.writeLong(prefKey1, System.currentTimeMillis());
-        Assert.assertTrue("Prompt for triggerId1 should be marked displayed.",
-                controller1.hasPromptBeenDisplayed());
-        Assert.assertFalse("Prompt for triggerId2 should not be marked displayed yet.",
-                controller2.hasPromptBeenDisplayed());
-        verifyFilteringResultRecorded(FilteringResult.SURVEY_PROMPT_ALREADY_DISPLAYED, 1);
-
-        mSharedPreferences.writeLong(prefKey2, System.currentTimeMillis());
-        Assert.assertTrue("Prompt for trggerId2 should be marked displayed.",
-                controller2.hasPromptBeenDisplayed());
-        verifyFilteringResultRecorded(FilteringResult.SURVEY_PROMPT_ALREADY_DISPLAYED, 2);
-    }
-
-    @Test
     public void testIsValidTabForSurvey_ValidTab() {
         doReturn(mWebContents).when(mTab).getWebContents();
         doReturn(false).when(mTab).isIncognito();
@@ -210,105 +165,6 @@
         verify(mSelector).addObserver(any());
     }
 
-    @Test
-    public void testSurveyAvailableUmaDisabled() {
-        ChromeSurveyController.forceIsUMAEnabledForTesting(false);
-        mTestController.onSurveyAvailable(null);
-        Assert.assertNull("Tab should be null", mTestController.getLastTabPromptShown());
-        verify(mSelector, never()).addObserver(any());
-    }
-
-    @Test
-    public void testEligibilityFirstRun() {
-        FirstRunStatus.setFirstRunTriggeredForTesting(true);
-        mRiggedThrottler = new RiggedSurveyThrottler(0, 1, 10);
-        Assert.assertFalse(
-                "Random selection should be false", mRiggedThrottler.isRandomlySelectedForSurvey());
-        verifyFilteringResultRecorded(FilteringResult.FIRST_TIME_USER, 1);
-    }
-
-    @Test
-    public void testEligibilityRolledYesterday() {
-        mRiggedThrottler = new RiggedSurveyThrottler(0, 5, 10);
-        mSharedPreferences.writeInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, 4);
-        Assert.assertTrue(
-                "Random selection should be true", mRiggedThrottler.isRandomlySelectedForSurvey());
-        verifyFilteringResultRecorded(FilteringResult.USER_SELECTED_FOR_SURVEY, 1);
-    }
-
-    @Test
-    public void testEligibilityRollingTwiceSameDay() {
-        mRiggedThrottler = new RiggedSurveyThrottler(0, 5, 10);
-        mSharedPreferences.writeInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, 5);
-        Assert.assertFalse(
-                "Random selection should be false", mRiggedThrottler.isRandomlySelectedForSurvey());
-        verifyFilteringResultRecorded(FilteringResult.USER_ALREADY_SAMPLED_TODAY, 1);
-    }
-
-    @Test
-    public void testEligibilityFirstTimeRollingQualifies() {
-        mRiggedThrottler = new RiggedSurveyThrottler(0, 5, 10);
-        Assert.assertFalse(
-                mSharedPreferences.contains(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED));
-        Assert.assertTrue(
-                "Random selection should be true", mRiggedThrottler.isRandomlySelectedForSurvey());
-        Assert.assertEquals("Numbers should match", 5,
-                mSharedPreferences.readInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, -1));
-    }
-
-    @Test
-    public void testEligibilityFirstTimeRollingDoesNotQualify() {
-        mRiggedThrottler = new RiggedSurveyThrottler(5, 1, 10);
-        Assert.assertFalse(
-                mSharedPreferences.contains(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED));
-        Assert.assertFalse(
-                "Random selection should be false", mRiggedThrottler.isRandomlySelectedForSurvey());
-        Assert.assertEquals("Numbers should match", 1,
-                mSharedPreferences.readInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, -1));
-        verifyFilteringResultRecorded(FilteringResult.ROLLED_NON_ZERO_NUMBER, 1);
-    }
-
-    @Test
-    public void testEligibilityNoMaxNumber() {
-        mRiggedThrottler = new RiggedSurveyThrottler(0, 1, -1);
-        Assert.assertFalse(
-                mSharedPreferences.contains(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED));
-        Assert.assertFalse(
-                "Random selection should be false", mRiggedThrottler.isRandomlySelectedForSurvey());
-        Assert.assertFalse(
-                mSharedPreferences.contains(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED));
-        verifyFilteringResultRecorded(FilteringResult.MAX_NUMBER_MISSING, 1);
-    }
-
-    private void verifyFilteringResultRecorded(@FilteringResult int reason, int expectedCount) {
-        int count = RecordHistogram.getHistogramValueCountForTesting(
-                "Android.Survey.SurveyFilteringResults", reason);
-        Assert.assertEquals(String.format("FilteringResult for type <%s> does not match.", reason),
-                expectedCount, count);
-    }
-
-    /** Test class used to test the rate limiting logic for {@link ChromeSurveyController} */
-    class RiggedSurveyThrottler extends SurveyThrottler {
-        private int mRandomNumberToReturn;
-        private int mDayOfYear;
-
-        RiggedSurveyThrottler(int randomNumberToReturn, int dayOfYear, int maxNumber) {
-            super(maxNumber);
-            mRandomNumberToReturn = randomNumberToReturn;
-            mDayOfYear = dayOfYear;
-        }
-
-        @Override
-        int getRandomNumberUpTo(int max) {
-            return mRandomNumberToReturn;
-        }
-
-        @Override
-        int getDayOfYear() {
-            return mDayOfYear;
-        }
-    }
-
     static class TestChromeSurveyController extends ChromeSurveyController {
         private Tab mTab;
 
diff --git a/chrome/app/chrome_main_delegate.cc b/chrome/app/chrome_main_delegate.cc
index 378fdc13..186b2523 100644
--- a/chrome/app/chrome_main_delegate.cc
+++ b/chrome/app/chrome_main_delegate.cc
@@ -165,8 +165,8 @@
 #if BUILDFLAG(IS_ANDROID)
 #include "base/android/java_exception_reporter.h"
 #include "base/android/library_loader/library_loader_hooks.h"
+#include "chrome/browser/android/flags/chrome_cached_flags.h"
 #include "chrome/browser/android/metrics/uma_session_stats.h"
-#include "chrome/browser/flags/android/cached_feature_flags.h"
 #include "chrome/browser/flags/android/chrome_feature_list.h"
 #include "chrome/common/chrome_descriptors.h"
 #include "components/crash/android/pure_java_exception_handler.h"
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 75369cc..e01aa2d 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -13049,12 +13049,9 @@
           Turn on "Google Chrome" in Location Services on your Mac
         </message>
       </if>
-      <message name="IDS_GEOLOCATION_TURNED_OFF_IN_OS" desc="Title for the geolocation bubble that is used when a site requests geolocation, but geolocation is blocked on an OS level (platform independent wording).">
-        Location is turned off in the System Preferences
-      </message>
-      <message name="IDS_GEOLOCATION_TURNED_OFF" desc="Description text in the omnibox icon showing when location permission is blocked on an OS level.">
-        Location turned off
-      </message>
+        <message name="IDS_GEOLOCATION_TURNED_OFF" desc="Description text in the omnibox icon showing when location permission is blocked on an OS level.">
+          Location turned off
+        </message>
 
       <!-- Web MIDI messages -->
       <message name="IDS_ALLOWED_MIDI_SYSEX_TITLE" desc="Title of the info bubble shown when a site is allowed to use MIDI system exclusive messages.">
@@ -13135,12 +13132,18 @@
         <message name="IDS_MIC_TURNED_OFF_IN_MACOS" desc="Title for the media status bubble that is used when a site requests microphone access, but microphone is blocked on an OS level in macOS.">
           Microphone is turned off in Mac System Preferences
         </message>
+        <message name="IDS_OPEN_SETTINGS_LINK" desc="Title for the button that takes the user to the Security and Privacy settings in macOS, in order for the user to be able to modify the ability to access camera and microphone for Chrome. The translation for this string should match the translation of the System Settings app title in the macOS target locale. You can find this by selecting the locale from https://support.apple.com/guide/mac-help/mh15217/mac/localeselector. The title of the next page after that includes the desired translation. Note that, for size reasons, the English string omits 'System' and the same contraction may be suitable in other languages.">
+          Open Settings
+        </message>
         <message name="IDS_CAMERA" desc="Description text for the camera.">
           Camera
         </message>
         <message name="IDS_MIC" desc="Decription text for the microphone.">
           Microphone
         </message>
+        <message name="IDS_TURNED_OFF" desc="Description text for the state of camera or microphone">
+          Turned off
+        </message>
         <message name="IDS_CAMERA_TURNED_OFF" desc="Description text in the omnibox icon showing when camera permission is turned off.">
           Camera turned off
         </message>
@@ -13149,16 +13152,6 @@
         </message>
       </if>
 
-      <message name="IDS_OPEN_SETTINGS_LINK" desc="Title for the button that takes the user to the Security and Privacy settings in the OS. In order for the user to be able to modify the ability to access camera and microphone for Chrome. The translation for this string should match the translation of the OS System Settings app title in the target locale. For Mac OS, you can find this by selecting the locale from https://support.apple.com/guide/mac-help/mh15217/mac/localeselector. The title of the next page after that includes the desired translation. Note that, for size reasons, the English string omits 'System' and the same contraction may be suitable in other languages.">
-        Open Settings
-      </message>
-
-      <if expr="is_macosx or is_chromeos">
-        <message name="IDS_TURNED_OFF" desc="Description text for the state of camera or microphone">
-          Turned off
-        </message>
-      </if>
-
       <message name="IDS_A11Y_OMNIBOX_CHIP_HINT" desc="A navigational hint given to screenreader users, informing them that a setting which was just announced is accessible via the address bar.">
         Change this setting in the address bar.
       </message>
@@ -15018,7 +15011,7 @@
         On other devices
       </message>
       <message name="IDS_WEBAUTHN_SOURCE_CHROME_PROFILE" desc="The subtitle shown in a button that lets the user select a passkey to sign in, indicating that the passkey resides in the user's Chrome Profile.">
-        From your Chrome Profile
+        From your Chrome profile
       </message>
       <message name="IDS_WEBAUTHN_SOURCE_ICLOUD_KEYCHAIN" desc="The subtitle shown in a button that lets the user select a passkey to sign in, indicating that the passkey resides in the user's iCloud Keychain.">
         From iCloud Keychain
diff --git a/chrome/app/generated_resources_grd/IDS_GEOLOCATION_TURNED_OFF_IN_OS.png.sha1 b/chrome/app/generated_resources_grd/IDS_GEOLOCATION_TURNED_OFF_IN_OS.png.sha1
deleted file mode 100644
index 1baaf26d..0000000
--- a/chrome/app/generated_resources_grd/IDS_GEOLOCATION_TURNED_OFF_IN_OS.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-b86b6746b92da34f7ac010969c83725356ee9dd8
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_SOURCE_CHROME_PROFILE.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_SOURCE_CHROME_PROFILE.png.sha1
index 844ed13a..106f6cd 100644
--- a/chrome/app/generated_resources_grd/IDS_WEBAUTHN_SOURCE_CHROME_PROFILE.png.sha1
+++ b/chrome/app/generated_resources_grd/IDS_WEBAUTHN_SOURCE_CHROME_PROFILE.png.sha1
@@ -1 +1 @@
-d15cc102441783d75863ec7d6b37da00e4a2d3df
\ No newline at end of file
+850697c297957b5b3f371bf1a3bab15a873f6a90
\ No newline at end of file
diff --git a/chrome/app/vector_icons/browser_logo.icon b/chrome/app/vector_icons/browser_logo.icon
index daaf287..8e0eccbb 100644
--- a/chrome/app/vector_icons/browser_logo.icon
+++ b/chrome/app/vector_icons/browser_logo.icon
@@ -3,44 +3,45 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 5.5f, 8.02f,
-R_CUBIC_TO, 0, 0.7f, 0.24f, 1.29f, 0.73f, 1.77f,
-R_ARC_TO, 2.41f, 2.41f, 0, 0, 0, 1.77f, 0.73f,
-R_CUBIC_TO, 0.7f, 0, 1.29f, -0.24f, 1.77f, -0.73f,
-R_ARC_TO, 2.41f, 2.41f, 0, 0, 0, 0.73f, -1.77f,
-R_CUBIC_TO, 0, -0.69f, -0.24f, -1.28f, -0.73f, -1.77f,
-ARC_TO, 2.41f, 2.41f, 0, 0, 0, 8, 5.52f,
-R_CUBIC_TO, -0.69f, 0, -1.28f, 0.24f, -1.77f, 0.73f,
-R_ARC_TO, 2.41f, 2.41f, 0, 0, 0, -0.73f, 1.77f,
+MOVE_TO, 5.38f, 8.02f,
+R_CUBIC_TO, 0, 0.74f, 0.25f, 1.36f, 0.76f, 1.87f,
+R_CUBIC_TO, 0.51f, 0.51f, 1.13f, 0.76f, 1.86f, 0.76f,
+R_CUBIC_TO, 0.73f, 0, 1.36f, -0.25f, 1.86f, -0.76f,
+R_CUBIC_TO, 0.5f, -0.51f, 0.76f, -1.13f, 0.76f, -1.87f,
+R_CUBIC_TO, 0, -0.73f, -0.25f, -1.36f, -0.76f, -1.86f,
+R_CUBIC_TO, -0.51f, -0.51f, -1.13f, -0.76f, -1.86f, -0.76f,
+R_CUBIC_TO, -0.73f, 0, -1.35f, 0.25f, -1.86f, 0.76f,
+R_CUBIC_TO, -0.51f, 0.51f, -0.76f, 1.13f, -0.76f, 1.86f,
 CLOSE,
-MOVE_TO, 8, 11.77f,
-R_CUBIC_TO, 0.13f, 0, 0.25f, 0, 0.39f, -0.01f,
-R_CUBIC_TO, 0.14f, -0.01f, 0.26f, -0.03f, 0.39f, -0.06f,
-LINE_TO, 7.09f, 14.59f,
-R_CUBIC_TO, -1.66f, -0.18f, -3.03f, -0.9f, -4.11f, -2.16f,
-R_CUBIC_TO, -1.08f, -1.26f, -1.62f, -2.73f, -1.62f, -4.41f,
-R_ARC_TO, 6.54f, 6.54f, 0, 0, 1, 0.66f, -2.86f,
-R_LINE_TO, 2.77f, 4.73f,
-R_CUBIC_TO, 0.33f, 0.59f, 0.77f, 1.05f, 1.35f, 1.38f,
-R_CUBIC_TO, 0.58f, 0.33f, 1.2f, 0.5f, 1.87f, 0.5f,
+MOVE_TO, 8, 11.97f,
+R_CUBIC_TO, 0.13f, 0, 0.26f, 0, 0.4f, -0.01f,
+R_CUBIC_TO, 0.14f, -0.01f, 0.28f, -0.03f, 0.41f, -0.06f,
+R_LINE_TO, -1.76f, 3.04f,
+R_CUBIC_TO, -1.75f, -0.19f, -3.18f, -0.95f, -4.32f, -2.27f,
+R_CUBIC_TO, -1.14f, -1.32f, -1.71f, -2.87f, -1.71f, -4.64f,
+R_CUBIC_TO, 0, -0.52f, 0.06f, -1.03f, 0.18f, -1.52f,
+R_CUBIC_TO, 0.11f, -0.5f, 0.28f, -0.99f, 0.51f, -1.47f,
+R_LINE_TO, 2.9f, 4.96f,
+R_CUBIC_TO, 0.34f, 0.62f, 0.82f, 1.1f, 1.42f, 1.45f,
+ARC_TO, 3.85f, 3.85f, 0, 0, 0, 8, 11.96f,
 CLOSE,
-MOVE_TO, 8, 4.27f,
-R_CUBIC_TO, -0.82f, 0, -1.55f, 0.24f, -2.19f, 0.73f,
-ARC_TO, 3.79f, 3.79f, 0, 0, 0, 4.46f, 6.87f,
-LINE_TO, 2.77f, 3.94f,
-R_ARC_TO, 6.2f, 6.2f, 0, 0, 1, 2.29f, -1.9f,
-ARC_TO, 6.64f, 6.64f, 0, 0, 1, 8, 1.38f,
-R_CUBIC_TO, 1.09f, 0, 2.13f, 0.26f, 3.09f, 0.77f,
-R_ARC_TO, 6.72f, 6.72f, 0, 0, 1, 2.38f, 2.12f,
+R_MOVE_TO, 0, -7.9f,
+R_ARC_TO, 3.74f, 3.74f, 0, 0, 0, -2.32f, 0.77f,
+ARC_TO, 3.94f, 3.94f, 0, 0, 0, 4.27f, 6.81f,
+LINE_TO, 2.5f, 3.75f,
+ARC_TO, 6.55f, 6.55f, 0, 0, 1, 4.91f, 1.75f,
+ARC_TO, 6.91f, 6.91f, 0, 0, 1, 8, 1.04f,
+R_CUBIC_TO, 1.15f, 0, 2.23f, 0.27f, 3.24f, 0.81f,
+R_ARC_TO, 6.95f, 6.95f, 0, 0, 1, 2.49f, 2.22f,
 CLOSE,
-R_MOVE_TO, 6.16f, 1.25f,
-R_CUBIC_TO, 0.17f, 0.41f, 0.3f, 0.82f, 0.37f, 1.23f,
-R_CUBIC_TO, 0.08f, 0.42f, 0.12f, 0.84f, 0.12f, 1.27f,
-R_CUBIC_TO, 0, 1.79f, -0.58f, 3.29f, -1.73f, 4.5f,
-R_CUBIC_TO, -1.15f, 1.22f, -2.62f, 1.93f, -4.41f, 2.12f,
-R_LINE_TO, 2.71f, -4.75f,
-R_CUBIC_TO, 0.16f, -0.29f, 0.29f, -0.59f, 0.38f, -0.9f,
-R_ARC_TO, 3.34f, 3.34f, 0, 0, 0, 0.14f, -0.97f,
-R_CUBIC_TO, 0, -0.46f, -0.09f, -0.91f, -0.26f, -1.34f,
-R_ARC_TO, 4.12f, 4.12f, 0, 0, 0, -0.71f, -1.16f,
-CLOSE
+R_MOVE_TO, 6.46f, 1.33f,
+R_CUBIC_TO, 0.18f, 0.43f, 0.31f, 0.86f, 0.4f, 1.3f,
+R_CUBIC_TO, 0.08f, 0.44f, 0.13f, 0.88f, 0.13f, 1.33f,
+R_CUBIC_TO, 0, 1.86f, -0.61f, 3.44f, -1.81f, 4.72f,
+R_CUBIC_TO, -1.21f, 1.29f, -2.75f, 2.03f, -4.62f, 2.23f,
+R_LINE_TO, 2.84f, -4.98f,
+R_CUBIC_TO, 0.17f, -0.31f, 0.3f, -0.63f, 0.41f, -0.95f,
+R_CUBIC_TO, 0.1f, -0.32f, 0.15f, -0.66f, 0.15f, -1.01f,
+R_CUBIC_TO, 0, -0.49f, -0.09f, -0.96f, -0.27f, -1.41f,
+R_CUBIC_TO, -0.18f, -0.45f, -0.43f, -0.85f, -0.75f, -1.22f,
+CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/developer_tools.icon b/chrome/app/vector_icons/developer_tools.icon
index f143c56..451d3675 100644
--- a/chrome/app/vector_icons/developer_tools.icon
+++ b/chrome/app/vector_icons/developer_tools.icon
@@ -3,19 +3,17 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 5.54f, 12.13f,
-LINE_TO, 1.41f, 8,
-R_LINE_TO, 4.13f, -4.13f,
-R_LINE_TO, 0.98f, 0.98f,
-R_LINE_TO, -3.15f, 3.15f,
+MOVE_TO, 5.46f, 12.3f,
+LINE_TO, 1.15f, 8,
+R_LINE_TO, 4.31f, -4.31f,
+LINE_TO, 6.62f, 4.84f,
+LINE_TO, 3.47f, 7.99f,
 R_LINE_TO, 3.15f, 3.15f,
 CLOSE,
-R_MOVE_TO, 4.92f, 0,
-R_LINE_TO, -0.98f, -0.98f,
+R_MOVE_TO, 5.09f, 0.01f,
+LINE_TO, 9.38f, 11.16f,
 R_LINE_TO, 3.15f, -3.15f,
-R_LINE_TO, -3.15f, -3.15f,
-R_LINE_TO, 0.98f, -0.98f,
-LINE_TO, 14.59f, 8,
-CLOSE,
-R_MOVE_TO, 0, 0,
+LINE_TO, 9.38f, 4.86f,
+R_LINE_TO, 1.16f, -1.16f,
+LINE_TO, 14.85f, 8,
 CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/exit_menu.icon b/chrome/app/vector_icons/exit_menu.icon
index d9097ea7..28aecbc 100644
--- a/chrome/app/vector_icons/exit_menu.icon
+++ b/chrome/app/vector_icons/exit_menu.icon
@@ -3,34 +3,34 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 3.65f, 13.73f,
-R_CUBIC_TO, -0.38f, 0, -0.71f, -0.13f, -0.98f, -0.4f,
-R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.98f,
-R_V_LINE_TO, -2.66f,
-R_H_LINE_TO, 1.38f,
-R_V_LINE_TO, 2.66f,
-R_H_LINE_TO, 8.7f,
-V_LINE_TO, 3.65f,
-H_LINE_TO, 3.65f,
-R_V_LINE_TO, 2.66f,
-H_LINE_TO, 2.27f,
-R_V_LINE_TO, -2.66f,
-R_CUBIC_TO, 0, -0.38f, 0.13f, -0.71f, 0.4f, -0.98f,
-R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.4f, 0.98f, -0.4f,
-R_H_LINE_TO, 8.7f,
-R_CUBIC_TO, 0.38f, 0, 0.71f, 0.13f, 0.98f, 0.4f,
-R_CUBIC_TO, 0.27f, 0.27f, 0.4f, 0.6f, 0.4f, 0.98f,
-R_V_LINE_TO, 8.7f,
-R_CUBIC_TO, 0, 0.38f, -0.13f, 0.71f, -0.4f, 0.98f,
-R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.4f, -0.98f, 0.4f,
+MOVE_TO, 3.72f, 13.92f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, -0.48f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.48f, -1.16f,
+V_LINE_TO, 9.82f,
+R_H_LINE_TO, 1.64f,
+R_V_LINE_TO, 2.47f,
+R_H_LINE_TO, 8.57f,
+V_LINE_TO, 3.71f,
+R_H_LINE_TO, -8.57f,
+R_V_LINE_TO, 2.47f,
+H_LINE_TO, 2.08f,
+R_V_LINE_TO, -2.47f,
+R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.48f, -1.16f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, 1.16f, -0.48f,
+R_H_LINE_TO, 8.57f,
+R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f,
+R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.7f, 0.48f, 1.16f,
+R_V_LINE_TO, 8.57f,
+R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.48f, 1.16f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, 0.48f,
 CLOSE,
-R_MOVE_TO, 3.63f, -2.37f,
-R_LINE_TO, -0.98f, -0.97f,
-LINE_TO, 7.99f, 8.69f,
-H_LINE_TO, 2.27f,
-V_LINE_TO, 7.31f,
-R_H_LINE_TO, 5.72f,
-LINE_TO, 6.29f, 5.61f,
-R_LINE_TO, 0.98f, -0.97f,
-LINE_TO, 10.63f, 8,
-CLOSE
+R_MOVE_TO, 3.66f, -2.34f,
+LINE_TO, 6.22f, 10.43f,
+R_LINE_TO, 1.62f, -1.62f,
+H_LINE_TO, 2.08f,
+V_LINE_TO, 7.18f,
+R_H_LINE_TO, 5.76f,
+LINE_TO, 6.22f, 5.57f,
+LINE_TO, 7.37f, 4.42f,
+LINE_TO, 10.95f, 8,
+CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/history.icon b/chrome/app/vector_icons/history.icon
index 5ec6f98..1defbdf25 100644
--- a/chrome/app/vector_icons/history.icon
+++ b/chrome/app/vector_icons/history.icon
@@ -3,39 +3,39 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 7.99f, 13.73f,
-R_CUBIC_TO, -1.59f, 0, -2.94f, -0.55f, -4.06f, -1.67f,
-CUBIC_TO, 2.81f, 10.95f, 2.26f, 9.59f, 2.26f, 8,
-H_LINE_TO, 3.64f,
-R_CUBIC_TO, 0, 1.2f, 0.43f, 2.22f, 1.28f, 3.07f,
-R_CUBIC_TO, 0.85f, 0.85f, 1.88f, 1.28f, 3.07f, 1.28f,
-R_CUBIC_TO, 1.2f, 0, 2.22f, -0.43f, 3.07f, -1.28f,
-R_CUBIC_TO, 0.85f, -0.85f, 1.28f, -1.87f, 1.28f, -3.07f,
-R_CUBIC_TO, 0, -1.2f, -0.43f, -2.22f, -1.28f, -3.07f,
-R_CUBIC_TO, -0.85f, -0.85f, -1.87f, -1.28f, -3.07f, -1.28f,
-R_CUBIC_TO, -0.66f, 0, -1.26f, 0.13f, -1.83f, 0.39f,
-ARC_TO, 4.16f, 4.16f, 0, 0, 0, 4.73f, 5.13f,
-R_H_LINE_TO, 1.67f,
-R_V_LINE_TO, 1.26f,
-H_LINE_TO, 2.3f,
-V_LINE_TO, 2.3f,
-R_H_LINE_TO, 1.26f,
-R_V_LINE_TO, 2.11f,
-ARC_TO, 5.75f, 5.75f, 0, 0, 1, 5.49f, 2.84f,
-R_ARC_TO, 5.51f, 5.51f, 0, 0, 1, 2.5f, -0.57f,
-R_CUBIC_TO, 0.79f, 0, 1.54f, 0.15f, 2.24f, 0.45f,
-R_CUBIC_TO, 0.7f, 0.3f, 1.3f, 0.71f, 1.82f, 1.23f,
-R_ARC_TO, 5.77f, 5.77f, 0, 0, 1, 1.23f, 1.82f,
-R_CUBIC_TO, 0.31f, 0.7f, 0.45f, 1.44f, 0.45f, 2.24f,
-R_CUBIC_TO, 0, 0.79f, -0.15f, 1.54f, -0.45f, 2.23f,
-R_CUBIC_TO, -0.3f, 0.7f, -0.71f, 1.31f, -1.23f, 1.82f,
-R_ARC_TO, 5.77f, 5.77f, 0, 0, 1, -1.82f, 1.23f,
-R_ARC_TO, 5.51f, 5.51f, 0, 0, 1, -2.23f, 0.45f,
+MOVE_TO, 7.98f, 13.92f,
+R_CUBIC_TO, -1.64f, 0, -3.04f, -0.57f, -4.19f, -1.72f,
+CUBIC_TO, 2.64f, 11.05f, 2.06f, 9.65f, 2.07f, 8,
+R_H_LINE_TO, 1.63f,
+R_CUBIC_TO, 0, 1.18f, 0.43f, 2.19f, 1.26f, 3.03f,
+R_CUBIC_TO, 0.84f, 0.84f, 1.84f, 1.26f, 3.02f, 1.26f,
+R_CUBIC_TO, 1.18f, 0, 2.19f, -0.42f, 3.03f, -1.26f,
+R_CUBIC_TO, 0.84f, -0.84f, 1.26f, -1.85f, 1.26f, -3.03f,
+R_CUBIC_TO, 0, -1.18f, -0.42f, -2.19f, -1.26f, -3.03f,
+R_CUBIC_TO, -0.84f, -0.84f, -1.85f, -1.26f, -3.03f, -1.26f,
+R_CUBIC_TO, -0.61f, 0, -1.19f, 0.11f, -1.72f, 0.34f,
+R_CUBIC_TO, -0.53f, 0.23f, -0.99f, 0.56f, -1.37f, 0.98f,
+R_H_LINE_TO, 1.52f,
+V_LINE_TO, 6.4f,
+H_LINE_TO, 2.15f,
+V_LINE_TO, 2.16f,
+R_H_LINE_TO, 1.34f,
+R_V_LINE_TO, 2.03f,
+R_ARC_TO, 5.88f, 5.88f, 0, 0, 1, 1.97f, -1.55f,
+R_ARC_TO, 5.68f, 5.68f, 0, 0, 1, 2.52f, -0.57f,
+R_CUBIC_TO, 0.82f, 0, 1.58f, 0.16f, 2.3f, 0.47f,
+R_ARC_TO, 6.04f, 6.04f, 0, 0, 1, 1.88f, 1.27f,
+R_CUBIC_TO, 0.53f, 0.53f, 0.96f, 1.16f, 1.27f, 1.88f,
+R_CUBIC_TO, 0.31f, 0.72f, 0.47f, 1.49f, 0.47f, 2.31f,
+R_CUBIC_TO, 0, 0.82f, -0.16f, 1.58f, -0.47f, 2.31f,
+R_ARC_TO, 5.96f, 5.96f, 0, 0, 1, -1.27f, 1.88f,
+R_ARC_TO, 6.04f, 6.04f, 0, 0, 1, -1.88f, 1.27f,
+R_ARC_TO, 5.74f, 5.74f, 0, 0, 1, -2.31f, 0.47f,
 CLOSE,
-R_MOVE_TO, 1.65f, -3.44f,
-LINE_TO, 7.37f, 8.03f,
-R_V_LINE_TO, -3.23f,
-R_H_LINE_TO, 1.26f,
+R_MOVE_TO, 1.62f, -3.58f,
+R_LINE_TO, -2.27f, -2.27f,
+V_LINE_TO, 4.8f,
+R_H_LINE_TO, 1.34f,
 V_LINE_TO, 7.5f,
-R_LINE_TO, 1.9f, 1.9f,
-CLOSE
+R_LINE_TO, 1.89f, 1.88f,
+CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/name_window.icon b/chrome/app/vector_icons/name_window.icon
index 33a087a1..fcc3088 100644
--- a/chrome/app/vector_icons/name_window.icon
+++ b/chrome/app/vector_icons/name_window.icon
@@ -3,23 +3,21 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 3.65f, 13.73f,
-R_CUBIC_TO, -0.38f, 0, -0.71f, -0.14f, -0.98f, -0.41f,
-R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.97f,
-V_LINE_TO, 3.65f,
-R_CUBIC_TO, 0, -0.37f, 0.13f, -0.7f, 0.4f, -0.97f,
-R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.41f, 0.98f, -0.41f,
-R_H_LINE_TO, 8.7f,
-R_CUBIC_TO, 0.38f, 0, 0.71f, 0.14f, 0.98f, 0.41f,
-R_CUBIC_TO, 0.27f, 0.27f, 0.4f, 0.6f, 0.4f, 0.97f,
-R_V_LINE_TO, 8.7f,
-R_CUBIC_TO, 0, 0.38f, -0.13f, 0.7f, -0.4f, 0.97f,
-R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.41f, -0.98f, 0.41f,
+MOVE_TO, 3.72f, 13.92f,
+R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.48f,
+R_ARC_TO, 1.6f, 1.6f, 0, 0, 1, -0.48f, -1.16f,
+R_V_LINE_TO, -8.57f,
+R_CUBIC_TO, 0, -0.45f, 0.16f, -0.83f, 0.48f, -1.16f,
+R_CUBIC_TO, 0.32f, -0.32f, 0.7f, -0.48f, 1.16f, -0.48f,
+R_H_LINE_TO, 8.57f,
+R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f,
+R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f,
+R_V_LINE_TO, 8.57f,
+R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.16f,
+R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.16f, 0.48f,
 CLOSE,
-R_MOVE_TO, -0.05f, -1.34f,
+R_MOVE_TO, -0.11f, -1.52f,
 R_H_LINE_TO, 8.8f,
-V_LINE_TO, 5.57f,
+V_LINE_TO, 5.54f,
 H_LINE_TO, 3.6f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
\ No newline at end of file
+CLOSE
diff --git a/chrome/app/vector_icons/performance.icon b/chrome/app/vector_icons/performance.icon
index 3a4c3ca..4613e20 100644
--- a/chrome/app/vector_icons/performance.icon
+++ b/chrome/app/vector_icons/performance.icon
@@ -4,44 +4,42 @@
 
 CANVAS_DIMENSIONS, 16,
 MOVE_TO, 7.15f, 10.04f,
-R_CUBIC_TO, 0.25f, 0.24f, 0.57f, 0.36f, 0.95f, 0.34f,
-R_CUBIC_TO, 0.38f, -0.02f, 0.66f, -0.16f, 0.84f, -0.43f,
-R_LINE_TO, 3.57f, -5.25f,
+R_CUBIC_TO, 0.25f, 0.24f, 0.57f, 0.36f, 0.94f, 0.34f,
+R_CUBIC_TO, 0.37f, -0.02f, 0.65f, -0.16f, 0.84f, -0.43f,
+R_LINE_TO, 3.71f, -5.39f,
 LINE_TO, 7.25f, 8.27f,
-R_CUBIC_TO, -0.27f, 0.19f, -0.43f, 0.47f, -0.44f, 0.84f,
-R_CUBIC_TO, -0.02f, 0.37f, 0.09f, 0.68f, 0.35f, 0.92f,
+R_CUBIC_TO, -0.27f, 0.2f, -0.43f, 0.48f, -0.44f, 0.85f,
+R_CUBIC_TO, -0.02f, 0.37f, 0.09f, 0.67f, 0.35f, 0.91f,
 CLOSE,
-R_MOVE_TO, 0.87f, -6.97f,
-R_CUBIC_TO, 0.69f, 0, 1.31f, 0.09f, 1.87f, 0.27f,
-R_CUBIC_TO, 0.56f, 0.18f, 1.06f, 0.4f, 1.5f, 0.66f,
-R_LINE_TO, -1.32f, 0.88f,
-R_ARC_TO, 5.13f, 5.13f, 0, 0, 0, -0.95f, -0.32f,
-R_ARC_TO, 5.18f, 5.18f, 0, 0, 0, -1.1f, -0.11f,
-R_CUBIC_TO, -1.43f, 0, -2.64f, 0.51f, -3.65f, 1.54f,
-R_CUBIC_TO, -1.01f, 1.03f, -1.51f, 2.23f, -1.51f, 3.61f,
-R_CUBIC_TO, 0, 0.42f, 0.03f, 0.76f, 0.09f, 1.02f,
-R_CUBIC_TO, 0.06f, 0.26f, 0.15f, 0.57f, 0.28f, 0.93f,
-R_H_LINE_TO, 9.56f,
-R_ARC_TO, 5.93f, 5.93f, 0, 0, 0, 0.3f, -0.98f,
-R_ARC_TO, 5.35f, 5.35f, 0, 0, 0, -0.1f, -2.33f,
-R_ARC_TO, 4.71f, 4.71f, 0, 0, 0, -0.54f, -1.27f,
-R_LINE_TO, 0.84f, -1.24f,
-R_ARC_TO, 6.26f, 6.26f, 0, 0, 1, 0.94f, 1.82f,
-R_CUBIC_TO, 0.22f, 0.67f, 0.33f, 1.34f, 0.33f, 2.03f,
-R_ARC_TO, 7.24f, 7.24f, 0, 0, 1, -0.15f, 1.52f,
-R_ARC_TO, 4.09f, 4.09f, 0, 0, 1, -0.47f, 1.2f,
-R_ARC_TO, 1.32f, 1.32f, 0, 0, 1, -0.48f, 0.49f,
-R_CUBIC_TO, -0.19f, 0.11f, -0.41f, 0.16f, -0.64f, 0.16f,
+R_MOVE_TO, 0.87f, -7.16f,
+R_CUBIC_TO, 0.71f, 0, 1.36f, 0.1f, 1.96f, 0.29f,
+R_ARC_TO, 7.18f, 7.18f, 0, 0, 1, 1.56f, 0.69f,
+LINE_TO, 9.98f, 4.91f,
+R_ARC_TO, 5.29f, 5.29f, 0, 0, 0, -0.91f, -0.3f,
+R_ARC_TO, 5.16f, 5.16f, 0, 0, 0, -1.05f, -0.1f,
+R_CUBIC_TO, -1.4f, 0, -2.6f, 0.51f, -3.6f, 1.53f,
+R_CUBIC_TO, -1, 1.02f, -1.5f, 2.2f, -1.5f, 3.56f,
+R_CUBIC_TO, 0, 0.42f, 0.03f, 0.75f, 0.08f, 0.99f,
+R_CUBIC_TO, 0.06f, 0.24f, 0.14f, 0.54f, 0.26f, 0.9f,
+R_H_LINE_TO, 9.47f,
+R_CUBIC_TO, 0.14f, -0.37f, 0.24f, -0.68f, 0.29f, -0.95f,
+R_CUBIC_TO, 0.05f, -0.27f, 0.07f, -0.58f, 0.07f, -0.93f,
+R_CUBIC_TO, 0, -0.43f, -0.05f, -0.87f, -0.17f, -1.32f,
+R_ARC_TO, 4.78f, 4.78f, 0, 0, 0, -0.51f, -1.25f,
+R_LINE_TO, 1.01f, -1.46f,
+R_CUBIC_TO, 0.43f, 0.56f, 0.75f, 1.19f, 0.98f, 1.89f,
+R_CUBIC_TO, 0.23f, 0.7f, 0.34f, 1.41f, 0.33f, 2.11f,
+R_ARC_TO, 7.39f, 7.39f, 0, 0, 1, -0.16f, 1.56f,
+R_ARC_TO, 4.36f, 4.36f, 0, 0, 1, -0.48f, 1.25f,
+R_ARC_TO, 1.54f, 1.54f, 0, 0, 1, -0.55f, 0.56f,
+R_CUBIC_TO, -0.22f, 0.13f, -0.46f, 0.19f, -0.72f, 0.19f,
 H_LINE_TO, 3.2f,
-R_ARC_TO, 1.26f, 1.26f, 0, 0, 1, -1.11f, -0.65f,
-R_ARC_TO, 4.25f, 4.25f, 0, 0, 1, -0.47f, -1.2f,
-R_ARC_TO, 7, 7, 0, 0, 1, -0.15f, -1.52f,
-R_CUBIC_TO, 0, -0.9f, 0.17f, -1.75f, 0.52f, -2.54f,
-R_ARC_TO, 6.59f, 6.59f, 0, 0, 1, 1.4f, -2.06f,
-R_ARC_TO, 6.62f, 6.62f, 0, 0, 1, 2.08f, -1.39f,
-R_ARC_TO, 6.43f, 6.43f, 0, 0, 1, 2.55f, -0.51f,
-CLOSE,
-R_MOVE_TO, 0.06f, 4.71f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
\ No newline at end of file
+R_ARC_TO, 1.44f, 1.44f, 0, 0, 1, -0.73f, -0.2f,
+R_ARC_TO, 1.4f, 1.4f, 0, 0, 1, -0.54f, -0.55f,
+R_ARC_TO, 4.5f, 4.5f, 0, 0, 1, -0.48f, -1.24f,
+R_ARC_TO, 6.77f, 6.77f, 0, 0, 1, -0.16f, -1.57f,
+R_CUBIC_TO, 0, -0.92f, 0.18f, -1.79f, 0.53f, -2.61f,
+R_ARC_TO, 6.77f, 6.77f, 0, 0, 1, 1.44f, -2.12f,
+R_ARC_TO, 6.79f, 6.79f, 0, 0, 1, 2.14f, -1.43f,
+R_ARC_TO, 6.59f, 6.59f, 0, 0, 1, 2.63f, -0.53f,
+CLOSE
diff --git a/chrome/app/vector_icons/quick_commands.icon b/chrome/app/vector_icons/quick_commands.icon
index 9dd4017..591dbeec 100644
--- a/chrome/app/vector_icons/quick_commands.icon
+++ b/chrome/app/vector_icons/quick_commands.icon
@@ -3,29 +3,27 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 1.6f, 13.79f,
-R_V_LINE_TO, -1.39f,
+MOVE_TO, 1.6f, 14.04f,
+R_V_LINE_TO, -1.64f,
 R_H_LINE_TO, 12.8f,
-R_V_LINE_TO, 1.39f,
+R_V_LINE_TO, 1.64f,
 CLOSE,
 MOVE_TO, 12.8f, 11.2f,
 V_LINE_TO, 2.4f,
-R_H_LINE_TO, 0.92f,
+R_H_LINE_TO, 1.09f,
 R_V_LINE_TO, 8.8f,
 CLOSE,
-R_MOVE_TO, -10.01f, 0,
-R_LINE_TO, 3.39f, -8.8f,
-R_H_LINE_TO, 1.74f,
-R_LINE_TO, 3.38f, 8.8f,
-H_LINE_TO, 9.55f,
-R_LINE_TO, -0.77f, -2.19f,
-H_LINE_TO, 5.27f,
-R_LINE_TO, -0.78f, 2.19f,
+R_MOVE_TO, -10.23f, 0,
+R_LINE_TO, 3.51f, -8.8f,
+R_H_LINE_TO, 1.98f,
+R_LINE_TO, 3.46f, 8.8f,
+H_LINE_TO, 9.49f,
+R_LINE_TO, -0.75f, -2.11f,
+H_LINE_TO, 5.29f,
+R_LINE_TO, -0.77f, 2.11f,
 CLOSE,
-R_MOVE_TO, 2.95f, -3.53f,
-R_H_LINE_TO, 2.56f,
-R_LINE_TO, -1.25f, -3.53f,
-R_H_LINE_TO, -0.06f,
-CLOSE,
-R_MOVE_TO, 0, 0,
+R_MOVE_TO, 3.2f, -3.53f,
+R_H_LINE_TO, 2.47f,
+LINE_TO, 7.04f, 4.27f,
+H_LINE_TO, 6.98f,
 CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/release_alert.icon b/chrome/app/vector_icons/release_alert.icon
index 22b0e346..77397ed 100644
--- a/chrome/app/vector_icons/release_alert.icon
+++ b/chrome/app/vector_icons/release_alert.icon
@@ -3,62 +3,62 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-R_MOVE_TO, 5.73f, 14.97f,
-R_LINE_TO, -1.28f, -2.12f,
-R_LINE_TO, -2.41f, -0.54f,
-R_LINE_TO, 0.23f, -2.46f,
-LINE_TO, 0.63f, 8,
-R_LINE_TO, 1.64f, -1.84f,
-R_LINE_TO, -0.23f, -2.46f,
-R_LINE_TO, 2.41f, -0.54f,
-R_LINE_TO, 1.28f, -2.12f,
-LINE_TO, 8, 2,
-R_LINE_TO, 2.27f, -0.98f,
-R_LINE_TO, 1.28f, 2.13f,
-R_LINE_TO, 2.41f, 0.54f,
-R_LINE_TO, -0.23f, 2.46f,
-LINE_TO, 15.38f, 8,
-R_LINE_TO, -1.64f, 1.84f,
-R_LINE_TO, 0.23f, 2.46f,
-R_LINE_TO, -2.41f, 0.54f,
-R_LINE_TO, -1.28f, 2.13f,
-LINE_TO, 8, 14,
+R_MOVE_TO, 5.65f, 15.21f,
+R_LINE_TO, -1.32f, -2.2f,
+R_LINE_TO, -2.5f, -0.56f,
+R_LINE_TO, 0.23f, -2.54f,
+LINE_TO, 0.39f, 8,
+LINE_TO, 2.07f, 6.1f,
+R_LINE_TO, -0.23f, -2.54f,
+R_LINE_TO, 2.5f, -0.56f,
+LINE_TO, 5.65f, 0.79f,
+LINE_TO, 8, 1.8f,
+LINE_TO, 10.35f, 0.79f,
+R_LINE_TO, 1.32f, 2.2f,
+R_LINE_TO, 2.5f, 0.56f,
+R_LINE_TO, -0.23f, 2.54f,
+LINE_TO, 15.61f, 8,
+LINE_TO, 13.93f, 9.9f,
+R_LINE_TO, 0.23f, 2.54f,
+R_LINE_TO, -2.5f, 0.56f,
+R_LINE_TO, -1.32f, 2.2f,
+LINE_TO, 8, 14.2f,
 CLOSE,
-R_MOVE_TO, 0.56f, -1.75f,
-LINE_TO, 8, 12.5f,
-R_LINE_TO, 1.72f, 0.73f,
-R_LINE_TO, 0.95f, -1.6f,
-R_LINE_TO, 1.81f, -0.41f,
-R_LINE_TO, -0.16f, -1.84f,
-LINE_TO, 13.53f, 8,
-R_LINE_TO, -1.21f, -1.38f,
-R_LINE_TO, 0.16f, -1.84f,
-R_LINE_TO, -1.81f, -0.41f,
-R_LINE_TO, -0.95f, -1.6f,
-LINE_TO, 8, 3.5f,
-R_LINE_TO, -1.71f, -0.73f,
-R_LINE_TO, -0.95f, 1.6f,
-R_LINE_TO, -1.81f, 0.39f,
-R_LINE_TO, 0.16f, 1.85f,
-LINE_TO, 2.47f, 8,
-R_LINE_TO, 1.23f, 1.38f,
-R_LINE_TO, -0.18f, 1.85f,
-R_LINE_TO, 1.81f, 0.41f,
+R_MOVE_TO, 0.66f, -2.07f,
+LINE_TO, 8, 12.42f,
+R_LINE_TO, 1.69f, 0.72f,
+R_LINE_TO, 0.94f, -1.58f,
+R_LINE_TO, 1.78f, -0.4f,
+R_LINE_TO, -0.15f, -1.81f,
+LINE_TO, 13.44f, 8,
+R_LINE_TO, -1.19f, -1.35f,
+R_LINE_TO, 0.15f, -1.81f,
+R_LINE_TO, -1.78f, -0.4f,
+R_LINE_TO, -0.94f, -1.58f,
+LINE_TO, 8, 3.58f,
+R_LINE_TO, -1.69f, -0.72f,
+R_LINE_TO, -0.94f, 1.58f,
+R_LINE_TO, -1.78f, 0.38f,
+R_LINE_TO, 0.15f, 1.83f,
+LINE_TO, 2.56f, 8,
+R_LINE_TO, 1.2f, 1.35f,
+R_LINE_TO, -0.16f, 1.83f,
+R_LINE_TO, 1.78f, 0.39f,
 CLOSE,
 MOVE_TO, 8, 8,
 CLOSE,
-R_MOVE_TO, 0, 3.34f,
-R_CUBIC_TO, 0.2f, 0, 0.37f, -0.07f, 0.51f, -0.21f,
-R_ARC_TO, 0.69f, 0.69f, 0, 0, 0, 0.21f, -0.5f,
-R_ARC_TO, 0.71f, 0.71f, 0, 0, 0, -0.21f, -0.51f,
-ARC_TO, 0.69f, 0.69f, 0, 0, 0, 8, 9.9f,
-R_ARC_TO, 0.69f, 0.69f, 0, 0, 0, -0.51f, 0.21f,
-R_ARC_TO, 0.71f, 0.71f, 0, 0, 0, -0.21f, 0.51f,
-R_CUBIC_TO, 0, 0.2f, 0.07f, 0.37f, 0.21f, 0.5f,
-R_CUBIC_TO, 0.14f, 0.14f, 0.31f, 0.21f, 0.51f, 0.21f,
+R_MOVE_TO, 0, 3.52f,
+R_CUBIC_TO, 0.24f, 0, 0.45f, -0.09f, 0.62f, -0.25f,
+R_ARC_TO, 0.84f, 0.84f, 0, 0, 0, 0.26f, -0.62f,
+R_ARC_TO, 0.86f, 0.86f, 0, 0, 0, -0.26f, -0.62f,
+ARC_TO, 0.83f, 0.83f, 0, 0, 0, 8, 9.77f,
+R_ARC_TO, 0.83f, 0.83f, 0, 0, 0, -0.62f, 0.26f,
+R_ARC_TO, 0.86f, 0.86f, 0, 0, 0, -0.26f, 0.63f,
+R_CUBIC_TO, 0, 0.24f, 0.09f, 0.45f, 0.26f, 0.62f,
+ARC_TO, 0.84f, 0.84f, 0, 0, 0, 8, 11.52f,
 CLOSE,
-R_MOVE_TO, -0.69f, -2.53f,
-H_LINE_TO, 8.69f,
-V_LINE_TO, 4.72f,
-H_LINE_TO, 7.31f,
-CLOSE
+R_MOVE_TO, -0.82f, -2.7f,
+R_H_LINE_TO, 1.63f,
+V_LINE_TO, 4.6f,
+H_LINE_TO, 7.18f,
+CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/report.icon b/chrome/app/vector_icons/report.icon
index e6246ae4..791e519 100644
--- a/chrome/app/vector_icons/report.icon
+++ b/chrome/app/vector_icons/report.icon
@@ -3,36 +3,36 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 8, 11.09f,
-R_CUBIC_TO, 0.18f, 0, 0.34f, -0.06f, 0.47f, -0.19f,
-R_ARC_TO, 0.63f, 0.63f, 0, 0, 0, 0.19f, -0.46f,
-R_ARC_TO, 0.64f, 0.64f, 0, 0, 0, -0.19f, -0.47f,
-ARC_TO, 0.63f, 0.63f, 0, 0, 0, 8, 9.77f,
-R_ARC_TO, 0.63f, 0.63f, 0, 0, 0, -0.47f, 0.2f,
-R_ARC_TO, 0.64f, 0.64f, 0, 0, 0, -0.19f, 0.47f,
-R_CUBIC_TO, 0, 0.18f, 0.06f, 0.34f, 0.19f, 0.46f,
-ARC_TO, 0.64f, 0.64f, 0, 0, 0, 8, 11.09f,
+MOVE_TO, 8, 11.22f,
+R_CUBIC_TO, 0.21f, 0, 0.38f, -0.07f, 0.53f, -0.21f,
+R_ARC_TO, 0.72f, 0.72f, 0, 0, 0, 0.22f, -0.52f,
+R_ARC_TO, 0.75f, 0.75f, 0, 0, 0, -0.21f, -0.53f,
+ARC_TO, 0.71f, 0.71f, 0, 0, 0, 8, 9.73f,
+R_ARC_TO, 0.71f, 0.71f, 0, 0, 0, -0.53f, 0.22f,
+R_ARC_TO, 0.75f, 0.75f, 0, 0, 0, -0.21f, 0.53f,
+R_ARC_TO, 0.73f, 0.73f, 0, 0, 0, 0.22f, 0.52f,
+R_CUBIC_TO, 0.14f, 0.14f, 0.32f, 0.22f, 0.53f, 0.22f,
 CLOSE,
-R_MOVE_TO, -0.63f, -2.18f,
-R_H_LINE_TO, 1.27f,
-V_LINE_TO, 4.73f,
-H_LINE_TO, 7.37f,
+R_MOVE_TO, -0.68f, -2.15f,
+R_H_LINE_TO, 1.35f,
+V_LINE_TO, 4.63f,
+H_LINE_TO, 7.32f,
 CLOSE,
-MOVE_TO, 5.63f, 13.73f,
-R_LINE_TO, -3.36f, -3.38f,
-V_LINE_TO, 5.63f,
-R_LINE_TO, 3.36f, -3.36f,
-R_H_LINE_TO, 4.75f,
-R_LINE_TO, 3.36f, 3.36f,
-R_V_LINE_TO, 4.75f,
-R_LINE_TO, -3.38f, 3.36f,
+R_MOVE_TO, -1.77f, 4.86f,
+R_LINE_TO, -3.47f, -3.49f,
+V_LINE_TO, 5.55f,
+R_LINE_TO, 3.47f, -3.47f,
+R_H_LINE_TO, 4.9f,
+R_LINE_TO, 3.47f, 3.47f,
+R_V_LINE_TO, 4.9f,
+R_LINE_TO, -3.49f, 3.47f,
 CLOSE,
-R_MOVE_TO, 0.57f, -1.38f,
-R_H_LINE_TO, 3.59f,
-R_LINE_TO, 2.56f, -2.56f,
-V_LINE_TO, 6.2f,
-R_LINE_TO, -2.57f, -2.56f,
-H_LINE_TO, 6.2f,
-LINE_TO, 3.65f, 6.2f,
-R_V_LINE_TO, 3.59f,
+R_MOVE_TO, 0.68f, -1.64f,
+H_LINE_TO, 9.77f,
+R_LINE_TO, 2.52f, -2.51f,
+V_LINE_TO, 6.23f,
+LINE_TO, 9.75f, 3.72f,
+H_LINE_TO, 6.23f,
+LINE_TO, 3.72f, 6.23f,
+R_V_LINE_TO, 3.54f,
 CLOSE
diff --git a/chrome/app/vector_icons/request_mobile_site_checked.icon b/chrome/app/vector_icons/request_mobile_site_checked.icon
index 5a60acf..c81b33b 100644
--- a/chrome/app/vector_icons/request_mobile_site_checked.icon
+++ b/chrome/app/vector_icons/request_mobile_site_checked.icon
@@ -3,49 +3,47 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 3.66f, 15.32f,
-R_CUBIC_TO, -0.38f, 0, -0.71f, -0.14f, -0.98f, -0.41f,
-R_ARC_TO, 1.33f, 1.33f, 0, 0, 1, -0.41f, -0.98f,
-V_LINE_TO, 2.06f,
-R_CUBIC_TO, 0, -0.38f, 0.13f, -0.7f, 0.41f, -0.98f,
-R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.41f, 0.98f, -0.41f,
-R_H_LINE_TO, 7.08f,
-R_CUBIC_TO, 0.38f, 0, 0.71f, 0.14f, 0.98f, 0.41f,
-R_CUBIC_TO, 0.27f, 0.27f, 0.41f, 0.6f, 0.41f, 0.98f,
+MOVE_TO, 3.74f, 15.49f,
+R_CUBIC_TO, -0.45f, 0, -0.84f, -0.16f, -1.16f, -0.48f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.48f, -1.15f,
+V_LINE_TO, 2.14f,
+R_CUBIC_TO, 0, -0.45f, 0.16f, -0.83f, 0.48f, -1.15f,
+R_CUBIC_TO, 0.32f, -0.32f, 0.71f, -0.48f, 1.16f, -0.48f,
+R_H_LINE_TO, 6.92f,
+R_CUBIC_TO, 0.45f, 0, 0.83f, 0.16f, 1.15f, 0.48f,
+R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.7f, 0.48f, 1.15f,
 V_LINE_TO, 4.8f,
-R_H_LINE_TO, -1.39f,
-R_V_LINE_TO, -0.74f,
-H_LINE_TO, 3.66f,
-R_V_LINE_TO, 7.88f,
-R_H_LINE_TO, 7.08f,
-V_LINE_TO, 11.2f,
-R_H_LINE_TO, 1.39f,
-R_V_LINE_TO, 2.74f,
-R_CUBIC_TO, 0, 0.38f, -0.14f, 0.7f, -0.41f, 0.98f,
-R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.41f, -0.98f, 0.41f,
+H_LINE_TO, 10.66f,
+R_V_LINE_TO, -0.66f,
+H_LINE_TO, 3.74f,
+R_V_LINE_TO, 7.72f,
+R_H_LINE_TO, 6.92f,
+R_V_LINE_TO, -0.66f,
+R_H_LINE_TO, 1.63f,
+R_V_LINE_TO, 2.66f,
+R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.15f,
+R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.15f, 0.48f,
 CLOSE,
-R_MOVE_TO, 0, -2.18f,
+R_MOVE_TO, 0, -2.43f,
 R_V_LINE_TO, 0.8f,
-R_H_LINE_TO, 7.08f,
+R_H_LINE_TO, 6.92f,
 R_V_LINE_TO, -0.8f,
 CLOSE,
-R_MOVE_TO, 6.37f, -2.72f,
-LINE_TO, 7.15f, 7.52f,
-R_LINE_TO, 0.96f, -0.96f,
-R_LINE_TO, 1.92f, 1.93f,
-R_LINE_TO, 3.63f, -3.63f,
-R_LINE_TO, 0.96f, 0.96f,
+R_MOVE_TO, 6.5f, -2.61f,
+R_LINE_TO, -2.96f, -2.98f,
+R_LINE_TO, 1.11f, -1.11f,
+R_LINE_TO, 1.85f, 1.86f,
+R_LINE_TO, 3.57f, -3.56f,
+R_LINE_TO, 1.11f, 1.1f,
 CLOSE,
-MOVE_TO, 3.66f, 2.86f,
-R_H_LINE_TO, 7.08f,
+R_MOVE_TO, -6.5f, -7.5f,
+R_H_LINE_TO, 6.92f,
 R_V_LINE_TO, -0.8f,
-H_LINE_TO, 3.66f,
+H_LINE_TO, 3.74f,
 CLOSE,
 R_MOVE_TO, 0, 0,
 R_V_LINE_TO, -0.8f,
 CLOSE,
-R_MOVE_TO, 0, 10.28f,
+R_MOVE_TO, 0, 10.12f,
 R_V_LINE_TO, 0.8f,
-CLOSE,
-R_MOVE_TO, 0, 0,
 CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/request_mobile_site_unchecked.icon b/chrome/app/vector_icons/request_mobile_site_unchecked.icon
index 68bc7c8..8fd6930 100644
--- a/chrome/app/vector_icons/request_mobile_site_unchecked.icon
+++ b/chrome/app/vector_icons/request_mobile_site_unchecked.icon
@@ -3,39 +3,37 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 4.46f, 15.32f,
-R_CUBIC_TO, -0.38f, 0, -0.71f, -0.14f, -0.98f, -0.41f,
-R_ARC_TO, 1.33f, 1.33f, 0, 0, 1, -0.4f, -0.98f,
-V_LINE_TO, 2.06f,
-R_CUBIC_TO, 0, -0.38f, 0.13f, -0.71f, 0.4f, -0.98f,
-R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.41f, 0.98f, -0.41f,
-R_H_LINE_TO, 7.08f,
-R_CUBIC_TO, 0.38f, 0, 0.71f, 0.14f, 0.98f, 0.41f,
-R_CUBIC_TO, 0.27f, 0.27f, 0.4f, 0.59f, 0.4f, 0.98f,
-V_LINE_TO, 13.94f,
-R_CUBIC_TO, 0, 0.38f, -0.13f, 0.71f, -0.4f, 0.98f,
-R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.41f, -0.98f, 0.41f,
+MOVE_TO, 4.54f, 15.49f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, -0.48f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.48f, -1.16f,
+V_LINE_TO, 2.14f,
+R_CUBIC_TO, 0, -0.45f, 0.16f, -0.84f, 0.48f, -1.16f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, 1.16f, -0.48f,
+R_H_LINE_TO, 6.91f,
+R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f,
+R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.7f, 0.48f, 1.16f,
+R_V_LINE_TO, 11.72f,
+R_CUBIC_TO, 0, 0.45f, -0.16f, 0.84f, -0.48f, 1.16f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, 0.48f,
 CLOSE,
-R_MOVE_TO, 0, -2.18f,
+R_MOVE_TO, 0, -2.43f,
 R_V_LINE_TO, 0.8f,
-R_H_LINE_TO, 7.08f,
+R_H_LINE_TO, 6.91f,
 R_V_LINE_TO, -0.8f,
 CLOSE,
 R_MOVE_TO, 0, -1.2f,
-R_H_LINE_TO, 7.08f,
-V_LINE_TO, 4.06f,
-H_LINE_TO, 4.46f,
+R_H_LINE_TO, 6.91f,
+V_LINE_TO, 4.14f,
+H_LINE_TO, 4.54f,
 CLOSE,
-R_MOVE_TO, 0, -9.08f,
-R_H_LINE_TO, 7.08f,
+R_MOVE_TO, 0, -8.92f,
+R_H_LINE_TO, 6.91f,
 R_V_LINE_TO, -0.8f,
-H_LINE_TO, 4.46f,
+H_LINE_TO, 4.54f,
 CLOSE,
 R_MOVE_TO, 0, 0,
 R_V_LINE_TO, -0.8f,
 CLOSE,
-R_MOVE_TO, 0, 10.28f,
+R_MOVE_TO, 0, 10.12f,
 R_V_LINE_TO, 0.8f,
-CLOSE,
-R_MOVE_TO, 0, 0,
 CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/search_menu.icon b/chrome/app/vector_icons/search_menu.icon
index 062a034..363fed82 100644
--- a/chrome/app/vector_icons/search_menu.icon
+++ b/chrome/app/vector_icons/search_menu.icon
@@ -3,43 +3,43 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-R_MOVE_TO, 9.69f, 13.15f,
-R_LINE_TO, 1.38f, 1.38f,
-H_LINE_TO, 4.45f,
-R_CUBIC_TO, -0.38f, 0, -0.71f, -0.13f, -0.98f, -0.4f,
-R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.98f,
-V_LINE_TO, 2.85f,
-R_CUBIC_TO, 0, -0.38f, 0.13f, -0.71f, 0.4f, -0.98f,
-R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.4f, 0.98f, -0.4f,
-R_H_LINE_TO, 5.21f,
-R_LINE_TO, 3.28f, 3.28f,
-R_V_LINE_TO, 7.99f,
-R_CUBIC_TO, 0, 0.41f, -0.04f, 0.73f, -0.11f, 0.95f,
-R_CUBIC_TO, -0.07f, 0.22f, -0.18f, 0.38f, -0.33f, 0.49f,
-LINE_TO, 9.25f, 10.92f,
-R_ARC_TO, 1.76f, 1.76f, 0, 0, 1, -0.57f, 0.25f,
-R_CUBIC_TO, -0.21f, 0.05f, -0.44f, 0.07f, -0.68f, 0.07f,
-R_ARC_TO, 2.38f, 2.38f, 0, 0, 1, -1.75f, -0.72f,
-R_CUBIC_TO, -0.48f, -0.48f, -0.72f, -1.06f, -0.72f, -1.75f,
-R_CUBIC_TO, 0, -0.69f, 0.24f, -1.27f, 0.72f, -1.75f,
-ARC_TO, 2.39f, 2.39f, 0, 0, 1, 8, 6.3f,
-R_CUBIC_TO, 0.69f, 0, 1.27f, 0.24f, 1.75f, 0.72f,
-R_CUBIC_TO, 0.48f, 0.48f, 0.72f, 1.06f, 0.72f, 1.75f,
-R_CUBIC_TO, 0, 0.25f, -0.03f, 0.47f, -0.09f, 0.69f,
+R_MOVE_TO, 9.45f, 13.09f,
+R_LINE_TO, 1.63f, 1.63f,
+H_LINE_TO, 4.51f,
+R_CUBIC_TO, -0.45f, 0, -0.84f, -0.16f, -1.16f, -0.47f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.48f, -1.16f,
+V_LINE_TO, 2.91f,
+R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.48f, -1.16f,
+R_ARC_TO, 1.57f, 1.57f, 0, 0, 1, 1.16f, -0.47f,
+H_LINE_TO, 9.73f,
+R_LINE_TO, 3.39f, 3.39f,
+R_V_LINE_TO, 8.07f,
+R_CUBIC_TO, 0, 0.44f, -0.05f, 0.78f, -0.14f, 1.02f,
+R_CUBIC_TO, -0.09f, 0.25f, -0.23f, 0.43f, -0.41f, 0.56f,
+R_LINE_TO, -3.28f, -3.3f,
+R_CUBIC_TO, -0.17f, 0.12f, -0.36f, 0.2f, -0.58f, 0.25f,
+R_CUBIC_TO, -0.21f, 0.05f, -0.45f, 0.07f, -0.71f, 0.07f,
+R_CUBIC_TO, -0.72f, 0, -1.33f, -0.25f, -1.83f, -0.74f,
+R_CUBIC_TO, -0.49f, -0.5f, -0.74f, -1.11f, -0.74f, -1.83f,
+R_CUBIC_TO, 0, -0.72f, 0.25f, -1.33f, 0.74f, -1.82f,
+R_CUBIC_TO, 0.5f, -0.5f, 1.11f, -0.75f, 1.83f, -0.75f,
+R_CUBIC_TO, 0.72f, 0, 1.33f, 0.25f, 1.83f, 0.75f,
+R_CUBIC_TO, 0.49f, 0.49f, 0.74f, 1.1f, 0.74f, 1.83f,
+R_ARC_TO, 2.8f, 2.8f, 0, 0, 1, -0.09f, 0.73f,
 R_CUBIC_TO, -0.06f, 0.22f, -0.14f, 0.41f, -0.25f, 0.57f,
-R_LINE_TO, 1.41f, 1.4f,
+R_LINE_TO, 1.25f, 1.22f,
 V_LINE_TO, 5.3f,
-LINE_TO, 9.1f, 2.85f,
-H_LINE_TO, 4.45f,
-R_V_LINE_TO, 10.3f,
+LINE_TO, 9.1f, 2.91f,
+R_H_LINE_TO, -4.59f,
+R_V_LINE_TO, 10.17f,
 CLOSE,
-MOVE_TO, 8, 9.92f,
-R_CUBIC_TO, 0.32f, 0, 0.59f, -0.12f, 0.81f, -0.35f,
-R_CUBIC_TO, 0.22f, -0.23f, 0.34f, -0.56f, 0.34f, -0.96f,
-R_CUBIC_TO, 0, -0.24f, -0.11f, -0.47f, -0.34f, -0.68f,
-R_ARC_TO, 1.17f, 1.17f, 0, 0, 0, -0.82f, -0.31f,
-R_CUBIC_TO, -0.32f, 0, -0.59f, 0.11f, -0.81f, 0.31f,
-R_CUBIC_TO, -0.22f, 0.21f, -0.34f, 0.43f, -0.34f, 0.68f,
-R_CUBIC_TO, 0, 0.41f, 0.11f, 0.73f, 0.34f, 0.96f,
-R_CUBIC_TO, 0.23f, 0.24f, 0.5f, 0.35f, 0.82f, 0.35f,
+R_MOVE_TO, -1.45f, -3.23f,
+R_CUBIC_TO, 0.31f, 0, 0.56f, -0.11f, 0.77f, -0.32f,
+R_CUBIC_TO, 0.21f, -0.21f, 0.31f, -0.47f, 0.31f, -0.78f,
+R_CUBIC_TO, 0, -0.3f, -0.11f, -0.56f, -0.32f, -0.77f,
+R_ARC_TO, 1.06f, 1.06f, 0, 0, 0, -0.77f, -0.31f,
+R_CUBIC_TO, -0.3f, 0, -0.56f, 0.11f, -0.77f, 0.32f,
+R_CUBIC_TO, -0.21f, 0.21f, -0.31f, 0.47f, -0.31f, 0.77f,
+R_CUBIC_TO, 0, 0.3f, 0.11f, 0.56f, 0.32f, 0.77f,
+R_CUBIC_TO, 0.21f, 0.21f, 0.47f, 0.31f, 0.77f, 0.31f,
 CLOSE
diff --git a/chrome/app/vector_icons/sync_refresh.icon b/chrome/app/vector_icons/sync_refresh.icon
index 48f16bc..2024902d 100644
--- a/chrome/app/vector_icons/sync_refresh.icon
+++ b/chrome/app/vector_icons/sync_refresh.icon
@@ -3,42 +3,40 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 3.61f, 12.88f,
-V_LINE_TO, 11.62f,
-R_H_LINE_TO, 1.1f,
-R_LINE_TO, 0.05f, 0.04f,
-R_ARC_TO, 5.3f, 5.3f, 0, 0, 1, -1.21f, -1.63f,
-ARC_TO, 4.57f, 4.57f, 0, 0, 1, 3.1f, 8,
-R_CUBIC_TO, 0, -1.16f, 0.36f, -2.18f, 1.08f, -3.06f,
-R_ARC_TO, 4.88f, 4.88f, 0, 0, 1, 2.72f, -1.7f,
-R_V_LINE_TO, 1.43f,
-R_ARC_TO, 3.49f, 3.49f, 0, 0, 0, -1.73f, 1.25f,
-R_CUBIC_TO, -0.45f, 0.6f, -0.68f, 1.29f, -0.68f, 2.07f,
-R_CUBIC_TO, 0, 0.52f, 0.11f, 1, 0.32f, 1.44f,
-R_CUBIC_TO, 0.22f, 0.45f, 0.5f, 0.83f, 0.86f, 1.14f,
-R_LINE_TO, -0.03f, -0.03f,
-V_LINE_TO, 9.6f,
-R_H_LINE_TO, 1.26f,
-R_V_LINE_TO, 3.28f,
+MOVE_TO, 3.62f, 12.99f,
+R_V_LINE_TO, -1.34f,
+R_H_LINE_TO, 0.93f,
+R_LINE_TO, 0.12f, 0.09f,
+R_ARC_TO, 5.92f, 5.92f, 0, 0, 1, -1.23f, -1.68f,
+ARC_TO, 4.62f, 4.62f, 0, 0, 1, 2.96f, 8,
+R_CUBIC_TO, 0, -1.22f, 0.39f, -2.29f, 1.17f, -3.2f,
+R_ARC_TO, 5.07f, 5.07f, 0, 0, 1, 2.91f, -1.73f,
+R_V_LINE_TO, 1.68f,
+R_CUBIC_TO, -0.71f, 0.2f, -1.29f, 0.59f, -1.75f, 1.19f,
+ARC_TO, 3.28f, 3.28f, 0, 0, 0, 4.6f, 8,
+R_CUBIC_TO, 0, 0.5f, 0.11f, 0.96f, 0.31f, 1.38f,
+R_CUBIC_TO, 0.21f, 0.43f, 0.48f, 0.8f, 0.82f, 1.11f,
+R_LINE_TO, -0.07f, -0.07f,
+R_V_LINE_TO, -0.81f,
+R_H_LINE_TO, 1.34f,
+R_V_LINE_TO, 3.39f,
 CLOSE,
-R_MOVE_TO, 5.49f, -0.12f,
-R_V_LINE_TO, -1.43f,
-R_ARC_TO, 3.49f, 3.49f, 0, 0, 0, 1.73f, -1.25f,
-R_CUBIC_TO, 0.45f, -0.6f, 0.68f, -1.29f, 0.68f, -2.07f,
-R_CUBIC_TO, 0, -0.52f, -0.11f, -1, -0.32f, -1.44f,
-R_ARC_TO, 3.61f, 3.61f, 0, 0, 0, -0.85f, -1.14f,
-R_LINE_TO, 0.03f, 0.03f,
-R_V_LINE_TO, 0.95f,
-H_LINE_TO, 9.12f,
-V_LINE_TO, 3.12f,
-R_H_LINE_TO, 3.27f,
-V_LINE_TO, 4.38f,
-R_H_LINE_TO, -1.1f,
-R_LINE_TO, -0.05f, -0.04f,
-R_CUBIC_TO, 0.51f, 0.46f, 0.91f, 1, 1.21f, 1.63f,
-R_CUBIC_TO, 0.3f, 0.63f, 0.45f, 1.31f, 0.45f, 2.04f,
-R_CUBIC_TO, 0, 1.16f, -0.36f, 2.18f, -1.08f, 3.06f,
-R_ARC_TO, 4.88f, 4.88f, 0, 0, 1, -2.72f, 1.7f,
-CLOSE,
-R_MOVE_TO, 0, 0,
+R_MOVE_TO, 5.35f, -0.06f,
+R_V_LINE_TO, -1.68f,
+R_CUBIC_TO, 0.71f, -0.2f, 1.29f, -0.59f, 1.75f, -1.19f,
+ARC_TO, 3.28f, 3.28f, 0, 0, 0, 11.4f, 8,
+R_CUBIC_TO, 0, -0.5f, -0.1f, -0.96f, -0.31f, -1.38f,
+R_ARC_TO, 3.57f, 3.57f, 0, 0, 0, -0.82f, -1.1f,
+R_LINE_TO, 0.07f, 0.07f,
+R_V_LINE_TO, 0.81f,
+R_H_LINE_TO, -1.34f,
+V_LINE_TO, 3.01f,
+R_H_LINE_TO, 3.38f,
+R_V_LINE_TO, 1.34f,
+R_H_LINE_TO, -0.93f,
+R_LINE_TO, -0.12f, -0.09f,
+R_CUBIC_TO, 0.52f, 0.47f, 0.93f, 1.03f, 1.24f, 1.67f,
+R_CUBIC_TO, 0.31f, 0.64f, 0.46f, 1.33f, 0.46f, 2.07f,
+R_CUBIC_TO, 0, 1.22f, -0.39f, 2.29f, -1.16f, 3.2f,
+R_ARC_TO, 5.07f, 5.07f, 0, 0, 1, -2.91f, 1.73f,
 CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/task_manager.icon b/chrome/app/vector_icons/task_manager.icon
index 49f1ee9..3ac5ba0 100644
--- a/chrome/app/vector_icons/task_manager.icon
+++ b/chrome/app/vector_icons/task_manager.icon
@@ -3,39 +3,37 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 13.15f, 13.73f,
-H_LINE_TO, 3.65f,
-R_CUBIC_TO, -0.37f, 0, -0.7f, -0.14f, -0.97f, -0.41f,
-R_ARC_TO, 1.33f, 1.33f, 0, 0, 1, -0.41f, -0.97f,
-V_LINE_TO, 3.65f,
-R_CUBIC_TO, 0, -0.38f, 0.14f, -0.71f, 0.41f, -0.98f,
-R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.4f, 0.97f, -0.4f,
-R_H_LINE_TO, 9.5f,
-R_CUBIC_TO, 0.38f, 0, 0.7f, 0.13f, 0.97f, 0.4f,
-R_CUBIC_TO, 0.27f, 0.27f, 0.41f, 0.6f, 0.41f, 0.98f,
-R_V_LINE_TO, 8.7f,
-R_CUBIC_TO, 0, 0.38f, -0.14f, 0.7f, -0.41f, 0.97f,
-R_ARC_TO, 1.33f, 1.33f, 0, 0, 1, -0.97f, 0.41f,
+MOVE_TO, 13.09f, 13.92f,
+H_LINE_TO, 3.72f,
+R_CUBIC_TO, -0.45f, 0, -0.83f, -0.16f, -1.16f, -0.48f,
+R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -0.48f, -1.16f,
+R_V_LINE_TO, -8.57f,
+R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.48f, -1.16f,
+R_ARC_TO, 1.6f, 1.6f, 0, 0, 1, 1.16f, -0.48f,
+R_H_LINE_TO, 9.37f,
+R_CUBIC_TO, 0.45f, 0, 0.83f, 0.16f, 1.15f, 0.48f,
+R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.7f, 0.48f, 1.16f,
+R_V_LINE_TO, 8.57f,
+R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.16f,
+R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.15f, 0.48f,
 CLOSE,
-MOVE_TO, 3.65f, 5.41f,
-R_H_LINE_TO, 9.5f,
-V_LINE_TO, 3.65f,
-H_LINE_TO, 3.65f,
+MOVE_TO, 3.72f, 5.43f,
+R_H_LINE_TO, 9.37f,
+V_LINE_TO, 3.72f,
+R_H_LINE_TO, -9.37f,
 CLOSE,
-R_MOVE_TO, 1.7f, 1.2f,
-H_LINE_TO, 3.65f,
-R_V_LINE_TO, 5.74f,
-R_H_LINE_TO, 1.7f,
+R_MOVE_TO, 1.66f, 1.2f,
+H_LINE_TO, 3.72f,
+R_V_LINE_TO, 5.66f,
+R_H_LINE_TO, 1.66f,
 CLOSE,
-R_MOVE_TO, 6.09f, 0,
-R_V_LINE_TO, 5.74f,
-R_H_LINE_TO, 1.71f,
-V_LINE_TO, 6.61f,
+R_MOVE_TO, 6.04f, 0,
+R_V_LINE_TO, 5.66f,
+R_H_LINE_TO, 1.67f,
+V_LINE_TO, 6.63f,
 CLOSE,
 R_MOVE_TO, -1.2f, 0,
-H_LINE_TO, 6.56f,
-R_V_LINE_TO, 5.74f,
-R_H_LINE_TO, 3.69f,
-CLOSE,
-R_MOVE_TO, 0, 0,
+H_LINE_TO, 6.58f,
+R_V_LINE_TO, 5.66f,
+R_H_LINE_TO, 3.64f,
 CLOSE
\ No newline at end of file
diff --git a/chrome/app/vector_icons/trash_can_refresh.icon b/chrome/app/vector_icons/trash_can_refresh.icon
index bcdd39d2..b85b647 100644
--- a/chrome/app/vector_icons/trash_can_refresh.icon
+++ b/chrome/app/vector_icons/trash_can_refresh.icon
@@ -3,38 +3,38 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 5.16f, 13.73f,
-R_CUBIC_TO, -0.38f, 0, -0.71f, -0.13f, -0.98f, -0.4f,
-R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.98f,
-V_LINE_TO, 4.45f,
-R_H_LINE_TO, -0.89f,
-V_LINE_TO, 3.06f,
-R_H_LINE_TO, 3.43f,
-R_V_LINE_TO, -0.89f,
-R_H_LINE_TO, 3.38f,
-R_V_LINE_TO, 0.89f,
-R_H_LINE_TO, 3.43f,
-R_V_LINE_TO, 1.39f,
-R_H_LINE_TO, -0.89f,
-R_V_LINE_TO, 7.9f,
-R_CUBIC_TO, 0, 0.39f, -0.13f, 0.72f, -0.4f, 0.99f,
-R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.4f, -0.98f, 0.4f,
+MOVE_TO, 5.1f, 13.92f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, -0.48f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.47f, -1.16f,
+V_LINE_TO, 4.5f,
+R_H_LINE_TO, -1.02f,
+V_LINE_TO, 2.87f,
+R_H_LINE_TO, 3.74f,
+V_LINE_TO, 1.86f,
+R_H_LINE_TO, 3.61f,
+R_V_LINE_TO, 1.02f,
+R_H_LINE_TO, 3.76f,
+R_V_LINE_TO, 1.63f,
+R_H_LINE_TO, -1.02f,
+R_V_LINE_TO, 7.78f,
+R_CUBIC_TO, 0, 0.46f, -0.16f, 0.85f, -0.47f, 1.17f,
+R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -1.16f, 0.47f,
 CLOSE,
-R_MOVE_TO, 5.69f, -9.29f,
-H_LINE_TO, 5.16f,
-R_V_LINE_TO, 7.91f,
-R_H_LINE_TO, 5.69f,
+R_MOVE_TO, 5.8f, -9.42f,
+H_LINE_TO, 5.1f,
+R_V_LINE_TO, 7.78f,
+R_H_LINE_TO, 5.8f,
 CLOSE,
-R_MOVE_TO, -4.52f, 6.75f,
-R_H_LINE_TO, 1.29f,
-V_LINE_TO, 5.6f,
-H_LINE_TO, 6.33f,
+MOVE_TO, 6.23f, 11.19f,
+R_H_LINE_TO, 1.42f,
+V_LINE_TO, 5.59f,
+H_LINE_TO, 6.23f,
 CLOSE,
-R_MOVE_TO, 2.05f, 0,
-R_H_LINE_TO, 1.29f,
-V_LINE_TO, 5.6f,
-H_LINE_TO, 8.38f,
+R_MOVE_TO, 2.12f, 0,
+H_LINE_TO, 9.77f,
+V_LINE_TO, 5.59f,
+H_LINE_TO, 8.35f,
 CLOSE,
-R_MOVE_TO, -3.22f, -6.75f,
-R_V_LINE_TO, 7.91f,
-CLOSE
+MOVE_TO, 5.1f, 4.5f,
+R_V_LINE_TO, 7.78f,
+CLOSE
\ No newline at end of file
diff --git a/chrome/browser/3pcd/heuristics/opener_heuristic_browsertest.cc b/chrome/browser/3pcd/heuristics/opener_heuristic_browsertest.cc
index 42bfe16a..19dc915 100644
--- a/chrome/browser/3pcd/heuristics/opener_heuristic_browsertest.cc
+++ b/chrome/browser/3pcd/heuristics/opener_heuristic_browsertest.cc
@@ -393,18 +393,23 @@
   GetDipsService()->storage()->FlushPostedTasksForTesting();
 
   // Assert that the UKM events and DIPS entries were recorded.
+  int64_t access_id;
   ASSERT_EQ(
       ukm_recorder.GetEntriesByName("OpenerHeuristic.PopupPastInteraction")
           .size(),
       1u);
-  ASSERT_EQ(ukm_recorder.GetEntriesByName("OpenerHeuristic.TopLevel").size(),
-            1u);
+  auto top_level_entries =
+      ukm_recorder.GetEntries("OpenerHeuristic.TopLevel", {"AccessId"});
+  ASSERT_EQ(top_level_entries.size(), 1u);
+  EXPECT_EQ(
+      ukm_recorder.GetSourceForSourceId(top_level_entries[0].source_id)->url(),
+      opener_url);
+  access_id = top_level_entries[0].metrics["AccessId"];
 
-  int64_t access_id;
   base::OnceCallback<void(absl::optional<PopupsStateValue>)> assert_popup =
       base::BindLambdaForTesting([&](absl::optional<PopupsStateValue> state) {
         ASSERT_TRUE(state.has_value());
-        access_id = state->access_id;
+        EXPECT_EQ(access_id, static_cast<int64_t>(state->access_id));
       });
   GetDipsService()
       ->storage()
@@ -561,17 +566,22 @@
   GetDipsService()->storage()->FlushPostedTasksForTesting();
 
   // Assert that the UKM events and DIPS entries were recorded.
+  int64_t access_id;
   ASSERT_EQ(
       ukm_recorder.GetEntriesByName("OpenerHeuristic.PopupInteraction").size(),
       1u);
-  ASSERT_EQ(ukm_recorder.GetEntriesByName("OpenerHeuristic.TopLevel").size(),
-            1u);
+  auto top_level_entries =
+      ukm_recorder.GetEntries("OpenerHeuristic.TopLevel", {"AccessId"});
+  ASSERT_EQ(top_level_entries.size(), 1u);
+  EXPECT_EQ(
+      ukm_recorder.GetSourceForSourceId(top_level_entries[0].source_id)->url(),
+      opener_url);
+  access_id = top_level_entries[0].metrics["AccessId"];
 
-  int64_t access_id;
   base::OnceCallback<void(absl::optional<PopupsStateValue>)> assert_popup =
       base::BindLambdaForTesting([&](absl::optional<PopupsStateValue> state) {
         ASSERT_TRUE(state.has_value());
-        access_id = state->access_id;
+        EXPECT_EQ(access_id, static_cast<int64_t>(state->access_id));
       });
   GetDipsService()
       ->storage()
diff --git a/chrome/browser/3pcd/heuristics/opener_heuristic_tab_helper.cc b/chrome/browser/3pcd/heuristics/opener_heuristic_tab_helper.cc
index 2551c28..c43bf02 100644
--- a/chrome/browser/3pcd/heuristics/opener_heuristic_tab_helper.cc
+++ b/chrome/browser/3pcd/heuristics/opener_heuristic_tab_helper.cc
@@ -307,7 +307,10 @@
     return;
   }
 
+  uint64_t access_id = base::RandUint64();
+
   ukm::builders::OpenerHeuristic_TopLevel(opener_source_id_)
+      .SetAccessId(access_id)
       .SetHasSameSiteIframe(static_cast<int64_t>(has_iframe))
       .SetPopupProvider(static_cast<int64_t>(GetPopupProvider(initial_url_)))
       .SetPopupId(popup_id_)
@@ -325,7 +328,7 @@
   dips->storage()
       ->AsyncCall(&DIPSStorage::WritePopup)
       .WithArgs(GetSiteForDIPS(opener_url_), GetSiteForDIPS(popup_url),
-                /*access_id=*/base::RandUint64(),
+                access_id,
                 /*popup_time=*/GetClock()->Now())
       .Then(base::BindOnce([](bool succeeded) { DCHECK(succeeded); }));
 }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index b75bcba..dbf9ec4 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2746,6 +2746,8 @@
       "android/feedback/screenshot_task.cc",
       "android/flags/bad_flags_snackbar_manager.cc",
       "android/flags/bad_flags_snackbar_manager.h",
+      "android/flags/chrome_cached_flags.cc",
+      "android/flags/chrome_cached_flags.h",
       "android/foreign_session_helper.cc",
       "android/foreign_session_helper.h",
       "android/framebust_intervention/framebust_blocked_delegate_android.cc",
@@ -8005,7 +8007,6 @@
       "//chrome/browser/resources/chromeos/account_manager:css_wrapper_files",
       "//chrome/browser/resources/chromeos/account_manager:html_wrapper_files",
       "//chrome/browser/resources/chromeos/account_manager/components:html_wrapper_files",
-      "//chrome/browser/resources/chromeos/add_supervision:web_components",
       "//chrome/browser/resources/chromeos/arc_account_picker:web_components",
       "//chrome/browser/resources/chromeos/crostini_installer:html_wrapper_files",
       "//chrome/browser/resources/chromeos/crostini_upgrader:html_wrapper_files",
@@ -8019,7 +8020,6 @@
       "//chrome/browser/resources/chromeos/set_time_dialog:html_wrapper_files",
       "//chrome/browser/resources/chromeos/smb_shares:web_components",
       "//chrome/browser/resources/chromeos/vm:web_components",
-      "//chrome/browser/ui/webui/ash/add_supervision:mojo_bindings_js",
       "//chrome/browser/ui/webui/ash/crostini_installer:mojo_bindings_js",
       "//chrome/browser/ui/webui/ash/crostini_upgrader:mojo_bindings_js",
       "//chrome/browser/ui/webui/ash/parent_access:mojo_bindings_js",
diff --git a/chrome/browser/android/customtabs/branding/BUILD.gn b/chrome/browser/android/customtabs/branding/BUILD.gn
index 901a51c..c00ff353 100644
--- a/chrome/browser/android/customtabs/branding/BUILD.gn
+++ b/chrome/browser/android/customtabs/branding/BUILD.gn
@@ -40,6 +40,7 @@
   sources = [
     "java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingCheckerUnitTest.java",
     "java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingControllerUnitTest.java",
+    "java/src/org/chromium/chrome/browser/customtabs/features/branding/SharedPreferencesBrandingTimeStorageUnitTest.java",
   ]
 
   deps = [
diff --git a/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingChecker.java b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingChecker.java
index f177a1e7..9002f452 100644
--- a/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingChecker.java
+++ b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingChecker.java
@@ -5,10 +5,13 @@
 package org.chromium.chrome.browser.customtabs.features.branding;
 
 import android.os.SystemClock;
+import android.text.TextUtils;
 
+import androidx.annotation.IntDef;
 import androidx.annotation.MainThread;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
 import androidx.annotation.WorkerThread;
 
 import org.chromium.base.Callback;
@@ -17,10 +20,24 @@
 import org.chromium.base.task.AsyncTask;
 
 /**
- * Class that maintain the data for the client app package name -> last time branding is shown.
+ * Class that maintain the data for the client app id -> last time branding is shown.
  */
 class BrandingChecker extends AsyncTask<Integer> {
     public static final int BRANDING_TIME_NOT_FOUND = -1;
+
+    // These values are persisted to logs. Entries should not be renumbered and numeric values
+    // should never be reused.
+    @IntDef({BrandingAppIdType.INVALID, BrandingAppIdType.PACKAGE_NAME, BrandingAppIdType.REFERRER,
+            BrandingAppIdType.NUM_ENTRIES})
+    @interface BrandingAppIdType {
+        int INVALID = 0;
+        int PACKAGE_NAME = 1;
+        int REFERRER = 2;
+
+        // Must be the last one.
+        int NUM_ENTRIES = 3;
+    }
+
     /**
      * Interface BrandingChecked used to fetch branding information.
      * If the storage involves any worker thread operation (e.g. Disk I/O), the storage impl has
@@ -31,45 +48,44 @@
          * Return the last time branding was shown for given embedded app. If not found, return
          * {@link BrandingChecker#BRANDING_TIME_NOT_FOUND}.
          *
-         * @param packageName Package name of CCT embedded app.
+         * @param appId ID of CCT embedded app.
          * @return Timestamp when CCT branding was last shown.
          * */
         @WorkerThread
-        long get(String packageName);
+        long get(String appId);
 
         /**
          * Record the timestamp when CCT branding was last shown.
          *
-         * @param packageName Package name of CCT embedded app.
+         * @param appId ID of CCT embedded app.
          * @param brandingLaunchTime Timestamp when CCT branding was last shown.
          * */
         @MainThread
-        void put(String packageName, long brandingLaunchTime);
+        void put(String appId, long brandingLaunchTime);
     }
 
-    private final String mPackageName;
+    private final String mAppId;
     private final long mBrandingCadence;
     @BrandingDecision
     private final Callback<Integer> mBrandingCheckCallback;
     @BrandingDecision
     private final int mDefaultBrandingDecision;
 
-    private @Nullable Boolean mIsPackageValid;
     private BrandingLaunchTimeStorage mStorage;
 
     /**
      * Create a BrandingChecker used to fetch BrandingDecision.
-     * @param packageName Package name of Embedded app.
+     * @param appId ID of Embedded app.
      * @param storage Storage option that used to retrieve branding information.
      * @param brandingCheckCallback Callback that will executed when branding check is complete.
      * @param brandingCadence The minimum time required to show another branding, to avoid overflow
      *                        clients with branding info.
      * @param defaultBrandingDecision Default branding decision when task is canceled.
      */
-    BrandingChecker(String packageName, BrandingLaunchTimeStorage storage,
+    BrandingChecker(String appId, BrandingLaunchTimeStorage storage,
             @NonNull @BrandingDecision Callback<Integer> brandingCheckCallback,
             long brandingCadence, @BrandingDecision int defaultBrandingDecision) {
-        mPackageName = packageName;
+        mAppId = appId;
         mStorage = storage;
         mBrandingCheckCallback = brandingCheckCallback;
         mBrandingCadence = brandingCadence;
@@ -82,16 +98,19 @@
         @BrandingDecision
         Integer brandingDecision = null;
         long startTime = SystemClock.elapsedRealtime();
-        mIsPackageValid = PackageUtils.isPackageInstalled(mPackageName);
-        if (mIsPackageValid) {
-            long timeLastBranding = mStorage.get(mPackageName);
+        if (!TextUtils.isEmpty(mAppId)) {
+            long timeLastBranding = mStorage.get(mAppId);
             brandingDecision = makeBrandingDecisionFromLaunchTime(startTime, timeLastBranding);
         }
-
+        @BrandingAppIdType
+        int appIdType = getAppIdType(mAppId);
+        boolean isPackageValid = appIdType == BrandingAppIdType.PACKAGE_NAME;
         RecordHistogram.recordTimesHistogram("CustomTabs.Branding.BrandingCheckDuration",
                 SystemClock.elapsedRealtime() - startTime);
+        RecordHistogram.recordEnumeratedHistogram(
+                "CustomTabs.Branding.AppIdType", appIdType, BrandingAppIdType.NUM_ENTRIES);
         RecordHistogram.recordBooleanHistogram(
-                "CustomTabs.Branding.IsPackageNameValid", mIsPackageValid);
+                "CustomTabs.Branding.IsPackageNameValid", isPackageValid);
 
         return brandingDecision;
     }
@@ -108,6 +127,13 @@
         onTaskFinished(null);
     }
 
+    @VisibleForTesting
+    static @BrandingAppIdType int getAppIdType(String appId) {
+        if (TextUtils.isEmpty(appId)) return BrandingAppIdType.INVALID;
+        if (PackageUtils.isPackageInstalled(appId)) return BrandingAppIdType.PACKAGE_NAME;
+        return BrandingAppIdType.REFERRER;
+    }
+
     private @BrandingDecision int makeBrandingDecisionFromLaunchTime(
             long startTime, long lastBrandingShowTime) {
         if (lastBrandingShowTime == BRANDING_TIME_NOT_FOUND) {
@@ -126,11 +152,9 @@
         }
         mBrandingCheckCallback.onResult(brandingDecision);
 
-        // Do not record branding time for invalid package name, or branding is not shown.
-        // TODO(https://crbug.com/1350658): Add short term storage option for invalid packages.
-        if (brandingDecision != BrandingDecision.NONE && mIsPackageValid != null
-                && mIsPackageValid) {
-            mStorage.put(mPackageName, taskFinishedTime);
+        // Do not record branding time for invalid app id, or branding is not shown.
+        if (brandingDecision != BrandingDecision.NONE && !TextUtils.isEmpty(mAppId)) {
+            mStorage.put(mAppId, taskFinishedTime);
         }
 
         RecordHistogram.recordEnumeratedHistogram("CustomTabs.Branding.BrandingDecision",
diff --git a/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingCheckerUnitTest.java b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingCheckerUnitTest.java
index bc16bf7..d1f1c23 100644
--- a/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingCheckerUnitTest.java
+++ b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingCheckerUnitTest.java
@@ -35,6 +35,7 @@
 import org.chromium.base.task.test.ShadowPostTask.TestImpl;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.chrome.browser.customtabs.features.branding.BrandingChecker.BrandingAppIdType;
 import org.chromium.chrome.browser.customtabs.features.branding.BrandingChecker.BrandingLaunchTimeStorage;
 
 import java.util.HashMap;
@@ -49,7 +50,7 @@
     private static final String PACKAGE_1 = "com.example.myapplication";
     private static final String PACKAGE_2 = "org.foo.bar";
     private static final String NEW_APPLICATION = "com.example.new.application";
-    private static final String INVALID_PACKAGE = "invalid.package";
+    private static final String INVALID_ID = "";
     private static final long TEST_BRANDING_CADENCE = 10;
     private static final long PACKAGE_1_BRANDING_SHOWN_SINCE_START = 2;
     private static final long PACKAGE_2_BRANDING_SHOWN_SINCE_START = 5;
@@ -152,20 +153,32 @@
     @Test
     public void testInvalidPackage() {
         CallbackDelegate callbackDelegate = new CallbackDelegate();
-        BrandingChecker checker = createBrandingChecker(INVALID_PACKAGE, callbackDelegate);
+        BrandingChecker checker = createBrandingChecker(INVALID_ID, callbackDelegate);
         checker.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
 
         mainLooper().idle();
         assertEquals("Package is invalid, BrandingDecision should be the test default. ",
                 BrandingDecision.TOAST, callbackDelegate.getBrandingDecision());
-        assertEquals("Branding time should not record for invalid package.", -1,
-                mStorage.get(INVALID_PACKAGE));
+        assertEquals(
+                "Branding time should not record for invalid id.", -1, mStorage.get(INVALID_ID));
 
         assertHistogramRecorded(/*decision*/ BrandingDecision.TOAST, /*isPackageValid*/ false,
                 /*isTaskCanceled*/ false);
     }
 
     @Test
+    public void testBrandingAppIdType() {
+        assertEquals(BrandingAppIdType.PACKAGE_NAME, BrandingChecker.getAppIdType(PACKAGE_1));
+        assertEquals(BrandingAppIdType.PACKAGE_NAME, BrandingChecker.getAppIdType(PACKAGE_2));
+
+        assertEquals(BrandingAppIdType.INVALID, BrandingChecker.getAppIdType(""));
+
+        // Package not installed. Regarded as referrer string.
+        assertEquals(BrandingAppIdType.REFERRER, BrandingChecker.getAppIdType("com.not.installed"));
+        assertEquals(BrandingAppIdType.REFERRER, BrandingChecker.getAppIdType("2//com.seedly"));
+    }
+
+    @Test
     public void testLongWaitingOnStorage() {
         CallbackDelegate callbackDelegate1 = new CallbackDelegate();
         CallbackDelegate callbackDelegate2 = new CallbackDelegate();
diff --git a/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingController.java b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingController.java
index 73aa522..15e6ac1 100644
--- a/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingController.java
+++ b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/BrandingController.java
@@ -81,7 +81,7 @@
             new OneshotSupplierImpl<>();
     private final BrandingChecker mBrandingChecker;
     private final Context mContext;
-    private final String mAppName;
+    private final String mBrowserName;
     private final boolean mEnableIconAnimation;
     @Nullable
     private final PureJavaExceptionReporter mExceptionReporter;
@@ -94,14 +94,14 @@
     /**
      * Branding controller responsible for showing branding.
      * @param context Context used to fetch package information for embedded app.
-     * @param packageName The package name for the embedded app.
-     * @param appName The appName shown on the branding toast.
+     * @param appId The ID for the embedded app.
+     * @param browserName The browser name shown on the branding toast.
      * @param exceptionReporter Optional reporter that reports wrong state quietly.
      */
-    public BrandingController(Context context, String packageName, String appName,
+    public BrandingController(Context context, String appId, String browserName,
             @Nullable PureJavaExceptionReporter exceptionReporter) {
         mContext = context;
-        mAppName = appName;
+        mBrowserName = browserName;
         mExceptionReporter = exceptionReporter;
         mEnableIconAnimation = ANIMATE_TOOLBAR_ICON_TRANSITION.getValue();
         mBrandingDecision.onAvailable(
@@ -110,7 +110,7 @@
                 ChromeFeatureList.sCctBrandTransparencyMemoryImprovement.isEnabled();
 
         // TODO(https://crbug.com/1350661): Start branding checker during CCT warm up.
-        mBrandingChecker = new BrandingChecker(packageName,
+        mBrandingChecker = new BrandingChecker(appId,
                 SharedPreferencesBrandingTimeStorage.getInstance(), mBrandingDecision::set,
                 BRANDING_CADENCE_MS.getValue(), BrandingDecision.TOAST);
         mBrandingChecker.executeWithTaskTraits(TaskTraits.USER_VISIBLE_MAY_BLOCK);
@@ -192,7 +192,7 @@
         }
 
         String toastText = mContext.getResources().getString(
-                R.string.twa_running_in_chrome_template, mAppName);
+                R.string.twa_running_in_chrome_template, mBrowserName);
         TextView runInChromeTextView = (TextView) LayoutInflater.from(mContext).inflate(
                 R.layout.custom_tabs_toast_branding_layout, null, false);
         runInChromeTextView.setText(toastText);
diff --git a/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/SharedPreferencesBrandingTimeStorage.java b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/SharedPreferencesBrandingTimeStorage.java
index 94bd497..5df51da 100644
--- a/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/SharedPreferencesBrandingTimeStorage.java
+++ b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/SharedPreferencesBrandingTimeStorage.java
@@ -7,22 +7,29 @@
 import android.annotation.SuppressLint;
 import android.content.Context;
 import android.content.SharedPreferences;
+import android.text.TextUtils;
 
 import androidx.annotation.MainThread;
 import androidx.annotation.VisibleForTesting;
 import androidx.annotation.WorkerThread;
 
 import org.chromium.base.ContextUtils;
+import org.chromium.base.PackageUtils;
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.chrome.browser.util.HashUtil;
 
+import java.util.Map;
+
 /**
  * Shared preference that stores the last branding time for CCT client apps. When recording, the
  * instance uses {@link SharedPreferences.Editor#commit()}.
  */
 class SharedPreferencesBrandingTimeStorage implements BrandingChecker.BrandingLaunchTimeStorage {
     private static final String KEY_SHARED_PREF = "pref_cct_brand_show_time";
+    private static final String NON_PACKAGE_PREFIX = "REFERRER_";
+    @VisibleForTesting
+    static final int MAX_NON_PACKAGE_ENTRIES = 50;
 
     private static SharedPreferencesBrandingTimeStorage sInstance;
 
@@ -48,19 +55,51 @@
 
     @WorkerThread
     @Override
-    public long get(String packageName) {
-        return getSharedPref().getLong(hash(packageName), BrandingChecker.BRANDING_TIME_NOT_FOUND);
+    public long get(String appId) {
+        return getSharedPref().getLong(getKey(appId), BrandingChecker.BRANDING_TIME_NOT_FOUND);
     }
 
     @MainThread
     @Override
     @SuppressLint({"ApplySharedPref"})
-    public void put(String packageName, long brandingLaunchTime) {
+    public void put(String appId, long brandingLaunchTime) {
         PostTask.postTask(TaskTraits.USER_VISIBLE_MAY_BLOCK, () -> {
-            getSharedPref().edit().putLong(hash(packageName), brandingLaunchTime).commit();
+            SharedPreferences.Editor pref = getSharedPref().edit();
+            String entry = getOldEntryToTrim();
+            if (entry != null) pref.remove(entry);
+            pref.putLong(getKey(appId), brandingLaunchTime);
+            pref.commit();
         });
     }
 
+    private String getKey(String appId) {
+        assert !TextUtils.isEmpty(appId);
+        String key = hash(appId);
+        // Keys will have a prefix if they are not a valid package name. They are likely
+        // to be numerous, therefore the number of such entries will be kept under a
+        // given threshold. The prefix makes it easy to do the job.
+        if (!PackageUtils.isPackageInstalled(appId)) key = NON_PACKAGE_PREFIX + key;
+        return key;
+    }
+
+    @WorkerThread
+    private String getOldEntryToTrim() {
+        String oldEntry = null;
+        long oldTime = -1;
+        int count = 0;
+        for (Map.Entry<String, ?> entry : getSharedPref().getAll().entrySet()) {
+            String key = entry.getKey();
+            if (!key.startsWith(NON_PACKAGE_PREFIX)) continue;
+            count++;
+            long time = (long) entry.getValue();
+            if (oldTime < 0 || time < oldTime) {
+                oldEntry = entry.getKey();
+                oldTime = time;
+            }
+        }
+        return count >= MAX_NON_PACKAGE_ENTRIES ? oldEntry : null;
+    }
+
     /**
      * @return Size of the current shared preference. Should not run on main thread as we are
      * reading all the keys from disk.
@@ -86,4 +125,8 @@
         }
         return mSharedPref;
     }
+
+    void setSharedPrefForTesting(SharedPreferences pref) {
+        mSharedPref = pref;
+    }
 }
diff --git a/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/SharedPreferencesBrandingTimeStorageUnitTest.java b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/SharedPreferencesBrandingTimeStorageUnitTest.java
new file mode 100644
index 0000000..f0d7cf1
--- /dev/null
+++ b/chrome/browser/android/customtabs/branding/java/src/org/chromium/chrome/browser/customtabs/features/branding/SharedPreferencesBrandingTimeStorageUnitTest.java
@@ -0,0 +1,59 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.customtabs.features.branding;
+
+import static org.junit.Assert.assertEquals;
+
+import static org.chromium.chrome.browser.customtabs.features.branding.SharedPreferencesBrandingTimeStorage.MAX_NON_PACKAGE_ENTRIES;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.task.TaskTraits;
+import org.chromium.base.task.test.ShadowPostTask;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.InMemorySharedPreferences;
+
+import java.util.function.Function;
+
+/**
+ * Unit test for {@link SharedPreferencesBrandingTimeStorage}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, shadows = {ShadowPostTask.class})
+public class SharedPreferencesBrandingTimeStorageUnitTest {
+    @Before
+    public void setup() {
+        var shadowPostTaskImpl = new ShadowPostTask.TestImpl() {
+            @Override
+            public void postDelayedTask(@TaskTraits int taskTraits, Runnable task, long delay) {
+                task.run();
+            }
+        };
+        ShadowPostTask.setTestImpl(shadowPostTaskImpl);
+    }
+
+    @Test
+    public void nonPackageIdEntrySizeCapped() {
+        var storage = SharedPreferencesBrandingTimeStorage.getInstance();
+        storage.setSharedPrefForTesting(new InMemorySharedPreferences());
+        Function<Integer, Integer> brandingTime = (i) -> i * 10;
+        for (int i = 0; i < MAX_NON_PACKAGE_ENTRIES; ++i) {
+            storage.put("id-" + i, brandingTime.apply(i));
+        }
+        assertEquals(0, storage.get("id-0"), brandingTime.apply(0));
+        assertEquals("The number of entries can't be bigger than |MAX_NON_PACKAGE_ENTRIES|",
+                MAX_NON_PACKAGE_ENTRIES, storage.getSize());
+
+        storage.put("id-max+1", (MAX_NON_PACKAGE_ENTRIES + 1) * 10);
+        assertEquals("The number of entries can't be bigger than |MAX_NON_PACKAGE_ENTRIES|",
+                MAX_NON_PACKAGE_ENTRIES, storage.getSize());
+
+        // The oldest entry should be evicted.
+        assertEquals(BrandingChecker.BRANDING_TIME_NOT_FOUND, storage.get("id-0"));
+    }
+}
diff --git a/chrome/browser/flags/android/cached_feature_flags.cc b/chrome/browser/android/flags/chrome_cached_flags.cc
similarity index 73%
rename from chrome/browser/flags/android/cached_feature_flags.cc
rename to chrome/browser/android/flags/chrome_cached_flags.cc
index b0c2256..98de274 100644
--- a/chrome/browser/flags/android/cached_feature_flags.cc
+++ b/chrome/browser/android/flags/chrome_cached_flags.cc
@@ -1,10 +1,10 @@
-// Copyright 2014 The Chromium Authors
+// 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/flags/android/cached_feature_flags.h"
+#include "chrome/browser/android/flags/chrome_cached_flags.h"
 
-#include "chrome/browser/flags/jni_headers/CachedFeatureFlags_jni.h"
+#include "chrome/android/chrome_jni_headers/ChromeCachedFlags_jni.h"
 
 #include "base/android/jni_string.h"
 #include "base/feature_list.h"
@@ -21,13 +21,13 @@
   JNIEnv* env = base::android::AttachCurrentThread();
   ScopedJavaLocalRef<jstring> j_feature_name(
       ConvertUTF8ToJavaString(env, feature.name));
-  return Java_CachedFeatureFlags_isEnabled(env, j_feature_name);
+  return Java_ChromeCachedFlags_isEnabled(env, j_feature_name);
 }
 
 std::string GetReachedCodeProfilerTrialGroup() {
   JNIEnv* env = base::android::AttachCurrentThread();
   ScopedJavaLocalRef<jstring> group =
-      Java_CachedFeatureFlags_getReachedCodeProfilerTrialGroup(env);
+      Java_ChromeCachedFlags_getReachedCodeProfilerTrialGroup(env);
   return ConvertJavaStringToUTF8(env, group);
 }
 
diff --git a/chrome/browser/flags/android/cached_feature_flags.h b/chrome/browser/android/flags/chrome_cached_flags.h
similarity index 68%
rename from chrome/browser/flags/android/cached_feature_flags.h
rename to chrome/browser/android/flags/chrome_cached_flags.h
index aa961b2..9df2a9a 100644
--- a/chrome/browser/flags/android/cached_feature_flags.h
+++ b/chrome/browser/android/flags/chrome_cached_flags.h
@@ -1,9 +1,9 @@
-// Copyright 2014 The Chromium Authors
+// 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_FLAGS_ANDROID_CACHED_FEATURE_FLAGS_H_
-#define CHROME_BROWSER_FLAGS_ANDROID_CACHED_FEATURE_FLAGS_H_
+#ifndef CHROME_BROWSER_ANDROID_FLAGS_CHROME_CACHED_FLAGS_H_
+#define CHROME_BROWSER_ANDROID_FLAGS_CHROME_CACHED_FLAGS_H_
 
 #include <jni.h>
 
@@ -23,4 +23,4 @@
 }  // namespace android
 }  // namespace chrome
 
-#endif  // CHROME_BROWSER_FLAGS_ANDROID_CACHED_FEATURE_FLAGS_H_
+#endif  // CHROME_BROWSER_ANDROID_FLAGS_CHROME_CACHED_FLAGS_H_
diff --git a/chrome/browser/ash/privacy_hub/privacy_hub_util.cc b/chrome/browser/ash/privacy_hub/privacy_hub_util.cc
index daf20eb5b..65d2e595 100644
--- a/chrome/browser/ash/privacy_hub/privacy_hub_util.cc
+++ b/chrome/browser/ash/privacy_hub/privacy_hub_util.cc
@@ -7,9 +7,7 @@
 #include <string>
 
 #include "ash/public/cpp/privacy_hub_delegate.h"
-#include "ash/public/cpp/system_tray_client.h"
 #include "ash/shell.h"
-#include "ash/system/model/system_tray_model.h"
 #include "ash/system/privacy_hub/camera_privacy_switch_controller.h"
 #include "ash/system/privacy_hub/geolocation_privacy_switch_controller.h"
 #include "ash/system/privacy_hub/privacy_hub_controller.h"
@@ -107,10 +105,6 @@
   return camera_led_fallback_for_testing.value();
 }
 
-void OpenPrivacyControlsInSettings() {
-  Shell::Get()->system_tray_model()->client()->ShowPrivacyHubSettings();
-}
-
 ScopedCameraLedFallbackForTesting::ScopedCameraLedFallbackForTesting(
     bool value) {
   CHECK(!camera_led_fallback_for_testing.has_value());
diff --git a/chrome/browser/ash/privacy_hub/privacy_hub_util.h b/chrome/browser/ash/privacy_hub/privacy_hub_util.h
index 4075875..38e2f48 100644
--- a/chrome/browser/ash/privacy_hub/privacy_hub_util.h
+++ b/chrome/browser/ash/privacy_hub/privacy_hub_util.h
@@ -36,9 +36,6 @@
 // switch.
 bool UsingCameraLEDFallback();
 
-// Opens the Privacy Controls section in the OS settings.
-void OpenPrivacyControlsInSettings();
-
 // Used to override the value of the LED Fallback value in tests.
 // Should not be nested.
 // TODO(b/289510726): remove when all cameras fully support the software
diff --git a/chrome/browser/browser_resources.grd b/chrome/browser/browser_resources.grd
index 602c69e..6eb0244 100644
--- a/chrome/browser/browser_resources.grd
+++ b/chrome/browser/browser_resources.grd
@@ -194,11 +194,6 @@
         <include name="IDR_SYS_INTERNALS_IMAGE_CPU_SVG" file="resources\chromeos\sys_internals\img\cpu.svg" type="BINDATA" />
         <include name="IDR_SYS_INTERNALS_IMAGE_MEMORY_SVG" file="resources\chromeos\sys_internals\img\memory.svg" type="BINDATA" />
         <include name="IDR_SYS_INTERNALS_IMAGE_ZRAM_SVG" file="resources\chromeos\sys_internals\img\zram.svg" type="BINDATA" />
-        <include name="IDR_ADD_SUPERVISION_HTML" file="resources\chromeos\add_supervision\add_supervision.html" type="chrome_html" />
-        <include name="IDR_ADD_SUPERVISION_APP_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\add_supervision\add_supervision_app.js" use_base_dir="false" type="chrome_html" />
-        <include name="IDR_ADD_SUPERVISION_UI_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\add_supervision\add_supervision_ui.js" use_base_dir="false" type="chrome_html" />
-        <include name="IDR_ADD_SUPERVISION_API_SERVER_JS" file="resources\chromeos\add_supervision\add_supervision_api_server.js" type="BINDATA" />
-        <include name="IDR_ADD_SUPERVISION_MOJOM_WEBUI_JS" file="${root_gen_dir}\mojom-webui\chrome\browser\ui\webui\ash\add_supervision\add_supervision.mojom-webui.js" use_base_dir="false" type="BINDATA" />
         <include name="IDR_PARENT_ACCESS_HTML" file="resources\chromeos\parent_access\parent_access.html" type="chrome_html" />
         <include name="IDR_PARENT_ACCESS_APP_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\parent_access\parent_access_app.js" use_base_dir="false" type="BINDATA" />
         <include name="IDR_PARENT_ACCESS_TEMPLATE_JS" file="${root_gen_dir}\chrome\browser\resources\chromeos\parent_access\parent_access_template.js" use_base_dir="false" type="BINDATA" />
diff --git a/chrome/browser/browsing_data/browsing_data_model_browsertest.cc b/chrome/browser/browsing_data/browsing_data_model_browsertest.cc
index c4105ac9..efb2653 100644
--- a/chrome/browser/browsing_data/browsing_data_model_browsertest.cc
+++ b/chrome/browser/browsing_data/browsing_data_model_browsertest.cc
@@ -105,7 +105,7 @@
             {
               name: 'cars',
               owner: $1,
-              biddingLogicUrl: $2,
+              biddingLogicURL: $2,
               trustedBiddingSignalsUrl: $3,
               trustedBiddingSignalsKeys: ['key1'],
               userBiddingSignals: {some: 'json', data: {here: [1, 2, 3]}},
diff --git a/chrome/browser/chrome_browser_field_trials.cc b/chrome/browser/chrome_browser_field_trials.cc
index c8dc99cc..967ff19 100644
--- a/chrome/browser/chrome_browser_field_trials.cc
+++ b/chrome/browser/chrome_browser_field_trials.cc
@@ -32,8 +32,8 @@
 #include "base/android/build_info.h"
 #include "base/android/bundle_utils.h"
 #include "base/task/thread_pool/environment_config.h"
+#include "chrome/browser/android/flags/chrome_cached_flags.h"
 #include "chrome/browser/android/signin/fre_mobile_identity_consistency_field_trial.h"
-#include "chrome/browser/flags/android/cached_feature_flags.h"
 #include "chrome/browser/flags/android/chrome_feature_list.h"
 #include "chrome/common/chrome_features.h"
 #endif
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index f678a92..1eb294d 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -3584,7 +3584,7 @@
   return google_apis::GetAPIKey();
 }
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
 device::GeolocationManager*
 ChromeContentBrowserClient::GetGeolocationManager() {
   return device::GeolocationManager::GetInstance();
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h
index e75b4bc..46d348b 100644
--- a/chrome/browser/chrome_content_browser_client.h
+++ b/chrome/browser/chrome_content_browser_client.h
@@ -36,7 +36,6 @@
 #include "media/media_buildflags.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
-#include "services/device/public/cpp/geolocation/buildflags.h"
 #include "services/metrics/public/cpp/ukm_source_id.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -366,7 +365,7 @@
   network::mojom::NetworkContext* GetSystemNetworkContext() override;
   std::string GetGeolocationApiKey() override;
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
   device::GeolocationManager* GetGeolocationManager() override;
 #endif
 
diff --git a/chrome/browser/download/android/download_manager_service.cc b/chrome/browser/download/android/download_manager_service.cc
index daede616..d3656f3 100644
--- a/chrome/browser/download/android/download_manager_service.cc
+++ b/chrome/browser/download/android/download_manager_service.cc
@@ -20,6 +20,7 @@
 #include "base/time/time.h"
 #include "chrome/android/chrome_jni_headers/DownloadItem_jni.h"
 #include "chrome/android/chrome_jni_headers/DownloadManagerService_jni.h"
+#include "chrome/browser/android/flags/chrome_cached_flags.h"
 #include "chrome/browser/android/profile_key_startup_accessor.h"
 #include "chrome/browser/download/android/download_controller.h"
 #include "chrome/browser/download/android/download_startup_utils.h"
@@ -28,7 +29,6 @@
 #include "chrome/browser/download/android/service/download_task_scheduler.h"
 #include "chrome/browser/download/offline_item_utils.h"
 #include "chrome/browser/download/simple_download_manager_coordinator_factory.h"
-#include "chrome/browser/flags/android/cached_feature_flags.h"
 #include "chrome/browser/flags/android/chrome_feature_list.h"
 #include "chrome/browser/profiles/profile_android.h"
 #include "chrome/browser/profiles/profile_key.h"
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
index dea653ef..2f2c4ab 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -6651,7 +6651,7 @@
                                 navigator.joinAdInterestGroup({
                                   name: 'cars',
                                   owner: $1,
-                                  biddingLogicUrl: $2,
+                                  biddingLogicURL: $2,
                                   userBiddingSignals: [],
                                   ads: [{
                                     renderURL: 'https://example.com/render',
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
index 227968c..9884728 100644
--- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
+++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.cc
@@ -62,7 +62,6 @@
 #include "extensions/common/api/management.h"
 #include "extensions/common/extension.h"
 #include "extensions/common/extension_urls.h"
-#include "services/data_decoder/public/cpp/data_decoder.h"
 #include "third_party/blink/public/mojom/manifest/display_mode.mojom.h"
 #include "third_party/blink/public/mojom/window_features/window_features.mojom.h"
 
@@ -446,18 +445,6 @@
   return extensions::GetLaunchType(prefs, extension);
 }
 
-void ChromeManagementAPIDelegate::
-    GetPermissionWarningsByManifestFunctionDelegate(
-        extensions::ManagementGetPermissionWarningsByManifestFunction* function,
-        const std::string& manifest_str) const {
-  data_decoder::DataDecoder::ParseJsonIsolated(
-      manifest_str,
-      base::BindOnce(
-          &extensions::ManagementGetPermissionWarningsByManifestFunction::
-              OnParse,
-          function));
-}
-
 std::unique_ptr<extensions::InstallPromptDelegate>
 ChromeManagementAPIDelegate::SetEnabledFunctionDelegate(
     content::WebContents* web_contents,
diff --git a/chrome/browser/extensions/api/management/chrome_management_api_delegate.h b/chrome/browser/extensions/api/management/chrome_management_api_delegate.h
index 48c18d1..91da4eb 100644
--- a/chrome/browser/extensions/api/management/chrome_management_api_delegate.h
+++ b/chrome/browser/extensions/api/management/chrome_management_api_delegate.h
@@ -23,9 +23,6 @@
   extensions::LaunchType GetLaunchType(
       const extensions::ExtensionPrefs* prefs,
       const extensions::Extension* extension) const override;
-  void GetPermissionWarningsByManifestFunctionDelegate(
-      extensions::ManagementGetPermissionWarningsByManifestFunction* function,
-      const std::string& manifest_str) const override;
   std::unique_ptr<extensions::InstallPromptDelegate> SetEnabledFunctionDelegate(
       content::WebContents* web_contents,
       content::BrowserContext* browser_context,
diff --git a/chrome/browser/extensions/api/management/management_api_unittest.cc b/chrome/browser/extensions/api/management/management_api_unittest.cc
index 1ee9dcb2..1ac7fbf 100644
--- a/chrome/browser/extensions/api/management/management_api_unittest.cc
+++ b/chrome/browser/extensions/api/management/management_api_unittest.cc
@@ -865,9 +865,6 @@
                            const Extension* extension) const override {
     return LaunchType::LAUNCH_TYPE_DEFAULT;
   }
-  void GetPermissionWarningsByManifestFunctionDelegate(
-      ManagementGetPermissionWarningsByManifestFunction* function,
-      const std::string& manifest_str) const override {}
   std::unique_ptr<InstallPromptDelegate> SetEnabledFunctionDelegate(
       content::WebContents* web_contents,
       content::BrowserContext* browser_context,
@@ -905,6 +902,7 @@
   void SetLaunchType(content::BrowserContext* context,
                      const std::string& extension_id,
                      LaunchType launch_type) const override {}
+
   std::unique_ptr<AppForLinkDelegate> GenerateAppForLinkFunctionDelegate(
       ManagementGenerateAppForLinkFunction* function,
       content::BrowserContext* context,
diff --git a/chrome/browser/flags/BUILD.gn b/chrome/browser/flags/BUILD.gn
index b821912..8c65f7af 100644
--- a/chrome/browser/flags/BUILD.gn
+++ b/chrome/browser/flags/BUILD.gn
@@ -42,7 +42,6 @@
 
 generate_jni("jni_headers") {
   sources = [
-    "android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java",
     "android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureMap.java",
     "android/java/src/org/chromium/chrome/browser/flags/ChromeSessionState.java",
   ]
@@ -50,8 +49,6 @@
 
 static_library("flags_android") {
   sources = [
-    "android/cached_feature_flags.cc",
-    "android/cached_feature_flags.h",
     "android/chrome_session_state.cc",
     "android/chrome_session_state.h",
   ]
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
index d736b51..d7c35570 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlags.java
@@ -6,10 +6,6 @@
 
 import androidx.annotation.AnyThread;
 
-import org.chromium.base.ApplicationStatus;
-import org.chromium.base.FieldTrialList;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
 import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
 
@@ -28,8 +24,6 @@
  * - Add it to the list passed to {@code ChromeCachedFlags#cacheNativeFlags()}.
  * - Call {@code ChromeFeatureList.sMyFlag.isEnabled()} to query whether the cached flag is enabled.
  *   Consider this the source of truth for whether the flag is turned on in the current session.
- * - When querying whether a cached feature is enabled from native, call IsJavaDrivenFeatureEnabled
- *   in cached_feature_flags.h.
  *
  * For cached flags that are queried before native is initialized, when a new experiment
  * configuration is received the metrics reporting system will record metrics as if the
@@ -40,17 +34,6 @@
 public class CachedFeatureFlags {
     private static ValuesOverridden sValuesOverridden = new ValuesOverridden();
 
-    private static String sReachedCodeProfilerTrialGroup;
-
-    @CalledByNative
-    @AnyThread
-    static boolean isEnabled(String featureName) {
-        CachedFlag cachedFlag = ChromeFeatureList.sAllCachedFlags.get(featureName);
-        assert cachedFlag != null;
-
-        return cachedFlag.isEnabled();
-    }
-
     /**
      * Sets the feature flags to use in JUnit and instrumentation tests.
      *
@@ -74,32 +57,6 @@
     }
 
     /**
-     * Caches a predetermined list of flags that must take effect on startup but are set via native
-     * code.
-     *
-     * Do not add new simple boolean flags here, use {@link #cacheNativeFlags} instead.
-     */
-    public static void cacheAdditionalNativeFlags() {
-        CachedFlagsSafeMode.getInstance().cacheSafeModeForCachedFlagsEnabled();
-        cacheReachedCodeProfilerTrialGroup();
-
-        // Propagate REACHED_CODE_PROFILER feature value to LibraryLoader. This can't be done in
-        // LibraryLoader itself because it lives in //base and can't depend on ChromeFeatureList.
-        LibraryLoader.setReachedCodeProfilerEnabledOnNextRuns(
-                ChromeFeatureList.isEnabled(ChromeFeatureList.REACHED_CODE_PROFILER),
-                ChromeFeatureList.getFieldTrialParamByFeatureAsInt(
-                        ChromeFeatureList.REACHED_CODE_PROFILER, "sampling_interval_us", 0));
-
-        // Similarly, propagate the BACKGROUND_THREAD_POOL feature value to LibraryLoader.
-        LibraryLoader.setBackgroundThreadPoolEnabledOnNextRuns(
-                ChromeFeatureList.isEnabled(ChromeFeatureList.BACKGROUND_THREAD_POOL));
-
-        // Propagate the CACHE_ACTIVITY_TASKID feature value to ApplicationStatus.
-        ApplicationStatus.setCachingEnabled(
-                ChromeFeatureList.isEnabled(ChromeFeatureList.CACHE_ACTIVITY_TASKID));
-    }
-
-    /**
      * Caches flags that must take effect on startup but are set via native code.
      */
     public static void cacheFieldTrialParameters(List<CachedFieldTrialParameter> parameters) {
@@ -123,33 +80,6 @@
     }
 
     /**
-     * Caches the trial group of the reached code profiler feature to be using on next startup.
-     */
-    private static void cacheReachedCodeProfilerTrialGroup() {
-        // Make sure that the existing value is saved in a static variable before overwriting it.
-        if (sReachedCodeProfilerTrialGroup == null) {
-            getReachedCodeProfilerTrialGroup();
-        }
-
-        SharedPreferencesManager.getInstance().writeString(
-                ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP,
-                FieldTrialList.findFullName(ChromeFeatureList.REACHED_CODE_PROFILER));
-    }
-
-    /**
-     * @return The trial group of the reached code profiler.
-     */
-    @CalledByNative
-    public static String getReachedCodeProfilerTrialGroup() {
-        if (sReachedCodeProfilerTrialGroup == null) {
-            sReachedCodeProfilerTrialGroup = SharedPreferencesManager.getInstance().readString(
-                    ChromePreferenceKeys.REACHED_CODE_PROFILER_GROUP, "");
-        }
-
-        return sReachedCodeProfilerTrialGroup;
-    }
-
-    /**
      * Call when entering an initialization flow that should result in caching flags.
      */
     public static void onStartOrResumeCheckpoint() {
@@ -291,8 +221,4 @@
     static void setOverrideForTesting(String preferenceKey, String overrideValue) {
         sValuesOverridden.setOverrideForTesting(preferenceKey, overrideValue);
     }
-
-    static void setSafeModeExperimentEnabledForTesting(Boolean value) {
-        CachedFlagsSafeMode.getInstance().setExperimentEnabledForTesting(value);
-    }
 }
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsSafeModeUnitTest.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsSafeModeUnitTest.java
index 4bb5667..e59ca8b1 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsSafeModeUnitTest.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFeatureFlagsSafeModeUnitTest.java
@@ -71,13 +71,13 @@
 
     @Before
     public void setUp() {
-        CachedFeatureFlags.setSafeModeExperimentEnabledForTesting(true);
+        CachedFlagsSafeMode.getInstance().setExperimentEnabledForTesting(true);
         CachedFeatureFlags.resetFlagsForTesting();
     }
 
     @After
     public void tearDown() {
-        CachedFeatureFlags.setSafeModeExperimentEnabledForTesting(null);
+        CachedFlagsSafeMode.getInstance().setExperimentEnabledForTesting(null);
         CachedFeatureFlags.resetFlagsForTesting();
 
         FeatureList.setTestFeatures(null);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java
index 5931b1eb..938a83f 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/CachedFlagsSafeMode.java
@@ -34,7 +34,7 @@
  * Safe Mode is a mechanism that allows Chrome to prevent crashes gated behind flags used before
  * native from becoming a crash loop that cannot be recovered from by disabling the experiment.
  */
-class CachedFlagsSafeMode {
+public class CachedFlagsSafeMode {
     private static final String TAG = "Flags";
     private static final int CRASH_STREAK_TO_ENTER_SAFE_MODE = 2;
 
@@ -381,7 +381,7 @@
         }
     }
 
-    void cacheSafeModeForCachedFlagsEnabled() {
+    public static void cacheSafeModeForCachedFlagsEnabled() {
         SharedPreferencesManager.getInstance().writeBoolean(
                 ChromePreferenceKeys.FLAGS_SAFE_MODE_ENABLED,
                 ChromeFeatureList.isEnabled(ChromeFeatureList.SAFE_MODE_FOR_CACHED_FLAGS));
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 b708e67..a958497 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
@@ -687,6 +687,6 @@
     public static final List<CachedFlag> sTestCachedFlags =
             List.of(sTestDefaultDisabled, sTestDefaultEnabled);
 
-    static final Map<String, CachedFlag> sAllCachedFlags = CachedFlag.createCachedFlagMap(
+    public static final Map<String, CachedFlag> sAllCachedFlags = CachedFlag.createCachedFlagMap(
             List.of(sFlagsCachedFullBrowser, sFlagsCachedInMinimalBrowser, sTestCachedFlags));
 }
diff --git a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc
index 360c362..de631a29 100644
--- a/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc
+++ b/chrome/browser/lacros/chrome_browser_main_extra_parts_lacros.cc
@@ -6,7 +6,6 @@
 
 #include <memory>
 
-#include "base/check_is_test.h"
 #include "base/feature_list.h"
 #include "base/unguessable_token.h"
 #include "build/chromeos_buildflags.h"
@@ -132,15 +131,9 @@
         std::make_unique<DeviceLocalAccountExtensionInstallerLacros>();
   }
 
-  const auto* const geolocation_manager =
-      device::GeolocationManager::GetInstance();
-  if (!geolocation_manager) {
-    device::GeolocationManager::SetInstance(
-        SystemGeolocationSourceLacros::CreateGeolocationManagerOnLacros());
-  } else {
-    // Geolocation manager instance can be set at this point only in tests.
-    CHECK_IS_TEST();
-  }
+  DCHECK(!device::GeolocationManager::GetInstance());
+  device::GeolocationManager::SetInstance(
+      SystemGeolocationSourceLacros::CreateGeolocationManagerOnLacros());
 }
 
 void ChromeBrowserMainExtraPartsLacros::PostBrowserStart() {
diff --git a/chrome/browser/notifications/notification_dispatcher_mojo.cc b/chrome/browser/notifications/notification_dispatcher_mojo.cc
index 1b767b4..dfadd04 100644
--- a/chrome/browser/notifications/notification_dispatcher_mojo.cc
+++ b/chrome/browser/notifications/notification_dispatcher_mojo.cc
@@ -43,7 +43,7 @@
   // Force start the notification service once so we show the permission request
   // to users on the first start of Chrome.
   // TODO(crbug.com/1129366): Find a better time to ask for permissions.
-  CheckIfNotificationsRemaining();
+  CheckIfServiceCanBeTerminated();
 }
 
 NotificationDispatcherMojo::~NotificationDispatcherMojo() = default;
@@ -67,7 +67,7 @@
           identifier.notification_id,
           mac_notifications::mojom::ProfileIdentifier::New(
               identifier.profile_id, identifier.incognito)));
-  CheckIfNotificationsRemaining();
+  CheckIfServiceCanBeTerminated();
 }
 
 void NotificationDispatcherMojo::CloseNotificationsWithProfileId(
@@ -78,7 +78,7 @@
 
   GetOrCreateService()->CloseNotificationsForProfile(
       mac_notifications::mojom::ProfileIdentifier::New(profile_id, incognito));
-  CheckIfNotificationsRemaining();
+  CheckIfServiceCanBeTerminated();
 }
 
 void NotificationDispatcherMojo::CloseAllNotifications() {
@@ -126,29 +126,26 @@
     mac_notifications::mojom::NotificationActionInfoPtr info) {
   ProcessMacNotificationResponse(provider_factory_->notification_style(),
                                  std::move(info));
-  CheckIfNotificationsRemaining();
+  CheckIfServiceCanBeTerminated();
 }
 
-void NotificationDispatcherMojo::CheckIfNotificationsRemaining() {
+void NotificationDispatcherMojo::CheckIfServiceCanBeTerminated() {
   no_notifications_checker_.Reset(base::BindOnce(
       &NotificationDispatcherMojo::OnServiceDisconnectedGracefully,
       base::Unretained(this), /*gracefully=*/true));
 
-  // This block will be called with all displayed notifications. If there are
-  // none left we close the mojo connection (only if the callback has not been
-  // canceled yet).
-  // TODO(crbug.com/1127306): Revisit this for the UNNotification API as we need
-  // to keep the process running during the initial permission request.
-  GetOrCreateService()->GetDisplayedNotifications(
-      /*profile=*/nullptr,
-      base::BindOnce(
-          [](base::OnceClosure disconnect_closure,
-             std::vector<mac_notifications::mojom::NotificationIdentifierPtr>
-                 notifications) {
-            if (notifications.empty())
-              std::move(disconnect_closure).Run();
-          },
-          no_notifications_checker_.callback()));
+  // The service will indicate it is okay to be terminated if there are no
+  // displayed notifications left, and (in the case of the UNNotification API)
+  // there are no pending permission requests either.
+  // If this happens, we close the mojo connection (only if the callback has not
+  // been canceled yet).
+  GetOrCreateService()->OkayToTerminateService(base::BindOnce(
+      [](base::OnceClosure disconnect_closure, bool can_terminate) {
+        if (can_terminate) {
+          std::move(disconnect_closure).Run();
+        }
+      },
+      no_notifications_checker_.callback()));
 }
 
 void NotificationDispatcherMojo::OnServiceDisconnectedGracefully(
@@ -180,13 +177,13 @@
     next_service_restart_timer_delay_ = next_service_restart_timer_delay_ * 2;
 
   if (!gracefully) {
-    // Calling CheckIfNotificationsRemaining() will force a new connection
+    // Calling CheckIfServiceCanBeTerminated() will force a new connection
     // attempt. base::Unretained(this) is safe here because |this| owns
     // |service_restart_timer_|.
     service_restart_timer_.Start(
         FROM_HERE, next_service_restart_timer_delay_,
         base::BindOnce(
-            &NotificationDispatcherMojo::CheckIfNotificationsRemaining,
+            &NotificationDispatcherMojo::CheckIfServiceCanBeTerminated,
             base::Unretained(this)));
   } else {
     service_restart_timer_.AbandonAndStop();
@@ -228,7 +225,7 @@
 
   // Check if there are any notifications left after this.
   if (notification_ids.empty())
-    CheckIfNotificationsRemaining();
+    CheckIfServiceCanBeTerminated();
 
   std::move(callback).Run(std::move(notification_ids),
                           /*supports_synchronization=*/true);
@@ -247,7 +244,7 @@
 
   // Check if there are any notifications left after this.
   if (notification_ids.empty())
-    CheckIfNotificationsRemaining();
+    CheckIfServiceCanBeTerminated();
 
   // Initialize the base::flat_set via a std::vector to avoid N^2 runtime.
   base::flat_set<MacNotificationIdentifier> identifiers(
diff --git a/chrome/browser/notifications/notification_dispatcher_mojo.h b/chrome/browser/notifications/notification_dispatcher_mojo.h
index 58b7d57f..4ee6a1a 100644
--- a/chrome/browser/notifications/notification_dispatcher_mojo.h
+++ b/chrome/browser/notifications/notification_dispatcher_mojo.h
@@ -55,7 +55,7 @@
       mac_notifications::mojom::NotificationActionInfoPtr info) override;
 
  private:
-  void CheckIfNotificationsRemaining();
+  void CheckIfServiceCanBeTerminated();
   void OnServiceDisconnectedGracefully(bool gracefully);
   bool HasNoDisplayedNotifications() const;
 
diff --git a/chrome/browser/notifications/notification_dispatcher_mojo_unittest.cc b/chrome/browser/notifications/notification_dispatcher_mojo_unittest.cc
index 08afc73..7714cd8 100644
--- a/chrome/browser/notifications/notification_dispatcher_mojo_unittest.cc
+++ b/chrome/browser/notifications/notification_dispatcher_mojo_unittest.cc
@@ -56,6 +56,10 @@
               (mac_notifications::mojom::ProfileIdentifierPtr),
               (override));
   MOCK_METHOD(void, CloseAllNotifications, (), (override));
+  MOCK_METHOD(void,
+              OkayToTerminateService,
+              (OkayToTerminateServiceCallback),
+              (override));
 };
 
 class MockNotificationProvider
@@ -191,10 +195,10 @@
             on_disconnect_.Get());
     provider_factory_ = provider_factory.get();
 
-    // NotificationDispatcherMojo will query the list of displayed notifications
+    // NotificationDispatcherMojo will query if it can terminate the service
     // at startup. Once that finishes it should disconnect due to inactivity.
     base::RunLoop run_loop;
-    EmulateNoNotifications();
+    EmulateOkayToTerminate(/*can_terminate=*/true);
     ExpectDisconnect(run_loop.QuitClosure());
 
     notification_dispatcher_ = std::make_unique<NotificationDispatcherMojo>(
@@ -221,26 +225,14 @@
     task_environment_.RunUntilIdle();
   }
 
-  void EmulateNoNotifications() {
-    EXPECT_CALL(service(), GetDisplayedNotifications)
-        .WillOnce([](mac_notifications::mojom::ProfileIdentifierPtr profile,
-                     MockNotificationService::GetDisplayedNotificationsCallback
-                         callback) {
-          // Emulate an empty list of notifications.
-          std::move(callback).Run({});
-        });
-  }
-
-  void EmulateOneNotification(base::OnceClosure callback) {
-    EXPECT_CALL(service(), GetDisplayedNotifications)
-        .WillOnce(testing::DoAll(
+  void EmulateOkayToTerminate(bool can_terminate,
+                              base::OnceClosure callback = base::DoNothing()) {
+    EXPECT_CALL(service(), OkayToTerminateService)
+        .WillRepeatedly(testing::DoAll(
             base::test::RunOnceClosure(std::move(callback)),
-            [](mac_notifications::mojom::ProfileIdentifierPtr profile,
-               MockNotificationService::GetDisplayedNotificationsCallback
-                   callback) {
-              // Emulate one remaining notification.
-              std::move(callback).Run(CreateOneNotificationList());
-            }));
+            [can_terminate](
+                MockNotificationService::OkayToTerminateServiceCallback
+                    callback) { std::move(callback).Run(can_terminate); }));
   }
 
   void DisplayNotificationSync() {
@@ -276,7 +268,7 @@
             EXPECT_EQ(kProfileId, identifier->profile->id);
             EXPECT_TRUE(identifier->profile->incognito);
           });
-  EmulateNoNotifications();
+  EmulateOkayToTerminate(/*can_terminate=*/true);
   notification_dispatcher_->CloseNotificationWithId(
       {kNotificationId, kProfileId, /*incognito=*/true});
   run_loop.Run();
@@ -288,7 +280,7 @@
   base::RunLoop run_loop;
   // Expect that we continue running if there are remaining notifications.
   EXPECT_CALL(service(), CloseNotification);
-  EmulateOneNotification(run_loop.QuitClosure());
+  EmulateOkayToTerminate(/*can_terminate=*/false, run_loop.QuitClosure());
   notification_dispatcher_->CloseNotificationWithId(
       {kNotificationId, kProfileId, /*incognito=*/true});
   run_loop.Run();
@@ -303,7 +295,7 @@
   // Expect that we continue running when showing a new notification just after
   // closing the last one.
   EXPECT_CALL(service(), CloseNotification);
-  EmulateNoNotifications();
+  EmulateOkayToTerminate(/*can_terminate=*/true);
   notification_dispatcher_->CloseNotificationWithId(
       {kNotificationId, kProfileId, /*incognito=*/true});
 
@@ -335,7 +327,7 @@
         EXPECT_EQ(kProfileId, profile->id);
         EXPECT_TRUE(profile->incognito);
       });
-  EmulateNoNotifications();
+  EmulateOkayToTerminate(/*can_terminate=*/true);
   notification_dispatcher_->CloseNotificationsWithProfileId(kProfileId,
                                                             /*incognito=*/true);
   run_loop.Run();
@@ -356,7 +348,7 @@
   // Expect that we disconnect after closing the last notification.
   base::RunLoop run_loop;
   ExpectDisconnect(run_loop.QuitClosure());
-  EmulateNoNotifications();
+  EmulateOkayToTerminate(/*can_terminate=*/true);
   EXPECT_CALL(service(), CloseNotification);
   notification_dispatcher_->CloseNotificationWithId(
       {kNotificationId, kProfileId, /*incognito=*/true});
@@ -395,7 +387,7 @@
 TEST_F(NotificationDispatcherMojoTest, DidActivateNotification) {
   base::HistogramTester histograms;
   // Show a new notification.
-  EmulateNoNotifications();
+  EmulateOkayToTerminate(/*can_terminate=*/true);
   EXPECT_CALL(service(), DisplayNotification);
   notification_dispatcher_->DisplayNotification(
       NotificationHandler::Type::WEB_PERSISTENT, profile_,
@@ -424,7 +416,7 @@
   EXPECT_FALSE(provider_factory_->is_service_connected());
 
   // Expect the service to be restarted after a short timeout.
-  EmulateOneNotification(base::DoNothing());
+  EmulateOkayToTerminate(/*can_terminate=*/false);
   task_environment_.FastForwardBy(base::Milliseconds(500));
   EXPECT_TRUE(provider_factory_->is_service_connected());
 }
@@ -440,7 +432,7 @@
   task_environment_.FastForwardBy(base::Milliseconds(499));
   EXPECT_FALSE(provider_factory_->is_service_connected());
   // Expect the service to be restarted after a short timeout.
-  EmulateOneNotification(base::DoNothing());
+  EmulateOkayToTerminate(/*can_terminate=*/false);
   task_environment_.FastForwardBy(base::Milliseconds(1));
   EXPECT_TRUE(provider_factory_->is_service_connected());
 
@@ -451,7 +443,7 @@
   task_environment_.FastForwardBy(base::Milliseconds(999));
   EXPECT_FALSE(provider_factory_->is_service_connected());
   // Expect the service to be restarted after a short timeout.
-  EmulateOneNotification(base::DoNothing());
+  EmulateOkayToTerminate(/*can_terminate=*/false);
   task_environment_.FastForwardBy(base::Milliseconds(1));
   EXPECT_TRUE(provider_factory_->is_service_connected());
 }
diff --git a/chrome/browser/notifications/notification_permission_context.cc b/chrome/browser/notifications/notification_permission_context.cc
index b161e516..0aec2d40 100644
--- a/chrome/browser/notifications/notification_permission_context.cc
+++ b/chrome/browser/notifications/notification_permission_context.cc
@@ -23,8 +23,8 @@
 
 #if BUILDFLAG(IS_ANDROID)
 #include "base/android/build_info.h"
+#include "chrome/browser/android/flags/chrome_cached_flags.h"
 #include "chrome/browser/android/shortcut_helper.h"
-#include "chrome/browser/flags/android/cached_feature_flags.h"
 #include "chrome/browser/flags/android/chrome_feature_list.h"
 #include "chrome/browser/installable/installed_webapp_bridge.h"
 #endif  // BUILDFLAG(IS_ANDROID)
diff --git a/chrome/browser/password_manager/android/password_generation_controller.h b/chrome/browser/password_manager/android/password_generation_controller.h
index 017f2e8..4d035b6 100644
--- a/chrome/browser/password_manager/android/password_generation_controller.h
+++ b/chrome/browser/password_manager/android/password_generation_controller.h
@@ -113,7 +113,8 @@
 
   virtual std::unique_ptr<TouchToFillPasswordGenerationController>
   CreateTouchToFillGenerationControllerForTesting(
-      std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge) = 0;
+      std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge,
+      base::WeakPtr<ManualFillingController> manual_filling_controller) = 0;
 
   // -----------------
   // Member accessors:
diff --git a/chrome/browser/password_manager/android/password_generation_controller_impl.cc b/chrome/browser/password_manager/android/password_generation_controller_impl.cc
index a00a844..79b818fa 100644
--- a/chrome/browser/password_manager/android/password_generation_controller_impl.cc
+++ b/chrome/browser/password_manager/android/password_generation_controller_impl.cc
@@ -224,19 +224,22 @@
       std::make_unique<TouchToFillPasswordGenerationBridgeImpl>(),
       base::BindOnce(&PasswordGenerationControllerImpl::
                          OnTouchToFillForGenerationDismissed,
-                     base::Unretained(this)));
+                     base::Unretained(this)),
+      ManualFillingController::GetOrCreate(&GetWebContents()));
 }
 
 std::unique_ptr<TouchToFillPasswordGenerationController>
 PasswordGenerationControllerImpl::
     CreateTouchToFillGenerationControllerForTesting(
-        std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge) {
+        std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge,
+        base::WeakPtr<ManualFillingController> manual_filling_controller) {
   return std::make_unique<TouchToFillPasswordGenerationController>(
       active_frame_driver_, &GetWebContents(), *generation_element_data_,
       std::move(bridge),
       base::BindOnce(&PasswordGenerationControllerImpl::
                          OnTouchToFillForGenerationDismissed,
-                     base::Unretained(this)));
+                     base::Unretained(this)),
+      manual_filling_controller);
 }
 
 void PasswordGenerationControllerImpl::ShowDialog(PasswordGenerationType type) {
diff --git a/chrome/browser/password_manager/android/password_generation_controller_impl.h b/chrome/browser/password_manager/android/password_generation_controller_impl.h
index e135e24b..5c9c7dd 100644
--- a/chrome/browser/password_manager/android/password_generation_controller_impl.h
+++ b/chrome/browser/password_manager/android/password_generation_controller_impl.h
@@ -78,7 +78,9 @@
   // for testing.
   std::unique_ptr<TouchToFillPasswordGenerationController>
   CreateTouchToFillGenerationControllerForTesting(
-      std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge) override;
+      std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge,
+      base::WeakPtr<ManualFillingController> manual_filling_controller)
+      override;
   gfx::NativeWindow top_level_native_window() override;
   content::WebContents* web_contents() override;
   autofill::FieldSignature get_field_signature_for_testing() override;
diff --git a/chrome/browser/password_manager/android/password_generation_controller_impl_unittest.cc b/chrome/browser/password_manager/android/password_generation_controller_impl_unittest.cc
index defbccb..945e5c5 100644
--- a/chrome/browser/password_manager/android/password_generation_controller_impl_unittest.cc
+++ b/chrome/browser/password_manager/android/password_generation_controller_impl_unittest.cc
@@ -173,7 +173,8 @@
 
     ON_CALL(create_ttf_generation_controller_, Run).WillByDefault([this]() {
       return controller()->CreateTouchToFillGenerationControllerForTesting(
-          std::make_unique<MockTouchToFillPasswordGenerationBridge>());
+          std::make_unique<MockTouchToFillPasswordGenerationBridge>(),
+          mock_manual_filling_controller_.AsWeakPtr());
     });
 
     PasswordGenerationControllerImpl::CreateForWebContentsForTesting(
@@ -491,7 +492,8 @@
   EXPECT_CALL(create_ttf_generation_controller_, Run)
       .WillOnce([this, &ttf_password_generation_bridge]() {
         return controller()->CreateTouchToFillGenerationControllerForTesting(
-            std::move(ttf_password_generation_bridge));
+            std::move(ttf_password_generation_bridge),
+            mock_manual_filling_controller_.AsWeakPtr());
       });
 
   // Keyboard accessory shouldn't show up.
@@ -543,7 +545,8 @@
   EXPECT_CALL(create_ttf_generation_controller_, Run)
       .WillOnce([this, &ttf_password_generation_bridge]() {
         return controller()->CreateTouchToFillGenerationControllerForTesting(
-            std::move(ttf_password_generation_bridge));
+            std::move(ttf_password_generation_bridge),
+            mock_manual_filling_controller_.AsWeakPtr());
       });
 
   // Keyboard accessory should show up.
@@ -567,7 +570,8 @@
   EXPECT_CALL(create_ttf_generation_controller_, Run)
       .WillOnce([this, &ttf_password_generation_bridge]() {
         return controller()->CreateTouchToFillGenerationControllerForTesting(
-            std::move(ttf_password_generation_bridge));
+            std::move(ttf_password_generation_bridge),
+            mock_manual_filling_controller_.AsWeakPtr());
       });
 
   // Keyboard accessory shouldn't be called.
diff --git a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/ExportDeletionDialogFragment.java b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/ExportDeletionDialogFragment.java
index c7397f78..57d8a3e 100644
--- a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/ExportDeletionDialogFragment.java
+++ b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/ExportDeletionDialogFragment.java
@@ -10,40 +10,18 @@
 
 import androidx.appcompat.app.AlertDialog;
 import androidx.fragment.app.DialogFragment;
-import androidx.fragment.app.FragmentManager;
-
-import org.chromium.chrome.browser.password_manager.PasswordStoreBridge;
-import org.chromium.chrome.browser.password_manager.PasswordStoreBridge.PasswordStoreObserver;
-import org.chromium.chrome.browser.password_manager.PasswordStoreCredential;
-import org.chromium.chrome.browser.password_manager.settings.DialogManager;
 
 /**
  * An alert dialog that offers to delete passwords which were exported.
  */
-public class ExportDeletionDialogFragment extends DialogFragment implements PasswordStoreObserver {
-    /** The delay after which the progress bar will be displayed. */
-    private static final int PROGRESS_BAR_DELAY_MS = 500;
-
-    private PasswordStoreBridge mPasswordStoreBridge;
-    private Runnable mHideProgressBarCallback;
+public class ExportDeletionDialogFragment extends DialogFragment {
+    private Runnable mOnDeletionAcceptedCallback;
     private Dialog mDialog;
-    private DialogManager mProgressBarManager;
-    private FragmentManager mFragmentManager;
 
     public ExportDeletionDialogFragment() {}
 
-    public void initialize(FragmentManager fragmentManager, Runnable hideProgressBarCallback,
-            PasswordStoreBridge passwordStoreBridge) {
-        mFragmentManager = fragmentManager;
-        mHideProgressBarCallback = hideProgressBarCallback;
-        mPasswordStoreBridge = passwordStoreBridge;
-    }
-
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        mPasswordStoreBridge.addObserver(this, true);
-        mProgressBarManager = new DialogManager(null);
+    public void initialize(Runnable onDeletionAcceptedCallback) {
+        mOnDeletionAcceptedCallback = onDeletionAcceptedCallback;
     }
 
     @Override
@@ -70,21 +48,7 @@
     }
 
     private void onDeleteButtonClicked(DialogInterface unused, int unusedButton) {
-        // Tapping the delete button should show a progress bar and start the deletion.
-        showProgressBar();
-        mPasswordStoreBridge.clearAllPasswords();
-    }
-
-    @Override
-    public void onSavedPasswordsChanged(int count) {
-        if (count == 0) {
-            hideProgressBar();
-        }
-    }
-
-    @Override
-    public void onEdit(PasswordStoreCredential credential) {
-        // Won't be used. It's overridden to implement {@link PasswordStoreObserver}.
+        mOnDeletionAcceptedCallback.run();
     }
 
     @Override
@@ -99,17 +63,5 @@
     @Override
     public void onDestroy() {
         super.onDestroy();
-        mPasswordStoreBridge.removeObserver(this);
-    }
-
-    private void showProgressBar() {
-        NonCancelableProgressBar progressBarDialogFragment = new NonCancelableProgressBar(
-                R.string.exported_passwords_deletion_in_progress_title);
-        mProgressBarManager.showWithDelay(
-                progressBarDialogFragment, mFragmentManager, PROGRESS_BAR_DELAY_MS);
-    }
-
-    private void hideProgressBar() {
-        mProgressBarManager.hide(mHideProgressBarCallback::run);
     }
 }
diff --git a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningCoordinator.java b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningCoordinator.java
index a28bb1e..632a0a0 100644
--- a/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningCoordinator.java
+++ b/chrome/browser/password_manager/android/pwd_migration/java/src/org/chromium/chrome/browser/pwd_migration/PasswordMigrationWarningCoordinator.java
@@ -18,6 +18,9 @@
 import org.chromium.base.Callback;
 import org.chromium.base.ContextUtils;
 import org.chromium.chrome.browser.password_manager.PasswordStoreBridge;
+import org.chromium.chrome.browser.password_manager.PasswordStoreBridge.PasswordStoreObserver;
+import org.chromium.chrome.browser.password_manager.PasswordStoreCredential;
+import org.chromium.chrome.browser.password_manager.settings.DialogManager;
 import org.chromium.chrome.browser.password_manager.settings.PasswordListObserver;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.pwd_migration.PasswordMigrationWarningMediator.MigrationWarningOptionsHandler;
@@ -31,7 +34,11 @@
 import org.chromium.ui.modelutil.PropertyModelChangeProcessor;
 
 /** The coordinator of the password migration warning. */
-public class PasswordMigrationWarningCoordinator implements MigrationWarningOptionsHandler {
+public class PasswordMigrationWarningCoordinator
+        implements MigrationWarningOptionsHandler, PasswordStoreObserver {
+    /** The delay after which the progress bar will be displayed. */
+    private static final int PROGRESS_BAR_DELAY_MS = 500;
+
     // The prefix for the histograms, which will be used log the export flow metrics.
     public static final String EXPORT_METRICS_ID =
             "PasswordManager.PasswordMigrationWarning.Export";
@@ -45,6 +52,7 @@
     private PasswordMigrationWarningView mView;
     private FragmentManager mFragmentManager;
     private PasswordStoreBridge mPasswordStoreBridge;
+    private DialogManager mProgressBarManager;
 
     public PasswordMigrationWarningCoordinator(Context context, Profile profile,
             BottomSheetController sheetController,
@@ -120,10 +128,7 @@
             public void onExportFlowSucceeded() {
                 ExportDeletionDialogFragment deletionDialogFragment =
                         new ExportDeletionDialogFragment();
-                deletionDialogFragment.initialize(mFragmentManager, () -> {
-                    mMediator.onDismissed(StateChangeReason.INTERACTION_COMPLETE);
-                    mPasswordStoreBridge.destroy();
-                }, mPasswordStoreBridge);
+                deletionDialogFragment.initialize(() -> { startPasswordsDeletion(); });
                 deletionDialogFragment.show(mFragmentManager, null);
             }
         }, PASSWORD_MIGRATION_WARNING_EXPORT_METRICS_ID);
@@ -148,4 +153,34 @@
     public PasswordMigrationWarningMediator getMediatorForTesting() {
         return mMediator;
     }
+
+    @Override
+    public void onSavedPasswordsChanged(int count) {
+        if (count == 0) {
+            onPasswordDeletionCompleted();
+        }
+    }
+
+    @Override
+    public void onEdit(PasswordStoreCredential credential) {
+        // Won't be used. It's overridden to implement {@link PasswordStoreObserver}.
+    }
+
+    private void startPasswordsDeletion() {
+        mProgressBarManager = new DialogManager(null);
+        NonCancelableProgressBar progressBarDialogFragment = new NonCancelableProgressBar(
+                R.string.exported_passwords_deletion_in_progress_title);
+        mProgressBarManager.showWithDelay(
+                progressBarDialogFragment, mFragmentManager, PROGRESS_BAR_DELAY_MS);
+        mPasswordStoreBridge.addObserver(this, true);
+        mPasswordStoreBridge.clearAllPasswords();
+    }
+
+    private void onPasswordDeletionCompleted() {
+        mProgressBarManager.hide(() -> {
+            mMediator.onDismissed(StateChangeReason.INTERACTION_COMPLETE);
+            mPasswordStoreBridge.removeObserver(this);
+            mPasswordStoreBridge.destroy();
+        });
+    }
 }
diff --git a/chrome/browser/preloading/prerender/prerender_browsertest.cc b/chrome/browser/preloading/prerender/prerender_browsertest.cc
index 142a048e0..edaac11 100644
--- a/chrome/browser/preloading/prerender/prerender_browsertest.cc
+++ b/chrome/browser/preloading/prerender/prerender_browsertest.cc
@@ -47,6 +47,7 @@
 
 // Following definitions are equal to content::PrerenderFinalStatus.
 constexpr int kFinalStatusActivated = 0;
+constexpr int kFinalStatusInvalidSchemeNavigation = 6;
 constexpr int kFinalStatusCrossSiteNavigationInMainFrameNavigation = 64;
 
 }  // namespace
@@ -177,6 +178,31 @@
       kFinalStatusActivated, 1);
 }
 
+IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, EmbedderTrigger_ChromeUrl) {
+  base::HistogramTester histogram_tester;
+
+  // Navigate to an initial page.
+  GURL url = embedded_test_server()->GetURL("/empty.html");
+  ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), url));
+
+  GURL prerender_url("chrome://new-tab-page");
+  ASSERT_FALSE(prerender_url.SchemeIsHTTPOrHTTPS());
+
+  // Start embedder triggered prerendering.
+  std::unique_ptr<content::PrerenderHandle> prerender_handle =
+      GetActiveWebContents()->StartPrerendering(
+          prerender_url, content::PrerenderTriggerType::kEmbedder,
+          prerender_utils::kDirectUrlInputMetricSuffix,
+          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
+                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
+          content::PreloadingHoldbackStatus::kUnspecified, nullptr);
+  EXPECT_FALSE(prerender_handle);
+
+  histogram_tester.ExpectUniqueSample(
+      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_DirectURLInput",
+      kFinalStatusInvalidSchemeNavigation, 1);
+}
+
 // Tests that UseCounter for SpeculationRules-triggered prerender is recorded.
 // This cannot be tested in content/ as SpeculationHostImpl records the usage
 // with ContentBrowserClient::LogWebFeatureForCurrentPage() that is not
diff --git a/chrome/browser/resources/ash/settings/BUILD.gn b/chrome/browser/resources/ash/settings/BUILD.gn
index 2c93ca7c..c69570f 100644
--- a/chrome/browser/resources/ash/settings/BUILD.gn
+++ b/chrome/browser/resources/ash/settings/BUILD.gn
@@ -244,6 +244,7 @@
     "os_languages_page/cr_checkbox_with_policy.ts",
     "os_languages_page/input_method_options_page.ts",
     "os_languages_page/input_page.ts",
+    "os_languages_page/language_settings_card.ts",
     "os_languages_page/os_add_languages_dialog.ts",
     "os_languages_page/os_edit_dictionary_page.ts",
     "os_languages_page/os_japanese_clear_ime_data_dialog.ts",
diff --git a/chrome/browser/resources/ash/settings/lazy_load.ts b/chrome/browser/resources/ash/settings/lazy_load.ts
index ba5f54c..32a6bd1 100644
--- a/chrome/browser/resources/ash/settings/lazy_load.ts
+++ b/chrome/browser/resources/ash/settings/lazy_load.ts
@@ -214,6 +214,7 @@
 export {CrCheckboxWithPolicyElement} from './os_languages_page/cr_checkbox_with_policy.js';
 export {SettingsInputMethodOptionsPageElement} from './os_languages_page/input_method_options_page.js';
 export {OsSettingsInputPageElement} from './os_languages_page/input_page.js';
+export {LanguageSettingsCardElement} from './os_languages_page/language_settings_card.js';
 export {SettingsLanguagesElement} from './os_languages_page/languages.js';
 export {LanguagesBrowserProxy, LanguagesBrowserProxyImpl} from './os_languages_page/languages_browser_proxy.js';
 export {InputsShortcutReminderState, LanguagesMetricsProxyImpl, LanguagesPageInteraction} from './os_languages_page/languages_metrics_proxy.js';
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/language_settings_card.html b/chrome/browser/resources/ash/settings/os_languages_page/language_settings_card.html
new file mode 100644
index 0000000..f0844c92b
--- /dev/null
+++ b/chrome/browser/resources/ash/settings/os_languages_page/language_settings_card.html
@@ -0,0 +1,30 @@
+<style include="settings-shared"></style>
+
+<settings-card header-text="$i18n{osLanguagesPageTitle}">
+  <cr-link-row
+      id="languagesRow"
+      label="$i18n{languagesPageTitle}"
+      sub-label="[[getLanguageDisplayName_(
+          languages.prospectiveUILanguage, languageHelper)]]"
+      on-click="onLanguagesV2Click_"
+      role-description="$i18n{subpageArrowRoleDescription}">
+  </cr-link-row>
+  <cr-link-row
+      id="inputRow"
+      class="hr"
+      label="$i18n{inputPageTitleV2}"
+      sub-label="[[getInputMethodDisplayName_(
+        languages.inputMethods.currentId, languageHelper)]]"
+      on-click="onInputClick_"
+      role-description="$i18n{subpageArrowRoleDescription}">
+  </cr-link-row>
+  <template is="dom-if" if="[[smartInputsEnabled_]]">
+    <cr-link-row
+        id="smartInputsRow"
+        class="hr"
+        label="$i18n{smartInputsTitle}"
+        on-click="onSmartInputsClick_"
+        role-description="$i18n{subpageArrowRoleDescription}">
+    </cr-link-row>
+  </template>
+</settings-card>
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/language_settings_card.ts b/chrome/browser/resources/ash/settings/os_languages_page/language_settings_card.ts
new file mode 100644
index 0000000..8c939b7
--- /dev/null
+++ b/chrome/browser/resources/ash/settings/os_languages_page/language_settings_card.ts
@@ -0,0 +1,140 @@
+// 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
+ * 'language-settings-card' is the card element containing language settings.
+ */
+
+import 'chrome://resources/cr_elements/cr_link_row/cr_link_row.js';
+import '../os_settings_page/settings_card.js';
+import '../settings_shared.css.js';
+
+import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+
+import {PrefsState} from '../common/types.js';
+import {RouteOriginMixin} from '../route_origin_mixin.js';
+import {Router, routes} from '../router.js';
+
+import {getTemplate} from './language_settings_card.html.js';
+import {LanguageHelper, LanguagesModel} from './languages_types.js';
+
+// The IME ID for the Accessibility Common extension used by Dictation.
+const ACCESSIBILITY_COMMON_IME_ID =
+    '_ext_ime_egfdjlfmgnehecnclamagfafdccgfndpdictation';
+
+const LanguageSettingsCardElementBase =
+    RouteOriginMixin(I18nMixin(PolymerElement));
+
+export class LanguageSettingsCardElement extends
+    LanguageSettingsCardElementBase {
+  static get is() {
+    return 'language-settings-card' as const;
+  }
+
+  static get template() {
+    return getTemplate();
+  }
+
+  static get properties() {
+    return {
+      prefs: {
+        type: Object,
+        notify: true,
+      },
+
+      languages: Object,
+
+      languageHelper: Object,
+
+      /**
+       * This is enabled when any of the smart inputs features are allowed.
+       */
+      smartInputsEnabled_: {
+        type: Boolean,
+        value() {
+          return loadTimeData.getBoolean('allowEmojiSuggestion');
+        },
+      },
+    };
+  }
+
+  // Public API: Bidirectional data flow.
+  /** Passed down to children. Do not access without using PrefsMixin. */
+  prefs: PrefsState;
+
+  // Public API: Downwards data flow.
+  languages: LanguagesModel|undefined;
+  languageHelper: LanguageHelper|undefined;
+
+  // Internal state.
+  private smartInputsEnabled_: boolean;
+
+  constructor() {
+    super();
+
+    /** RouteOriginMixin override */
+    this.route = routes.OS_LANGUAGES;
+  }
+
+  override ready(): void {
+    super.ready();
+
+    this.addFocusConfig(routes.OS_LANGUAGES_LANGUAGES, '#languagesRow');
+    this.addFocusConfig(routes.OS_LANGUAGES_INPUT, '#inputRow');
+    this.addFocusConfig(routes.OS_LANGUAGES_SMART_INPUTS, '#smartInputsRow');
+  }
+
+  private onLanguagesV2Click_(): void {
+    Router.getInstance().navigateTo(routes.OS_LANGUAGES_LANGUAGES);
+  }
+
+  private onInputClick_(): void {
+    Router.getInstance().navigateTo(routes.OS_LANGUAGES_INPUT);
+  }
+
+  private onSmartInputsClick_(): void {
+    Router.getInstance().navigateTo(routes.OS_LANGUAGES_SMART_INPUTS);
+  }
+
+  /**
+   * @param code The language code of the language.
+   * @return The display name of the language specified.
+   */
+  private getLanguageDisplayName_(code: string|undefined): string {
+    if (!code || !this.languageHelper) {
+      return '';
+    }
+    const language = this.languageHelper.getLanguage(code);
+    if (!language) {
+      return '';
+    }
+    return language.displayName;
+  }
+
+  /**
+   * @param id The input method ID.
+   * @return The display name of the input method.
+   */
+  private getInputMethodDisplayName_(id: string|undefined): string {
+    if (!id || !this.languageHelper) {
+      return '';
+    }
+    if (id === ACCESSIBILITY_COMMON_IME_ID) {
+      return '';
+    }
+    return this.languageHelper.getInputMethodDisplayName(id);
+  }
+}
+
+customElements.define(
+    LanguageSettingsCardElement.is, LanguageSettingsCardElement);
+
+declare global {
+  interface HTMLElementTagNameMap {
+    [LanguageSettingsCardElement.is]: LanguageSettingsCardElement;
+  }
+}
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html
index 326f0c1..833376ee 100644
--- a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html
+++ b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.html
@@ -8,34 +8,11 @@
 <!-- Top-level settings section. -->
 <os-settings-animated-pages id="pages" section="[[section_]]">
   <div route-path="default">
-    <settings-card header-text="$i18n{osLanguagesPageTitle}">
-      <cr-link-row
-          id="languagesRow"
-          label="$i18n{languagesPageTitle}"
-          sub-label="[[getLanguageDisplayName_(
-              languages.prospectiveUILanguage, languageHelper)]]"
-          on-click="onLanguagesV2Click_"
-          role-description="$i18n{subpageArrowRoleDescription}">
-      </cr-link-row>
-      <cr-link-row
-          id="inputRow"
-          class="hr"
-          label="[[inputPageTitle_]]"
-          sub-label="[[getInputMethodDisplayName_(
-            languages.inputMethods.currentId, languageHelper)]]"
-          on-click="onInputClick_"
-          role-description="$i18n{subpageArrowRoleDescription}">
-      </cr-link-row>
-      <template is="dom-if" if="[[smartInputsEnabled_]]">
-        <cr-link-row
-            id="smartInputsRow"
-            class="hr"
-            label="$i18n{smartInputsTitle}"
-            on-click="onSmartInputsClick_"
-            role-description="$i18n{subpageArrowRoleDescription}">
-        </cr-link-row>
-      </template>
-    </settings-card>
+    <language-settings-card
+        prefs="{{prefs}}"
+        languages="[[languages]]"
+        language-helper="[[languageHelper]]">
+    </language-settings-card>
   </div>
 
   <!-- "Languages" page. -->
@@ -51,7 +28,7 @@
 
   <!-- "Input" page. -->
   <template is="dom-if" route-path="/osLanguages/input">
-    <os-settings-subpage page-title="[[inputPageTitle_]]">
+    <os-settings-subpage page-title="$i18n{inputPageTitleV2}">
       <os-settings-input-page language-helper="[[languageHelper]]"
           languages="[[languages]]" prefs="{{prefs}}">
       </os-settings-input-page>
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.ts b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.ts
index ca82126..693a4a5 100644
--- a/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.ts
+++ b/chrome/browser/resources/ash/settings/os_languages_page/os_languages_section.ts
@@ -10,35 +10,23 @@
 
 import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js';
 import 'chrome://resources/cr_elements/cr_shared_vars.css.js';
-import './input_method_options_page.js';
-import './input_page.js';
 import './languages.js';
-import './os_japanese_manage_user_dictionary_page.js';
-import './os_languages_page_v2.js';
-import './smart_inputs_page.js';
+import './language_settings_card.js';
 import '../os_settings_page/os_settings_animated_pages.js';
 import '../os_settings_page/os_settings_subpage.js';
-import '../os_settings_page/settings_card.js';
 import '../settings_shared.css.js';
 import '../settings_vars.css.js';
 
 import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
-import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {PrefsState} from '../common/types.js';
 import {Section} from '../mojom-webui/routes.mojom-webui.js';
-import {RouteOriginMixin} from '../route_origin_mixin.js';
-import {Router, routes} from '../router.js';
 
 import {LanguageHelper, LanguagesModel} from './languages_types.js';
 import {getTemplate} from './os_languages_section.html.js';
 
-// The IME ID for the Accessibility Common extension used by Dictation.
-const ACCESSIBILITY_COMMON_IME_ID =
-    '_ext_ime_egfdjlfmgnehecnclamagfafdccgfndpdictation';
-
-const OsSettingsLanguagesSectionElementBase =
-    RouteOriginMixin(I18nMixin(PolymerElement));
+const OsSettingsLanguagesSectionElementBase = I18nMixin(PolymerElement);
 
 export class OsSettingsLanguagesSectionElement extends
     OsSettingsLanguagesSectionElementBase {
@@ -52,7 +40,10 @@
 
   static get properties() {
     return {
-      prefs: Object,
+      prefs: {
+        type: Object,
+        notify: true,
+      },
 
       section_: {
         type: Number,
@@ -65,105 +56,21 @@
         notify: true,
       },
 
-      languageHelper: Object,
-
-      inputPageTitle_: {
-        type: String,
-        value(this: OsSettingsLanguagesSectionElement): string {
-          // TODO: b/263823772 - Inline this variable.
-          const isUpdate2 = true;
-          return this.i18n(isUpdate2 ? 'inputPageTitleV2' : 'inputPageTitle');
-        },
+      languageHelper: {
+        type: Object,
       },
-
-      /**
-       * This is enabled when any of the smart inputs features is allowed.
-       */
-      smartInputsEnabled_: {
-        type: Boolean,
-        value() {
-          return loadTimeData.getBoolean('allowEmojiSuggestion');
-        },
-      },
-
     };
   }
 
   // Public API: Bidirectional data flow.
   /** Passed down to children. Do not access without using PrefsMixin. */
-  prefs: unknown;
+  prefs: PrefsState;
 
   // Internal state.
   private languages: LanguagesModel|undefined;
   // Only defined after a render.
   private languageHelper: LanguageHelper;
   private section_: Section;
-
-  // loadTimeData flags and strings.
-  private inputPageTitle_: string;
-  private smartInputsEnabled_: boolean;
-
-  constructor() {
-    super();
-
-    /** RouteOriginMixin override */
-    this.route = routes.OS_LANGUAGES;
-  }
-
-  override ready(): void {
-    super.ready();
-
-    this.addFocusConfig(routes.OS_LANGUAGES_LANGUAGES, '#languagesRow');
-    this.addFocusConfig(routes.OS_LANGUAGES_INPUT, '#inputRow');
-    this.addFocusConfig(routes.OS_LANGUAGES_SMART_INPUTS, '#smartInputsRow');
-  }
-
-  private onLanguagesV2Click_(): void {
-    Router.getInstance().navigateTo(routes.OS_LANGUAGES_LANGUAGES);
-  }
-
-  private onInputClick_(): void {
-    Router.getInstance().navigateTo(routes.OS_LANGUAGES_INPUT);
-  }
-
-  private onSmartInputsClick_(): void {
-    Router.getInstance().navigateTo(routes.OS_LANGUAGES_SMART_INPUTS);
-  }
-
-  /**
-   * @param code The language code of the language.
-   * @param languageHelper The LanguageHelper object.
-   * @return The display name of the language specified.
-   */
-  private getLanguageDisplayName_(
-      code: string|undefined, languageHelper: LanguageHelper): string {
-    if (!code) {
-      return '';
-    }
-    const language = languageHelper.getLanguage(code);
-    if (!language) {
-      return '';
-    }
-    return language.displayName;
-  }
-
-  /**
-   * @param id The input method ID.
-   * @param languageHelper The LanguageHelper object.
-   * @return The display name of the input method.
-   */
-  private getInputMethodDisplayName_(
-      id: string|undefined, languageHelper: LanguageHelper): string {
-    if (id === undefined) {
-      return '';
-    }
-
-    if (id === ACCESSIBILITY_COMMON_IME_ID) {
-      return '';
-    }
-
-    return languageHelper.getInputMethodDisplayName(id);
-  }
 }
 
 customElements.define(
diff --git a/chrome/browser/resources/ash/settings/os_settings.ts b/chrome/browser/resources/ash/settings/os_settings.ts
index 688cfee..f0862782 100644
--- a/chrome/browser/resources/ash/settings/os_settings.ts
+++ b/chrome/browser/resources/ash/settings/os_settings.ts
@@ -197,7 +197,6 @@
 export {GoogleDriveBrowserProxy, GoogleDrivePageCallbackRouter, GoogleDrivePageHandlerRemote, GoogleDrivePageRemote, Stage} from './os_files_page/google_drive_browser_proxy.js';
 export {ConfirmationDialogType, SettingsGoogleDriveSubpageElement} from './os_files_page/google_drive_subpage.js';
 export {OneDriveBrowserProxy, OneDrivePageCallbackRouter, OneDrivePageHandlerRemote, OneDrivePageRemote} from './os_files_page/one_drive_browser_proxy.js';
-export {OsSettingsLanguagesSectionElement} from './os_languages_page/os_languages_section.js';
 export {createPageAvailability as createPageAvailabilityForTesting, OsPageAvailability} from './os_page_availability.js';
 export {OsSettingsPeoplePageElement} from './os_people_page/os_people_page.js';
 export {MetricsConsentBrowserProxy, MetricsConsentBrowserProxyImpl, MetricsConsentState} from './os_privacy_page/metrics_consent_browser_proxy.js';
diff --git a/chrome/browser/resources/chromeos/BUILD.gn b/chrome/browser/resources/chromeos/BUILD.gn
index 63c802b8..ddb12d9 100644
--- a/chrome/browser/resources/chromeos/BUILD.gn
+++ b/chrome/browser/resources/chromeos/BUILD.gn
@@ -14,6 +14,7 @@
     ":app_icon_resources",
     ":multidevice_setup_resources",
     "accessibility:build",
+    "add_supervision:resources",
     "arc_account_picker:resources",
     "assistant_optin:resources",
     "audio:resources",
@@ -85,7 +86,6 @@
     "accessibility/switch_access:closure_compile",
     "account_manager:closure_compile",
     "account_manager/components:closure_compile",
-    "add_supervision:closure_compile",
     "arc_account_picker:closure_compile",
     "assistant_optin:closure_compile",
     "bluetooth_pairing_dialog:closure_compile",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_range.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_range.js
index f45bf43..b9e487b2 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_range.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox_range.js
@@ -58,24 +58,6 @@
         TARGET, Action.CLEAR_CURRENT_RANGE, () => ChromeVoxRange.set(null));
   }
 
-  /** @param {ChromeVoxRangeObserver} observer */
-  static addObserver(observer) {
-    ChromeVoxRange.observers_.push(observer);
-  }
-
-  /** @param {ChromeVoxRangeObserver} observer */
-  static removeObserver(observer) {
-    const index = ChromeVoxRange.observers_.indexOf(observer);
-    if (index > -1) {
-      ChromeVoxRange.observers_.splice(index, 1);
-    }
-  }
-
-  /** @return {?CursorRange} */
-  static getCurrentRangeWithoutRecovery() {
-    return ChromeVoxRange.instance.current_;
-  }
-
   /** @return {?CursorRange} */
   static get current() {
     if (ChromeVoxRange.instance.current_?.isValid()) {
@@ -89,6 +71,11 @@
     return ChromeVoxRange.instance.previous_;
   }
 
+  /** @return {?CursorRange} */
+  static getCurrentRangeWithoutRecovery() {
+    return ChromeVoxRange.instance.current_;
+  }
+
   /**
    * @param {?CursorRange} newRange The new range.
    * @param {boolean=} opt_fromEditing
@@ -98,61 +85,6 @@
   }
 
   /**
-   * @param {?CursorRange} newRange
-   * @param {boolean=} opt_fromEditing
-   * @private
-   */
-  set_(newRange, opt_fromEditing) {
-    // Clear anything that was frozen on the braille display whenever
-    // the user navigates.
-    ChromeVox.braille.thaw();
-
-    // There's nothing to be updated in this case.
-    if ((!newRange && !this.current_) || (newRange && !newRange.isValid())) {
-      FocusBounds.set([]);
-      return;
-    }
-
-    this.previous_ = this.current_;
-    this.current_ = newRange;
-
-    ChromeVoxState.ready().then(
-        ChromeVoxRange.onCurrentRangeChanged(newRange, opt_fromEditing));
-
-    if (!this.current_) {
-      FocusBounds.set([]);
-      return;
-    }
-
-    const start = this.current_.start.node;
-    start.makeVisible();
-    start.setAccessibilityFocus();
-
-    const root = AutomationUtil.getTopLevelRoot(start);
-    if (!root || root.role === RoleType.DESKTOP || root === start) {
-      return;
-    }
-
-    const position = {};
-    const loc = start.unclippedLocation;
-    position.x = loc.left + loc.width / 2;
-    position.y = loc.top + loc.height / 2;
-    let url = root.docUrl;
-    url = url.substring(0, url.indexOf('#')) || url;
-    ChromeVoxState.position[url] = position;
-  }
-
-  /**
-   * @param {?CursorRange} range The new range.
-   * @param {boolean=} opt_fromEditing
-   */
-  static onCurrentRangeChanged(range, opt_fromEditing = undefined) {
-    for (const observer of ChromeVoxRange.observers_) {
-      observer.onCurrentRangeChanged(range, opt_fromEditing);
-    }
-  }
-
-  /**
    * Check for loss of focus which results in us invalidating our current
    * range. Note the getFocus() callback is synchronous, so the focus will be
    * updated when this function returns (despite being technicallly a separate
@@ -185,7 +117,82 @@
       }
     });
   }
+
+  // ================= Observer Functions =================
+
+  /** @param {ChromeVoxRangeObserver} observer */
+  static addObserver(observer) {
+    ChromeVoxRange.observers_.push(observer);
+  }
+
+  /** @param {ChromeVoxRangeObserver} observer */
+  static removeObserver(observer) {
+    const index = ChromeVoxRange.observers_.indexOf(observer);
+    if (index > -1) {
+      ChromeVoxRange.observers_.splice(index, 1);
+    }
+  }
+
+  // ================= Private Methods =================
+
+  /**
+   * @param {?CursorRange} range The new range.
+   * @param {boolean=} opt_fromEditing
+   */
+  static notifyObservers_(range, opt_fromEditing = undefined) {
+    for (const observer of ChromeVoxRange.observers_) {
+      observer.onCurrentRangeChanged(range, opt_fromEditing);
+    }
+  }
+
+  /**
+   * @param {?CursorRange} newRange
+   * @param {boolean=} opt_fromEditing
+   * @private
+   */
+  set_(newRange, opt_fromEditing) {
+    // Clear anything that was frozen on the braille display whenever
+    // the user navigates.
+    ChromeVox.braille.thaw();
+
+    // There's nothing to be updated in this case.
+    if ((!newRange && !this.current_) || (newRange && !newRange.isValid())) {
+      FocusBounds.set([]);
+      return;
+    }
+
+    this.previous_ = this.current_;
+    this.current_ = newRange;
+
+    ChromeVoxState.ready().then(
+        ChromeVoxRange.notifyObservers_(newRange, opt_fromEditing));
+
+    if (!this.current_) {
+      FocusBounds.set([]);
+      return;
+    }
+
+    const start = this.current_.start.node;
+    start.makeVisible();
+    start.setAccessibilityFocus();
+
+    const root = AutomationUtil.getTopLevelRoot(start);
+    if (!root || root.role === RoleType.DESKTOP || root === start) {
+      return;
+    }
+
+    const position = {};
+    const loc = start.unclippedLocation;
+    position.x = loc.left + loc.width / 2;
+    position.y = loc.top + loc.height / 2;
+    let url = root.docUrl;
+    url = url.substring(0, url.indexOf('#')) || url;
+    ChromeVoxState.position[url] = position;
+  }
 }
 
 /** @private {!Array<ChromeVoxRangeObserver>} */
 ChromeVoxRange.observers_ = [];
+
+/** @type {ChromeVoxRange} */
+ChromeVoxRange.instance;
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/portals_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/portals_test.js
index 56b2aaa..92fc210 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/portals_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/portals_test.js
@@ -28,8 +28,6 @@
       // Alphabetical based on file path.
       importModule(
           'ChromeVoxRange', '/chromevox/background/chromevox_range.js'),
-      importModule(
-          'ChromeVoxState', '/chromevox/background/chromevox_state.js'),
     ]);
 
     globalThis.EventType = chrome.automation.EventType;
diff --git a/chrome/browser/resources/chromeos/account_manager/account_manager_browser_proxy.js b/chrome/browser/resources/chromeos/account_manager/account_manager_browser_proxy.js
index 957afd1..b1bdb33f 100644
--- a/chrome/browser/resources/chromeos/account_manager/account_manager_browser_proxy.js
+++ b/chrome/browser/resources/chromeos/account_manager/account_manager_browser_proxy.js
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {addSingletonGetter} from 'chrome://resources/ash/common/cr_deprecated.js';
-
 /**
  * @fileoverview Functions for Account manager screens.
  */
@@ -36,6 +34,17 @@
   closeDialog() {
     chrome.send('closeDialog');
   }
+
+  /** @return {!AccountManagerBrowserProxy} */
+  static getInstance() {
+    return instance || (instance = new AccountManagerBrowserProxyImpl());
+  }
+
+  /** @param {!AccountManagerBrowserProxy} obj */
+  static setInstance(obj) {
+    instance = obj;
+  }
 }
 
-addSingletonGetter(AccountManagerBrowserProxyImpl);
+/** @type {?AccountManagerBrowserProxy} */
+let instance = null;
diff --git a/chrome/browser/resources/chromeos/add_supervision/BUILD.gn b/chrome/browser/resources/chromeos/add_supervision/BUILD.gn
index d54dbc6..9645c6d 100644
--- a/chrome/browser/resources/chromeos/add_supervision/BUILD.gn
+++ b/chrome/browser/resources/chromeos/add_supervision/BUILD.gn
@@ -2,57 +2,36 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//third_party/closure_compiler/compile_js.gni")
-import("//tools/polymer/html_to_js.gni")
+import("//ui/webui/resources/tools/build_webui.gni")
 
-js_type_check("closure_compile") {
-  is_polymer3 = true
-  closure_flags = default_closure_args + mojom_js_args + [
-                    "js_module_root=" + rebase_path(".", root_build_dir),
-                    "js_module_root=" + rebase_path(
-                            "$root_gen_dir/mojom-webui/chrome/browser/ui/webui/ash/add_supervision/",
-                            root_build_dir),
-                  ]
-  deps = [
-    ":add_supervision_api_server",
-    ":add_supervision_app",
-    ":add_supervision_ui",
-  ]
-}
+build_webui("build") {
+  grd_prefix = "add_supervision"
 
-js_library("add_supervision_api_server") {
-  deps = [
-    "//ash/webui/common/resources/post_message_api:post_message_api_server",
-    "//chrome/browser/ui/webui/ash/add_supervision:mojo_bindings_js_library_for_compile",
-  ]
-}
+  static_files = [ "add_supervision.html" ]
 
-js_library("add_supervision_app") {
-  deps = [
-    ":add_supervision_ui",
-    "//chrome/browser/resources/chromeos/supervision:supervised_user_error",
-    "//chrome/browser/resources/chromeos/supervision:supervised_user_offline",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
+  web_component_files = [
+    "add_supervision_app.ts",
+    "add_supervision_ui.ts",
   ]
-  externs_list = [ "//ui/webui/resources/cr_elements/cr_view_manager/cr_view_manager_externs.js" ]
-}
 
-js_library("add_supervision_ui") {
-  deps = [
-    ":add_supervision_api_server",
-    "//ash/webui/common/resources:load_time_data.m",
-    "//chrome/browser/ui/webui/ash/add_supervision:mojo_bindings_webui_js",
-    "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled",
-  ]
-  externs_list = [
-    "$externs_path/chrome_extensions.js",
-    "$externs_path/webview_tag.js",
-  ]
-}
+  non_web_component_files = [ "add_supervision_api_server.ts" ]
 
-html_to_js("web_components") {
-  js_files = [
-    "add_supervision_app.js",
-    "add_supervision_ui.js",
+  mojo_files = [ "$root_gen_dir/chrome/browser/ui/webui/ash/add_supervision/add_supervision.mojom-webui.ts" ]
+  mojo_files_deps = [
+    "//chrome/browser/ui/webui/ash/add_supervision:mojo_bindings_ts__generator",
+  ]
+  ts_definitions = [
+    "//tools/typescript/definitions/webview_tag.d.ts",
+    "//tools/typescript/definitions/web_request.d.ts",
+    "//tools/typescript/definitions/context_menus.d.ts",
+    "//tools/typescript/definitions/tabs.d.ts",
+    "//tools/typescript/definitions/extension_types.d.ts",
+  ]
+
+  ts_deps = [
+    "//ash/webui/common/resources:build_ts",
+    "//third_party/polymer/v3_0:library",
+    "//ui/webui/resources/cr_elements:build_ts",
+    "//ui/webui/resources/mojo:build_ts",
   ]
 }
diff --git a/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_server.js b/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_server.js
deleted file mode 100644
index 7b86460c..0000000
--- a/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_server.js
+++ /dev/null
@@ -1,108 +0,0 @@
-// Copyright 2019 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {PostMessageApiServer} from 'chrome://resources/ash/common/post_message_api/post_message_api_server.js';
-
-import {AddSupervisionHandler} from './add_supervision.mojom-webui.js';
-import {isLocalHostForTesting} from './add_supervision_ui.js';
-
-/**
- * Class that implements the server side of the AddSupervision postMessage
- * API.  In the case of this API, the Add Supervision WebUI is the server, and
- * the remote website that calls the API  is the client.  This is the opposite
- * of the normal browser/web-server client/server relationship.
- */
-export class AddSupervisionAPIServer extends PostMessageApiServer {
-  /*
-   * @constructor
-   * @param {!Element} ui  Polymer object add-supervision-ui
-   * @param {!Element} webviewElement  The <webview> element to listen to as a
-   *     client.
-   * @param {string} targetURL  The target URL to use for outgoing messages.
-   *     This should be the same as the URL loaded in the webview.
-   * @param {string} originURLPrefix  The URL prefix to use to filter incoming
-   *     messages via the postMessage API.
-   */
-  constructor(ui, webviewElement, targetURL, originURLPrefix) {
-    super(webviewElement, targetURL, originURLPrefix);
-
-    this.ui_ = ui;
-
-    this.addSupervisionHandler_ = AddSupervisionHandler.getRemote();
-
-    this.registerMethod('logOut', this.logOut.bind(this));
-    this.registerMethod(
-        'getInstalledArcApps', this.getInstalledArcApps.bind(this));
-    this.registerMethod('requestClose', this.requestClose.bind(this));
-    this.registerMethod(
-        'notifySupervisionEnabled', this.notifySupervisionEnabled.bind(this));
-    this.registerMethod('setCloseOnEscape', this.setCloseOnEscape.bind(this));
-  }
-
-  /** @override */
-  initialize() {
-    // The server cannot communicate with the mock webview used
-    // in the browser test, so skip initialization during tests.
-    if (isLocalHostForTesting(this.targetUrl())) {
-      return;
-    }
-    super.initialize();
-  }
-
-  /** @override */
-  onInitializationError(origin) {
-    this.ui_.showErrorPage();
-  }
-
-  /**
-   * Logs out of the device.
-   * @param {!Array} unused Placeholder unused empty parameter.
-   */
-  logOut(unused) {
-    return this.addSupervisionHandler_.logOut();
-  }
-
-  /**
-   * @param {!Array} unused Placeholder unused empty parameter.
-   * @return {Promise<{
-   *         packageNames: !Array<string>,
-   *  }>}  a promise whose success result is an array of package names of ARC
-   *     apps installed on the device.
-   */
-  getInstalledArcApps(unused) {
-    return this.addSupervisionHandler_.getInstalledArcApps();
-  }
-
-  /**
-   * Attempts to close the widget hosting the Add Supervision flow.
-   * If supervision has already been enabled, this will prompt the
-   * user to sign out.
-   * @param {!Array} unused Placeholder unused empty parameter.
-   * @return {Promise <{closed: boolean}>} If the dialog is not closed
-   *     this promise will
-   * resolve with boolean result indicating whether the dialog was closed.
-   */
-  requestClose(unused) {
-    return this.addSupervisionHandler_.requestClose();
-  }
-
-  /**
-   * Signals to the API that supervision has been enabled for the current user.
-   * @param {!Array} unused Placeholder unused empty parameter.
-   */
-  notifySupervisionEnabled(unused) {
-    return this.addSupervisionHandler_.notifySupervisionEnabled();
-  }
-
-  /**
-   * Configures whether the Add Supervision dialog should close when
-   * the user presses the Escape key.
-   * @param {!Array} params Param 0 is a <boolean> that denotes whether the
-   * dialog should close.
-   */
-  setCloseOnEscape(params) {
-    const enabled = params[0];
-    return this.addSupervisionHandler_.setCloseOnEscape(enabled);
-  }
-}
diff --git a/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_server.ts b/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_server.ts
new file mode 100644
index 0000000..8e5df6bf
--- /dev/null
+++ b/chrome/browser/resources/chromeos/add_supervision/add_supervision_api_server.ts
@@ -0,0 +1,89 @@
+// Copyright 2019 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import {PostMessageApiServer} from 'chrome://resources/ash/common/post_message_api/post_message_api_server.js';
+
+import {AddSupervisionHandler, AddSupervisionHandlerRemote} from './add_supervision.mojom-webui.js';
+import {AddSupervisionUi, isLocalHostForTesting} from './add_supervision_ui.js';
+
+/**
+ * Class that implements the server side of the AddSupervision postMessage
+ * API.  In the case of this API, the Add Supervision WebUI is the server, and
+ * the remote website that calls the API  is the client.  This is the opposite
+ * of the normal browser/web-server client/server relationship.
+ */
+export class AddSupervisionApiServer extends PostMessageApiServer {
+  private ui_: AddSupervisionUi;
+  private addSupervisionHandler_: AddSupervisionHandlerRemote;
+
+  constructor(
+      ui: AddSupervisionUi, webviewElement: Element, targetURL: string,
+      originURLPrefix: string) {
+    super(webviewElement, targetURL, originURLPrefix);
+
+    this.ui_ = ui;
+
+    this.addSupervisionHandler_ = AddSupervisionHandler.getRemote();
+
+    this.registerMethod('logOut', this.logOut.bind(this));
+    this.registerMethod(
+        'getInstalledArcApps', this.getInstalledArcApps.bind(this));
+    this.registerMethod('requestClose', this.requestClose.bind(this));
+    this.registerMethod(
+        'notifySupervisionEnabled', this.notifySupervisionEnabled.bind(this));
+    this.registerMethod('setCloseOnEscape', this.setCloseOnEscape.bind(this));
+  }
+
+  override initialize() {
+    // The server cannot communicate with the mock webview used
+    // in the browser test, so skip initialization during tests.
+    if (isLocalHostForTesting(this.targetUrl())) {
+      return;
+    }
+    super.initialize();
+  }
+
+  override onInitializationError() {
+    this.ui_.showErrorPage();
+  }
+
+  logOut(): void {
+    return this.addSupervisionHandler_.logOut();
+  }
+
+  /**
+   * Returns a promise whose success result is an array of package names of ARC
+   * apps installed on the device.
+   */
+  getInstalledArcApps(): Promise<{packageNames: string[]}> {
+    return this.addSupervisionHandler_.getInstalledArcApps();
+  }
+
+  /**
+   * Attempts to close the widget hosting the Add Supervision flow.
+   * If supervision has already been enabled, this will prompt the
+   * user to sign out. If the dialog is not closed this promise will
+   * resolve with boolean result indicating whether the dialog was closed.
+   */
+  requestClose(): Promise<{closed: boolean}> {
+    return this.addSupervisionHandler_.requestClose();
+  }
+
+  /**
+   * Signals to the API that supervision has been enabled for the current user.
+   */
+  notifySupervisionEnabled(): void {
+    return this.addSupervisionHandler_.notifySupervisionEnabled();
+  }
+
+  /**
+   * Configures whether the Add Supervision dialog should close when
+   * the user presses the Escape key.
+   */
+  setCloseOnEscape(params: any[]): void {
+    // Param 0 is a <boolean> that denotes whether the dialog should close.
+    const enabled = params[0];
+    return this.addSupervisionHandler_.setCloseOnEscape(enabled);
+  }
+}
diff --git a/chrome/browser/resources/chromeos/add_supervision/add_supervision_app.js b/chrome/browser/resources/chromeos/add_supervision/add_supervision_app.ts
similarity index 62%
rename from chrome/browser/resources/chromeos/add_supervision/add_supervision_app.js
rename to chrome/browser/resources/chromeos/add_supervision/add_supervision_app.ts
index ebd92e0..a6e4f3c 100644
--- a/chrome/browser/resources/chromeos/add_supervision/add_supervision_app.js
+++ b/chrome/browser/resources/chromeos/add_supervision/add_supervision_app.ts
@@ -7,20 +7,27 @@
 import './supervision/supervised_user_offline.js';
 import 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
 
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {CrViewManagerElement} from 'chrome://resources/cr_elements/cr_view_manager/cr_view_manager.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
+import {getTemplate} from './add_supervision_app.html.js';
 
-/** @enum {string} */
-const Screens = {
+enum Screens {
   /**
    * ERROR: Shown permanently after an error event.
    * OFFLINE: Shown when the device is offline.
    * ONLINE: Shown when the device is online.
    */
-  ERROR: 'supervised-user-error',
-  OFFLINE: 'supervised-user-offline',
-  ONLINE: 'add-supervision-ui',
-};
+  ERROR = 'supervised-user-error',
+  OFFLINE = 'supervised-user-offline',
+  ONLINE = 'add-supervision-ui',
+}
+
+interface AddSupervisionApp {
+  $: {
+    viewManager: CrViewManagerElement,
+  };
+}
 
 class AddSupervisionApp extends PolymerElement {
   static get is() {
@@ -28,30 +35,26 @@
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
     return {
-      /**
-       * Specifies what the current screen is.
-       * @private {Screens}
-       */
       currentScreen_: {
         type: Screens,
       },
     };
   }
 
-  /** @override */
-  ready() {
+  private currentScreen_: Screens;
+
+  override ready() {
     super.ready();
     this.addEventListeners_();
     this.switchToScreen_(navigator.onLine ? Screens.ONLINE : Screens.OFFLINE);
   }
 
-  /** @private */
-  addEventListeners_() {
+  private addEventListeners_() {
     window.addEventListener('online', () => {
       this.switchToScreen_(Screens.ONLINE);
     });
@@ -65,28 +68,15 @@
     });
   }
 
-  /**
-   * Switches to the specified screen.
-   * @param {Screens} screen
-   * @private
-   */
-  switchToScreen_(screen) {
+  private switchToScreen_(screen: Screens) {
     if (this.isinvalidScreenSwitch_(screen)) {
       return;
     }
     this.currentScreen_ = screen;
-    /** @type {CrViewManagerElement} */ (this.$.viewManager)
-        .switchView(this.currentScreen_);
+    this.$.viewManager.switchView(this.currentScreen_);
   }
 
-  /**
-   * Returns true if the app cannot navigate from the current screen to the
-   * screen provided.
-   * @param {Screens} screen
-   * @return {boolean}
-   * @private
-   */
-  isinvalidScreenSwitch_(screen) {
+  private isinvalidScreenSwitch_(screen: Screens): boolean {
     return this.currentScreen_ === screen ||
         this.currentScreen_ === Screens.ERROR;
   }
diff --git a/chrome/browser/resources/chromeos/add_supervision/add_supervision_ui.js b/chrome/browser/resources/chromeos/add_supervision/add_supervision_ui.ts
similarity index 70%
rename from chrome/browser/resources/chromeos/add_supervision/add_supervision_ui.js
rename to chrome/browser/resources/chromeos/add_supervision/add_supervision_ui.ts
index 31158f7..b3dd5b0a 100644
--- a/chrome/browser/resources/chromeos/add_supervision/add_supervision_ui.js
+++ b/chrome/browser/resources/chromeos/add_supervision/add_supervision_ui.ts
@@ -8,16 +8,20 @@
 import './strings.m.js';
 
 import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js';
-import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {AddSupervisionHandler, OAuthTokenFetchStatus} from './add_supervision.mojom-webui.js';
-import {AddSupervisionAPIServer} from './add_supervision_api_server.js';
+import {AddSupervisionApiServer} from './add_supervision_api_server.js';
+import {getTemplate} from './add_supervision_ui.html.js';
 
-/**
- * List of URL hosts that can be requested by the webview.
- * @const {!Array<string>}
- */
-const ALLOWED_HOSTS = [
+declare global {
+  interface HTMLElementEventMap {
+    'newwindow': chrome.webviewTag.NewWindowEvent;
+  }
+}
+
+/** List of URL hosts that can be requested by the webview. */
+const ALLOWED_HOSTS: string[] = [
   'google.com',
   'gstatic.com',
   'googleapis.com',
@@ -32,53 +36,45 @@
 /**
  * Time in ms to wait before focusing the webview. Refer to the webview's
  * loadstop event listener for details.
- * @const {number}
  */
-const INITIAL_FOCUS_DELAY_MS = 50;
+const INITIAL_FOCUS_DELAY_MS: number = 50;
 
-/**
- * Returns true if the URL references an HTTP request to localhost.
- * @param {URL} url
- * @return {boolean}
- */
-export function isLocalHostForTesting(url) {
+/** Returns true if the URL references an HTTP request to localhost. */
+export function isLocalHostForTesting(url: URL): boolean {
   return url.protocol == 'http:' && url.hostname == '127.0.0.1';
 }
 
-/**
- * Returns true if the URL references one of the allowed hosts.
- * @param {URL} url
- * @return {boolean}
- */
-function isAllowedHost(url) {
+/** Returns true if the URL references one of the allowed hosts. */
+function isAllowedHost(url: URL): boolean {
   return url.protocol == 'https:' &&
       ALLOWED_HOSTS.some(
           (allowedHost) =>
               url.host == allowedHost || url.host.endsWith('.' + allowedHost));
 }
 
-/**
- * Returns true if the request should be allowed.
- * @param {!{url: string}} requestDetails Request that is issued by the webview.
- * @return {boolean}
- */
-function isAllowedRequest(requestDetails) {
-  const requestUrl = new URL(requestDetails.url);
+/** Returns true if the request should be allowed. */
+function isAllowedRequest(requestDetails: string): boolean {
+  const requestUrl = new URL(requestDetails);
   return isLocalHostForTesting(requestUrl) || isAllowedHost(requestUrl);
 }
 
-class AddSupervisionUi extends PolymerElement {
+export interface AddSupervisionUi {
+  $: {
+    webview: chrome.webviewTag.WebView,
+  };
+}
+
+export class AddSupervisionUi extends PolymerElement {
   static get is() {
     return 'add-supervision-ui';
   }
 
   static get template() {
-    return html`{__html_template__}`;
+    return getTemplate();
   }
 
   static get properties() {
     return {
-      /** Indicates whether the webview is loading. */
       webviewLoading: {
         type: Boolean,
         value: true,
@@ -86,13 +82,10 @@
     };
   }
 
-  constructor() {
-    super();
-    this.server_ = null;
-  }
+  webviewLoading: boolean;
+  private server_: AddSupervisionApiServer|null;
 
-  /** @override */
-  ready() {
+  override ready() {
     super.ready();
     const addSupervisionHandler = AddSupervisionHandler.getRemote();
     addSupervisionHandler.getOAuthToken().then((result) => {
@@ -104,8 +97,7 @@
 
       const webviewUrl = loadTimeData.getString('webviewUrl');
       const eventOriginFilter = loadTimeData.getString('eventOriginFilter');
-      const webview =
-          /** @type {!WebView} */ (this.$.webview);
+      const webview = this.$.webview;
 
       const accessToken = result.oauthToken;
       const flowType = loadTimeData.getString('flowType');
@@ -119,9 +111,10 @@
       url.searchParams.set('hl', languageCode);
 
       // Allow guest webview content to open links in new windows.
-      webview.addEventListener('newwindow', function(e) {
-        window.open(e.targetUrl);
-      });
+      webview.addEventListener(
+          'newwindow', (e: chrome.webviewTag.NewWindowEvent) => {
+            window.open(e.targetUrl);
+          });
 
       // Change loading indicator on load in order to hide loading spinner.
       webview.addEventListener('contentload', () => {
@@ -147,15 +140,15 @@
 
       // Block any requests to URLs other than one specified
       // by eventOriginFilter.
-      webview.request.onBeforeRequest.addListener(function(details) {
-        return {cancel: !isAllowedRequest(details)};
+      webview.request.onBeforeRequest.addListener((details: {url: string}) => {
+        return {cancel: !isAllowedRequest(details.url)};
       }, {urls: ['<all_urls>']}, ['blocking']);
 
       webview.src = url.toString();
 
       // Set up the server.
-      this.server_ =
-          new AddSupervisionAPIServer(this, webview, url, eventOriginFilter);
+      this.server_ = new AddSupervisionApiServer(
+          this, webview, url.toString(), eventOriginFilter);
     });
   }
 
@@ -166,7 +159,7 @@
     }));
   }
 
-  getAPIServerForTest() {
+  getApiServerForTest(): AddSupervisionApiServer|null {
     return this.server_;
   }
 }
diff --git a/chrome/browser/touch_to_fill/password_generation/android/BUILD.gn b/chrome/browser/touch_to_fill/password_generation/android/BUILD.gn
index 5b164d75..328c63ab1 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/BUILD.gn
+++ b/chrome/browser/touch_to_fill/password_generation/android/BUILD.gn
@@ -8,6 +8,7 @@
   deps = [
     ":android",
     "//base",
+    "//chrome/browser/autofill:autofill",
     "//chrome/browser/password_manager/android:password_generation_utils",
     "//components/password_manager/content/browser:browser",
     "//content/public/browser",
diff --git a/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.cc b/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.cc
index 53b86cc..57d4070 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.cc
+++ b/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.cc
@@ -13,7 +13,7 @@
 
 bool FakeTouchToFillPasswordGenerationBridge::Show(
     content::WebContents* web_contents,
-    base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate,
+    TouchToFillPasswordGenerationDelegate* delegate,
     std::u16string password,
     std::string account) {
   delegate_ = delegate;
@@ -31,3 +31,6 @@
 void FakeTouchToFillPasswordGenerationBridge::OnGeneratedPasswordAccepted(
     JNIEnv* env,
     const base::android::JavaParamRef<jstring>& password) {}
+
+void FakeTouchToFillPasswordGenerationBridge::OnGeneratedPasswordRejected(
+    JNIEnv* env) {}
diff --git a/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.h b/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.h
index ce34d8c..91072ec 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.h
+++ b/chrome/browser/touch_to_fill/password_generation/android/fake_touch_to_fill_password_generation_bridge.h
@@ -16,7 +16,7 @@
   ~FakeTouchToFillPasswordGenerationBridge() override;
 
   bool Show(content::WebContents* web_contents,
-            base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate,
+            TouchToFillPasswordGenerationDelegate* delegate,
             std::u16string password,
             std::string account) override;
   void Hide() override;
@@ -24,9 +24,10 @@
   void OnGeneratedPasswordAccepted(
       JNIEnv* env,
       const base::android::JavaParamRef<jstring>& password) override;
+  void OnGeneratedPasswordRejected(JNIEnv* env) override;
 
  private:
-  base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate_;
+  raw_ptr<TouchToFillPasswordGenerationDelegate> delegate_;
 };
 
 #endif  // CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_FAKE_TOUCH_TO_FILL_PASSWORD_GENERATION_BRIDGE_H_
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/res/layout/touch_to_fill_password_generation.xml b/chrome/browser/touch_to_fill/password_generation/android/internal/java/res/layout/touch_to_fill_password_generation.xml
index 940c695b..78768b98 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/res/layout/touch_to_fill_password_generation.xml
+++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/res/layout/touch_to_fill_password_generation.xml
@@ -58,7 +58,7 @@
       android:gravity="center"
       style="style/FilledButton.Flat"/>
   <org.chromium.ui.widget.ButtonCompat
-      android:id="@+id/create_password_button"
+      android:id="@+id/reject_password_button"
       android:text="@string/password_generation_bottom_sheet_dismiss_button"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridge.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridge.java
index 15f5c12..1b9bb62 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridge.java
+++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridge.java
@@ -63,10 +63,19 @@
                 mNativeTouchToFillPasswordGenerationBridge, password);
     }
 
+    @Override
+    public void onGeneratedPasswordRejected() {
+        if (mNativeTouchToFillPasswordGenerationBridge == 0) return;
+
+        TouchToFillPasswordGenerationBridgeJni.get().onGeneratedPasswordRejected(
+                mNativeTouchToFillPasswordGenerationBridge);
+    }
+
     @NativeMethods
     interface Natives {
         void onDismissed(long nativeTouchToFillPasswordGenerationBridge);
         void onGeneratedPasswordAccepted(
                 long nativeTouchToFillPasswordGenerationBridge, String password);
+        void onGeneratedPasswordRejected(long nativeTouchToFillPasswordGenerationBridge);
     }
 }
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridgeTest.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridgeTest.java
index f937e7e..4a10ffa6 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridgeTest.java
+++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationBridgeTest.java
@@ -68,4 +68,10 @@
         mBridge.onGeneratedPasswordAccepted(generatedPassword);
         verify(mBridgeJniMock).onGeneratedPasswordAccepted(sTestNativePointer, generatedPassword);
     }
+
+    @Test
+    public void testOnGeneratedPasswordRejected() {
+        mBridge.onGeneratedPasswordRejected();
+        verify(mBridgeJniMock).onGeneratedPasswordRejected(sTestNativePointer);
+    }
 }
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationCoordinator.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationCoordinator.java
index 66ca879..f552482 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationCoordinator.java
+++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationCoordinator.java
@@ -7,6 +7,7 @@
 import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.ACCOUNT_EMAIL;
 import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.GENERATED_PASSWORD;
 import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.PASSWORD_ACCEPTED_CALLBACK;
+import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.PASSWORD_REJECTED_CALLBACK;
 
 import android.content.Context;
 import android.view.LayoutInflater;
@@ -35,6 +36,9 @@
          * @param password the password, which was used.
          */
         void onGeneratedPasswordAccepted(String password);
+
+        /** Called when the user rejects the generated password. */
+        void onGeneratedPasswordRejected();
     }
 
     private final TouchToFillPasswordGenerationView mTouchToFillPasswordGenerationView;
@@ -76,6 +80,7 @@
                         .with(ACCOUNT_EMAIL, account)
                         .with(GENERATED_PASSWORD, generatedPassword)
                         .with(PASSWORD_ACCEPTED_CALLBACK, this::onGeneratedPasswordAccepted)
+                        .with(PASSWORD_REJECTED_CALLBACK, this::onGeneratedPasswordRejected)
                         .build();
         setUpModelChangeProcessors(model, mTouchToFillPasswordGenerationView);
 
@@ -99,7 +104,12 @@
 
     private void onGeneratedPasswordAccepted(String password) {
         mTouchToFillPasswordGenerationDelegate.onGeneratedPasswordAccepted(password);
-        onDismissed(StateChangeReason.NONE);
+        onDismissed(StateChangeReason.INTERACTION_COMPLETE);
+    }
+
+    private void onGeneratedPasswordRejected() {
+        mTouchToFillPasswordGenerationDelegate.onGeneratedPasswordRejected();
+        onDismissed(StateChangeReason.INTERACTION_COMPLETE);
     }
 
     /**
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationModuleTest.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationModuleTest.java
index d8e9746..7b98e89 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationModuleTest.java
+++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationModuleTest.java
@@ -123,4 +123,23 @@
         verify(mBottomSheetController).hideContent(any(), anyBoolean());
         verify(mDelegate).onDismissed();
     }
+
+    @Test
+    public void testGeneratedPasswordRejectedCalled() {
+        mCoordinator.show(sGeneratedPassword, sTestEmailAddress);
+
+        Button rejectPasswordButton = mContent.findViewById(R.id.reject_password_button);
+        rejectPasswordButton.performClick();
+        verify(mDelegate).onGeneratedPasswordRejected();
+    }
+
+    @Test
+    public void testBottomSheetIsHiddenAfterRejectingPassword() {
+        mCoordinator.show(sGeneratedPassword, sTestEmailAddress);
+
+        Button rejectPasswordButton = mContent.findViewById(R.id.reject_password_button);
+        rejectPasswordButton.performClick();
+        verify(mBottomSheetController).hideContent(any(), anyBoolean());
+        verify(mDelegate).onDismissed();
+    }
 }
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationProperties.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationProperties.java
index d06cba5..7bbd2d0 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationProperties.java
+++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationProperties.java
@@ -21,6 +21,9 @@
     public static final ReadableObjectPropertyKey<Callback<String>> PASSWORD_ACCEPTED_CALLBACK =
             new ReadableObjectPropertyKey<>();
 
-    public static final PropertyKey[] ALL_KEYS =
-            new PropertyKey[] {ACCOUNT_EMAIL, GENERATED_PASSWORD, PASSWORD_ACCEPTED_CALLBACK};
+    public static final ReadableObjectPropertyKey<Runnable> PASSWORD_REJECTED_CALLBACK =
+            new ReadableObjectPropertyKey<>();
+
+    public static final PropertyKey[] ALL_KEYS = new PropertyKey[] {ACCOUNT_EMAIL,
+            GENERATED_PASSWORD, PASSWORD_ACCEPTED_CALLBACK, PASSWORD_REJECTED_CALLBACK};
 }
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationView.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationView.java
index 280c1b1..bea016b 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationView.java
+++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationView.java
@@ -63,6 +63,11 @@
                 (v) -> callback.onResult(mPasswordView.getText().toString()));
     }
 
+    void setPasswordRejectedCallback(Runnable callback) {
+        Button passwordRejectedButton = mContent.findViewById(R.id.reject_password_button);
+        passwordRejectedButton.setOnClickListener((v) -> callback.run());
+    }
+
     @Override
     public View getContentView() {
         return mContent;
diff --git a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationViewBinder.java b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationViewBinder.java
index 689a8e9..01418da 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationViewBinder.java
+++ b/chrome/browser/touch_to_fill/password_generation/android/internal/java/src/org/chromium/chrome/browser/touch_to_fill/password_generation/TouchToFillPasswordGenerationViewBinder.java
@@ -7,6 +7,7 @@
 import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.ACCOUNT_EMAIL;
 import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.GENERATED_PASSWORD;
 import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.PASSWORD_ACCEPTED_CALLBACK;
+import static org.chromium.chrome.browser.touch_to_fill.password_generation.TouchToFillPasswordGenerationProperties.PASSWORD_REJECTED_CALLBACK;
 
 import org.chromium.ui.modelutil.PropertyKey;
 import org.chromium.ui.modelutil.PropertyModel;
@@ -30,6 +31,8 @@
             view.setGeneratedPassword(model.get(GENERATED_PASSWORD));
         } else if (propertyKey == PASSWORD_ACCEPTED_CALLBACK) {
             view.setPasswordAcceptedCallback(model.get(PASSWORD_ACCEPTED_CALLBACK));
+        } else if (propertyKey == PASSWORD_REJECTED_CALLBACK) {
+            view.setPasswordRejectedCallback(model.get(PASSWORD_REJECTED_CALLBACK));
         }
     }
 }
diff --git a/chrome/browser/touch_to_fill/password_generation/android/mock_touch_to_fill_password_generation_bridge.h b/chrome/browser/touch_to_fill/password_generation/android/mock_touch_to_fill_password_generation_bridge.h
index d45a682..ee819a1 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/mock_touch_to_fill_password_generation_bridge.h
+++ b/chrome/browser/touch_to_fill/password_generation/android/mock_touch_to_fill_password_generation_bridge.h
@@ -19,7 +19,7 @@
   MOCK_METHOD(bool,
               Show,
               (content::WebContents*,
-               base::WeakPtr<TouchToFillPasswordGenerationDelegate>,
+               TouchToFillPasswordGenerationDelegate*,
                std::u16string,
                std::string),
               (override));
@@ -29,6 +29,7 @@
               OnGeneratedPasswordAccepted,
               (JNIEnv*, const base::android::JavaParamRef<jstring>&),
               (override));
+  MOCK_METHOD(void, OnGeneratedPasswordRejected, (JNIEnv*), (override));
 };
 
 #endif  // CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_MOCK_TOUCH_TO_FILL_PASSWORD_GENERATION_BRIDGE_H_
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h
index 81da717..5d10a0a 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h
+++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h
@@ -16,16 +16,16 @@
  public:
   virtual ~TouchToFillPasswordGenerationBridge() = default;
 
-  virtual bool Show(
-      content::WebContents* web_contents,
-      base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate_,
-      std::u16string password,
-      std::string account) = 0;
+  virtual bool Show(content::WebContents* web_contents,
+                    TouchToFillPasswordGenerationDelegate* delegate,
+                    std::u16string password,
+                    std::string account) = 0;
   virtual void Hide() = 0;
   virtual void OnDismissed(JNIEnv* env) = 0;
   virtual void OnGeneratedPasswordAccepted(
       JNIEnv* env,
       const base::android::JavaParamRef<jstring>& password) = 0;
+  virtual void OnGeneratedPasswordRejected(JNIEnv* env) = 0;
 };
 
 #endif  // CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_BRIDGE_H_
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.cc b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.cc
index b1e9d7d..20564c2 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.cc
+++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.cc
@@ -24,7 +24,7 @@
 
 bool TouchToFillPasswordGenerationBridgeImpl::Show(
     content::WebContents* web_contents,
-    base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate,
+    TouchToFillPasswordGenerationDelegate* delegate,
     std::u16string password,
     std::string account) {
   if (!web_contents->GetNativeView() ||
@@ -70,3 +70,9 @@
   delegate_->OnGeneratedPasswordAccepted(
       base::android::ConvertJavaStringToUTF16(env, password));
 }
+
+void TouchToFillPasswordGenerationBridgeImpl::OnGeneratedPasswordRejected(
+    JNIEnv* env) {
+  CHECK(delegate_);
+  delegate_->OnGeneratedPasswordRejected();
+}
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h
index fb34f5c..2951990 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h
+++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge_impl.h
@@ -5,8 +5,7 @@
 #ifndef CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_BRIDGE_IMPL_H_
 #define CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_BRIDGE_IMPL_H_
 
-#include "base/android/scoped_java_ref.h"
-#include "base/memory/weak_ptr.h"
+#include "base/memory/raw_ptr.h"
 #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h"
 #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_delegate.h"
 #include "content/public/browser/web_contents.h"
@@ -22,7 +21,7 @@
   ~TouchToFillPasswordGenerationBridgeImpl() override;
 
   bool Show(content::WebContents* web_contents,
-            base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate,
+            TouchToFillPasswordGenerationDelegate* delegate,
             std::u16string password,
             std::string account) override;
 
@@ -34,10 +33,14 @@
       JNIEnv* env,
       const base::android::JavaParamRef<jstring>& password) override;
 
+  void OnGeneratedPasswordRejected(JNIEnv* env) override;
+
  private:
   // The corresponding Java TouchToFillCreditCardViewBridge.
   base::android::ScopedJavaGlobalRef<jobject> java_object_;
-  base::WeakPtr<TouchToFillPasswordGenerationDelegate> delegate_;
+  // The `delegate_` is the owner of this bridge, so its lifetime is for sure
+  // longer than this bridge's lifetime.
+  raw_ptr<TouchToFillPasswordGenerationDelegate> delegate_ = nullptr;
 };
 
 #endif  // CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_BRIDGE_IMPL_H_
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.cc b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.cc
index 53157559..ac3d90e 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.cc
+++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.cc
@@ -8,12 +8,15 @@
 #include <string>
 #include "base/check.h"
 #include "base/memory/weak_ptr.h"
+#include "chrome/browser/autofill/manual_filling_controller.h"
 #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h"
 #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h"
 #include "components/password_manager/content/browser/content_password_manager_driver.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/browser/web_contents.h"
 
+using ShouldShowAction = ManualFillingController::ShouldShowAction;
+
 TouchToFillPasswordGenerationController::
     ~TouchToFillPasswordGenerationController() {
   HideTouchToFill();
@@ -27,12 +30,14 @@
         content::WebContents* web_contents,
         PasswordGenerationElementData generation_element_data,
         std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge,
-        OnDismissedCallback on_dismissed_callback)
+        OnDismissedCallback on_dismissed_callback,
+        base::WeakPtr<ManualFillingController> manual_filling_controller)
     : frame_driver_(frame_driver),
       web_contents_(web_contents),
       generation_element_data_(std::move(generation_element_data)),
       bridge_(std::move(bridge)),
-      on_dismissed_callback_(std::move(on_dismissed_callback)) {
+      on_dismissed_callback_(std::move(on_dismissed_callback)),
+      manual_filling_controller_(manual_filling_controller) {
   CHECK(bridge_);
   CHECK(on_dismissed_callback_);
   suppress_showing_ime_callback_ = base::BindRepeating([]() {
@@ -50,8 +55,7 @@
           generation_element_data_.form_signature,
           generation_element_data_.field_signature,
           generation_element_data_.max_password_length);
-  if (!bridge_->Show(web_contents_, base::AsWeakPtr(this),
-                     std::move(generated_password),
+  if (!bridge_->Show(web_contents_, this, std::move(generated_password),
                      std::move(account_display_name))) {
     return false;
   }
@@ -77,6 +81,12 @@
       generation_element_data_.generation_element_id, password);
 }
 
+void TouchToFillPasswordGenerationController::OnGeneratedPasswordRejected() {
+  manual_filling_controller_->OnAccessoryActionAvailabilityChanged(
+      ShouldShowAction(true),
+      autofill::AccessoryAction::GENERATE_PASSWORD_AUTOMATIC);
+}
+
 void TouchToFillPasswordGenerationController::AddSuppressShowingImeCallback() {
   if (suppress_showing_ime_callback_added_) {
     return;
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h
index cfcfee1..cdcc744 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h
+++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h
@@ -8,6 +8,7 @@
 #include <string>
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
+#include "chrome/browser/autofill/manual_filling_controller.h"
 #include "chrome/browser/password_manager/android/password_generation_element_data.h"
 #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_bridge.h"
 #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_delegate.h"
@@ -33,7 +34,8 @@
       content::WebContents* web_contents,
       PasswordGenerationElementData generation_element_data,
       std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge,
-      OnDismissedCallback on_dismissed_callback);
+      OnDismissedCallback on_dismissed_callback,
+      base::WeakPtr<ManualFillingController> manual_filling_controller);
   TouchToFillPasswordGenerationController(
       const TouchToFillPasswordGenerationController&) = delete;
   TouchToFillPasswordGenerationController& operator=(
@@ -47,6 +49,8 @@
 
   void OnGeneratedPasswordAccepted(const std::u16string& password) override;
 
+  void OnGeneratedPasswordRejected() override;
+
  private:
   // Suppressing IME input is necessary for Touch-To-Fill.
   void AddSuppressShowingImeCallback();
@@ -62,6 +66,8 @@
   PasswordGenerationElementData generation_element_data_;
   std::unique_ptr<TouchToFillPasswordGenerationBridge> bridge_;
   OnDismissedCallback on_dismissed_callback_;
+  // The manual filling controller object to forward client requests to.
+  base::WeakPtr<ManualFillingController> manual_filling_controller_;
 
   content::RenderWidgetHost::SuppressShowingImeCallback
       suppress_showing_ime_callback_;
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller_unittest.cc b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller_unittest.cc
index d4d06a5..4a0c19a 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller_unittest.cc
+++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller_unittest.cc
@@ -7,6 +7,7 @@
 
 #include "base/memory/weak_ptr.h"
 #include "base/test/mock_callback.h"
+#include "chrome/browser/autofill/mock_manual_filling_controller.h"
 #include "chrome/browser/password_manager/android/password_generation_element_data.h"
 #include "chrome/browser/touch_to_fill/password_generation/android/mock_touch_to_fill_password_generation_bridge.h"
 #include "chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_controller.h"
@@ -19,6 +20,7 @@
 
 using testing::_;
 using testing::Eq;
+using ShouldShowAction = ManualFillingController::ShouldShowAction;
 
 class TouchToFillPasswordGenerationControllerTest
     : public ChromeRenderViewHostTestHarness {
@@ -37,6 +39,7 @@
 
   base::MockCallback<base::OnceCallback<void()>> on_dismissed_callback_;
   const std::string test_user_account_ = "test@email.com";
+  MockManualFillingController mock_manual_filling_controller_;
 
  private:
   std::unique_ptr<password_manager::ContentPasswordManagerDriver>
@@ -51,7 +54,8 @@
   auto controller = std::make_unique<TouchToFillPasswordGenerationController>(
       password_mananger_driver(), web_contents(),
       PasswordGenerationElementData(), std::move(bridge),
-      on_dismissed_callback_.Get());
+      on_dismissed_callback_.Get(),
+      mock_manual_filling_controller_.AsWeakPtr());
   EXPECT_CALL(*bridge_ptr, Show);
   controller->ShowTouchToFill(test_user_account_);
 
@@ -82,7 +86,8 @@
       password_mananger_driver(), web_contents(),
       PasswordGenerationElementData(),
       std::make_unique<MockTouchToFillPasswordGenerationBridge>(),
-      on_dismissed_callback_.Get());
+      on_dismissed_callback_.Get(),
+      mock_manual_filling_controller_.AsWeakPtr());
 
   controller->ShowTouchToFill(test_user_account_);
 
@@ -97,7 +102,8 @@
   auto controller = std::make_unique<TouchToFillPasswordGenerationController>(
       password_mananger_driver(), web_contents(),
       PasswordGenerationElementData(), std::move(bridge),
-      on_dismissed_callback_.Get());
+      on_dismissed_callback_.Get(),
+      mock_manual_filling_controller_.AsWeakPtr());
 
   EXPECT_CALL(*bridge_ptr, Show(_, _, _, Eq(test_user_account_)));
   controller->ShowTouchToFill(test_user_account_);
@@ -105,3 +111,21 @@
   EXPECT_CALL(*bridge_ptr, Hide);
   controller.reset();
 }
+
+TEST_F(TouchToFillPasswordGenerationControllerTest,
+       TriggersKeyboardAccessoryWhenGeneratedPasswordRejected) {
+  auto controller = std::make_unique<TouchToFillPasswordGenerationController>(
+      password_mananger_driver(), web_contents(),
+      PasswordGenerationElementData(),
+      std::make_unique<MockTouchToFillPasswordGenerationBridge>(),
+      on_dismissed_callback_.Get(),
+      mock_manual_filling_controller_.AsWeakPtr());
+
+  controller->ShowTouchToFill(test_user_account_);
+
+  EXPECT_CALL(mock_manual_filling_controller_,
+              OnAccessoryActionAvailabilityChanged(
+                  ShouldShowAction(true),
+                  autofill::AccessoryAction::GENERATE_PASSWORD_AUTOMATIC));
+  controller->OnGeneratedPasswordRejected();
+}
diff --git a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_delegate.h b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_delegate.h
index ca0de30..af9ebd1 100644
--- a/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_delegate.h
+++ b/chrome/browser/touch_to_fill/password_generation/android/touch_to_fill_password_generation_delegate.h
@@ -5,13 +5,10 @@
 #ifndef CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_DELEGATE_H_
 #define CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_DELEGATE_H_
 
-#include "base/memory/weak_ptr.h"
-
 // The delegate, which handles the Password generation bottom sheet
 // (Touch-To-Fill) functionality. Implemented by
 // `TouchToFillPasswordGenerationController`.
-class TouchToFillPasswordGenerationDelegate
-    : public base::SupportsWeakPtr<TouchToFillPasswordGenerationDelegate> {
+class TouchToFillPasswordGenerationDelegate {
  public:
   virtual ~TouchToFillPasswordGenerationDelegate() = default;
 
@@ -22,6 +19,11 @@
   // Called if the user accepts the proposed generated password. Here the
   // password should be saved and filled into the form.
   virtual void OnGeneratedPasswordAccepted(const std::u16string& password) = 0;
+
+  // Called if the user doesn't accept the proposed generated password. Here the
+  // keyboard accessory bar with "Suggest strong password" button should be
+  // displayed.
+  virtual void OnGeneratedPasswordRejected() = 0;
 };
 
 #endif  // CHROME_BROWSER_TOUCH_TO_FILL_PASSWORD_GENERATION_ANDROID_TOUCH_TO_FILL_PASSWORD_GENERATION_DELEGATE_H_
diff --git a/chrome/browser/ui/android/hats/BUILD.gn b/chrome/browser/ui/android/hats/BUILD.gn
index 8d70540..36a8b56 100644
--- a/chrome/browser/ui/android/hats/BUILD.gn
+++ b/chrome/browser/ui/android/hats/BUILD.gn
@@ -16,6 +16,7 @@
     "//base:jni_java",
     "//third_party/androidx:androidx_annotation_annotation_java",
   ]
+  public_deps = [ ":utils_java" ]
 }
 
 android_library_factory("factory_java") {
@@ -26,6 +27,38 @@
   sources = [ "internal/java/src/org/chromium/chrome/browser/ui/hats/SurveyClientFactory.java" ]
 }
 
+# Temporarily public to the rest of components during code movement.
+# TODO(crbug/1400731): Move into internal once public references are removed.
+android_library("utils_java") {
+  sources =
+      [ "java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottler.java" ]
+
+  deps = [
+    "//base:base_java",
+    "//chrome/browser/first_run/android:java",
+    "//chrome/browser/flags:java",
+    "//chrome/browser/preferences:java",
+    "//third_party/androidx:androidx_annotation_annotation_java",
+  ]
+}
+
+robolectric_library("junit") {
+  testonly = true
+  sources = [
+    "java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottlerUnitTest.java",
+  ]
+  deps = [
+    ":utils_java",
+    "//base:base_java",
+    "//base:base_java_test_support",
+    "//base:base_junit_test_support",
+    "//chrome/browser/first_run/android:java",
+    "//chrome/browser/preferences:java",
+    "//chrome/browser/ui/android/hats:java",
+    "//third_party/junit",
+  ]
+}
+
 android_library("unit_device_javatests") {
   testonly = true
   sources =
diff --git a/chrome/browser/ui/android/hats/DEPS b/chrome/browser/ui/android/hats/DEPS
index e73d4f9f..07839b7 100644
--- a/chrome/browser/ui/android/hats/DEPS
+++ b/chrome/browser/ui/android/hats/DEPS
@@ -1,3 +1,10 @@
 include_rules = [
   "-chrome/browser/ui/android/hats/internal",
+]
+
+specific_include_rules = {
+  # Special-case that's temporary during modularization.
+  "SurveyThrottler\.java" : [
+    "+chrome/android/java/src/org/chromium/chrome/browser/survey/ChromeSurveyController.java"
   ]
+}
diff --git a/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottler.java b/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottler.java
new file mode 100644
index 0000000..b9526d7e
--- /dev/null
+++ b/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottler.java
@@ -0,0 +1,199 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.ui.hats;
+
+import androidx.annotation.IntDef;
+import androidx.annotation.VisibleForTesting;
+
+import org.chromium.base.CommandLine;
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.base.supplier.Supplier;
+import org.chromium.chrome.browser.firstrun.FirstRunStatus;
+import org.chromium.chrome.browser.flags.ChromeSwitches;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Calendar;
+import java.util.Random;
+
+/**
+ * Class used to check whether survey can be shown based on metadata. The class is also responsible
+ * to collect survey related information, and update the metadata for and triggerId.
+ */
+public class SurveyThrottler {
+    private static final int DOWNLOAD_ATTEMPTS_HIST_NUM_BUCKETS = 20;
+
+    /**
+     * Reasons that the user was rejected from being selected for a survey
+     * Note: these values cannot change and must match the SurveyFilteringResult enum in enums.xml
+     * because they're written to logs.
+     */
+    @IntDef({FilteringResult.SURVEY_PROMPT_ALREADY_DISPLAYED,
+            FilteringResult.FORCE_SURVEY_ON_COMMAND_PRESENT,
+            FilteringResult.USER_ALREADY_SAMPLED_TODAY, FilteringResult.MAX_NUMBER_MISSING,
+            FilteringResult.ROLLED_NON_ZERO_NUMBER, FilteringResult.USER_SELECTED_FOR_SURVEY,
+            FilteringResult.FIRST_TIME_USER, FilteringResult.NUM_ENTRIES})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FilteringResult {
+        int SURVEY_PROMPT_ALREADY_DISPLAYED = 0;
+        int FORCE_SURVEY_ON_COMMAND_PRESENT = 2;
+        int USER_ALREADY_SAMPLED_TODAY = 3;
+        int MAX_NUMBER_MISSING = 4;
+        int ROLLED_NON_ZERO_NUMBER = 5;
+        int USER_SELECTED_FOR_SURVEY = 6;
+        int FIRST_TIME_USER = 8;
+        // Number of entries
+        int NUM_ENTRIES = 9;
+    }
+
+    private final String mTriggerId;
+    private final float mProbability;
+    private final Supplier<Boolean> mCrashUploadPermissionSupplier;
+
+    private final String mPrefKeyPromptDisplayed;
+    private final String mPrefKeyDownloadAttempts;
+    private final int mMaxDownloadAttempts;
+
+    /**
+     * @param triggerId The trigger Id for the given survey.
+     * @param probability The rate an eligible user is randomly selected for the survey.
+     * @param crashUploadPermissionSupplier Whether crash upload is permitted.
+     * @param maxDownloadCap Max number of downloads allowed.
+     */
+    public SurveyThrottler(String triggerId, float probability,
+            Supplier<Boolean> crashUploadPermissionSupplier, int maxDownloadCap) {
+        mTriggerId = triggerId;
+        mProbability = probability;
+        mCrashUploadPermissionSupplier = crashUploadPermissionSupplier;
+        mMaxDownloadAttempts = maxDownloadCap;
+
+        mPrefKeyPromptDisplayed =
+                ChromePreferenceKeys.CHROME_SURVEY_PROMPT_DISPLAYED_TIMESTAMP.createKey(mTriggerId);
+        mPrefKeyDownloadAttempts =
+                ChromePreferenceKeys.CHROME_SURVEY_DOWNLOAD_ATTEMPTS.createKey(mTriggerId);
+    }
+
+    /**
+     * @return Whether the given survey can be shown.
+     */
+    public boolean canShowSurvey() {
+        if (Boolean.FALSE.equals(mCrashUploadPermissionSupplier.get())) {
+            return false;
+        }
+
+        if (isSurveyForceEnabled()) {
+            recordSurveyFilteringResult(FilteringResult.FORCE_SURVEY_ON_COMMAND_PRESENT);
+            return true;
+        }
+
+        if (FirstRunStatus.isFirstRunTriggered()) {
+            recordSurveyFilteringResult(FilteringResult.FIRST_TIME_USER);
+            return false;
+        }
+
+        if (hasPromptBeenDisplayed()) {
+            recordSurveyFilteringResult(FilteringResult.SURVEY_PROMPT_ALREADY_DISPLAYED);
+            return false;
+        }
+
+        if (!isDownloadAttemptAllowed()) {
+            // TODO(wenyufu): Add new FilteringResult for download attempts.
+            return false;
+        }
+
+        return isRandomlySelectedForSurvey();
+    }
+
+    /**  Record a survey download is attempted. */
+    public void recordDownloadAttempted() {
+        SharedPreferencesManager.getInstance().incrementInt(mPrefKeyDownloadAttempts);
+    }
+
+    /** Logs in SharedPreferences that the survey prompt was displayed. */
+    public void recordSurveyPromptDisplayed() {
+        SharedPreferencesManager preferences = SharedPreferencesManager.getInstance();
+        preferences.writeLong(mPrefKeyPromptDisplayed, System.currentTimeMillis());
+    }
+
+    /** Logs in SharedPreferences that the survey is accepted. */
+    public void recordSurveyAccepted() {
+        int downloadAttemptsMade =
+                SharedPreferencesManager.getInstance().readInt(mPrefKeyDownloadAttempts, 0);
+        RecordHistogram.recordLinearCountHistogram("Android.Survey.DownloadAttemptsBeforeAccepted",
+                downloadAttemptsMade, 1, DOWNLOAD_ATTEMPTS_HIST_NUM_BUCKETS,
+                DOWNLOAD_ATTEMPTS_HIST_NUM_BUCKETS + 1);
+    }
+
+    /**
+     * Rolls a random number to see if the user was eligible for the survey. The user will skip the
+     * roll if:
+     *  1. User is a first time user
+     *  2. User as performed the roll today
+     *  3. Max number is not setup correctly
+     *
+     * @return Whether the user is eligible (i.e. the random number rolled was 0).
+     */
+    private boolean isRandomlySelectedForSurvey() {
+        SharedPreferencesManager preferences = SharedPreferencesManager.getInstance();
+        int lastDate = preferences.readInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, -1);
+        int today = getDayOfYear();
+        if (lastDate == today) {
+            recordSurveyFilteringResult(FilteringResult.USER_ALREADY_SAMPLED_TODAY);
+            return false;
+        }
+
+        if (mProbability <= 0) {
+            recordSurveyFilteringResult(FilteringResult.MAX_NUMBER_MISSING);
+            return false;
+        }
+
+        preferences.writeInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, today);
+        if (isSelectedWithByRandom()) {
+            recordSurveyFilteringResult(FilteringResult.USER_SELECTED_FOR_SURVEY);
+            return true;
+        } else {
+            recordSurveyFilteringResult(FilteringResult.ROLLED_NON_ZERO_NUMBER);
+            return false;
+        }
+    }
+
+    /** @return If the survey info bar for this survey was logged as seen before. */
+    private boolean hasPromptBeenDisplayed() {
+        SharedPreferencesManager preferences = SharedPreferencesManager.getInstance();
+        // TODO(https://crbug.com/1195928): Get an expiration date from feature flag.
+        return preferences.readLong(mPrefKeyPromptDisplayed, -1L) != -1L;
+    }
+
+    private boolean isDownloadAttemptAllowed() {
+        int downloadAttemptsMade =
+                SharedPreferencesManager.getInstance().readInt(mPrefKeyDownloadAttempts, 0);
+        return mMaxDownloadAttempts <= 0 || downloadAttemptsMade < mMaxDownloadAttempts;
+    }
+
+    @VisibleForTesting
+    boolean isSelectedWithByRandom() {
+        return new Random().nextFloat() <= mProbability;
+    }
+
+    /** @return The day of the year for today. */
+    @VisibleForTesting
+    int getDayOfYear() {
+        ThreadUtils.assertOnBackgroundThread();
+        return Calendar.getInstance().get(Calendar.DAY_OF_YEAR);
+    }
+
+    private static void recordSurveyFilteringResult(@FilteringResult int value) {
+        RecordHistogram.recordEnumeratedHistogram(
+                "Android.Survey.SurveyFilteringResults", value, FilteringResult.NUM_ENTRIES);
+    }
+
+    /** @return Whether survey is enabled by command line flag. */
+    private static boolean isSurveyForceEnabled() {
+        return CommandLine.getInstance().hasSwitch(ChromeSwitches.CHROME_FORCE_ENABLE_SURVEY);
+    }
+}
diff --git a/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottlerUnitTest.java b/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottlerUnitTest.java
new file mode 100644
index 0000000..43e479d
--- /dev/null
+++ b/chrome/browser/ui/android/hats/java/src/org/chromium/chrome/browser/ui/hats/SurveyThrottlerUnitTest.java
@@ -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.
+
+package org.chromium.chrome.browser.ui.hats;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.supplier.ObservableSupplierImpl;
+import org.chromium.base.supplier.Supplier;
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.HistogramWatcher;
+import org.chromium.chrome.browser.firstrun.FirstRunStatus;
+import org.chromium.chrome.browser.preferences.ChromePreferenceKeys;
+import org.chromium.chrome.browser.preferences.SharedPreferencesManager;
+import org.chromium.chrome.browser.ui.hats.SurveyThrottler.FilteringResult;
+
+/**
+ * Unit tests for {@link SurveyThrottler}.
+ */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(manifest = Config.NONE)
+public class SurveyThrottlerUnitTest {
+    private static final String TEST_TRIGGER_ID = "foobar";
+
+    private SharedPreferencesManager mSharedPref;
+    private ObservableSupplierImpl<Boolean> mCrashUploadEnabledSupplier;
+
+    @Before
+    public void setup() {
+        mSharedPref = SharedPreferencesManager.getInstance();
+        mCrashUploadEnabledSupplier = new ObservableSupplierImpl<>();
+        mCrashUploadEnabledSupplier.set(true);
+
+        FirstRunStatus.setFirstRunTriggeredForTesting(false);
+    }
+
+    @Test
+    public void testSuccessfullyShown() {
+        // Set Requirements to show the survey.
+        mCrashUploadEnabledSupplier.set(true);
+        RiggedSurveyThrottler throttler = new RiggedSurveyThrottler(/*randomlySelected=*/true, 1);
+
+        try (HistogramWatcher ignored = HistogramWatcher.newSingleRecordWatcher(
+                     "Android.Survey.SurveyFilteringResults",
+                     FilteringResult.USER_SELECTED_FOR_SURVEY)) {
+            Assert.assertTrue("Survey should be shown.", throttler.canShowSurvey());
+        }
+    }
+
+    @Test
+    public void testFirstTimeUser() {
+        FirstRunStatus.setFirstRunTriggeredForTesting(true);
+        mCrashUploadEnabledSupplier.set(true);
+        RiggedSurveyThrottler throttler =
+                new RiggedSurveyThrottler(/*randomlySelected=*/true, /*dayOfYear=*/1);
+
+        try (HistogramWatcher ignored = HistogramWatcher.newSingleRecordWatcher(
+                     "Android.Survey.SurveyFilteringResults", FilteringResult.FIRST_TIME_USER)) {
+            Assert.assertFalse(
+                    "Survey shouldn't shown for first time users.", throttler.canShowSurvey());
+        }
+    }
+
+    @Test
+    public void testCrashUploadsDisabled() {
+        mCrashUploadEnabledSupplier.set(false);
+        RiggedSurveyThrottler throttler = new RiggedSurveyThrottler(/*randomlySelected=*/true, 1);
+
+        try (HistogramWatcher ignored =
+                        HistogramWatcher.newBuilder()
+                                .expectNoRecords("Android.Survey.SurveyFilteringResults")
+                                .build()) {
+            Assert.assertFalse("Survey shouldn't shown when UMA upload is disabled.",
+                    throttler.canShowSurvey());
+        }
+    }
+
+    @Test
+    public void testPromptDisplayedBefore() {
+        final String triggerId1 = "triggerId1";
+        int dateOfYear = 1;
+        RiggedSurveyThrottler throttler1 = new RiggedSurveyThrottler(
+                true, dateOfYear, triggerId1, mCrashUploadEnabledSupplier, 0);
+        throttler1.recordSurveyPromptDisplayed();
+        try (HistogramWatcher ignored = HistogramWatcher.newSingleRecordWatcher(
+                     "Android.Survey.SurveyFilteringResults",
+                     FilteringResult.SURVEY_PROMPT_ALREADY_DISPLAYED)) {
+            Assert.assertFalse("Survey can't shown if shown before.", throttler1.canShowSurvey());
+        }
+    }
+
+    @Test
+    public void testPromptDisplayedForOtherTriggerId() {
+        final String triggerId1 = "triggerId1";
+        final String triggerId2 = "triggerId2";
+        int dateOfYear = 1;
+        mCrashUploadEnabledSupplier.set(true);
+
+        String prefKey1 =
+                ChromePreferenceKeys.CHROME_SURVEY_PROMPT_DISPLAYED_TIMESTAMP.createKey(triggerId1);
+        mSharedPref.writeLong(prefKey1, System.currentTimeMillis());
+
+        RiggedSurveyThrottler throttler2 = new RiggedSurveyThrottler(
+                /*randomlySelected=*/true, dateOfYear, triggerId2, mCrashUploadEnabledSupplier, 0);
+
+        try (HistogramWatcher ignored = HistogramWatcher.newSingleRecordWatcher(
+                     "Android.Survey.SurveyFilteringResults",
+                     FilteringResult.USER_SELECTED_FOR_SURVEY)) {
+            Assert.assertTrue(
+                    "Survey with different triggerId can show.", throttler2.canShowSurvey());
+        }
+    }
+
+    @Test
+    public void testEligibilityRolledYesterday() {
+        mCrashUploadEnabledSupplier.set(true);
+
+        mSharedPref.writeInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, 4);
+        RiggedSurveyThrottler throttler =
+                new RiggedSurveyThrottler(/*randomlySelected=*/true, /*dayOfYear=*/5);
+
+        try (HistogramWatcher ignored = HistogramWatcher.newSingleRecordWatcher(
+                     "Android.Survey.SurveyFilteringResults",
+                     FilteringResult.USER_SELECTED_FOR_SURVEY)) {
+            Assert.assertTrue("Random selection should be true", throttler.canShowSurvey());
+        }
+    }
+
+    @Test
+    public void testEligibilityRollingTwiceSameDay() {
+        mCrashUploadEnabledSupplier.set(true);
+        RiggedSurveyThrottler throttler =
+                new RiggedSurveyThrottler(/*randomlySelected=*/true, /*dayOfYear=*/5);
+        mSharedPref.writeInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, 5);
+        try (HistogramWatcher ignored = HistogramWatcher.newSingleRecordWatcher(
+                     "Android.Survey.SurveyFilteringResults",
+                     FilteringResult.USER_ALREADY_SAMPLED_TODAY)) {
+            Assert.assertFalse("Random selection should be false.", throttler.canShowSurvey());
+        }
+    }
+
+    @Test
+    public void testEligibilityFirstTimeRollingQualifies() {
+        mCrashUploadEnabledSupplier.set(true);
+        RiggedSurveyThrottler throttler =
+                new RiggedSurveyThrottler(/*randomlySelected=*/true, /*dayOfYear=*/5);
+        Assert.assertFalse(mSharedPref.contains(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED));
+        Assert.assertTrue("Random selection should be true", throttler.canShowSurvey());
+        Assert.assertEquals("Numbers should match", 5,
+                mSharedPref.readInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, -1));
+    }
+
+    @Test
+    public void testDownloadAttemptsWithinCap() {
+        mCrashUploadEnabledSupplier.set(true);
+        RiggedSurveyThrottler throttler = new RiggedSurveyThrottler(/*randomlySelected=*/true,
+                /*dayOfYear=*/1, TEST_TRIGGER_ID, mCrashUploadEnabledSupplier, 1);
+        Assert.assertTrue("Download allowed within cap", throttler.canShowSurvey());
+    }
+
+    @Test
+    public void testStartDownloadIfEligibleTask_DownloadReachCap() {
+        mCrashUploadEnabledSupplier.set(true);
+        RiggedSurveyThrottler throttler = new RiggedSurveyThrottler(/*randomlySelected=*/true,
+                /*dayOfYear=*/1, TEST_TRIGGER_ID, mCrashUploadEnabledSupplier, 1);
+        // Assume download attempted previously.
+        throttler.recordDownloadAttempted();
+        Assert.assertFalse("Download exceed cap.", throttler.canShowSurvey());
+    }
+
+    @Test
+    public void testEligibilityFirstTimeRollingDoesNotQualify() {
+        mCrashUploadEnabledSupplier.set(true);
+        RiggedSurveyThrottler throttler =
+                new RiggedSurveyThrottler(/*randomlySelected=*/false, /*dayOfYear=*/1);
+        Assert.assertFalse(mSharedPref.contains(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED));
+        try (HistogramWatcher ignored = HistogramWatcher.newSingleRecordWatcher(
+                     "Android.Survey.SurveyFilteringResults",
+                     FilteringResult.ROLLED_NON_ZERO_NUMBER)) {
+            Assert.assertFalse("Random selection should be false.", throttler.canShowSurvey());
+        }
+        Assert.assertEquals("Numbers should match", 1,
+                mSharedPref.readInt(ChromePreferenceKeys.SURVEY_DATE_LAST_ROLLED, -1));
+    }
+
+    /** Test class used to test the rate limiting logic for {@link SurveyThrottler}. */
+    private class RiggedSurveyThrottler extends SurveyThrottler {
+        private final boolean mRandomlySelected;
+        private final int mDayOfYear;
+
+        RiggedSurveyThrottler(boolean randomlySelected, int dayOfYear, String triggerId,
+                Supplier<Boolean> crashUploadPermissionSupplier, int maxDownloadCap) {
+            super(triggerId, 0.5f, crashUploadPermissionSupplier, maxDownloadCap);
+            mRandomlySelected = randomlySelected;
+            mDayOfYear = dayOfYear;
+        }
+
+        RiggedSurveyThrottler(boolean randomlySelected, int dayOfYear) {
+            this(randomlySelected, dayOfYear, TEST_TRIGGER_ID, mCrashUploadEnabledSupplier, 0);
+        }
+
+        @Override
+        boolean isSelectedWithByRandom() {
+            return mRandomlySelected;
+        }
+
+        @Override
+        int getDayOfYear() {
+            return mDayOfYear;
+        }
+    }
+}
diff --git a/chrome/browser/ui/ash/accessibility/ax_tree_source_aura_unittest.cc b/chrome/browser/ui/ash/accessibility/ax_tree_source_aura_unittest.cc
index e9fc6cf6..1d91b0c 100644
--- a/chrome/browser/ui/ash/accessibility/ax_tree_source_aura_unittest.cc
+++ b/chrome/browser/ui/ash/accessibility/ax_tree_source_aura_unittest.cc
@@ -33,7 +33,9 @@
 using views::View;
 using views::Widget;
 
-using AuraAXTreeSerializer = ui::AXTreeSerializer<views::AXAuraObjWrapper*>;
+using AuraAXTreeSerializer =
+    ui::AXTreeSerializer<views::AXAuraObjWrapper*,
+                         std::vector<views::AXAuraObjWrapper*>>;
 
 // Helper to count the number of nodes in a tree.
 size_t GetSize(AXAuraObjWrapper* tree) {
diff --git a/chrome/browser/ui/aura/accessibility/automation_manager_aura.h b/chrome/browser/ui/aura/accessibility/automation_manager_aura.h
index 498488f..4d0ae2b 100644
--- a/chrome/browser/ui/aura/accessibility/automation_manager_aura.h
+++ b/chrome/browser/ui/aura/accessibility/automation_manager_aura.h
@@ -33,7 +33,9 @@
 class View;
 }  // namespace views
 
-using AuraAXTreeSerializer = ui::AXTreeSerializer<views::AXAuraObjWrapper*>;
+using AuraAXTreeSerializer =
+    ui::AXTreeSerializer<views::AXAuraObjWrapper*,
+                         std::vector<views::AXAuraObjWrapper*>>;
 
 // Manages a tree of automation nodes backed by aura constructs.
 class AutomationManagerAura : public ui::AXActionHandler,
diff --git a/chrome/browser/ui/color/OWNERS b/chrome/browser/ui/color/OWNERS
index 8af0d1d4..a7f7574 100644
--- a/chrome/browser/ui/color/OWNERS
+++ b/chrome/browser/ui/color/OWNERS
@@ -1,3 +1,4 @@
 file://ui/color/OWNERS
 
 per-file new_tab_page_color_mixer*=file://chrome/browser/ui/webui/new_tab_page/OWNERS
+per-file material_new_tab_page_color_mixer*=file://chrome/browser/ui/webui/new_tab_page/OWNERS
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
index ef945a0..e9b55ec3 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model.cc
@@ -77,7 +77,6 @@
 #include "mojo/public/cpp/bindings/associated_remote.h"
 #include "ppapi/buildflags/buildflags.h"
 #include "services/device/public/cpp/device_features.h"
-#include "services/device/public/cpp/geolocation/buildflags.h"
 #include "services/device/public/cpp/geolocation/location_system_permission_status.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
 #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
@@ -95,11 +94,6 @@
 #if BUILDFLAG(IS_MAC)
 #include "base/mac/mac_util.h"
 #include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h"
-#endif
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-#include "chrome/browser/ash/privacy_hub/privacy_hub_util.h"
-#endif
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
 #include "services/device/public/cpp/geolocation/geolocation_manager.h"
 #endif
 
@@ -1421,7 +1415,7 @@
                                      web_contents,
                                      ContentSettingsType::GEOLOCATION) {
   SetCustomLink();
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
   // Get the stored geolocation content setting and the system permission state
   // to determine whether geolocation is blocked by a system permission.
   //
@@ -1438,11 +1432,11 @@
   if (content_setting == CONTENT_SETTING_ALLOW &&
       device::GeolocationManager::GetInstance()->GetSystemPermission() !=
           LocationSystemPermissionStatus::kAllowed) {
-    // If the permission is turned off in OS preferences, overwrite
+    // If the permission is turned off in MacOS system preferences, overwrite
     // the bubble to enable the user to trigger the system dialog.
     InitializeSystemGeolocationPermissionBubble();
   }
-#endif  // BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 ContentSettingGeolocationBubbleModel::~ContentSettingGeolocationBubbleModel() =
@@ -1450,24 +1444,16 @@
 
 void ContentSettingGeolocationBubbleModel::OnDoneButtonClicked() {
   if (show_system_geolocation_bubble_) {
-    // This is a no-op on platforms that do not support OS-level geolocation
-    // permissions.
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
     if (show_system_geolocation_bubble_) {
       base::RecordAction(UserMetricsAction(
           "ContentSettings.GeolocationDialog.OpenPreferencesClicked"));
     }
 
-#if BUILDFLAG(IS_MAC)
     base::mac::OpenSystemSettingsPane(
         base::mac::SystemSettingsPane::kPrivacySecurity_LocationServices);
-#elif BUILDFLAG(IS_CHROMEOS_ASH)
-    ash::privacy_hub_util::OpenPrivacyControlsInSettings();
-#elif BUILDFLAG(IS_CHROMEOS_LACROS)
-    // TODO(b/280836944): Open system settings on ChromeOS.
-#endif
-
-#endif
+    return;
+#endif  // BUILDFLAG(IS_MAC)
   }
 }
 
@@ -1484,16 +1470,13 @@
 
 void ContentSettingGeolocationBubbleModel::
     InitializeSystemGeolocationPermissionBubble() {
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
 #if BUILDFLAG(IS_MAC)
-  const int message_id =
-      base::FeatureList::IsEnabled(features::kLocationPermissionsExperiment)
-          ? IDS_GEOLOCATION_TURNED_OFF_IN_MACOS_SETTINGS
-          : IDS_GEOLOCATION_TURNED_OFF_IN_MACOS;
-#else
-  const int message_id = IDS_GEOLOCATION_TURNED_OFF_IN_OS;
-#endif
-  set_title(l10n_util::GetStringUTF16(message_id));
+  if (base::FeatureList::IsEnabled(features::kLocationPermissionsExperiment)) {
+    set_title(l10n_util::GetStringUTF16(
+        IDS_GEOLOCATION_TURNED_OFF_IN_MACOS_SETTINGS));
+  } else {
+    set_title(l10n_util::GetStringUTF16(IDS_GEOLOCATION_TURNED_OFF_IN_MACOS));
+  }
 
   clear_message();
   AddListItem(ContentSettingBubbleModel::ListItem(
@@ -1504,7 +1487,7 @@
   set_done_button_text(l10n_util::GetStringUTF16(IDS_OPEN_SETTINGS_LINK));
   set_radio_group(RadioGroup());
   show_system_geolocation_bubble_ = true;
-#endif  // BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#endif  // BUILDFLAG(IS_MAC)
 }
 
 void ContentSettingGeolocationBubbleModel::SetCustomLink() {
diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
index 42c5afa..c6edd8e 100644
--- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc
@@ -52,12 +52,11 @@
 #include "content/public/test/web_contents_tester.h"
 #include "net/base/schemeful_site.h"
 #include "services/device/public/cpp/device_features.h"
-#include "services/device/public/cpp/geolocation/buildflags.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/mojom/mediastream/media_stream.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
 #include "services/device/public/cpp/geolocation/geolocation_manager.h"
 #include "services/device/public/cpp/geolocation/location_system_permission_status.h"
 #include "services/device/public/cpp/test/fake_geolocation_manager.h"
@@ -755,13 +754,13 @@
 }
 
 TEST_F(ContentSettingBubbleModelTest, Geolocation) {
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
   auto fake_geolocation_manager =
       std::make_unique<device::FakeGeolocationManager>();
   device::FakeGeolocationManager* geolocation_manager =
       fake_geolocation_manager.get();
   device::GeolocationManager::SetInstance(std::move(fake_geolocation_manager));
-#endif
+#endif  // BUILDFLAG(IS_MAC)
 
   WebContentsTester::For(web_contents())
       ->NavigateAndCommit(GURL("https://www.example.com"));
@@ -776,7 +775,7 @@
                                          CONTENT_SETTING_ALLOW);
   content_settings->OnContentAllowed(ContentSettingsType::GEOLOCATION);
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
   // System-level geolocation permission is blocked.
   {
     auto content_setting_bubble_model =
@@ -786,14 +785,8 @@
         FakeOwner::Create(*content_setting_bubble_model, 0);
     const auto& bubble_content = content_setting_bubble_model->bubble_content();
 
-#if BUILDFLAG(IS_MAC)
     EXPECT_EQ(bubble_content.title,
               l10n_util::GetStringUTF16(IDS_GEOLOCATION_TURNED_OFF_IN_MACOS));
-#else
-    EXPECT_EQ(bubble_content.title,
-              l10n_util::GetStringUTF16(IDS_GEOLOCATION_TURNED_OFF_IN_OS));
-#endif
-
     EXPECT_TRUE(bubble_content.message.empty());
     EXPECT_EQ(bubble_content.radio_group.radio_items.size(), 0U);
 
@@ -814,13 +807,8 @@
     geolocation_manager->SetSystemPermission(
         device::LocationSystemPermissionStatus::kAllowed);
 
-#if BUILDFLAG(IS_MAC)
     EXPECT_EQ(bubble_content.title,
               l10n_util::GetStringUTF16(IDS_GEOLOCATION_TURNED_OFF_IN_MACOS));
-#else
-    EXPECT_EQ(bubble_content.title,
-              l10n_util::GetStringUTF16(IDS_GEOLOCATION_TURNED_OFF_IN_OS));
-#endif
     EXPECT_TRUE(bubble_content.message.empty());
     EXPECT_EQ(bubble_content.radio_group.radio_items.size(), 0U);
 
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model.cc b/chrome/browser/ui/content_settings/content_setting_image_model.cc
index 486f1ad..cdfcb18 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model.cc
@@ -63,7 +63,7 @@
 #include "chrome/browser/media/webrtc/system_media_capture_permissions_mac.h"
 #endif
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS)
 #include "services/device/public/cpp/geolocation/geolocation_manager.h"
 #endif
 
@@ -726,7 +726,7 @@
           "ContentSettings.Geolocation.BlockedIconShown"));
       set_tooltip(l10n_util::GetStringUTF16(IDS_BLOCKED_GEOLOCATION_MESSAGE));
       if (content_settings->geolocation_was_just_granted_on_site_level()) {
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
         if (IsGeolocationPermissionDetermined()) {
           // If the system permission is already denied then requesting the
           // system permission will not show a prompt. Show the bubble instead.
@@ -792,7 +792,7 @@
 }
 
 bool ContentSettingGeolocationImageModel::IsGeolocationAllowedOnASystemLevel() {
-#if !BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_CHROMEOS)
   return true;
 #else
   device::GeolocationManager* geolocation_manager =
@@ -806,7 +806,7 @@
 }
 
 bool ContentSettingGeolocationImageModel::IsGeolocationPermissionDetermined() {
-#if !BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if !BUILDFLAG(IS_MAC) && !BUILDFLAG(IS_CHROMEOS)
   return true;
 #else
 
diff --git a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
index d93294ad..d8370a1 100644
--- a/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
+++ b/chrome/browser/ui/content_settings/content_setting_image_model_unittest.cc
@@ -48,14 +48,13 @@
 #include "content/public/test/web_contents_tester.h"
 #include "net/cookies/cookie_options.h"
 #include "services/device/public/cpp/device_features.h"
-#include "services/device/public/cpp/geolocation/buildflags.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/gfx/color_palette.h"
 #include "ui/gfx/paint_vector_icon.h"
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
 #include "services/device/public/cpp/geolocation/geolocation_manager.h"
 #include "services/device/public/cpp/geolocation/location_system_permission_status.h"
 #include "services/device/public/cpp/test/fake_geolocation_manager.h"
@@ -304,7 +303,7 @@
       /* explanatory_string_id = */ 0);
 }
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
 // Test the correct ContentSettingImageModel for various permutations of site
 // and system level Geolocation permissions
 TEST_F(ContentSettingImageModelTest, GeolocationAccessPermissionsChanged) {
@@ -410,10 +409,7 @@
       /* tooltip_empty = */ false, IDS_BLOCKED_GEOLOCATION_MESSAGE, 0);
 }
 
-#if BUILDFLAG(IS_MAC)
 TEST_F(ContentSettingImageModelTest, GeolocationAccessDeniedExperiment) {
-  // This is run only on Mac, because the kLocationPermissionExperiment is a Mac
-  // only feature.
   base::test::ScopedFeatureList feature_list;
   feature_list.InitWithFeatures({features::kLocationPermissionsExperiment}, {});
   auto test_geolocation_manager =
@@ -478,9 +474,7 @@
         IDS_GEOLOCATION_TURNED_OFF);
   }
 }
-#endif  // BUILDFLAG(IS_MAC)
-
-#endif  // BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#endif
 
 // Regression test for https://crbug.com/955408
 // See also: ContentSettingBubbleModelTest.SensorAccessPermissionsChanged
diff --git a/chrome/browser/ui/tabs/tab_style.cc b/chrome/browser/ui/tabs/tab_style.cc
index 38e9d32..aa9cd30 100644
--- a/chrome/browser/ui/tabs/tab_style.cc
+++ b/chrome/browser/ui/tabs/tab_style.cc
@@ -226,7 +226,8 @@
 }
 
 gfx::Insets ChromeRefresh2023TabStyle::GetSeparatorMargins() const {
-  return gfx::Insets::TLBR(0, kChromeRefreshSeparatorHorizontalMargin,
+  return gfx::Insets::TLBR(GetLayoutConstant(TAB_STRIP_PADDING),
+                           kChromeRefreshSeparatorHorizontalMargin,
                            GetLayoutConstant(TAB_STRIP_PADDING),
                            kChromeRefreshSeparatorHorizontalMargin);
 }
diff --git a/chrome/browser/ui/toolbar/chrome_labs_model.cc b/chrome/browser/ui/toolbar/chrome_labs_model.cc
index a222ae0..d944f9a 100644
--- a/chrome/browser/ui/toolbar/chrome_labs_model.cc
+++ b/chrome/browser/ui/toolbar/chrome_labs_model.cc
@@ -48,16 +48,16 @@
         l10n_util::GetStringUTF16(IDS_TAB_GROUPS_SAVE_DESCRIPTION),
         "tab-groups-save", version_info::Channel::BETA);
 
-    // ChromeRefresh2023
+    // ChromeRefresh2023.
     std::vector<std::u16string> chrome_refresh_variation_descriptions = {
         l10n_util::GetStringUTF16(IDS_CHROMEREFRESH2023_WITHOUT_OMNIBOX)};
 
-    lab_info.emplace_back(LabInfo(
+    lab_info.emplace_back(
         flag_descriptions::kChromeRefresh2023Id,
         l10n_util::GetStringUTF16(IDS_CHROMEREFRESH2023_EXPERIMENT_NAME),
         l10n_util::GetStringUTF16(IDS_CHROMEREFRESH2023_DESCRIPTION),
         "chrome-refresh", version_info::Channel::BETA,
-        chrome_refresh_variation_descriptions));
+        chrome_refresh_variation_descriptions);
 
     // Tab Scrolling.
     std::vector<std::u16string> tab_scrolling_variation_descriptions = {
@@ -66,22 +66,22 @@
         l10n_util::GetStringUTF16(IDS_TABS_SHRINK_TO_LARGE_WIDTH),
         l10n_util::GetStringUTF16(IDS_TABS_DO_NOT_SHRINK)};
 
-    lab_info.emplace_back(LabInfo(
+    lab_info.emplace_back(
         flag_descriptions::kScrollableTabStripFlagId,
         l10n_util::GetStringUTF16(IDS_TAB_SCROLLING_EXPERIMENT_NAME),
         l10n_util::GetStringUTF16(IDS_TAB_SCROLLING_EXPERIMENT_DESCRIPTION),
         "chrome-labs-tab-scrolling", version_info::Channel::BETA,
-        tab_scrolling_variation_descriptions));
+        tab_scrolling_variation_descriptions);
 
-    // Thumbnail Tab Strip for Windows
+    // Thumbnail Tab Strip for Windows.
 #if BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) && \
     (BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS_ASH))
-    lab_info.emplace_back(LabInfo(
+    lab_info.emplace_back(
         flag_descriptions::kWebUITabStripFlagId,
         l10n_util::GetStringUTF16(IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_NAME),
         l10n_util::GetStringUTF16(
             IDS_THUMBNAIL_TAB_STRIP_EXPERIMENT_DESCRIPTION),
-        "chrome-labs-thumbnail-tab-strip", version_info::Channel::BETA));
+        "chrome-labs-thumbnail-tab-strip", version_info::Channel::BETA);
 #endif
 
     return lab_info;
diff --git a/chrome/browser/ui/views/frame/browser_frame.cc b/chrome/browser/ui/views/frame/browser_frame.cc
index be8a546..ed0eb11e 100644
--- a/chrome/browser/ui/views/frame/browser_frame.cc
+++ b/chrome/browser/ui/views/frame/browser_frame.cc
@@ -153,8 +153,9 @@
     }
   }
 
+  params.native_theme = SelectNativeTheme();
+
   Init(std::move(params));
-  SelectNativeTheme();
 
   if (!native_browser_frame_->UsesNativeSystemMenu()) {
     DCHECK(non_client_view());
@@ -251,7 +252,7 @@
   // When the browser theme changes, the NativeTheme may also change.
   // In Incognito, the usage of dark or normal hinges on the browser theme.
   if (theme_change_type == BrowserThemeChangeType::kBrowserTheme)
-    SelectNativeTheme();
+    SetNativeTheme(SelectNativeTheme());
 
   if (!RegenerateFrameOnThemeChange(theme_change_type)) {
     // If RegenerateFrame() returns true, ThemeChanged() was implicitly called,
@@ -532,15 +533,14 @@
   GetRootView()->Layout();
 }
 
-void BrowserFrame::SelectNativeTheme() {
+ui::NativeTheme* BrowserFrame::SelectNativeTheme() const {
   // Select between regular and Linux toolkit themes.
   ui::NativeTheme* native_theme = ui::NativeTheme::GetInstanceForNativeUi();
 
   // Use the regular NativeTheme instance if running incognito mode, regardless
   // of system theme (gtk, qt etc).
   if (IsIncognitoBrowser()) {
-    SetNativeTheme(native_theme);
-    return;
+    return native_theme;
   }
 
 #if BUILDFLAG(IS_LINUX)
@@ -554,7 +554,7 @@
     native_theme = linux_ui_theme->GetNativeTheme();
 #endif
 
-  SetNativeTheme(native_theme);
+  return native_theme;
 }
 
 bool BrowserFrame::RegenerateFrameOnThemeChange(
diff --git a/chrome/browser/ui/views/frame/browser_frame.h b/chrome/browser/ui/views/frame/browser_frame.h
index 77ca1db..53781b68 100644
--- a/chrome/browser/ui/views/frame/browser_frame.h
+++ b/chrome/browser/ui/views/frame/browser_frame.h
@@ -190,7 +190,7 @@
   void OnMenuClosed();
 
   // Select a native theme that is appropriate for the current context.
-  void SelectNativeTheme();
+  ui::NativeTheme* SelectNativeTheme() const;
 
   // Regenerate the frame on theme change if necessary. Returns true if
   // regenerated.
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 19ed82e..c810632 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -4185,8 +4185,6 @@
 
 void BrowserView::OnThemeChanged() {
   views::ClientView::OnThemeChanged();
-  if (!initialized_)
-    return;
 
   if (status_bubble_)
     status_bubble_->OnThemeChanged();
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 97d393fb..83e19c0 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -201,7 +201,7 @@
     }
     views::InstallPillHighlightPathGenerator(this);
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
     geolocation_permission_observation_.Observe(
         device::GeolocationManager::GetInstance());
 #endif
@@ -1049,7 +1049,7 @@
   return delegate_->GetContentSettingBubbleModelDelegate();
 }
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
 void LocationBarView::OnSystemPermissionUpdated(
     device::LocationSystemPermissionStatus new_status) {
   UpdateContentSettingsIcons();
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h
index 3378d72a..6fd3631 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.h
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.h
@@ -73,7 +73,7 @@
                         public IconLabelBubbleView::Delegate,
                         public LocationIconView::Delegate,
                         public ContentSettingImageView::Delegate,
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
                         public device::GeolocationManager::PermissionObserver,
 #endif
                         public PageActionIconView::Delegate {
@@ -206,7 +206,7 @@
   ContentSettingBubbleModelDelegate* GetContentSettingBubbleModelDelegate()
       override;
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
   // GeolocationManager::PermissionObserver:
   void OnSystemPermissionUpdated(
       device::LocationSystemPermissionStatus new_status) override;
@@ -262,7 +262,7 @@
                            IMEInlineAutocompletePosition);
   using ContentSettingViews = std::vector<ContentSettingImageView*>;
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
   // Manage a subscription to GeolocationManager, which may
   // outlive this object.
   base::ScopedObservation<device::GeolocationManager,
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view.cc b/chrome/browser/ui/views/passwords/password_save_update_view.cc
index eda9618b7..d139fbb1 100644
--- a/chrome/browser/ui/views/passwords/password_save_update_view.cc
+++ b/chrome/browser/ui/views/passwords/password_save_update_view.cc
@@ -339,6 +339,8 @@
             password_form,
             base::BindRepeating(&PasswordSaveUpdateView::TogglePasswordRevealed,
                                 base::Unretained(this)));
+    password_dropdown->SetCallback(base::BindRepeating(
+        &PasswordSaveUpdateView::OnContentChanged, base::Unretained(this)));
     // Set up layout:
     SetLayoutManager(std::make_unique<AutoResizingLayout>());
     views::View* root_view = AddChildView(std::make_unique<views::View>());
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view.h b/chrome/browser/ui/views/passwords/password_save_update_view.h
index b918da1..bd138da0 100644
--- a/chrome/browser/ui/views/passwords/password_save_update_view.h
+++ b/chrome/browser/ui/views/passwords/password_save_update_view.h
@@ -34,7 +34,7 @@
   PasswordSaveUpdateView(content::WebContents* web_contents,
                          views::View* anchor_view,
                          DisplayReason reason);
-
+#ifdef UNIT_TEST
   views::Combobox* DestinationDropdownForTesting() {
     return destination_dropdown_;
   }
@@ -43,6 +43,11 @@
     return username_dropdown_.get();
   }
 
+  views::EditablePasswordCombobox* password_dropdown_for_testing() const {
+    return password_dropdown_.get();
+  }
+#endif  // #ifdef UNIT_TEST
+
  private:
   // Type of the IPH to show.
   enum class IPHType {
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view_unittest.cc b/chrome/browser/ui/views/passwords/password_save_update_view_unittest.cc
index 9acd6c74..dad0270 100644
--- a/chrome/browser/ui/views/passwords/password_save_update_view_unittest.cc
+++ b/chrome/browser/ui/views/passwords/password_save_update_view_unittest.cc
@@ -25,6 +25,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/views/controls/combobox/combobox.h"
+#include "ui/views/controls/editable_combobox/editable_password_combobox.h"
 
 using ::testing::Return;
 using ::testing::ReturnRef;
@@ -178,3 +179,20 @@
       password_manager::PasswordForm::MatchType::kExact;
   CreateViewAndShow();
 }
+
+// This is a regression test for crbug.com/1475021
+TEST_F(PasswordSaveUpdateViewTest, SaveButtonIsDisabledWhenPasswordIsEmpty) {
+  CreateViewAndShow();
+  const PasswordSaveUpdateView* save_bubble =
+      static_cast<const PasswordSaveUpdateView*>(view());
+  const views::DialogDelegate* dialog_delegate = view();
+
+  save_bubble->password_dropdown_for_testing()->SetText(u"password");
+  EXPECT_TRUE(dialog_delegate->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
+
+  save_bubble->password_dropdown_for_testing()->SetText(u"");
+  EXPECT_FALSE(dialog_delegate->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
+
+  save_bubble->password_dropdown_for_testing()->SetText(u"pass");
+  EXPECT_TRUE(dialog_delegate->IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK));
+}
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
index 3f1079b..f8726cc 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_base.cc
@@ -232,6 +232,7 @@
     if (features::IsChromeRefresh2023() && has_background_color_) {
       SetBackground(views::CreateThemedRoundedRectBackground(
           kColorProfileMenuIconButtonBackground, kButtonRadius));
+      views::FocusRing::Get(this)->SetOutsetFocusRingDisabled(false);
       views::InkDrop::Get(this)->GetInkDrop()->SetShowHighlightOnHover(true);
       views::InkDrop::Get(this)->SetLayerRegion(views::LayerRegion::kAbove);
       views::InkDrop::Get(this)->SetCreateHighlightCallback(base::BindRepeating(
diff --git a/chrome/browser/ui/views/tabs/tab_container_impl.cc b/chrome/browser/ui/views/tabs/tab_container_impl.cc
index 8e90576..126b626 100644
--- a/chrome/browser/ui/views/tabs/tab_container_impl.cc
+++ b/chrome/browser/ui/views/tabs/tab_container_impl.cc
@@ -139,8 +139,11 @@
 Tab* TabContainerImpl::AddTab(std::unique_ptr<Tab> tab,
                               int model_index,
                               TabPinned pinned) {
+  // First add the tab to the view model, this is done because AddChildView sets
+  // some tooltip information which tries to calculate the hit test, which needs
+  // information about its adjacent tabs which it gets from the view model.
+  AddTabToViewModel(tab.get(), model_index, pinned);
   Tab* tab_ptr = AddChildView(std::move(tab));
-  AddTabToViewModel(tab_ptr, model_index, pinned);
   OrderTabSlotView(tab_ptr);
 
   // Don't animate the first tab, it looks weird, and don't animate anything
diff --git a/chrome/browser/ui/views/tabs/tab_group_highlight.cc b/chrome/browser/ui/views/tabs/tab_group_highlight.cc
index d0bdc3b..d461aa2 100644
--- a/chrome/browser/ui/views/tabs/tab_group_highlight.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_highlight.cc
@@ -55,19 +55,20 @@
   // the tabs around it, so there are no special cases needed when determining
   // its shape.
   const int corner_radius = TabStyle::Get()->GetBottomCornerRadius();
+  const int top = GetLayoutConstant(TAB_STRIP_PADDING);
 
   SkPath path;
   path.moveTo(0, bounds().height());
   path.arcTo(corner_radius, corner_radius, 0, SkPath::kSmall_ArcSize,
              SkPathDirection::kCCW, corner_radius,
              bounds().height() - corner_radius);
-  path.lineTo(corner_radius, corner_radius);
+  path.lineTo(corner_radius, top + corner_radius);
   path.arcTo(corner_radius, corner_radius, 0, SkPath::kSmall_ArcSize,
-             SkPathDirection::kCW, 2 * corner_radius, 0);
-  path.lineTo(bounds().width() - 2 * corner_radius, 0);
+             SkPathDirection::kCW, 2 * corner_radius, top);
+  path.lineTo(bounds().width() - 2 * corner_radius, top);
   path.arcTo(corner_radius, corner_radius, 0, SkPath::kSmall_ArcSize,
              SkPathDirection::kCW, bounds().width() - corner_radius,
-             corner_radius);
+             top + corner_radius);
   path.lineTo(bounds().width() - corner_radius,
               bounds().height() - corner_radius);
   path.arcTo(corner_radius, corner_radius, 0, SkPath::kSmall_ArcSize,
diff --git a/chrome/browser/ui/views/tabs/tab_group_style.cc b/chrome/browser/ui/views/tabs/tab_group_style.cc
index c05dd15..72df608 100644
--- a/chrome/browser/ui/views/tabs/tab_group_style.cc
+++ b/chrome/browser/ui/views/tabs/tab_group_style.cc
@@ -37,7 +37,6 @@
 constexpr int kChromeRefreshEmptyChipSize = 20;
 constexpr int kChromeRefreshSyncIconWidth = 16;
 constexpr int kChromeRefreshCornerRadius = 6;
-constexpr int kTabGroupRefreshBottomMargin = 10;
 constexpr int kTabGroupOverlapAdjustment = 2;
 
 }  // namespace
@@ -188,10 +187,10 @@
 
 gfx::Point ChromeRefresh2023TabGroupStyle::GetTitleChipOffset(
     absl::optional<int> text_height) const {
-  return gfx::Point(TabStyle::Get()->GetTabOverlap() - 2,
-                    GetLayoutConstant(TAB_HEIGHT) -
-                        GetLayoutConstant(TABSTRIP_TOOLBAR_OVERLAP) -
-                        kTabGroupRefreshBottomMargin - GetEmptyChipSize());
+  const int total_space = GetLayoutConstant(TAB_STRIP_HEIGHT) -
+                          GetEmptyChipSize() -
+                          GetLayoutConstant(TABSTRIP_TOOLBAR_OVERLAP);
+  return gfx::Point(TabStyle::Get()->GetTabOverlap() - 2, total_space / 2);
 }
 
 gfx::Insets ChromeRefresh2023TabGroupStyle::GetInsetsForHeaderChip() const {
diff --git a/chrome/browser/ui/views/tabs/tab_style_views.cc b/chrome/browser/ui/views/tabs/tab_style_views.cc
index e421808..4df33e11 100644
--- a/chrome/browser/ui/views/tabs/tab_style_views.cc
+++ b/chrome/browser/ui/views/tabs/tab_style_views.cc
@@ -608,12 +608,15 @@
 
   TabStyle::SeparatorBounds separator_bounds;
 
+  const int extra_vertical_space =
+      aligned_bounds.height() -
+      (separator_size.height() + separator_margin.bottom() +
+       separator_margin.top());
+
   separator_bounds.leading = gfx::RectF(
       aligned_bounds.x() + corner_radius - separator_margin.right() -
           separator_size.width(),
-      aligned_bounds.y() + (aligned_bounds.height() - separator_size.height() -
-                            separator_margin.bottom()) /
-                               2,
+      aligned_bounds.y() + extra_vertical_space / 2 + separator_margin.top(),
       separator_size.width(), separator_size.height());
 
   separator_bounds.trailing = separator_bounds.leading;
@@ -1191,12 +1194,22 @@
       const int right_separator_overlap =
           tab_style()->GetSeparatorSize().width() - left_separator_overlap;
 
-      left -= (tab_style()->GetSeparatorMargins().right() +
-               left_separator_overlap) *
-              scale;
-      right += (tab_style()->GetSeparatorMargins().left() +
-                right_separator_overlap) *
-               scale;
+      // If there is a tab before this one, then expand into its overlap.
+      const Tab* const previous_tab =
+          tab()->controller()->GetAdjacentTab(tab(), -1);
+      if (previous_tab) {
+        left -= (tab_style()->GetSeparatorMargins().right() +
+                 left_separator_overlap) *
+                scale;
+      }
+
+      // If there is a tab after this one, then expand into its overlap.
+      const Tab* const next_tab = tab()->controller()->GetAdjacentTab(tab(), 1);
+      if (next_tab) {
+        right += (tab_style()->GetSeparatorMargins().left() +
+                  right_separator_overlap) *
+                 scale;
+      }
     }
 
     SkPath path;
diff --git a/chrome/browser/ui/webui/ash/add_supervision/BUILD.gn b/chrome/browser/ui/webui/ash/add_supervision/BUILD.gn
index 216deb1..0c8f3d3 100644
--- a/chrome/browser/ui/webui/ash/add_supervision/BUILD.gn
+++ b/chrome/browser/ui/webui/ash/add_supervision/BUILD.gn
@@ -10,4 +10,5 @@
 mojom("mojo_bindings") {
   webui_module_path = "/"
   sources = [ "add_supervision.mojom" ]
+  use_typescript_sources = true
 }
diff --git a/chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui.cc b/chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui.cc
index c8eb44ad..0ba6745 100644
--- a/chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui.cc
+++ b/chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui.cc
@@ -20,6 +20,8 @@
 #include "chrome/browser/ui/webui/ash/add_supervision/confirm_signout_dialog.h"
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/add_supervision_resources.h"
+#include "chrome/grit/add_supervision_resources_map.h"
 #include "chrome/grit/browser_resources.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/supervision_resources.h"
@@ -204,12 +206,8 @@
   source->EnableReplaceI18nInJS();
 
   // Forward data to the WebUI.
-  source->AddResourcePath("add_supervision_api_server.js",
-                          IDR_ADD_SUPERVISION_API_SERVER_JS);
-  source->AddResourcePath("add_supervision_ui.js", IDR_ADD_SUPERVISION_UI_JS);
-  source->AddResourcePath("add_supervision_app.js", IDR_ADD_SUPERVISION_APP_JS);
-  source->AddResourcePath("add_supervision.mojom-webui.js",
-                          IDR_ADD_SUPERVISION_MOJOM_WEBUI_JS);
+  source->AddResourcePaths(
+      base::make_span(kAddSupervisionResources, kAddSupervisionResourcesSize));
   source->AddResourcePaths(
       base::make_span(kSupervisionResources, kSupervisionResourcesSize));
 
@@ -226,7 +224,7 @@
                              IDS_SUPERVISED_USER_OFFLINE_TITLE);
 
   source->UseStringsJs();
-  source->SetDefaultResource(IDR_ADD_SUPERVISION_HTML);
+  source->SetDefaultResource(IDR_ADD_SUPERVISION_ADD_SUPERVISION_HTML);
   source->AddString("webviewUrl", supervision_url_.spec());
   source->AddString("eventOriginFilter",
                     supervision_url_.DeprecatedGetOriginAsURL().spec());
diff --git a/chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui_browsertest.cc b/chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui_browsertest.cc
index f1fa253..d46e9e2 100644
--- a/chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui_browsertest.cc
+++ b/chrome/browser/ui/webui/ash/add_supervision/add_supervision_ui_browsertest.cc
@@ -181,7 +181,7 @@
   // Request that the dialog close before supervision has been enabled.
   ASSERT_TRUE(content::ExecJs(
       contents(), std::string(kGetAddSupervisionUIElementJS) +
-                      std::string(".getAPIServerForTest().requestClose()")));
+                      std::string(".getApiServerForTest().requestClose()")));
   // Confirm that the signout dialog isn't showing
   ASSERT_FALSE(ConfirmSignoutDialog::IsShowing());
 
@@ -189,12 +189,12 @@
   ASSERT_TRUE(content::ExecJs(
       contents(),
       std::string(kGetAddSupervisionUIElementJS) +
-          std::string(".getAPIServerForTest().notifySupervisionEnabled()")));
+          std::string(".getApiServerForTest().notifySupervisionEnabled()")));
 
   // Request that the dialog is closed again.
   ASSERT_TRUE(content::ExecJs(
       contents(), std::string(kGetAddSupervisionUIElementJS) +
-                      std::string(".getAPIServerForTest().requestClose()")));
+                      std::string(".getApiServerForTest().requestClose()")));
 
   // Confirm that the dialog is showing.
   ASSERT_TRUE(ConfirmSignoutDialog::IsShowing());
@@ -221,7 +221,7 @@
   ASSERT_TRUE(content::ExecJs(
       contents(),
       std::string(kGetAddSupervisionUIElementJS) +
-          std::string(".getAPIServerForTest().notifySupervisionEnabled()")));
+          std::string(".getApiServerForTest().notifySupervisionEnabled()")));
 
   // Should see 1 Add Supervision process completed.
   histogram_tester.ExpectUniqueSample(
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni
index 59965719..7469d73 100644
--- a/chrome/chrome_paks.gni
+++ b/chrome/chrome_paks.gni
@@ -252,6 +252,7 @@
         "$root_gen_dir/ash/webui/connectivity_diagnostics_resources.pak",
         "$root_gen_dir/ash/webui/file_manager/resources/file_manager_swa_resources.pak",
         "$root_gen_dir/ash/webui/file_manager/untrusted_resources/file_manager_untrusted_resources.pak",
+        "$root_gen_dir/chrome/add_supervision_resources.pak",
         "$root_gen_dir/chrome/arc_account_picker_resources.pak",
         "$root_gen_dir/chrome/assistant_optin_resources.pak",
         "$root_gen_dir/chrome/audio_resources.pak",
diff --git a/chrome/renderer/accessibility/read_anything_app_controller.cc b/chrome/renderer/accessibility/read_anything_app_controller.cc
index c36b00c..bc2f0aa 100644
--- a/chrome/renderer/accessibility/read_anything_app_controller.cc
+++ b/chrome/renderer/accessibility/read_anything_app_controller.cc
@@ -457,7 +457,8 @@
       model_.GetTreeFromId(model_.active_tree_id()).get();
   std::unique_ptr<ui::AXTreeSource<const ui::AXNode*>> tree_source(
       tree->CreateTreeSource());
-  ui::AXTreeSerializer<const ui::AXNode*> serializer(tree_source.get());
+  ui::AXTreeSerializer<const ui::AXNode*, std::vector<const ui::AXNode*>>
+      serializer(tree_source.get());
   ui::AXTreeUpdate snapshot;
   CHECK(serializer.SerializeChanges(tree->root(), &snapshot));
   model_.SetDistillationInProgress(true);
diff --git a/chrome/services/mac_notifications/mac_notification_service_ns.h b/chrome/services/mac_notifications/mac_notification_service_ns.h
index 6f2263b..e639916 100644
--- a/chrome/services/mac_notifications/mac_notification_service_ns.h
+++ b/chrome/services/mac_notifications/mac_notification_service_ns.h
@@ -36,6 +36,7 @@
   void CloseNotificationsForProfile(
       mojom::ProfileIdentifierPtr profile) override;
   void CloseAllNotifications() override;
+  void OkayToTerminateService(OkayToTerminateServiceCallback callback) override;
 
  private:
   mojo::Receiver<mojom::MacNotificationService> binding_;
diff --git a/chrome/services/mac_notifications/mac_notification_service_ns.mm b/chrome/services/mac_notifications/mac_notification_service_ns.mm
index 59e0a15..bb7fed20 100644
--- a/chrome/services/mac_notifications/mac_notification_service_ns.mm
+++ b/chrome/services/mac_notifications/mac_notification_service_ns.mm
@@ -276,6 +276,15 @@
   [notification_center_ removeAllDeliveredNotifications];
 }
 
+void MacNotificationServiceNS::OkayToTerminateService(
+    OkayToTerminateServiceCallback callback) {
+  GetDisplayedNotifications(
+      nullptr, base::BindOnce([](std::vector<mojom::NotificationIdentifierPtr>
+                                     notifications) {
+                 return notifications.empty();
+               }).Then(std::move(callback)));
+}
+
 }  // namespace mac_notifications
 
 @implementation AlertNSNotificationCenterDelegate {
diff --git a/chrome/services/mac_notifications/mac_notification_service_un.h b/chrome/services/mac_notifications/mac_notification_service_un.h
index fdc9718..f8a5b5f 100644
--- a/chrome/services/mac_notifications/mac_notification_service_un.h
+++ b/chrome/services/mac_notifications/mac_notification_service_un.h
@@ -49,6 +49,7 @@
   void CloseNotificationsForProfile(
       mojom::ProfileIdentifierPtr profile) override;
   void CloseAllNotifications() override;
+  void OkayToTerminateService(OkayToTerminateServiceCallback callback) override;
 
  private:
   // Requests notification permissions from the system. This will ask the user
@@ -90,6 +91,11 @@
       delivered_notifications_ GUARDED_BY_CONTEXT(sequence_checker_);
   base::RepeatingTimer synchronize_displayed_notifications_timer_;
 
+  // The constructor immediately kicks of a permission request, so on
+  // construction this should be true. Set to false when that permission request
+  // resolves.
+  bool permission_request_is_pending_ = true;
+
   // Ensures that the methods in this class are called on the same sequence.
   SEQUENCE_CHECKER(sequence_checker_);
   base::WeakPtrFactory<MacNotificationServiceUN> weak_factory_{this};
diff --git a/chrome/services/mac_notifications/mac_notification_service_un.mm b/chrome/services/mac_notifications/mac_notification_service_un.mm
index 722fd1a..f88f4272 100644
--- a/chrome/services/mac_notifications/mac_notification_service_un.mm
+++ b/chrome/services/mac_notifications/mac_notification_service_un.mm
@@ -109,7 +109,9 @@
                                 weak_factory_.GetWeakPtr())];
   notification_center_.delegate = delegate_;
   LogUNNotificationSettings(notification_center_);
-  // TODO(crbug.com/1129366): Determine when to ask for permissions.
+  // TODO(crbug.com/1129366): Determine when to ask for permissions. Make sure
+  // to also update the initial value of `permission_request_is_pending_` when
+  // this changes.
   RequestPermission();
   // Schedule a timer to regularly check for any closed notifications.
   ScheduleSynchronizeNotifications();
@@ -308,8 +310,32 @@
   delivered_notifications_.clear();
 }
 
+void MacNotificationServiceUN::OkayToTerminateService(
+    OkayToTerminateServiceCallback callback) {
+  if (permission_request_is_pending_) {
+    std::move(callback).Run(false);
+    return;
+  }
+
+  GetDisplayedNotifications(
+      nullptr, base::BindOnce([](std::vector<mojom::NotificationIdentifierPtr>
+                                     notifications) {
+                 return notifications.empty();
+               }).Then(std::move(callback)));
+}
+
 void MacNotificationServiceUN::RequestPermission() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  __block auto update_pending_status_callback =
+      base::BindPostTaskToCurrentDefault(base::BindOnce(
+          [](base::WeakPtr<MacNotificationServiceUN> service) {
+            if (service) {
+              service->permission_request_is_pending_ = false;
+            }
+          },
+          weak_factory_.GetWeakPtr()));
+
   UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
                                        UNAuthorizationOptionSound |
                                        UNAuthorizationOptionBadge;
@@ -322,6 +348,7 @@
                    : UNNotificationRequestPermissionResult::kPermissionDenied;
     }
     LogUNNotificationRequestPermissionResult(result);
+    std::move(update_pending_status_callback).Run();
   };
 
   [notification_center_ requestAuthorizationWithOptions:authOptions
diff --git a/chrome/services/mac_notifications/public/mojom/mac_notifications.mojom b/chrome/services/mac_notifications/public/mojom/mac_notifications.mojom
index 167c066..e213c77 100644
--- a/chrome/services/mac_notifications/public/mojom/mac_notifications.mojom
+++ b/chrome/services/mac_notifications/public/mojom/mac_notifications.mojom
@@ -129,6 +129,11 @@
   // Closes all notifications shown by the helper app in the system notification
   // center for all profiles.
   CloseAllNotifications();
+
+  // Checks if it is okay to terminate this service. Returns false if for
+  // example there are still displayed notifications, or if terminating the
+  // service would interrupt/abort any pending permission requests.
+  OkayToTerminateService() => (bool can_terminate);
 };
 
 // Handles notification actions such as click or close. Implemented in the
diff --git a/chrome/test/data/webui/chromeos/account_manager/account_migration_welcome_test.js b/chrome/test/data/webui/chromeos/account_manager/account_migration_welcome_test.js
index 6f2a17c9..b8dd37d 100644
--- a/chrome/test/data/webui/chromeos/account_manager/account_migration_welcome_test.js
+++ b/chrome/test/data/webui/chromeos/account_manager/account_migration_welcome_test.js
@@ -32,7 +32,7 @@
   setup(() => {
     document.body.innerHTML = window.trustedTypes.emptyHTML;
     testBrowserProxy = new TestAccountManagerBrowserProxy();
-    AccountManagerBrowserProxyImpl.instance_ = testBrowserProxy;
+    AccountManagerBrowserProxyImpl.setInstance(testBrowserProxy);
     element = /** @type {AccountMigrationWelcomeElement} */ (
         document.createElement('account-migration-welcome'));
     document.body.appendChild(element);
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn
index 69c2ec1..a660b2c 100644
--- a/chrome/test/data/webui/settings/chromeos/BUILD.gn
+++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -222,9 +222,9 @@
 
     "os_languages_page/input_method_options_page_test.ts",
     "os_languages_page/input_page_test.ts",
+    "os_languages_page/language_settings_card_test.ts",
     "os_languages_page/os_clear_personalization_data_page_test.ts",
     "os_languages_page/os_edit_dictionary_page_test.ts",
-    "os_languages_page/os_languages_page_test.ts",
     "os_languages_page/os_languages_page_v2_test.ts",
     "os_languages_page/smart_inputs_page_test.ts",
 
diff --git a/chrome/test/data/webui/settings/chromeos/os_languages_page/language_settings_card_test.ts b/chrome/test/data/webui/settings/chromeos/os_languages_page/language_settings_card_test.ts
new file mode 100644
index 0000000..628dd32
--- /dev/null
+++ b/chrome/test/data/webui/settings/chromeos/os_languages_page/language_settings_card_test.ts
@@ -0,0 +1,94 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'chrome://os-settings/lazy_load.js';
+
+import {LanguageSettingsCardElement} from 'chrome://os-settings/lazy_load.js';
+import {OsSettingsRoutes, Router, routes} from 'chrome://os-settings/os_settings.js';
+import {loadTimeData} from 'chrome://resources/js/load_time_data.js';
+import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
+import {eventToPromise, isVisible} from 'chrome://webui-test/test_util.js';
+
+interface SubpageTriggerData {
+  triggerSelector: string;
+  routeName: keyof OsSettingsRoutes;
+}
+
+suite('<language-settings-card>', () => {
+  let card: LanguageSettingsCardElement;
+
+  function createLanguagesCard(): void {
+    card = document.createElement('language-settings-card');
+    document.body.appendChild(card);
+    flush();
+  }
+
+  setup(() => {
+    loadTimeData.overrideValues({allowEmojiSuggestion: true});
+  });
+
+  teardown(() => {
+    card.remove();
+    Router.getInstance().resetRouteForTesting();
+  });
+
+  test('Smart inputs row is visible if smart inputs are enabled', () => {
+    loadTimeData.overrideValues({allowEmojiSuggestion: true});
+    createLanguagesCard();
+    const smartInputsRow =
+        card.shadowRoot!.querySelector<HTMLElement>('#smartInputsRow');
+    assertTrue(isVisible(smartInputsRow));
+  });
+
+  test('Smart inputs row is hidden if smart inputs are disabled', () => {
+    loadTimeData.overrideValues({allowEmojiSuggestion: false});
+    createLanguagesCard();
+    const smartInputsRow =
+        card.shadowRoot!.querySelector<HTMLElement>('#smartInputsRow');
+    assertFalse(isVisible(smartInputsRow));
+  });
+
+  const subpageTriggerData: SubpageTriggerData[] = [
+    {
+      triggerSelector: '#languagesRow',
+      routeName: 'OS_LANGUAGES_LANGUAGES',
+    },
+    {
+      triggerSelector: '#inputRow',
+      routeName: 'OS_LANGUAGES_INPUT',
+    },
+    {
+      triggerSelector: '#smartInputsRow',
+      routeName: 'OS_LANGUAGES_SMART_INPUTS',
+    },
+  ];
+  subpageTriggerData.forEach(({triggerSelector, routeName}) => {
+    test(
+        `Row for ${routeName} is focused when returning from subpage`,
+        async () => {
+          Router.getInstance().navigateTo(routes.OS_LANGUAGES);
+          createLanguagesCard();
+
+          const subpageTrigger =
+              card.shadowRoot!.querySelector<HTMLElement>(triggerSelector);
+          assertTrue(!!subpageTrigger);
+
+          // Sub-page trigger navigates to subpage for route
+          subpageTrigger.click();
+          assertEquals(routes[routeName], Router.getInstance().currentRoute);
+
+          // Navigate back
+          const popStateEventPromise = eventToPromise('popstate', window);
+          Router.getInstance().navigateToPreviousRoute();
+          await popStateEventPromise;
+          await waitAfterNextRender(card);
+
+          assertEquals(
+              subpageTrigger, card.shadowRoot!.activeElement,
+              `${triggerSelector} should be focused.`);
+        });
+  });
+});
diff --git a/chrome/test/data/webui/settings/chromeos/os_languages_page/os_languages_page_test.ts b/chrome/test/data/webui/settings/chromeos/os_languages_page/os_languages_page_test.ts
deleted file mode 100644
index ca47d31..0000000
--- a/chrome/test/data/webui/settings/chromeos/os_languages_page/os_languages_page_test.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import 'chrome://os-settings/os_settings.js';
-
-import {OsSettingsLanguagesSectionElement, OsSettingsRoutes, Router, routes} from 'chrome://os-settings/os_settings.js';
-import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js';
-import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js';
-import {eventToPromise} from 'chrome://webui-test/test_util.js';
-
-interface SubpageTriggerData {
-  triggerSelector: string;
-  routeName: keyof OsSettingsRoutes;
-}
-
-suite('<os-settings-languages-section>', () => {
-  let page: OsSettingsLanguagesSectionElement;
-
-  function createPage() {
-    page = document.createElement('os-settings-languages-section');
-    document.body.appendChild(page);
-    flush();
-  }
-
-  teardown(() => {
-    page.remove();
-    Router.getInstance().resetRouteForTesting();
-  });
-
-  const subpageTriggerData: SubpageTriggerData[] = [
-    {
-      triggerSelector: '#languagesRow',
-      routeName: 'OS_LANGUAGES_LANGUAGES',
-    },
-    {
-      triggerSelector: '#inputRow',
-      routeName: 'OS_LANGUAGES_INPUT',
-    },
-    {
-      triggerSelector: '#smartInputsRow',
-      routeName: 'OS_LANGUAGES_SMART_INPUTS',
-    },
-  ];
-  subpageTriggerData.forEach(({triggerSelector, routeName}) => {
-    test(
-        `Row for ${routeName} is focused when returning from subpage`,
-        async () => {
-          Router.getInstance().navigateTo(routes.OS_LANGUAGES);
-          createPage();
-
-          const subpageTrigger =
-              page.shadowRoot!.querySelector<HTMLElement>(triggerSelector);
-          assertTrue(!!subpageTrigger);
-
-          // Sub-page trigger navigates to subpage for route
-          subpageTrigger.click();
-          assertEquals(routes[routeName], Router.getInstance().currentRoute);
-
-          // Navigate back
-          const popStateEventPromise = eventToPromise('popstate', window);
-          Router.getInstance().navigateToPreviousRoute();
-          await popStateEventPromise;
-          await waitAfterNextRender(page);
-
-          assertEquals(
-              subpageTrigger, page.shadowRoot!.activeElement,
-              `${triggerSelector} should be focused.`);
-        });
-  });
-});
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
index ad1734f..0fcb896 100644
--- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
+++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -656,15 +656,15 @@
    },
  ],
  [
-   'OsLanguagesPage',
-   'os_languages_page/os_languages_page_test.js',
- ],
- [
    'OsLanguagesPageInputMethodOptionsPage',
    'os_languages_page/input_method_options_page_test.js'
  ],
  ['OsLanguagesPageInputPage', 'os_languages_page/input_page_test.js'],
  [
+   'OsLanguagesPageLanguageSettingsCard',
+   'os_languages_page/language_settings_card_test.js',
+ ],
+ [
    'OsLanguagesPageOsClearPersonalizationDataPage',
    'os_languages_page/os_clear_personalization_data_page_test.js'
  ],
diff --git a/chrome/updater/BUILD.gn b/chrome/updater/BUILD.gn
index 8883c04b5..96689e18 100644
--- a/chrome/updater/BUILD.gn
+++ b/chrome/updater/BUILD.gn
@@ -866,6 +866,14 @@
         "//chrome/updater/win/test:updater_test_process",
       ]
 
+      # TODO(crbug.com/1472846): WiX tools are only available on `src-internal`.
+      if (is_chrome_branded) {
+        data_deps += [
+          "//chrome/updater/test/test_installer:test_msi_installer1.0.0.0",
+          "//chrome/updater/test/test_installer:test_msi_installer_crx",
+        ]
+      }
+
       data += [
         "test/data/ProcmonConfiguration.pmc",
         "//chrome/test/data/updater/OfflineManifest.gup",
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index eb1d165..46df2e2 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -1620,6 +1620,20 @@
     EXPECT_EQ(pv, base::ASCIIToWide(expected_version.GetString()));
   }
 
+  void RemoveMsiProductData(const std::wstring& msi_product_id) {
+    ASSERT_FALSE(msi_product_id.empty());
+    for (const auto& [root, key] :
+         {std::make_pair(HKEY_LOCAL_MACHINE,
+                         L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Instal"
+                         L"ler\\UserData\\S-1-5-18\\Products"),
+          std::make_pair(HKEY_CLASSES_ROOT, L"Installer\\Products")}) {
+      for (const auto& access_mask : {KEY_WOW64_32KEY, KEY_WOW64_64KEY}) {
+        base::win::RegKey(root, key, DELETE | access_mask)
+            .DeleteKey(msi_product_id.c_str());
+      }
+    }
+  }
+
   std::unique_ptr<ScopedServer> test_server_;
   static constexpr char kEnrollmentToken[] = "integration-enrollment-token";
   static constexpr char kDMToken[] = "integration-dm-token";
@@ -1818,6 +1832,69 @@
   ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
   ASSERT_NO_FATAL_FAILURE(Uninstall());
 }
+
+// TODO(crbug.com/1472846): WiX tools are only available on `src-internal`.
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+TEST_F(IntegrationTestDeviceManagement, MsiInstallUpgrade) {
+  constexpr char kMsiAppId[] = "{c28fcf72-bcf2-45c5-8def-31a74ac02012}";
+  constexpr char kMsiCrx[] = "TestSystemMsiInstaller.msi.crx3";
+  const base::Version kMsiInitialVersion = base::Version("1.0.0.0");
+  const base::Version kMsiUpdatedVersion = base::Version("2.0.0.0");
+  constexpr wchar_t kMsiProductIdInitialVersion[] =
+      L"40C670A26D240095081B31C3EDEF2BD2";
+  constexpr wchar_t kMsiProductIdUpdatedVersion[] =
+      L"D2B2AC298EFCE2757A975961532CDE7D";
+
+  ASSERT_NO_FATAL_FAILURE(RemoveMsiProductData(kMsiProductIdInitialVersion));
+  ASSERT_NO_FATAL_FAILURE(RemoveMsiProductData(kMsiProductIdUpdatedVersion));
+  ASSERT_NO_FATAL_FAILURE(Install());
+  ASSERT_NO_FATAL_FAILURE(ExpectInstalled());
+  InstallApp(kMsiAppId, kMsiInitialVersion, [&]() {
+    base::FilePath msi_path;
+    ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &msi_path));
+    msi_path = msi_path.Append(
+        GetInstallerPath(
+            base::StrCat({kMsiAppId, ".", kMsiInitialVersion.GetString()}))
+            .AppendASCII(kMsiCrx)
+            .RemoveExtension());
+    const std::wstring command = BuildMsiCommandLine({}, {}, msi_path);
+    base::Process process = base::LaunchProcess(command, {});
+    if (!process.IsValid()) {
+      LOG(ERROR) << "Invalid process launching command: " << command;
+    }
+    int exit_code = -1;
+    EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_timeout(),
+                                               &exit_code));
+    EXPECT_EQ(0, exit_code);
+  });
+  ExpectAppInstalled(kMsiAppId, kMsiInitialVersion);
+
+  // Cloud policy sets update default to enabled.
+  PushEnrollmentToken(kEnrollmentToken);
+  ExpectDeviceManagementRegistrationRequest(test_server_.get(),
+                                            kEnrollmentToken, kDMToken);
+  OmahaSettingsClientProto omaha_settings;
+  omaha_settings.set_update_default(enterprise_management::UPDATES_ENABLED);
+  ExpectDeviceManagementPolicyFetchRequest(test_server_.get(), kDMToken,
+                                           omaha_settings);
+
+  const base::FilePath crx_path = GetInstallerPath(kMsiCrx);
+  ExpectAppsUpdateSequence(
+      UpdaterScope::kSystem, test_server_.get(),
+      {
+          AppUpdateExpectation({kMsiAppId, kMsiInitialVersion,
+                                kMsiUpdatedVersion,
+                                /*should_update=*/true, false, "", crx_path}),
+      });
+  ASSERT_NO_FATAL_FAILURE(RunWake(0));
+  ASSERT_TRUE(WaitForUpdaterExit());
+  ASSERT_NO_FATAL_FAILURE(ExpectAppInstalled(kMsiAppId, kMsiUpdatedVersion));
+  ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
+  ASSERT_NO_FATAL_FAILURE(Uninstall());
+  ASSERT_NO_FATAL_FAILURE(RemoveMsiProductData(kMsiProductIdInitialVersion));
+  ASSERT_NO_FATAL_FAILURE(RemoveMsiProductData(kMsiProductIdUpdatedVersion));
+}
+#endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
 #endif  // !defined(COMPONENT_BUILD)
 #endif  // BUILDFLAG(IS_WIN)
 #endif  // BUILDFLAG(IS_WIN) || !defined(COMPONENT_BUILD)
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc
index 23cb8c9b..4bfb3d3b 100644
--- a/chrome/updater/test/integration_tests_impl.cc
+++ b/chrome/updater/test/integration_tests_impl.cc
@@ -505,17 +505,20 @@
     const base::FilePath crx_path = exe_path.Append(app.crx_relative_path);
     app_requests.push_back(
         base::StringPrintf(R"("appid":"%s")", app.app_id.c_str()));
+    const base::FilePath base_name = crx_path.BaseName().RemoveExtension();
+    const base::FilePath run_action =
+        base_name.Extension().empty() ? base_name.AddExtension(kExeExtension)
+                                      : base_name;
+    const std::string args =
+        base_name.Extension().empty()
+            ? base::StringPrintf(
+                  "%s --appid=%s --company=%s --product_version=%s",
+                  IsSystemInstall(scope) ? "--system" : "", app.app_id.c_str(),
+                  COMPANY_SHORTNAME_STRING, app.to_version.GetString().c_str())
+            : "";
     app_responses.push_back(GetUpdateResponseForApp(
         app.app_id, "", test_server->update_url().spec(), app.to_version,
-        crx_path,
-        crx_path.BaseName()
-            .ReplaceExtension(kExeExtension)
-            .MaybeAsASCII()
-            .c_str(),
-        base::StringPrintf("%s --appid=%s --company=%s --product_version=%s",
-                           IsSystemInstall(scope) ? "--system" : "",
-                           app.app_id.c_str(), COMPANY_SHORTNAME_STRING,
-                           app.to_version.GetString().c_str())));
+        crx_path, run_action.MaybeAsASCII().c_str(), args));
   }
   test_server->ExpectOnce({request::GetPathMatcher(test_server->update_path()),
                            request::GetContentMatcher(app_requests),
diff --git a/chrome/updater/test/test_installer/BUILD.gn b/chrome/updater/test/test_installer/BUILD.gn
index 551d9fa..2de2967 100644
--- a/chrome/updater/test/test_installer/BUILD.gn
+++ b/chrome/updater/test/test_installer/BUILD.gn
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//chrome/updater/branding.gni")
 import("//components/crx_file/crx3.gni")
 
 executable("test_meta_installer") {
@@ -100,3 +101,73 @@
   inputs = [ "$root_build_dir/test_installer/TestApp2Setup.exe" ]
   deps = [ ":test_app2_installer" ]
 }
+
+# TODO(crbug.com/1472846): WiX tools are only available on `src-internal`.
+if (is_chrome_branded) {
+  template("test_msi_installer") {
+    action("test_msi_installer" + target_name) {
+      testonly = true
+      script = "create_test_msi_installer.py"
+      test_installer_wxs_xml = "test_installer.wxs.xml"
+      appid = "{c28fcf72-bcf2-45c5-8def-31a74ac02012}"
+      version = invoker.version
+      msi_base_name = "TestSystemMsiInstaller"
+
+      inputs = [
+        script,
+        test_installer_wxs_xml,
+      ]
+
+      output_installer = "$root_build_dir/test_installer/" + appid + "." +
+                         version + "/" + msi_base_name + ".msi"
+      outputs = [ output_installer ]
+
+      args = [
+        "--candle_path",
+        rebase_path("//third_party/wix/candle.exe", root_build_dir),
+        "--light_path",
+        rebase_path("//third_party/wix/light.exe", root_build_dir),
+        "--product_name",
+        "Test System MSI Installer",
+        "--product_version",
+        version,
+        "--appid",
+        appid,
+        "--msi_base_name",
+        msi_base_name,
+        "--msi_template_path",
+        rebase_path(test_installer_wxs_xml),
+        "--company_name",
+        updater_company_short_name,
+        "--company_full_name",
+        updater_company_full_name,
+        "--output_dir",
+        rebase_path("$root_build_dir/test_installer"),
+      ]
+    }
+  }
+
+  test_msi_installer("1.0.0.0") {
+    version = "1.0.0.0"
+  }
+
+  test_msi_installer("2.0.0.0") {
+    version = "2.0.0.0"
+  }
+
+  copy("copy_test_msi_installer2.0.0.0") {
+    testonly = true
+    sources = get_target_outputs(":test_msi_installer2.0.0.0")
+    deps = [ ":test_msi_installer2.0.0.0" ]
+    outputs = [ "$root_build_dir/test_installer/{{source_file_part}}" ]
+  }
+
+  crx3("test_msi_installer_crx") {
+    testonly = true
+    base_dir = "$root_build_dir/test_installer"
+    key = "//chrome/updater/test/data/selfupdate_test_key.der"
+    inputs = get_target_outputs(":copy_test_msi_installer2.0.0.0")
+    output = "$root_build_dir/test_installer/TestSystemMsiInstaller.msi.crx3"
+    deps = [ ":copy_test_msi_installer2.0.0.0" ]
+  }
+}
diff --git a/chrome/version.gni b/chrome/version.gni
index 938b664..3cb4661 100644
--- a/chrome/version.gni
+++ b/chrome/version.gni
@@ -70,6 +70,7 @@
         "trichrome_64_version_code = \"@TRICHROME_64_VERSION_CODE@\" "
     if (target_cpu == "arm64") {
       _version_dictionary_template += "trichrome_64_32_high_version_code = \"@TRICHROME_64_32_HIGH_VERSION_CODE@\" "
+      _version_dictionary_template += "trichrome_auto_64_32_high_version_code = \"@TRICHROME_AUTO_64_32_HIGH_VERSION_CODE@\" "
     }
     _version_dictionary_template +=
         "trichrome_32_beta_version_code = \"@TRICHROME_32_BETA_VERSION_CODE@\" "
@@ -151,6 +152,7 @@
                            "trichrome_64_32_version_code",
                            "trichrome_64_32_high_version_code",
                            "trichrome_auto_64_32_version_code",
+                           "trichrome_auto_64_32_high_version_code",
                            "trichrome_64_version_code",
                            "trichrome_beta_version_code",
                            "trichrome_32_beta_version_code",
@@ -197,8 +199,10 @@
       "TrichromeChromeAuto6432: $trichrome_auto_64_32_version_code",
     ]
     if (target_cpu == "arm64") {
-      lines_to_write +=
-          [ "TrichromeChrome6432High: $trichrome_64_32_high_version_code" ]
+      lines_to_write += [
+        "TrichromeChrome6432High: $trichrome_64_32_high_version_code",
+        "TrichromeChromeAuto6432High: $trichrome_auto_64_32_high_version_code"
+      ]
     }
     lines_to_write += [
       "TrichromeChrome32OpenBeta: $trichrome_32_beta_version_code",
diff --git a/chromeos/ash/components/audio/audio_device.cc b/chromeos/ash/components/audio/audio_device.cc
index 59ca3f1..8b8ec4ae 100644
--- a/chromeos/ash/components/audio/audio_device.cc
+++ b/chromeos/ash/components/audio/audio_device.cc
@@ -5,7 +5,9 @@
 #include "chromeos/ash/components/audio/audio_device.h"
 
 #include <stdint.h>
+
 #include "ash/constants/ash_features.h"
+#include "base/containers/contains.h"
 #include "base/format_macros.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/stringprintf.h"
@@ -94,44 +96,46 @@
 
 // static
 AudioDeviceType AudioDevice::GetAudioType(const std::string& node_type) {
-  if (node_type.find("HEADPHONE") != std::string::npos)
+  if (base::Contains(node_type, "HEADPHONE")) {
     return AudioDeviceType::kHeadphone;
-  else if (node_type.find("INTERNAL_MIC") != std::string::npos)
+  } else if (base::Contains(node_type, "INTERNAL_MIC")) {
     return AudioDeviceType::kInternalMic;
-  else if (node_type.find("FRONT_MIC") != std::string::npos)
+  } else if (base::Contains(node_type, "FRONT_MIC")) {
     return AudioDeviceType::kFrontMic;
-  else if (node_type.find("REAR_MIC") != std::string::npos)
+  } else if (base::Contains(node_type, "REAR_MIC")) {
     return AudioDeviceType::kRearMic;
-  else if (node_type.find("KEYBOARD_MIC") != std::string::npos)
+  } else if (base::Contains(node_type, "KEYBOARD_MIC")) {
     return AudioDeviceType::kKeyboardMic;
-  else if (node_type.find("BLUETOOTH_NB_MIC") != std::string::npos)
+  } else if (base::Contains(node_type, "BLUETOOTH_NB_MIC")) {
     return AudioDeviceType::kBluetoothNbMic;
-  else if (node_type.find("MIC") != std::string::npos)
+  } else if (base::Contains(node_type, "MIC")) {
     return AudioDeviceType::kMic;
-  else if (node_type.find("USB") != std::string::npos)
+  } else if (base::Contains(node_type, "USB")) {
     return AudioDeviceType::kUsb;
-  else if (node_type.find("BLUETOOTH") != std::string::npos)
+  } else if (base::Contains(node_type, "BLUETOOTH")) {
     return AudioDeviceType::kBluetooth;
-  else if (node_type.find("HDMI") != std::string::npos)
+  } else if (base::Contains(node_type, "HDMI")) {
     return AudioDeviceType::kHdmi;
-  else if (node_type.find("INTERNAL_SPEAKER") != std::string::npos)
+  } else if (base::Contains(node_type, "INTERNAL_SPEAKER")) {
     return AudioDeviceType::kInternalSpeaker;
+  }
   // TODO(hychao): Remove the 'AOKR' matching line after CRAS switches
   // node type naming to 'HOTWORD'.
-  else if (node_type.find("AOKR") != std::string::npos)
+  else if (base::Contains(node_type, "AOKR")) {
     return AudioDeviceType::kHotword;
-  else if (node_type.find("HOTWORD") != std::string::npos)
+  } else if (base::Contains(node_type, "HOTWORD")) {
     return AudioDeviceType::kHotword;
-  else if (node_type.find("LINEOUT") != std::string::npos)
+  } else if (base::Contains(node_type, "LINEOUT")) {
     return AudioDeviceType::kLineout;
-  else if (node_type.find("POST_MIX_LOOPBACK") != std::string::npos)
+  } else if (base::Contains(node_type, "POST_MIX_LOOPBACK")) {
     return AudioDeviceType::kPostMixLoopback;
-  else if (node_type.find("POST_DSP_LOOPBACK") != std::string::npos)
+  } else if (base::Contains(node_type, "POST_DSP_LOOPBACK")) {
     return AudioDeviceType::kPostDspLoopback;
-  else if (node_type.find("ALSA_LOOPBACK") != std::string::npos)
+  } else if (base::Contains(node_type, "ALSA_LOOPBACK")) {
     return AudioDeviceType::kAlsaLoopback;
-  else
+  } else {
     return AudioDeviceType::kOther;
+  }
 }
 
 AudioDevice::AudioDevice() = default;
diff --git a/chromeos/ash/components/dbus/biod/fake_biod_client.cc b/chromeos/ash/components/dbus/biod/fake_biod_client.cc
index b63a92b..0eb4207 100644
--- a/chromeos/ash/components/dbus/biod/fake_biod_client.cc
+++ b/chromeos/ash/components/dbus/biod/fake_biod_client.cc
@@ -313,8 +313,10 @@
 void FakeBiodClient::SetRecordLabel(const dbus::ObjectPath& record_path,
                                     const std::string& label,
                                     chromeos::VoidDBusMethodCallback callback) {
-  if (records_.find(record_path) != records_.end())
-    records_[record_path].label = label;
+  auto it = records_.find(record_path);
+  if (it != records_.end()) {
+    it->second.label = label;
+  }
   SaveRecords();
   base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
       FROM_HERE, base::BindOnce(std::move(callback), true));
@@ -332,8 +334,10 @@
 void FakeBiodClient::RequestRecordLabel(const dbus::ObjectPath& record_path,
                                         LabelCallback callback) {
   std::string record_label;
-  if (records_.find(record_path) != records_.end())
-    record_label = records_[record_path].label;
+  auto it = records_.find(record_path);
+  if (it != records_.end()) {
+    record_label = it->second.label;
+  }
 
   base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
       FROM_HERE, base::BindOnce(std::move(callback), record_label));
diff --git a/chromeos/ash/components/dbus/kerberos/fake_kerberos_client.cc b/chromeos/ash/components/dbus/kerberos/fake_kerberos_client.cc
index 565defa3..22dffee 100644
--- a/chromeos/ash/components/dbus/kerberos/fake_kerberos_client.cc
+++ b/chromeos/ash/components/dbus/kerberos/fake_kerberos_client.cc
@@ -52,8 +52,9 @@
 // non-allowlisted keywords. Returns true if no blocklisted items are contained.
 bool ValidateConfigLine(const std::string& line) {
   for (const char* option : kBlocklistedConfigOptions) {
-    if (line.find(option) != std::string::npos)
+    if (base::Contains(line, option)) {
       return false;
+    }
   }
   return true;
 }
diff --git a/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client.cc b/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client.cc
index 89b0b4e2..cd53594c 100644
--- a/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client.cc
+++ b/chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client.cc
@@ -10,6 +10,7 @@
 #include <map>
 #include <set>
 
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/logging.h"
@@ -218,7 +219,7 @@
   dbus::MessageWriter array_writer(nullptr);
   writer.OpenArray("{ss}", &array_writer);
   for (auto it : parameters) {
-    if (valid_keys_.find(it.first) == valid_keys_.end()) {
+    if (!base::Contains(valid_keys_, it.first)) {
       LOG(WARNING) << "Unknown key " << it.first;
       continue;
     }
diff --git a/chromeos/ash/components/device_activity/device_active_use_case.cc b/chromeos/ash/components/device_activity/device_active_use_case.cc
index dc23642..29457bd 100644
--- a/chromeos/ash/components/device_activity/device_active_use_case.cc
+++ b/chromeos/ash/components/device_activity/device_active_use_case.cc
@@ -200,9 +200,11 @@
 
 base::Time DeviceActiveUseCase::RetrievePsmIdDate(
     private_membership::rlwe::RlwePlaintextId id) {
-  if (psm_id_to_date_.find(id.sensitive_id()) == psm_id_to_date_.end())
+  auto it = psm_id_to_date_.find(id.sensitive_id());
+  if (it == psm_id_to_date_.end()) {
     return base::Time::UnixEpoch();
-  return psm_id_to_date_.at(id.sensitive_id());
+  }
+  return it->second;
 }
 
 std::string DeviceActiveUseCase::GetDigestString(
diff --git a/chromeos/ash/components/disks/disk_mount_manager.cc b/chromeos/ash/components/disks/disk_mount_manager.cc
index 5f2e861..882305b 100644
--- a/chromeos/ash/components/disks/disk_mount_manager.cc
+++ b/chromeos/ash/components/disks/disk_mount_manager.cc
@@ -16,6 +16,7 @@
 #include <vector>
 
 #include "base/barrier_closure.h"
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/logging.h"
@@ -1072,8 +1073,7 @@
   }
 
   bool IsPendingPartitioningDisk(const std::string& device_path) {
-    if (pending_partitioning_disks_.find(device_path) !=
-        pending_partitioning_disks_.end()) {
+    if (base::Contains(pending_partitioning_disks_, device_path)) {
       return true;
     }
 
diff --git a/chromeos/ash/components/disks/fake_disk_mount_manager.cc b/chromeos/ash/components/disks/fake_disk_mount_manager.cc
index 5dc79f0..638b657 100644
--- a/chromeos/ash/components/disks/fake_disk_mount_manager.cc
+++ b/chromeos/ash/components/disks/fake_disk_mount_manager.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "chromeos/ash/components/disks/disk.h"
 
@@ -166,7 +167,7 @@
 
 bool FakeDiskMountManager::AddMountPointForTest(const MountPoint& mount_point) {
   if (mount_point.mount_type == MountType::kDevice &&
-      disks_.find(mount_point.source_path) == disks_.end()) {
+      !base::Contains(disks_, mount_point.source_path)) {
     // Device mount point must have a disk entry.
     return false;
   }
diff --git a/chromeos/ash/components/geolocation/simple_geolocation_unittest.cc b/chromeos/ash/components/geolocation/simple_geolocation_unittest.cc
index a120523..e1497edd 100644
--- a/chromeos/ash/components/geolocation/simple_geolocation_unittest.cc
+++ b/chromeos/ash/components/geolocation/simple_geolocation_unittest.cc
@@ -6,6 +6,7 @@
 
 #include <memory>
 
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -286,13 +287,12 @@
   receiver.WaitUntilRequestDone();
 
   std::string receiver_position = receiver.position().ToString();
-  EXPECT_NE(
-      std::string::npos,
-      receiver_position.find(
-          "latitude=200.000000, longitude=200.000000, accuracy=-1.000000, "
-          "error_code=0, error_message='SimpleGeolocation provider at "
-          "'https://localhost/' : JSONReader failed:"));
-  EXPECT_NE(std::string::npos, receiver_position.find("status=4 (TIMEOUT)"));
+  EXPECT_TRUE(base::Contains(
+      receiver_position,
+      "latitude=200.000000, longitude=200.000000, accuracy=-1.000000, "
+      "error_code=0, error_message='SimpleGeolocation provider at "
+      "'https://localhost/' : JSONReader failed:"));
+  EXPECT_TRUE(base::Contains(receiver_position, "status=4 (TIMEOUT)"));
   EXPECT_TRUE(receiver.server_error());
   EXPECT_GE(url_factory.attempts(), 2U);
   if (url_factory.attempts() > expected_retries + 1) {
diff --git a/chromeos/ash/components/local_search_service/inverted_index.cc b/chromeos/ash/components/local_search_service/inverted_index.cc
index b87b73b..edf0cae 100644
--- a/chromeos/ash/components/local_search_service/inverted_index.cc
+++ b/chromeos/ash/components/local_search_service/inverted_index.cc
@@ -174,8 +174,10 @@
 InvertedIndex::~InvertedIndex() = default;
 
 PostingList InvertedIndex::FindTerm(const std::u16string& term) const {
-  if (dictionary_.find(term) != dictionary_.end())
-    return dictionary_.at(term);
+  auto it = dictionary_.find(term);
+  if (it != dictionary_.end()) {
+    return it->second;
+  }
 
   return {};
 }
@@ -281,8 +283,9 @@
 
 std::vector<TfidfResult> InvertedIndex::GetTfidf(
     const std::u16string& term) const {
-  if (tfidf_cache_.find(term) != tfidf_cache_.end()) {
-    return tfidf_cache_.at(term);
+  auto it = tfidf_cache_.find(term);
+  if (it != tfidf_cache_.end()) {
+    return it->second;
   }
 
   return {};
diff --git a/chromeos/ash/components/login/hibernate/hibernate_manager.cc b/chromeos/ash/components/login/hibernate/hibernate_manager.cc
index 0641130..c559db8d 100644
--- a/chromeos/ash/components/login/hibernate/hibernate_manager.cc
+++ b/chromeos/ash/components/login/hibernate/hibernate_manager.cc
@@ -4,6 +4,7 @@
 
 #include "chromeos/ash/components/login/hibernate/hibernate_manager.h"
 
+#include "base/containers/contains.h"
 #include "base/files/file_util.h"
 #include "base/functional/bind.h"
 #include "base/logging.h"
@@ -47,7 +48,7 @@
       return false;
     }
 
-    return (crypto_info.find("aeskl") != std::string::npos);
+    return base::Contains(crypto_info, "aeskl");
   }();
   return hasKL;
 }
diff --git a/chromeos/ash/components/network/network_configuration_handler_unittest.cc b/chromeos/ash/components/network/network_configuration_handler_unittest.cc
index 737f333..2d822af38 100644
--- a/chromeos/ash/components/network/network_configuration_handler_unittest.cc
+++ b/chromeos/ash/components/network/network_configuration_handler_unittest.cc
@@ -9,6 +9,7 @@
 #include <map>
 #include <set>
 
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
 #include "base/location.h"
@@ -94,15 +95,13 @@
 
   void OnBeforeConfigurationRemoved(const std::string& service_path,
                                     const std::string& guid) override {
-    ASSERT_EQ(before_remove_configurations_.end(),
-              before_remove_configurations_.find(service_path));
+    ASSERT_FALSE(base::Contains(before_remove_configurations_, service_path));
     before_remove_configurations_[service_path] = guid;
   }
 
   void OnConfigurationRemoved(const std::string& service_path,
                               const std::string& guid) override {
-    ASSERT_EQ(removed_configurations_.end(),
-              removed_configurations_.find(service_path));
+    ASSERT_FALSE(base::Contains(removed_configurations_, service_path));
     removed_configurations_[service_path] = guid;
   }
 
@@ -114,23 +113,19 @@
   }
 
   bool HasCreatedConfiguration(const std::string& service_path) {
-    return created_configurations_.find(service_path) !=
-           created_configurations_.end();
+    return base::Contains(created_configurations_, service_path);
   }
 
   bool HasCalledBeforeRemoveConfiguration(const std::string& service_path) {
-    return before_remove_configurations_.find(service_path) !=
-           before_remove_configurations_.end();
+    return base::Contains(before_remove_configurations_, service_path);
   }
 
   bool HasRemovedConfiguration(const std::string& service_path) {
-    return removed_configurations_.find(service_path) !=
-           removed_configurations_.end();
+    return base::Contains(removed_configurations_, service_path);
   }
 
   bool HasUpdatedConfiguration(const std::string& service_path) {
-    return updated_configurations_.find(service_path) !=
-           updated_configurations_.end();
+    return base::Contains(updated_configurations_, service_path);
   }
 
  private:
diff --git a/chromeos/ash/components/network/network_device_handler_impl.cc b/chromeos/ash/components/network/network_device_handler_impl.cc
index 54645e6..720c4574 100644
--- a/chromeos/ash/components/network/network_device_handler_impl.cc
+++ b/chromeos/ash/components/network/network_device_handler_impl.cc
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include "ash/constants/ash_features.h"
+#include "base/containers/contains.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback_helpers.h"
@@ -506,8 +507,8 @@
   return device_state && device_state->link_up() &&
          device_state->Matches(NetworkTypePattern::Ethernet()) &&
          device_state->device_bus_type() == shill::kDeviceBusTypeUsb &&
-         mac_address_change_not_supported_.find(device_state->mac_address()) ==
-             mac_address_change_not_supported_.end();
+         !base::Contains(mac_address_change_not_supported_,
+                         device_state->mac_address());
 }
 
 void NetworkDeviceHandlerImpl::UpdatePrimaryEnabledUsbEthernetDevice() {
diff --git a/chromeos/ash/components/network/network_sms_handler_unittest.cc b/chromeos/ash/components/network/network_sms_handler_unittest.cc
index c05195c..b3e9184 100644
--- a/chromeos/ash/components/network/network_sms_handler_unittest.cc
+++ b/chromeos/ash/components/network/network_sms_handler_unittest.cc
@@ -10,6 +10,7 @@
 
 #include "ash/constants/ash_features.h"
 #include "base/command_line.h"
+#include "base/containers/contains.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/test/scoped_feature_list.h"
@@ -178,7 +179,7 @@
   // ModemMessagingClientStubImpl and SmsClientStubImpl.
   // TODO(stevenjb): Use a TestInterface to set this up to remove dependency.
   const char kMessage1[] = "FakeSMSClient: Test Message: /SMS/0";
-  EXPECT_EQ(messages.find(kMessage1), messages.end());
+  EXPECT_FALSE(base::Contains(messages, kMessage1));
 
   // Test for messages delivered by signals.
   test_observer_->ClearMessages();
@@ -191,7 +192,7 @@
   network_sms_handler_->RequestUpdate();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(test_observer_->message_count(), 1);
-  EXPECT_NE(messages.find(kMessage1), messages.end());
+  EXPECT_TRUE(base::Contains(messages, kMessage1));
 
   // There should be a request to delete the message after the message has been
   // received. Complete the request.
@@ -267,7 +268,7 @@
   // Note: The following string corresponds to values in
   // ModemMessagingClientStubImpl and SmsClientStubImpl.
   const char kMessage1[] = "FakeSMSClient: Test Message: /SMS/0";
-  EXPECT_EQ(messages.find(kMessage1), messages.end());
+  EXPECT_FALSE(base::Contains(messages, kMessage1));
 
   // Test for messages delivered by signals.
   test_observer_->ClearMessages();
@@ -280,7 +281,7 @@
   network_sms_handler_->RequestUpdate();
   base::RunLoop().RunUntilIdle();
   EXPECT_GE(test_observer_->message_count(), 1);
-  EXPECT_NE(messages.find(kMessage1), messages.end());
+  EXPECT_TRUE(base::Contains(messages, kMessage1));
 
   // There should be a request to delete the message after the message has been
   // received.
@@ -366,7 +367,7 @@
   // ModemMessagingClientStubImpl and SmsClientStubImpl.
   // TODO(stevenjb): Use a TestInterface to set this up to remove dependency.
   const char kMessage1[] = "FakeSMSClient: Test Message: /SMS/0";
-  EXPECT_EQ(messages.find(kMessage1), messages.end());
+  EXPECT_FALSE(base::Contains(messages, kMessage1));
 
   // Receive 2 SMSes.
   test_observer_->ClearMessages();
@@ -390,9 +391,8 @@
   network_sms_handler_->RequestUpdate();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(test_observer_->message_count(), 1);
-  EXPECT_EQ(messages.find(kMessage1), messages.end());
-  EXPECT_NE(messages.find("FakeSMSClient: Test Message: /SMS/2"),
-            messages.end());
+  EXPECT_FALSE(base::Contains(messages, kMessage1));
+  EXPECT_TRUE(base::Contains(messages, "FakeSMSClient: Test Message: /SMS/2"));
 
   // There should be a request to delete the second SMS. Complete the request.
   EXPECT_EQ(sms_path_2,
@@ -439,7 +439,7 @@
   // ModemMessagingClientStubImpl and SmsClientStubImpl.
   // TODO(stevenjb): Use a TestInterface to set this up to remove dependency.
   const char kMessage1[] = "FakeSMSClient: Test Message: /SMS/0";
-  EXPECT_EQ(messages.find(kMessage1), messages.end());
+  EXPECT_FALSE(base::Contains(messages, kMessage1));
 
   // Test for messages delivered by signals.
   test_observer_->ClearMessages();
@@ -451,7 +451,7 @@
   network_sms_handler_->RequestUpdate();
   base::RunLoop().RunUntilIdle();
   EXPECT_GE(test_observer_->message_count(), 1);
-  EXPECT_NE(messages.find(kMessage1), messages.end());
+  EXPECT_TRUE(base::Contains(messages, kMessage1));
 }
 
 }  // namespace ash
diff --git a/chromeos/ash/components/network/policy_applicator.cc b/chromeos/ash/components/network/policy_applicator.cc
index a163a213..d54af41 100644
--- a/chromeos/ash/components/network/policy_applicator.cc
+++ b/chromeos/ash/components/network/policy_applicator.cc
@@ -9,6 +9,7 @@
 
 #include "ash/constants/ash_features.h"
 #include "base/check.h"
+#include "base/containers/contains.h"
 #include "base/containers/flat_map.h"
 #include "base/containers/flat_set.h"
 #include "base/functional/bind.h"
@@ -297,7 +298,7 @@
                                       base::OnceClosure callback) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   if (old_guid == new_guid &&
-      remaining_policy_guids_.find(new_guid) == remaining_policy_guids_.end()) {
+      !base::Contains(remaining_policy_guids_, new_guid)) {
     VLOG(1) << "Not updating existing managed configuration with guid "
             << new_guid << " because the policy didn't change.";
     std::move(callback).Run();
diff --git a/chromeos/ash/components/network/profile_policies.cc b/chromeos/ash/components/network/profile_policies.cc
index 8a035dc..2cb95fe 100644
--- a/chromeos/ash/components/network/profile_policies.cc
+++ b/chromeos/ash/components/network/profile_policies.cc
@@ -8,6 +8,7 @@
 #include <string>
 #include <utility>
 
+#include "base/containers/contains.h"
 #include "base/containers/flat_set.h"
 #include "base/values.h"
 #include "chromeos/ash/components/network/client_cert_util.h"
@@ -151,7 +152,7 @@
         network.FindString(::onc::network_config::kGUID);
     DCHECK(guid_str && !guid_str->empty());
     std::string guid = *guid_str;
-    if (processed_guids.find(guid) != processed_guids.end()) {
+    if (base::Contains(processed_guids, guid)) {
       NET_LOG(ERROR) << "ONC Contains multiple entries for the same guid: "
                      << guid;
       continue;
diff --git a/chromeos/ash/components/network/shill_property_handler.cc b/chromeos/ash/components/network/shill_property_handler.cc
index 09471577..0269a492 100644
--- a/chromeos/ash/components/network/shill_property_handler.cc
+++ b/chromeos/ash/components/network/shill_property_handler.cc
@@ -160,8 +160,7 @@
     network_handler::ErrorCallback error_callback,
     base::OnceClosure success_callback) {
   if (enabled) {
-    if (prohibited_technologies_.find(technology) !=
-        prohibited_technologies_.end()) {
+    if (base::Contains(prohibited_technologies_, technology)) {
       NET_LOG(ERROR) << "Attempt to enable prohibited network technology: "
                      << technology;
       network_handler::RunErrorCallback(std::move(error_callback),
@@ -273,8 +272,9 @@
 
 void ShillPropertyHandler::RequestProperties(ManagedState::ManagedType type,
                                              const std::string& path) {
-  if (pending_updates_[type].find(path) != pending_updates_[type].end())
+  if (base::Contains(pending_updates_[type], path)) {
     return;  // Update already requested.
+  }
 
   NET_LOG(DEBUG) << "Request Properties for: " << NetworkPathId(path);
   pending_updates_[type].insert(path);
@@ -453,7 +453,7 @@
     // that prevents it from sending property changed signals for cellular
     // devices (see crbug.com/321854).
     if (type == ManagedState::MANAGED_TYPE_DEVICE ||
-        requested_updates.find(*path) == requested_updates.end()) {
+        !base::Contains(requested_updates, *path)) {
       RequestProperties(type, *path);
     }
     new_requested_updates.insert(*path);
diff --git a/chromeos/ash/components/proximity_auth/proximity_auth_system.cc b/chromeos/ash/components/proximity_auth/proximity_auth_system.cc
index e2acaf6..d6e0e48 100644
--- a/chromeos/ash/components/proximity_auth/proximity_auth_system.cc
+++ b/chromeos/ash/components/proximity_auth/proximity_auth_system.cc
@@ -76,9 +76,11 @@
 ash::multidevice::RemoteDeviceRefList
 ProximityAuthSystem::GetRemoteDevicesForUser(
     const AccountId& account_id) const {
-  if (remote_devices_map_.find(account_id) == remote_devices_map_.end())
+  auto it = remote_devices_map_.find(account_id);
+  if (it == remote_devices_map_.end()) {
     return ash::multidevice::RemoteDeviceRefList();
-  return remote_devices_map_.at(account_id);
+  }
+  return it->second;
 }
 
 void ProximityAuthSystem::OnAuthAttempted() {
@@ -146,13 +148,15 @@
     }
   }
 
-  if (remote_devices_map_.find(account_id) == remote_devices_map_.end() ||
-      remote_devices_map_[account_id].size() == 0) {
+  auto remote_devices_it = remote_devices_map_.find(account_id);
+  if (remote_devices_it == remote_devices_map_.end() ||
+      remote_devices_it->second.empty()) {
     PA_LOG(INFO) << "User " << account_id.Serialize()
                  << " does not have a Smart Lock host device.";
     return;
   }
-  if (local_device_map_.find(account_id) == local_device_map_.end()) {
+  auto local_device_it = local_device_map_.find(account_id);
+  if (local_device_it == local_device_map_.end()) {
     PA_LOG(INFO) << "User " << account_id.Serialize()
                  << " does not have a local device.";
     return;
@@ -161,10 +165,10 @@
   // TODO(tengs): We currently assume each user has only one RemoteDevice, so we
   // can simply take the first item in the list.
   ash::multidevice::RemoteDeviceRef remote_device =
-      remote_devices_map_[account_id][0];
+      remote_devices_it->second[0];
 
   absl::optional<ash::multidevice::RemoteDeviceRef> local_device;
-  local_device = local_device_map_.at(account_id);
+  local_device = local_device_it->second;
 
   if (!suspended_) {
     PA_LOG(INFO) << "Creating RemoteDeviceLifeCycle for focused user: "
diff --git a/chromeos/ash/components/sync_wifi/synced_network_metrics_logger.cc b/chromeos/ash/components/sync_wifi/synced_network_metrics_logger.cc
index 7a9c7cf..4b45a973 100644
--- a/chromeos/ash/components/sync_wifi/synced_network_metrics_logger.cc
+++ b/chromeos/ash/components/sync_wifi/synced_network_metrics_logger.cc
@@ -4,6 +4,7 @@
 
 #include "chromeos/ash/components/sync_wifi/synced_network_metrics_logger.h"
 
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/metrics/histogram_functions.h"
 #include "chromeos/ash/components/network/network_configuration_handler.h"
@@ -287,9 +288,8 @@
 void SyncedNetworkMetricsLogger::RecordZeroNetworksEligibleForSync(
     base::flat_set<NetworkEligibilityStatus> network_eligibility_status_codes) {
   // There is an eligible network that was not synced for some reason.
-  if (network_eligibility_status_codes.find(
-          NetworkEligibilityStatus::kNetworkIsEligible) !=
-      network_eligibility_status_codes.end()) {
+  if (base::Contains(network_eligibility_status_codes,
+                     NetworkEligibilityStatus::kNetworkIsEligible)) {
     base::UmaHistogramEnumeration(kZeroNetworksSyncedReasonHistogram,
                                   NetworkEligibilityStatus::kNetworkIsEligible);
     return;
diff --git a/chromeos/ash/components/system/statistics_provider_impl.cc b/chromeos/ash/components/system/statistics_provider_impl.cc
index 84ebcdd2..52a61e5 100644
--- a/chromeos/ash/components/system/statistics_provider_impl.cc
+++ b/chromeos/ash/components/system/statistics_provider_impl.cc
@@ -13,6 +13,7 @@
 #include "ash/constants/ash_switches.h"
 #include "base/check.h"
 #include "base/command_line.h"
+#include "base/containers/contains.h"
 #include "base/files/file_util.h"
 #include "base/json/json_file_value_serializer.h"
 #include "base/logging.h"
@@ -471,8 +472,7 @@
     // Use the write-protect value from crossystem only if it hasn't been loaded
     // from any other source, since the result of crossystem is less reliable
     // for this key.
-    if (machine_info_.find(kFirmwareWriteProtectCurrentKey) ==
-            machine_info_.end() &&
+    if (!base::Contains(machine_info_, kFirmwareWriteProtectCurrentKey) &&
         !crossystem_wpsw.empty()) {
       LOG(WARNING) << "wpsw_cur missing from machine_info, using value: "
                    << crossystem_wpsw;
@@ -500,10 +500,10 @@
     VLOG(1) << "CrOS region set to '" << region << "'";
   }
 
+  const auto it = machine_info_.find(kRegionKey);
+
   LoadRegionsFile(sources_.cros_regions_filepath,
-                  machine_info_.find(kRegionKey) != machine_info_.end()
-                      ? machine_info_[kRegionKey]
-                      : "");
+                  it != machine_info_.end() ? it->second : "");
 
   SignalStatisticsLoaded();
 }
@@ -652,11 +652,13 @@
 
 absl::optional<base::StringPiece>
 StatisticsProviderImpl::GetRegionalInformation(base::StringPiece name) const {
-  if (machine_info_.find(kRegionKey) == machine_info_.end())
+  if (!base::Contains(machine_info_, kRegionKey)) {
     return absl::nullopt;
+  }
 
-  if (const auto iter = region_info_.find(name); iter != region_info_.end())
+  if (const auto iter = region_info_.find(name); iter != region_info_.end()) {
     return base::StringPiece(iter->second);
+  }
 
   return absl::nullopt;
 }
diff --git a/chromeos/ash/components/tether/top_level_host_scan_cache.cc b/chromeos/ash/components/tether/top_level_host_scan_cache.cc
index df75a7b..2bb04f0 100644
--- a/chromeos/ash/components/tether/top_level_host_scan_cache.cc
+++ b/chromeos/ash/components/tether/top_level_host_scan_cache.cc
@@ -6,6 +6,7 @@
 
 #include <algorithm>
 
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
 #include "chromeos/ash/components/multidevice/logging/logging.h"
@@ -126,8 +127,7 @@
   bool exists_in_persistent_cache =
       persistent_host_scan_cache_->ExistsInCache(tether_network_guid);
   bool exists_in_timer_map =
-      tether_guid_to_timer_map_.find(tether_network_guid) !=
-      tether_guid_to_timer_map_.end();
+      base::Contains(tether_guid_to_timer_map_, tether_network_guid);
 
   // The caches are expected to remain in sync.
   DCHECK(exists_in_network_cache == exists_in_persistent_cache &&
diff --git a/chromeos/ash/components/timezone/timezone_unittest.cc b/chromeos/ash/components/timezone/timezone_unittest.cc
index 1bc97750..2395a788 100644
--- a/chromeos/ash/components/timezone/timezone_unittest.cc
+++ b/chromeos/ash/components/timezone/timezone_unittest.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <utility>
 
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
@@ -238,14 +239,14 @@
                                           base::Unretained(&receiver)));
   receiver.WaitUntilRequestDone();
   std::string receiver_timezone = receiver.timezone()->ToStringForDebug();
-  EXPECT_NE(std::string::npos,
-            receiver_timezone.find("dstOffset=0.000000, rawOffset=0.000000, "
-                                   "timeZoneId='', timeZoneName='', "
-                                   "error_message='TimeZone provider at "
-                                   "'https://localhost/' : JSONReader "
-                                   "failed:"));
-  EXPECT_NE(std::string::npos,
-            receiver_timezone.find("status=6 (REQUEST_ERROR)"));
+  EXPECT_TRUE(base::Contains(receiver_timezone,
+                             "dstOffset=0.000000, rawOffset=0.000000, "
+                             "timeZoneId='', timeZoneName='', "
+                             "error_message='TimeZone provider at "
+                             "'https://localhost/' : JSONReader "
+                             "failed:"));
+
+  EXPECT_TRUE(base::Contains(receiver_timezone, "status=6 (REQUEST_ERROR)"));
   EXPECT_FALSE(receiver.server_error());
   EXPECT_GE(url_factory.attempts(), 2U);
   if (url_factory.attempts() > expected_retries + 1) {
diff --git a/chromeos/ash/services/assistant/assistant_manager_service_impl.cc b/chromeos/ash/services/assistant/assistant_manager_service_impl.cc
index a82cc7d..6189e14 100644
--- a/chromeos/ash/services/assistant/assistant_manager_service_impl.cc
+++ b/chromeos/ash/services/assistant/assistant_manager_service_impl.cc
@@ -16,6 +16,7 @@
 #include "base/barrier_closure.h"
 #include "base/check.h"
 #include "base/command_line.h"
+#include "base/containers/contains.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/i18n/rtl.h"
@@ -696,8 +697,7 @@
   if (device_settings_host_->has_setting_changed()) {
     return AssistantQueryResponseType::kDeviceAction;
   } else if (!receive_url_response_.empty()) {
-    if (receive_url_response_.find("www.google.com/search?") !=
-        std::string::npos) {
+    if (base::Contains(receive_url_response_, "www.google.com/search?")) {
       return AssistantQueryResponseType::kSearchFallback;
     } else {
       return AssistantQueryResponseType::kTargetedAction;
diff --git a/chromeos/ash/services/device_sync/fake_ecies_encryption.cc b/chromeos/ash/services/device_sync/fake_ecies_encryption.cc
index ba16e67..e8ad762 100644
--- a/chromeos/ash/services/device_sync/fake_ecies_encryption.cc
+++ b/chromeos/ash/services/device_sync/fake_ecies_encryption.cc
@@ -5,6 +5,7 @@
 #include "chromeos/ash/services/device_sync/fake_ecies_encryption.h"
 
 #include "base/check_op.h"
+#include "base/containers/contains.h"
 
 namespace ash {
 
@@ -22,7 +23,7 @@
 }
 
 std::string GetPublicKeyFromPrivateKeyForTest(const std::string& private_key) {
-  DCHECK_NE(std::string::npos, private_key.find(kPrivateKeyPrefix));
+  DCHECK(base::Contains(private_key, kPrivateKeyPrefix));
 
   return private_key.substr(strlen(kPrivateKeyPrefix), private_key.length());
 }
diff --git a/chromeos/components/quick_answers/utils/language_detector_unittest.cc b/chromeos/components/quick_answers/utils/language_detector_unittest.cc
index 3a17c0a..e06c32c 100644
--- a/chromeos/components/quick_answers/utils/language_detector_unittest.cc
+++ b/chromeos/components/quick_answers/utils/language_detector_unittest.cc
@@ -47,13 +47,14 @@
                      FindLanguagesCallback callback) override {
     std::vector<TextLanguagePtr> languages;
 
-    if (detection_results_.find(text) == detection_results_.end()) {
+    const auto it = detection_results_.find(text);
+    if (it == detection_results_.end()) {
       languages.push_back(DefaultLanguage());
       std::move(callback).Run(std::move(languages));
       return;
     }
 
-    languages.push_back(detection_results_[text].Clone());
+    languages.push_back(it->second.Clone());
     std::move(callback).Run(std::move(languages));
   }
 
diff --git a/chromeos/components/sensors/ash/sensor_hal_dispatcher.cc b/chromeos/components/sensors/ash/sensor_hal_dispatcher.cc
index 70ddf28..d1518eaa 100644
--- a/chromeos/components/sensors/ash/sensor_hal_dispatcher.cc
+++ b/chromeos/components/sensors/ash/sensor_hal_dispatcher.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/time/time.h"
 #include "chromeos/ash/components/mojo_service_manager/connection.h"
@@ -100,7 +101,7 @@
     const base::UnguessableToken& token) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  return client_token_set_.find(token) != client_token_set_.end();
+  return base::Contains(client_token_set_, token);
 }
 
 void SensorHalDispatcher::TryToEstablishMojoChannelByServiceManager() {
diff --git a/chromeos/dbus/missive/missive_client.cc b/chromeos/dbus/missive/missive_client.cc
index fb096d5..141aad8 100644
--- a/chromeos/dbus/missive/missive_client.cc
+++ b/chromeos/dbus/missive/missive_client.cc
@@ -9,6 +9,7 @@
 #include <string_view>
 #include <utility>
 
+#include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/functional/callback_helpers.h"
@@ -57,7 +58,7 @@
   }
   const std::string lowercase_api_key = base::ToLowerASCII(api_key);
   for (const auto* key : kBlockListedKeys) {
-    if (lowercase_api_key.find(key) != std::string::npos) {
+    if (base::Contains(lowercase_api_key, key)) {
       LOG(ERROR) << "API Key is block-listed: " << api_key;
       return false;
     }
diff --git a/chromeos/printing/ppd_provider.cc b/chromeos/printing/ppd_provider.cc
index e720cc2..18d2d7f7 100644
--- a/chromeos/printing/ppd_provider.cc
+++ b/chromeos/printing/ppd_provider.cc
@@ -8,6 +8,7 @@
 #include <utility>
 #include <vector>
 
+#include "base/containers/contains.h"
 #include "base/containers/queue.h"
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
@@ -81,7 +82,7 @@
 // IEEE 1284 device id make and model.
 bool SupportsGenericZebraPPD(const PrinterSearchData& search_data) {
   return search_data.printer_id.make() == "Zebra" &&
-         search_data.printer_id.model().find("ZPL") != std::string::npos;
+         base::Contains(search_data.printer_id.model(), "ZPL");
 }
 
 // Helper struct for PpdProviderImpl. Allows PpdProviderImpl to defer
diff --git a/chromeos/printing/uri_unittest_consistency.cc b/chromeos/printing/uri_unittest_consistency.cc
index 2a0c09cd..518733609 100644
--- a/chromeos/printing/uri_unittest_consistency.cc
+++ b/chromeos/printing/uri_unittest_consistency.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/containers/contains.h"
 #include "base/strings/string_number_conversions.h"
 #include "chromeos/printing/uri.h"
 #include "chromeos/printing/uri_unittest.h"
@@ -30,7 +31,7 @@
 std::string Encode(const std::string& input, const std::string& allowed_chars) {
   std::string out;
   for (char c : input) {
-    if (IsStdChar(c) || allowed_chars.find(c) != std::string::npos) {
+    if (IsStdChar(c) || base::Contains(allowed_chars, c)) {
       out.push_back(c);
     } else {
       out.push_back('%');
diff --git a/chromeos/profiles/atom.afdo.newest.txt b/chromeos/profiles/atom.afdo.newest.txt
index f8f6bc2..74f3b6d 100644
--- a/chromeos/profiles/atom.afdo.newest.txt
+++ b/chromeos/profiles/atom.afdo.newest.txt
@@ -1 +1 @@
-chromeos-chrome-amd64-atom-118-5938.13-1692612678-benchmark-118.0.5966.0-r1-redacted.afdo.xz
+chromeos-chrome-amd64-atom-118-5938.13-1692612678-benchmark-118.0.5968.0-r2-redacted.afdo.xz
diff --git a/clank b/clank
index 53a7e81..1958ab7 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 53a7e81a8728e0b93c34a1a7d162c4b75e960f6d
+Subproject commit 1958ab73e7ce5784e7e9337dff79971786d35506
diff --git a/components/browser_ui/modaldialog/android/java/res/values/dimens.xml b/components/browser_ui/modaldialog/android/java/res/values/dimens.xml
index 4d3d7ae6..e16853f 100644
--- a/components/browser_ui/modaldialog/android/java/res/values/dimens.xml
+++ b/components/browser_ui/modaldialog/android/java/res/values/dimens.xml
@@ -6,9 +6,7 @@
 -->
 
 <resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="UnusedResources">
-    <dimen name="modal_dialog_control_vertical_padding">2dp</dimen>
-    <dimen name="modal_dialog_control_horizontal_padding">8dp</dimen>
-    <dimen name="modal_dialog_control_vertical_padding_filled">10dp</dimen>
+    <dimen name="modal_dialog_control_vertical_padding_filled">16dp</dimen>
     <dimen name="modal_dialog_control_horizontal_padding_filled">16dp</dimen>
     <dimen name="modal_dialog_button_with_icon_start_padding">12dp</dimen>
     <dimen name="modal_dialog_button_with_icon_text_padding">8dp</dimen>
diff --git a/components/browser_ui/modaldialog/android/java/res/values/styles.xml b/components/browser_ui/modaldialog/android/java/res/values/styles.xml
index d18e987..80f4569 100644
--- a/components/browser_ui/modaldialog/android/java/res/values/styles.xml
+++ b/components/browser_ui/modaldialog/android/java/res/values/styles.xml
@@ -11,32 +11,28 @@
         <item name="android:windowFrame">@null</item>
         <item name="android:backgroundDimAmount">0.65</item>
         <item name="android:windowSoftInputMode">adjustResize|stateHidden</item>
+        <item name="dualControlLayoutVerticalPadding">@dimen/modal_dialog_control_vertical_padding_filled</item>
+        <item name="dualControlLayoutHorizontalPadding">@dimen/modal_dialog_control_horizontal_padding_filled</item>
     </style>
 
     <style name="ThemeOverlay.BrowserUI.ModalDialog.TextPrimaryButton" parent="ThemeOverlay.BrowserUI.ModalDialog">
         <item name="buttonBarButtonStyle">@style/TextButton</item>
-        <item name="dualControlLayoutVerticalPadding">@dimen/modal_dialog_control_vertical_padding</item>
-        <item name="dualControlLayoutHorizontalPadding">@dimen/modal_dialog_control_horizontal_padding</item>
     </style>
 
     <style name="ThemeOverlay.BrowserUI.ModalDialog.FilledPrimaryButton" parent="ThemeOverlay.BrowserUI.ModalDialog">
         <item name="buttonBarPositiveButtonStyle">@style/FilledButton.Flat</item>
         <item name="buttonBarNegativeButtonStyle">@style/TextButton</item>
-        <item name="dualControlLayoutVerticalPadding">@dimen/modal_dialog_control_vertical_padding_filled</item>
-        <item name="dualControlLayoutHorizontalPadding">@dimen/modal_dialog_control_horizontal_padding_filled</item>
     </style>
 
     <style name="ThemeOverlay.BrowserUI.ModalDialog.FilledNegativeButton" parent="ThemeOverlay.BrowserUI.ModalDialog">
         <item name="buttonBarPositiveButtonStyle">@style/TextButton</item>
         <item name="buttonBarNegativeButtonStyle">@style/FilledButton.Flat</item>
-        <item name="dualControlLayoutVerticalPadding">@dimen/modal_dialog_control_vertical_padding_filled</item>
-        <item name="dualControlLayoutHorizontalPadding">@dimen/modal_dialog_control_horizontal_padding_filled</item>
     </style>
 
     <style name="ThemeOverlay.BrowserUI.ModalDialog.TextPrimaryButton.Fullscreen" parent="ThemeOverlay.BrowserUI.Fullscreen">
         <item name="buttonBarButtonStyle">@style/TextButton</item>
-        <item name="dualControlLayoutVerticalPadding">@dimen/modal_dialog_control_vertical_padding</item>
-        <item name="dualControlLayoutHorizontalPadding">@dimen/modal_dialog_control_horizontal_padding</item>
+        <item name="dualControlLayoutVerticalPadding">@dimen/modal_dialog_control_vertical_padding_filled</item>
+        <item name="dualControlLayoutHorizontalPadding">@dimen/modal_dialog_control_horizontal_padding_filled</item>
     </style>
 
     <style name="ThemeOverlay.BrowserUI.ModalDialog.FilledPrimaryButton.Fullscreen" parent="ThemeOverlay.BrowserUI.Fullscreen">
@@ -79,8 +75,8 @@
 
     <style name="ThemeOverlay.BrowserUI.ModalDialog.TextPrimaryButton.DialogWhenLarge" parent="ThemeOverlay.BrowserUI.Fullscreen.DialogWhenLarge">
         <item name="buttonBarButtonStyle">@style/TextButton</item>
-        <item name="dualControlLayoutVerticalPadding">@dimen/modal_dialog_control_vertical_padding</item>
-        <item name="dualControlLayoutHorizontalPadding">@dimen/modal_dialog_control_horizontal_padding</item>
+        <item name="dualControlLayoutVerticalPadding">@dimen/modal_dialog_control_vertical_padding_filled</item>
+        <item name="dualControlLayoutHorizontalPadding">@dimen/modal_dialog_control_horizontal_padding_filled</item>
     </style>
 
     <style name="ThemeOverlay.BrowserUI.ModalDialog.FilledPrimaryButton.DialogWhenLarge" parent="ThemeOverlay.BrowserUI.Fullscreen.DialogWhenLarge">
diff --git a/components/exo/server/wayland_server_controller.cc b/components/exo/server/wayland_server_controller.cc
index 4b60713..145f5669 100644
--- a/components/exo/server/wayland_server_controller.cc
+++ b/components/exo/server/wayland_server_controller.cc
@@ -52,10 +52,26 @@
   // TODO(https://crbug.com/1124106): Investigate if we can eliminate Shutdown
   // methods.
   display_->Shutdown();
+  wayland::Server::SetServerGetter(base::NullCallback());
   DCHECK_EQ(g_instance, this);
   g_instance = nullptr;
 }
 
+wayland::Server* WaylandServerController::GetServerForDisplay(
+    wl_display* display) {
+  if (default_server_ && default_server_->GetWaylandDisplay() == display) {
+    return default_server_.get();
+  }
+
+  for (const auto& pair : on_demand_servers_) {
+    if (pair.second->GetWaylandDisplay() == display) {
+      return pair.second.get();
+    }
+  }
+
+  return nullptr;
+}
+
 WaylandServerController::WaylandServerController(
     std::unique_ptr<DataExchangeDelegate> data_exchange_delegate,
     std::unique_ptr<NotificationSurfaceManager> notification_surface_manager,
@@ -74,6 +90,8 @@
   default_server_->StartWithDefaultPath(base::BindOnce([](bool success) {
     DCHECK(success) << "Failed to start the default wayland server.";
   }));
+  wayland::Server::SetServerGetter(base::BindRepeating(
+      &WaylandServerController::GetServerForDisplay, base::Unretained(this)));
 }
 
 void WaylandServerController::ListenOnSocket(
diff --git a/components/exo/server/wayland_server_controller.h b/components/exo/server/wayland_server_controller.h
index af22ffe..8e5854c2 100644
--- a/components/exo/server/wayland_server_controller.h
+++ b/components/exo/server/wayland_server_controller.h
@@ -14,6 +14,8 @@
 #include "components/exo/security_delegate.h"
 #include "components/exo/wayland/server.h"
 
+struct wl_display;
+
 namespace exo {
 
 namespace wayland {
@@ -49,6 +51,9 @@
 
   ~WaylandServerController();
 
+  // Gets the Server instance for the `display` if it exists.
+  wayland::Server* GetServerForDisplay(wl_display* display);
+
   InputMethodSurfaceManager* input_method_surface_manager() {
     return display_->input_method_surface_manager();
   }
diff --git a/components/exo/wayland/BUILD.gn b/components/exo/wayland/BUILD.gn
index 852f749..6f3b94a 100644
--- a/components/exo/wayland/BUILD.gn
+++ b/components/exo/wayland/BUILD.gn
@@ -17,6 +17,8 @@
 
 source_set("wayland") {
   sources = [
+    "client_tracker.cc",
+    "client_tracker.h",
     "content_type.cc",
     "content_type.h",
     "output_metrics.cc",
@@ -276,6 +278,7 @@
   testonly = true
 
   sources = [
+    "client_tracker_unittest.cc",
     "clients/security_delegate_binding_test.cc",
     "output_metrics_unittest.cc",
     "server_unittest.cc",
diff --git a/components/exo/wayland/client_tracker.cc b/components/exo/wayland/client_tracker.cc
new file mode 100644
index 0000000..f6a239b
--- /dev/null
+++ b/components/exo/wayland/client_tracker.cc
@@ -0,0 +1,76 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/client_tracker.h"
+
+namespace exo::wayland {
+
+ClientTracker::ClientTracker(wl_display* wl_display)
+    : wl_display_(wl_display),
+      client_created_listener_(this, &ClientTracker::OnClientCreated) {
+  wl_display_add_client_created_listener(wl_display,
+                                         &client_created_listener_.listener);
+}
+
+ClientTracker::~ClientTracker() {
+  while (client_destroyed_listeners_.size() > 0) {
+    auto it = client_destroyed_listeners_.begin();
+    wl_list_remove(&it->second->listener.link);
+    client_destroyed_listeners_.erase(it->first);
+  }
+  // Remove the listener from the display's destroy signal.
+  wl_list_remove(&client_created_listener_.listener.link);
+}
+
+bool ClientTracker::IsClientDestroyed(wl_client* client) const {
+  return client_destroyed_listeners_.find(client) ==
+         client_destroyed_listeners_.end();
+}
+
+int ClientTracker::NumClientsTrackedForTesting() const {
+  return client_destroyed_listeners_.size();
+}
+
+ClientTracker::ClientListener::ClientListener(ClientTracker* tracker,
+                                              wl_notify_func_t notify)
+    : tracker(tracker) {
+  listener.notify = notify;
+}
+
+// static.
+void ClientTracker::OnClientCreated(struct wl_listener* listener, void* data) {
+  ClientListener* client_created_listener = wl_container_of(
+      listener, /*sample=*/client_created_listener, /*member=*/listener);
+  wl_client* client = static_cast<wl_client*>(data);
+  ClientTracker* tracker = client_created_listener->tracker;
+  tracker->HandleClientCreated(client);
+}
+
+// static.
+void ClientTracker::OnClientDestroyed(struct wl_listener* listener,
+                                      void* data) {
+  ClientListener* client_destroyed_listener = wl_container_of(
+      listener, /*sample=*/client_destroyed_listener, /*member=*/listener);
+  wl_client* client = static_cast<wl_client*>(data);
+  ClientTracker* tracker = client_destroyed_listener->tracker;
+  tracker->HandleClientDestroyed(client);
+}
+
+void ClientTracker::HandleClientCreated(wl_client* client) {
+  // Set up the destruction listener for the newly created client.
+  client_destroyed_listeners_.emplace(
+      client, std::make_unique<ClientListener>(
+                  this, &ClientTracker::OnClientDestroyed));
+  auto& client_destroyed_listener = client_destroyed_listeners_.at(client);
+  wl_client_add_destroy_listener(client, &client_destroyed_listener->listener);
+}
+
+void ClientTracker::HandleClientDestroyed(wl_client* client) {
+  // Remove the listener from the client's destroy signal.
+  auto& client_destroyed_listener = client_destroyed_listeners_.at(client);
+  wl_list_remove(&client_destroyed_listener->listener.link);
+  client_destroyed_listeners_.erase(client);
+}
+
+}  // namespace exo::wayland
diff --git a/components/exo/wayland/client_tracker.h b/components/exo/wayland/client_tracker.h
new file mode 100644
index 0000000..13cae0ab
--- /dev/null
+++ b/components/exo/wayland/client_tracker.h
@@ -0,0 +1,72 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_EXO_WAYLAND_CLIENT_TRACKER_H_
+#define COMPONENTS_EXO_WAYLAND_CLIENT_TRACKER_H_
+
+#include <memory>
+
+#include <wayland-server-protocol-core.h>
+
+#include "base/containers/flat_map.h"
+#include "base/memory/raw_ptr.h"
+
+struct wl_client;
+struct wl_display;
+
+namespace exo::wayland {
+
+// Utility class to keep track of the lifetime of wl_client. This is necessary
+// as resources owned by wl_client are freed in the process of destruction, and
+// accessing client resources should not happen after this time (see
+// crbug.com/1433187). All resources and associated user data are destroyed and
+// freed before the wl_client is itself deleted.
+class ClientTracker {
+ public:
+  explicit ClientTracker(wl_display* wl_display);
+  virtual ~ClientTracker();
+
+  // Returns true if `client` has begun destruction. Client resources should not
+  // be queried after this point.
+  bool IsClientDestroyed(wl_client* client) const;
+
+  int NumClientsTrackedForTesting() const;
+
+ private:
+  // Listener called when the wl_client has been successfully created for
+  // `wl_display_` and immediately when the clients begins destruction (before
+  // associated resources have been freed).
+  struct ClientListener {
+    ClientListener(ClientTracker* tracker, wl_notify_func_t notify);
+    wl_listener listener;
+    raw_ptr<ClientTracker> tracker;
+  };
+
+  // Called when a wl_client has successfully been created for `wl_display_`.
+  static void OnClientCreated(struct wl_listener* listener, void* data);
+
+  // Called when a wl_client associated with the listener begins destruction.
+  static void OnClientDestroyed(struct wl_listener* listener, void* data);
+
+  // Handles the `OnClientCreated()` event for clients associated with this
+  // tracker instance.
+  void HandleClientCreated(wl_client* client);
+
+  // Handles the `OnClientDestroyed()` event for clients associated with this
+  // tracker instance.
+  void HandleClientDestroyed(wl_client* client);
+
+  raw_ptr<wl_display> wl_display_;
+
+  ClientListener client_created_listener_;
+
+  // Presence in `client_destroyed_listeners_` indicates the client has been
+  // created and has yet to be destroyed.
+  base::flat_map<wl_client*, std::unique_ptr<ClientListener>>
+      client_destroyed_listeners_;
+};
+
+}  // namespace exo::wayland
+
+#endif  // COMPONENTS_EXO_WAYLAND_CLIENT_TRACKER_H_
diff --git a/components/exo/wayland/client_tracker_unittest.cc b/components/exo/wayland/client_tracker_unittest.cc
new file mode 100644
index 0000000..e439192
--- /dev/null
+++ b/components/exo/wayland/client_tracker_unittest.cc
@@ -0,0 +1,126 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/exo/wayland/client_tracker.h"
+
+#include <sys/socket.h>
+#include <wayland-server-protocol-core.h>
+
+#include "base/memory/raw_ptr.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace exo {
+namespace wayland {
+
+class WaylandClientTrackerTest : public testing::Test {
+ protected:
+  struct ClientData {
+    raw_ptr<wl_client> client = nullptr;
+    int fds[2] = {0, 0};
+  };
+
+  // testing::Test:
+  void SetUp() override {
+    testing::Test::SetUp();
+    wayland_display_ = wl_display_create();
+    client_tracker_ = std::make_unique<ClientTracker>(wayland_display_);
+  }
+  void TearDown() override {
+    while (clients_.size() > 0) {
+      DestroyClient(clients_.back().client);
+    }
+    client_tracker_.reset();
+    wl_display_destroy(wayland_display_.ExtractAsDangling());
+    testing::Test::TearDown();
+  }
+
+  // Creates a wl_client for this test's display.
+  wl_client* CreateClient() {
+    ClientData client_data;
+    socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, client_data.fds);
+    client_data.client = wl_client_create(wayland_display_, client_data.fds[0]);
+    clients_.push_back(std::move(client_data));
+    return clients_.back().client;
+  }
+
+  // Destroys the wl_client.
+  void DestroyClient(wl_client* client) {
+    auto it = std::find_if(
+        clients_.begin(), clients_.end(),
+        [&](const ClientData& data) { return data.client == client; });
+
+    if (it != clients_.end()) {
+      wl_client_destroy(it->client.ExtractAsDangling());
+      close(it->fds[1]);
+      clients_.erase(it);
+    }
+  }
+
+  raw_ptr<wl_display> wayland_display_ = nullptr;
+  std::unique_ptr<ClientTracker> client_tracker_;
+  std::vector<ClientData> clients_;
+};
+
+// Tests that clients are tracked correctly when they are created and destroyed.
+TEST_F(WaylandClientTrackerTest, ClientRegistersAndDeregistersSuccessfully) {
+  EXPECT_EQ(0, client_tracker_->NumClientsTrackedForTesting());
+
+  // Create two client, both should report as not destroyed.
+  wl_client* client_1 = CreateClient();
+  EXPECT_TRUE(client_1);
+  EXPECT_EQ(1, client_tracker_->NumClientsTrackedForTesting());
+  EXPECT_FALSE(client_tracker_->IsClientDestroyed(client_1));
+
+  wl_client* client_2 = CreateClient();
+  EXPECT_TRUE(client_2);
+  EXPECT_EQ(2, client_tracker_->NumClientsTrackedForTesting());
+  EXPECT_FALSE(client_tracker_->IsClientDestroyed(client_2));
+
+  // Destroy the second client. It should have been removed from the client
+  // tracker and the first client should still be tracked.
+  DestroyClient(client_2);
+  EXPECT_EQ(1, client_tracker_->NumClientsTrackedForTesting());
+  EXPECT_FALSE(client_tracker_->IsClientDestroyed(client_1));
+
+  // Destroy the first client, it should have been removed from the client
+  // tracker.
+  DestroyClient(client_1);
+  EXPECT_EQ(0, client_tracker_->NumClientsTrackedForTesting());
+}
+
+// Simulate a situation where wayland will call back into test code after client
+// destruction has started, but before the client destruction has finished.
+// Assert that the client is reported as destroted after destruction has begun.
+TEST_F(WaylandClientTrackerTest, ClientTaggedDestroyedAfterDestructionStarted) {
+  wl_client* client = CreateClient();
+  EXPECT_FALSE(client_tracker_->IsClientDestroyed(client));
+
+  // Create a resource associated with the client. Attach user data and a
+  // destructor to the resource.
+  struct UserData {
+    raw_ptr<ClientTracker> client_tracker = nullptr;
+    raw_ptr<wl_client> client = nullptr;
+  };
+  UserData data = {.client_tracker = client_tracker_.get(), .client = client};
+
+  wl_resource* output_resource =
+      wl_resource_create(client, &wl_output_interface, 2, 0);
+  wl_resource_set_user_data(output_resource, &data);
+
+  // Assert that the client is no longer valid once destruction has begun and
+  // the client's resources subsequently begin destruction.
+  auto wl_resource_callback = [](wl_resource* resource) {
+    UserData* data =
+        static_cast<UserData*>(wl_resource_get_user_data(resource));
+    EXPECT_TRUE(data->client_tracker->IsClientDestroyed(
+        data->client.ExtractAsDangling()));
+  };
+  wl_resource_set_destructor(output_resource, wl_resource_callback);
+
+  DestroyClient(client);
+}
+
+}  // namespace wayland
+}  // namespace exo
diff --git a/components/exo/wayland/clients/security_delegate_binding_test.cc b/components/exo/wayland/clients/security_delegate_binding_test.cc
index 0b11cc9..92d54c17 100644
--- a/components/exo/wayland/clients/security_delegate_binding_test.cc
+++ b/components/exo/wayland/clients/security_delegate_binding_test.cc
@@ -30,7 +30,7 @@
   void SetUp() override {
     WaylandServerTest::SetUp();
     server_security_delegate_ =
-        GetSecurityDelegate(server_->GetWaylandDisplayForTesting());
+        GetSecurityDelegate(server_->GetWaylandDisplay());
     ASSERT_NE(server_security_delegate_, nullptr);
   }
 
diff --git a/components/exo/wayland/server.cc b/components/exo/wayland/server.cc
index 8105c275..2f91df6 100644
--- a/components/exo/wayland/server.cc
+++ b/components/exo/wayland/server.cc
@@ -59,6 +59,7 @@
 #include "build/build_config.h"
 #include "components/exo/display.h"
 #include "components/exo/security_delegate.h"
+#include "components/exo/wayland/client_tracker.h"
 #include "components/exo/wayland/content_type.h"
 #include "components/exo/wayland/overlay_prioritizer.h"
 #include "components/exo/wayland/serial_tracker.h"
@@ -135,6 +136,9 @@
 // (see `man 2 listen`).
 constexpr int kMaxPendingConnections = 128;
 
+// Callback used to find a Server instance for a given wl_display.
+Server::ServerGetter g_server_getter;
+
 bool IsDrmAtomicAvailable() {
 #if BUILDFLAG(IS_OZONE)
   auto& host_properties =
@@ -269,6 +273,8 @@
 
   wl_display_.reset(wl_display_create());
   SetSecurityDelegate(wl_display_.get(), security_delegate_.get());
+
+  client_tracker_ = std::make_unique<ClientTracker>(wl_display_.get());
 }
 
 void Server::Initialize() {
@@ -450,6 +456,17 @@
   return server;
 }
 
+// static.
+Server* Server::GetServerForDisplay(wl_display* display) {
+  return g_server_getter ? g_server_getter.Run(display) : nullptr;
+}
+
+// static.
+void Server::SetServerGetter(Server::ServerGetter server_getter) {
+  CHECK(!server_getter || !g_server_getter);
+  g_server_getter = std::move(server_getter);
+}
+
 void Server::StartWithDefaultPath(StartCallback callback) {
   if (!Open()) {
     std::move(callback).Run(/*success=*/false);
@@ -513,6 +530,10 @@
   return iter->second.get()->GetOutputResourceForClient(client);
 }
 
+bool Server::IsClientDestroyed(wl_client* client) const {
+  return client_tracker_->IsClientDestroyed(client);
+}
+
 void Server::AddWaylandOutput(int64_t id,
                               std::unique_ptr<WaylandDisplayOutput> output) {
   outputs_.insert(std::make_pair(id, std::move(output)));
diff --git a/components/exo/wayland/server.h b/components/exo/wayland/server.h
index 1fff81e..2ba3507 100644
--- a/components/exo/wayland/server.h
+++ b/components/exo/wayland/server.h
@@ -27,6 +27,7 @@
 
 namespace wayland {
 
+class ClientTracker;
 class SerialTracker;
 class UiControls;
 struct WaylandDataDeviceManager;
@@ -45,6 +46,7 @@
 // requests are dispatched into the given Exosphere display.
 class Server : public display::DisplayObserver {
  public:
+  using ServerGetter = base::RepeatingCallback<Server*(wl_display*)>;
   using StartCallback = base::OnceCallback<void(bool)>;
 
   Server(Display* display, std::unique_ptr<SecurityDelegate> security_delegate);
@@ -63,6 +65,12 @@
       Display* display,
       std::unique_ptr<SecurityDelegate> security_delegate);
 
+  // Gets the Server instance for a given wl_display.
+  static Server* GetServerForDisplay(wl_display* display);
+
+  // Sets the callback used to find the Server instance for a given wl_display.
+  static void SetServerGetter(ServerGetter server_getter);
+
   void StartWithDefaultPath(StartCallback callback);
   void StartWithFdAsync(base::ScopedFD fd, StartCallback callback);
 
@@ -93,18 +101,17 @@
   wl_resource* GetOutputResource(wl_client* client, int64_t display_id);
 
   Display* GetDisplay() { return display_; }
+  wl_display* GetWaylandDisplay() { return wl_display_.get(); }
 
-  // Public version of the protected accessor below, to be used in tests.
-  wl_display* GetWaylandDisplayForTesting() const {
-    return GetWaylandDisplay();
-  }
+  // Returns whether a client associated with this server has started
+  // destruction.
+  bool IsClientDestroyed(wl_client* client) const;
 
  protected:
   friend class UiControls;
   friend class WestonTest;
   void AddWaylandOutput(int64_t id,
                         std::unique_ptr<WaylandDisplayOutput> output);
-  wl_display* GetWaylandDisplay() const { return wl_display_.get(); }
 
  private:
   friend class ScopedEventDispatchDisabler;
@@ -132,6 +139,7 @@
   std::unique_ptr<WaylandXdgShell> xdg_shell_data_;
   std::unique_ptr<WaylandRemoteShellData> remote_shell_data_;
   std::unique_ptr<UiControls> ui_controls_holder_;
+  std::unique_ptr<ClientTracker> client_tracker_;
 };
 
 }  // namespace wayland
diff --git a/components/exo/wayland/server_unittest.cc b/components/exo/wayland/server_unittest.cc
index 384c90e..90d2b42 100644
--- a/components/exo/wayland/server_unittest.cc
+++ b/components/exo/wayland/server_unittest.cc
@@ -68,7 +68,7 @@
 
   auto server = CreateServer(std::move(security_delegate));
 
-  EXPECT_EQ(GetSecurityDelegate(server->GetWaylandDisplayForTesting()),
+  EXPECT_EQ(GetSecurityDelegate(server->GetWaylandDisplay()),
             security_delegate_ptr);
 }
 
@@ -101,7 +101,7 @@
   EXPECT_NE(client_display, nullptr);
 
   wl_list* all_clients =
-      wl_display_get_client_list(server->GetWaylandDisplayForTesting());
+      wl_display_get_client_list(server->GetWaylandDisplay());
   ASSERT_FALSE(wl_list_empty(all_clients));
   wl_client* client = wl_client_from_link(all_clients->next);
 
@@ -126,7 +126,7 @@
   client_thread.Start();
 
   TestListener client_creation_listener;
-  wl_display_add_client_created_listener(server->GetWaylandDisplayForTesting(),
+  wl_display_add_client_created_listener(server->GetWaylandDisplay(),
                                          &client_creation_listener.listener);
 
   base::Lock lock;
@@ -154,7 +154,7 @@
   }
 
   wl_list* all_clients =
-      wl_display_get_client_list(server->GetWaylandDisplayForTesting());
+      wl_display_get_client_list(server->GetWaylandDisplay());
   ASSERT_FALSE(wl_list_empty(all_clients));
   wl_client* client = wl_client_from_link(all_clients->next);
 
diff --git a/components/exo/wayland/server_util.cc b/components/exo/wayland/server_util.cc
index cadfbde6..96fab49 100644
--- a/components/exo/wayland/server_util.cc
+++ b/components/exo/wayland/server_util.cc
@@ -9,6 +9,7 @@
 #include "base/containers/flat_map.h"
 #include "base/time/time.h"
 #include "components/exo/data_offer.h"
+#include "components/exo/wayland/server.h"
 #include "ui/display/display.h"
 #include "ui/gfx/geometry/insets.h"
 #include "ui/gfx/geometry/rect.h"
@@ -86,5 +87,17 @@
   return GetSecurityDelegate(wl_client_get_display(client));
 }
 
+bool IsClientDestroyed(wl_client* client) {
+  CHECK(client);
+
+  // There should always be a display associated with a client and display will
+  // always outlive the wl_client object.
+  wl_display* display = wl_client_get_display(client);
+  CHECK(display);
+
+  Server* server = Server::GetServerForDisplay(display);
+  return server ? server->IsClientDestroyed(client) : true;
+}
+
 }  // namespace wayland
 }  // namespace exo
diff --git a/components/exo/wayland/server_util.h b/components/exo/wayland/server_util.h
index ba329db5..d666e4b 100644
--- a/components/exo/wayland/server_util.h
+++ b/components/exo/wayland/server_util.h
@@ -77,6 +77,11 @@
 // connected to.
 SecurityDelegate* GetSecurityDelegate(wl_client* client);
 
+// Returns whether a client has initiated destruction. After destruction begins
+// resources associated with the client start to be freed and there is a risk of
+// UAFs in querying for client resources (see crbug.com/1433187).
+bool IsClientDestroyed(wl_client* client);
+
 }  // namespace wayland
 }  // namespace exo
 
diff --git a/components/exo/wayland/test/server_util.cc b/components/exo/wayland/test/server_util.cc
index c7382ba..77a1513 100644
--- a/components/exo/wayland/test/server_util.cc
+++ b/components/exo/wayland/test/server_util.cc
@@ -21,7 +21,7 @@
 
   wl_client* client = nullptr;
   wl_list* all_clients =
-      wl_display_get_client_list(server->GetWaylandDisplayForTesting());
+      wl_display_get_client_list(server->GetWaylandDisplay());
 
   auto find_closure = [](struct wl_resource* resource, void* data) {
     IteratorData* iterator_data = static_cast<IteratorData*>(data);
diff --git a/components/exo/wayland/test/wayland_server_test.cc b/components/exo/wayland/test/wayland_server_test.cc
index 8375eca..82b027e 100644
--- a/components/exo/wayland/test/wayland_server_test.cc
+++ b/components/exo/wayland/test/wayland_server_test.cc
@@ -12,13 +12,22 @@
 #include "base/run_loop.h"
 #include "base/test/bind.h"
 #include "components/exo/security_delegate.h"
+#include "components/exo/wayland/server.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace exo::wayland::test {
 
-WaylandServerTest::WaylandServerTest() = default;
+WaylandServerTest::WaylandServerTest() {
+  Server::SetServerGetter(base::BindLambdaForTesting([&](wl_display* display) {
+    // Currently tests run with a single Server instance.
+    EXPECT_EQ(display, server_->GetWaylandDisplay());
+    return server_.get();
+  }));
+}
 
-WaylandServerTest::~WaylandServerTest() = default;
+WaylandServerTest::~WaylandServerTest() {
+  Server::SetServerGetter(base::NullCallback());
+}
 
 void WaylandServerTest::SetUp() {
   WaylandServerTestBase::SetUp();
diff --git a/components/exo/wayland/test/wlcs/wlcs_helpers.cc b/components/exo/wayland/test/wlcs/wlcs_helpers.cc
index 7338eb3..8316478 100644
--- a/components/exo/wayland/test/wlcs/wlcs_helpers.cc
+++ b/components/exo/wayland/test/wlcs/wlcs_helpers.cc
@@ -64,7 +64,7 @@
   }
 
   struct wl_client* client =
-      wl_client_create(Get()->GetWaylandDisplayForTesting(), server_fd.get());
+      wl_client_create(Get()->GetWaylandDisplay(), server_fd.get());
   if (!client) {
     return -1;
   }
diff --git a/components/exo/wayland/wayland_display_observer.cc b/components/exo/wayland/wayland_display_observer.cc
index 04e9597..057766b0 100644
--- a/components/exo/wayland/wayland_display_observer.cc
+++ b/components/exo/wayland/wayland_display_observer.cc
@@ -29,22 +29,9 @@
 
 WaylandDisplayHandler::WaylandDisplayHandler(WaylandDisplayOutput* output,
                                              wl_resource* output_resource)
-    : output_(output), output_resource_(output_resource) {
-  // At construction time the client object is guaranteed to exist.
-  wl_client* client = wl_resource_get_client(output_resource_);
-  CHECK(client);
-  client_destroy_listener_.listener.notify =
-      &WaylandDisplayHandler::OnClientDestroyed;
-  wl_client_add_destroy_listener(client, &client_destroy_listener_.listener);
-}
+    : output_(output), output_resource_(output_resource) {}
 
 WaylandDisplayHandler::~WaylandDisplayHandler() {
-  // Remove the listener to cover the case where the client outlives the
-  // handler.
-  if (!client_destroy_listener_.notified) {
-    wl_list_remove(&client_destroy_listener_.listener.link);
-  }
-
   ash::Shell::Get()->RemoveShellObserver(this);
   for (auto& obs : observers_) {
     obs.OnOutputDestroyed();
@@ -158,14 +145,6 @@
   xdg_output_resource_ = nullptr;
 }
 
-bool WaylandDisplayHandler::IsClientDestroyedForTesting() const {
-  return client_destroy_listener_.notified;
-}
-
-AuraOutputManager* WaylandDisplayHandler::GetAuraOutputManagerForTesting() {
-  return GetAuraOutputManager();
-}
-
 void WaylandDisplayHandler::XdgOutputSendLogicalPosition(
     const gfx::Point& position) {
   zxdg_output_v1_send_logical_position(xdg_output_resource_, position.x(),
@@ -185,15 +164,6 @@
   zxdg_output_v1_send_description(xdg_output_resource_, desc.c_str());
 }
 
-// static.
-void WaylandDisplayHandler::OnClientDestroyed(struct wl_listener* listener,
-                                              void* data) {
-  ClientDestroyListener* client_destroy_listener = wl_container_of(
-      listener, /*sample=*/client_destroy_listener, /*member=*/listener);
-  client_destroy_listener->notified = true;
-  wl_list_remove(&client_destroy_listener->listener.link);
-}
-
 bool WaylandDisplayHandler::SendDisplayMetrics(const display::Display& display,
                                                uint32_t changed_metrics) {
   if (!output_resource_) {
@@ -278,14 +248,6 @@
 }
 
 AuraOutputManager* WaylandDisplayHandler::GetAuraOutputManager() {
-  // If the client has begun destruction avoid attempting to access the client's
-  // AuraOutputManager instance as libwayland may have freed the object's memory
-  // but not yet updated the data structures used to find the object (see
-  // crbug.com/1433187).
-  if (client_destroy_listener_.notified) {
-    return nullptr;
-  }
-
   wl_client* client = wl_resource_get_client(output_resource_);
   CHECK(client);
   return AuraOutputManager::Get(client);
diff --git a/components/exo/wayland/wayland_display_observer.h b/components/exo/wayland/wayland_display_observer.h
index 8881975..63f7c2e 100644
--- a/components/exo/wayland/wayland_display_observer.h
+++ b/components/exo/wayland/wayland_display_observer.h
@@ -71,8 +71,6 @@
   void UnsetXdgOutputResource();
 
   size_t CountObserversForTesting() const;
-  bool IsClientDestroyedForTesting() const;
-  AuraOutputManager* GetAuraOutputManagerForTesting();
 
  protected:
   wl_resource* output_resource() const { return output_resource_; }
@@ -83,18 +81,6 @@
   virtual void XdgOutputSendDescription(const std::string& desc);
 
  private:
-  // Tracks whether destruction of the associated server-side client object has
-  // begun. Note that the wl_resource associated with this output will remain
-  // valid until its cleanup routine is run during a later phase of the client's
-  // multi-part teardown.
-  struct ClientDestroyListener {
-    wl_listener listener;
-    bool notified = false;
-  };
-
-  // Called when the client associated with the handler begins destruction.
-  static void OnClientDestroyed(struct wl_listener* listener, void* data);
-
   // Overridden from WaylandDisplayObserver:
   bool SendDisplayMetrics(const display::Display& display,
                           uint32_t changed_metrics) override;
@@ -124,9 +110,6 @@
   raw_ptr<wl_resource, DanglingUntriaged | ExperimentalAsh>
       xdg_output_resource_ = nullptr;
 
-  // The listener is notified when the server-side client destruction begins.
-  ClientDestroyListener client_destroy_listener_;
-
   base::ObserverList<WaylandDisplayObserver> observers_;
 
   display::ScopedDisplayObserver display_observer_{this};
diff --git a/components/exo/wayland/wayland_display_observer_unittest.cc b/components/exo/wayland/wayland_display_observer_unittest.cc
index f9ded9f..3001506 100644
--- a/components/exo/wayland/wayland_display_observer_unittest.cc
+++ b/components/exo/wayland/wayland_display_observer_unittest.cc
@@ -120,24 +120,6 @@
   handler_->OnDisplayMetricsChanged(display, kAllChanges);
 }
 
-// Regression test for crbug.com/1433187. Ensures that the AuraOutputManager is
-// not accessible after client destruction (the client and its resources may be
-// destroyed before the handler).
-TEST_F(WaylandDisplayObserverTest,
-       AuraOutputManagerInaccessibleAfterClientDestruction) {
-  // Prior to client destruction the AuraOutputManager should be accessible.
-  EXPECT_FALSE(handler_->IsClientDestroyedForTesting());
-  EXPECT_TRUE(handler_->GetAuraOutputManagerForTesting());
-
-  // Destroys the client, which also destroys all associated resources.
-  DestroyClient();
-
-  // After client destruction has occurred assert the handler has been notified
-  // and the AuraOutputManager is no longer accessible.
-  EXPECT_TRUE(handler_->IsClientDestroyedForTesting());
-  EXPECT_FALSE(handler_->GetAuraOutputManagerForTesting());
-}
-
 }  // namespace
 }  // namespace wayland
 }  // namespace exo
diff --git a/components/exo/wayland/zaura_output_manager.cc b/components/exo/wayland/zaura_output_manager.cc
index def30f63..e411809 100644
--- a/components/exo/wayland/zaura_output_manager.cc
+++ b/components/exo/wayland/zaura_output_manager.cc
@@ -22,6 +22,11 @@
 
 // static.
 AuraOutputManager* AuraOutputManager::Get(wl_client* client) {
+  // Avoid querying client resources if it has already begun destruction.
+  if (IsClientDestroyed(client)) {
+    return nullptr;
+  }
+
   AuraOutputManager* output_manager = nullptr;
   wl_client_for_each_resource(
       client,
diff --git a/components/exo/wayland/zaura_output_manager_unittest.cc b/components/exo/wayland/zaura_output_manager_unittest.cc
index 99802f5..32da2a3 100644
--- a/components/exo/wayland/zaura_output_manager_unittest.cc
+++ b/components/exo/wayland/zaura_output_manager_unittest.cc
@@ -4,8 +4,10 @@
 
 #include "components/exo/wayland/zaura_output_manager.h"
 
+#include <sys/socket.h>
 #include <cstdint>
 
+#include "components/exo/wayland/server_util.h"
 #include "components/exo/wayland/test/test_client.h"
 #include "components/exo/wayland/test/wayland_server_test.h"
 #include "testing/gmock/include/gmock/gmock.h"
@@ -210,12 +212,56 @@
     return test_client;
   }
 
+  // Creates a wl_client instance for this test.
+  void CreateClient() {
+    ASSERT_FALSE(client_);
+    socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, fds_);
+    client_ = wl_client_create(server_->GetWaylandDisplay(), fds_[0]);
+  }
+
+  // Destroys the wl_client instance for this test if it exists.
+  void DestroyClient() {
+    if (client_) {
+      wl_client_destroy(client_.ExtractAsDangling());
+      close(fds_[1]);
+      client_ = nullptr;
+    }
+  }
+
  protected:
   std::unique_ptr<MockAuraOutputManagerListener> mock_aura_output_manager_;
+  int fds_[2] = {0, 0};
+  raw_ptr<wl_client> client_ = nullptr;
 };
 
 }  // namespace
 
+// Regression test for crbug.com/1433187. Ensures AuraOutputManager::Get() does
+// not cause UAF crashes by attempting to iterate over resources belonging to a
+// client that has started destruction.
+TEST_F(AuraOutputManagerTest, GetterReturnsNullAfterClientDestroyed) {
+  CreateClient();
+  EXPECT_FALSE(IsClientDestroyed(client_));
+
+  // Create a resource associated with the client.
+  wl_resource* output_resource =
+      wl_resource_create(client_, &wl_output_interface, 2, 0);
+  wl_resource_set_user_data(output_resource, client_);
+
+  // Ensure that calls to AuraOutputManager::Get() after client destruction
+  // does not result in UAF crashes. This callback will run after the client's
+  // destruction sequence begins and associated resources are freed.
+  auto wl_resource_callback = [](wl_resource* resource) {
+    wl_client* client =
+        static_cast<wl_client*>(wl_resource_get_user_data(resource));
+    EXPECT_TRUE(IsClientDestroyed(client));
+    EXPECT_FALSE(AuraOutputManager::Get(client));
+  };
+  wl_resource_set_destructor(output_resource, wl_resource_callback);
+
+  DestroyClient();
+}
+
 TEST_F(AuraOutputManagerTest, SendOverscanInsets) {
   wl_output* client_output = nullptr;
 
diff --git a/components/feature_engagement/internal/chrome_variations_configuration.cc b/components/feature_engagement/internal/chrome_variations_configuration.cc
index 12ba2214..c0cf9ae3 100644
--- a/components/feature_engagement/internal/chrome_variations_configuration.cc
+++ b/components/feature_engagement/internal/chrome_variations_configuration.cc
@@ -68,19 +68,19 @@
 
 }  // namespace
 
-ChromeVariationsConfiguration::ChromeVariationsConfiguration(
-    ConfigurationProviderList configuration_providers)
-    : configuration_providers_(std::move(configuration_providers)) {}
+ChromeVariationsConfiguration::ChromeVariationsConfiguration() = default;
 ChromeVariationsConfiguration::~ChromeVariationsConfiguration() = default;
 
-void ChromeVariationsConfiguration::LoadConfigs(const FeatureVector& features,
-                                                const GroupVector& groups) {
+void ChromeVariationsConfiguration::LoadConfigs(
+    const ConfigurationProviderList& configuration_providers,
+    const FeatureVector& features,
+    const GroupVector& groups) {
   // This method should only be called once.
   CHECK(configs_.empty());
   CHECK(group_configs_.empty());
 
   for (auto* feature : features) {
-    LoadFeatureConfig(*feature, features, groups);
+    LoadFeatureConfig(*feature, configuration_providers, features, groups);
   }
 
   if (!base::FeatureList::IsEnabled(kIPHGroups)) {
@@ -90,12 +90,13 @@
   ExpandGroupNamesInFeatures(groups);
 
   for (auto* group : groups) {
-    LoadGroupConfig(*group);
+    LoadGroupConfig(*group, configuration_providers);
   }
 }
 
 void ChromeVariationsConfiguration::LoadFeatureConfig(
     const base::Feature& feature,
+    const ConfigurationProviderList& configuration_providers,
     const FeatureVector& all_features,
     const GroupVector& all_groups) {
   DCHECK(!base::Contains(configs_, feature.name));
@@ -103,7 +104,7 @@
   DVLOG(3) << "Loading feature config for " << feature.name;
   bool loaded = false;
   FeatureConfig& config = configs_[feature.name];
-  for (const auto& provider : configuration_providers_) {
+  for (const auto& provider : configuration_providers) {
     const bool result = provider->MaybeProvideFeatureConfiguration(
         feature, config, all_features, all_groups);
     if (result) {
@@ -122,14 +123,15 @@
 }
 
 void ChromeVariationsConfiguration::LoadGroupConfig(
-    const base::Feature& group) {
+    const base::Feature& group,
+    const ConfigurationProviderList& configuration_providers) {
   DCHECK(!base::Contains(group_configs_, group.name));
 
   DVLOG(3) << "Parsing group config for " << group.name;
 
   bool loaded = false;
   GroupConfig& config = group_configs_[group.name];
-  for (const auto& provider : configuration_providers_) {
+  for (const auto& provider : configuration_providers) {
     const bool result = provider->MaybeProvideGroupConfiguration(group, config);
     if (result) {
       RecordParseResult(group.name, config, *provider);
diff --git a/components/feature_engagement/internal/chrome_variations_configuration.h b/components/feature_engagement/internal/chrome_variations_configuration.h
index 7f2f7c1..b09b787 100644
--- a/components/feature_engagement/internal/chrome_variations_configuration.h
+++ b/components/feature_engagement/internal/chrome_variations_configuration.h
@@ -19,9 +19,7 @@
 // specified from code.
 class ChromeVariationsConfiguration : public Configuration {
  public:
-  explicit ChromeVariationsConfiguration(
-      ConfigurationProviderList configuration_providers);
-
+  ChromeVariationsConfiguration();
   ChromeVariationsConfiguration(const ChromeVariationsConfiguration&) = delete;
   ChromeVariationsConfiguration& operator=(
       const ChromeVariationsConfiguration&) = delete;
@@ -45,13 +43,19 @@
   // Read the variations configuration for all of the given |features| and
   // |groups| using the `configuration_providers`, and stores the result. It is
   // only valid to call this method once.
-  void LoadConfigs(const FeatureVector& features, const GroupVector& groups);
+  void LoadConfigs(const ConfigurationProviderList& configuration_providers,
+                   const FeatureVector& features,
+                   const GroupVector& groups);
 
  private:
-  void LoadFeatureConfig(const base::Feature& feature,
-                         const FeatureVector& all_features,
-                         const GroupVector& all_groups);
-  void LoadGroupConfig(const base::Feature& group);
+  void LoadFeatureConfig(
+      const base::Feature& feature,
+      const ConfigurationProviderList& configuration_providers,
+      const FeatureVector& all_features,
+      const GroupVector& all_groups);
+  void LoadGroupConfig(
+      const base::Feature& group,
+      const ConfigurationProviderList& configuration_providers);
 
   // Expands any group names in the existing FeatureConfig fields into the
   // feature names that are in the group.
@@ -62,10 +66,6 @@
 
   // The current group configurations.
   GroupConfigMap group_configs_;
-
-  // The configuration providers that will be used to fill out feature and group
-  // configurations.
-  const ConfigurationProviderList configuration_providers_;
 };
 
 }  // namespace feature_engagement
diff --git a/components/feature_engagement/internal/chrome_variations_configuration_unittest.cc b/components/feature_engagement/internal/chrome_variations_configuration_unittest.cc
index 87005e7..266a84d 100644
--- a/components/feature_engagement/internal/chrome_variations_configuration_unittest.cc
+++ b/components/feature_engagement/internal/chrome_variations_configuration_unittest.cc
@@ -70,8 +70,7 @@
 
 class ChromeVariationsConfigurationTest : public ::testing::Test {
  public:
-  ChromeVariationsConfigurationTest()
-      : configuration_(Tracker::GetDefaultConfigurationProviders()) {
+  ChromeVariationsConfigurationTest() {
     base::FieldTrial* foo_trial =
         base::FieldTrialList::CreateFieldTrial(kFooTrialName, kTrialGroupName);
     base::FieldTrial* bar_trial =
@@ -149,6 +148,11 @@
     EXPECT_EQ(params, actualParams);
   }
 
+  void LoadConfigs(const FeatureVector& features, const GroupVector& groups) {
+    configuration_.LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
+                               features, groups);
+  }
+
  protected:
   void VerifyInvalid(const std::string& event_config) {
     std::map<std::string, std::string> foo_params;
@@ -159,7 +163,7 @@
 
     std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
     GroupVector groups;
-    configuration_.LoadConfigs(features, groups);
+    LoadConfigs(features, groups);
 
     FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
     EXPECT_FALSE(foo.valid);
@@ -184,7 +188,7 @@
   GroupVector groups;
   base::HistogramTester histogram_tester;
 
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo_config =
       configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
@@ -212,7 +216,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_TRUE(foo.valid);
@@ -257,7 +261,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_TRUE(foo.valid);
@@ -303,7 +307,7 @@
   std::vector<const base::Feature*> features = {
       &kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   FeatureConfig bar = configuration_.GetFeatureConfig(kChromeTestFeatureBar);
@@ -333,7 +337,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_FALSE(foo.valid);
@@ -355,7 +359,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_FALSE(foo.valid);
@@ -379,7 +383,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_TRUE(foo.valid);
@@ -409,7 +413,8 @@
   test->SetFeatureParams(kChromeTestFeatureFoo, foo_params);
 
   GroupVector groups;
-  configuration->LoadConfigs(features, groups);
+  configuration->LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
+                             features, groups);
   FeatureConfig foo = configuration->GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(is_valid, foo.valid);
   FeatureConfig expected_foo;
@@ -438,7 +443,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(foo.blocking.type, Blocking::Type::NONE);
@@ -454,7 +459,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(foo.blocking.type, Blocking::Type::ALL);
@@ -471,7 +476,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(foo.blocking.type, Blocking::Type::ALL);
@@ -549,7 +554,8 @@
   test->SetFeatureParams(kChromeTestFeatureFoo, foo_params);
 
   GroupVector groups;
-  configuration->LoadConfigs(features, groups);
+  configuration->LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
+                             features, groups);
   FeatureConfig foo = configuration->GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(is_valid, foo.valid);
 
@@ -814,7 +820,8 @@
   foo_params["groups"] = groups_param_value;
   test->SetFeatureParams(kChromeTestFeatureFoo, foo_params);
 
-  configuration->LoadConfigs(features, groups);
+  configuration->LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
+                             features, groups);
   FeatureConfig foo = configuration->GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(is_valid, foo.valid);
   FeatureConfig expected_foo;
@@ -926,7 +933,7 @@
   std::vector<const base::Feature*> features = {
       &kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_TRUE(foo.valid);
@@ -976,7 +983,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_TRUE(foo.valid);
@@ -1003,7 +1010,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_TRUE(foo.valid);
@@ -1071,7 +1078,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_FALSE(foo.valid);
@@ -1096,7 +1103,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_FALSE(foo.valid);
@@ -1119,7 +1126,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_FALSE(foo.valid);
@@ -1145,7 +1152,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_FALSE(foo.valid);
@@ -1174,7 +1181,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_FALSE(foo.valid);
@@ -1191,7 +1198,7 @@
   base::HistogramTester histogram_tester;
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_FALSE(foo.valid);
@@ -1219,7 +1226,8 @@
   test->SetFeatureParams(kChromeTestFeatureFoo, foo_params);
 
   GroupVector groups;
-  configuration->LoadConfigs(features, groups);
+  configuration->LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
+                             features, groups);
   FeatureConfig foo = configuration->GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(is_valid, foo.valid);
 
@@ -1292,7 +1300,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_TRUE(foo.valid);
@@ -1328,7 +1336,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_TRUE(foo.valid);
@@ -1378,7 +1386,7 @@
   std::vector<const base::Feature*> features = {
       &kChromeTestFeatureFoo, &kChromeTestFeatureBar, &kChromeTestFeatureQux};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_TRUE(foo.valid);
@@ -1426,7 +1434,7 @@
   FeatureVector features;
   features.push_back(&kIPHDummyFeature);
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig expected;
   expected.valid = true;
@@ -1454,7 +1462,7 @@
   FeatureVector features;
   features.push_back(&kIPHDummyFeature);
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig expected;
   expected.valid = false;
@@ -1473,7 +1481,7 @@
   FeatureVector features;
   features.push_back(&kChromeTestFeatureFoo);
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig expected;
   expected.valid = false;
@@ -1496,7 +1504,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(foo.snooze_params.max_limit, 5u);
@@ -1513,7 +1521,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(foo.snooze_params.max_limit, 3u);
@@ -1530,7 +1538,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(foo.snooze_params.max_limit, 0u);
@@ -1547,7 +1555,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(foo.snooze_params.max_limit, 0u);
@@ -1564,7 +1572,7 @@
 
   std::vector<const base::Feature*> features = {&kChromeTestFeatureFoo};
   GroupVector groups;
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
   EXPECT_EQ(foo.snooze_params.max_limit, 0u);
@@ -1582,7 +1590,7 @@
   base::HistogramTester histogram_tester;
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one_config =
       configuration_.GetGroupConfig(kChromeTestGroupOne);
@@ -1612,7 +1620,7 @@
   base::HistogramTester histogram_tester;
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
   EXPECT_TRUE(group_one.valid);
@@ -1645,7 +1653,7 @@
   base::HistogramTester histogram_tester;
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
   EXPECT_FALSE(group_one.valid);
@@ -1672,7 +1680,7 @@
   base::HistogramTester histogram_tester;
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
   EXPECT_TRUE(group_one.valid);
@@ -1703,7 +1711,7 @@
 
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
   EXPECT_TRUE(group_one.valid);
@@ -1736,7 +1744,7 @@
   base::HistogramTester histogram_tester;
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
   EXPECT_FALSE(group_one.valid);
@@ -1764,7 +1772,7 @@
   base::HistogramTester histogram_tester;
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
   EXPECT_FALSE(group_one.valid);
@@ -1799,7 +1807,7 @@
 
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
   EXPECT_FALSE(group_one.valid);
@@ -1820,7 +1828,7 @@
 
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
   EXPECT_TRUE(group_one.valid);
@@ -1871,7 +1879,7 @@
   FeatureVector features;
   GroupVector groups = {&kChromeTestGroupOne, &kChromeTestGroupTwo,
                         &kChromeTestGroupThree};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig group_one = configuration_.GetGroupConfig(kChromeTestGroupOne);
   EXPECT_TRUE(group_one.valid);
@@ -1918,7 +1926,7 @@
   base::HistogramTester histogram_tester;
   FeatureVector features;
   GroupVector groups = {&kIPHDummyGroup};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig expected;
   expected.valid = true;
@@ -1943,7 +1951,7 @@
   base::HistogramTester histogram_tester;
   FeatureVector features;
   GroupVector groups = {&kIPHDummyGroup};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig expected;
   expected.valid = false;
@@ -1964,7 +1972,7 @@
   base::HistogramTester histogram_tester;
   FeatureVector features;
   GroupVector groups = {&kIPHDummyGroup};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   GroupConfig expected;
   expected.valid = false;
@@ -1998,7 +2006,7 @@
 
   FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar};
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
 
@@ -2031,7 +2039,7 @@
 
   FeatureVector features = {&kChromeTestFeatureFoo};
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
 
@@ -2075,7 +2083,7 @@
   FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar,
                             &kChromeTestFeatureQux};
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
 
@@ -2120,7 +2128,7 @@
   FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar,
                             &kChromeTestFeatureQux};
   GroupVector groups = {&kChromeTestGroupOne, &kChromeTestGroupTwo};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
 
@@ -2159,7 +2167,7 @@
 
   FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar};
   GroupVector groups = {&kChromeTestGroupOne, &kChromeTestGroupTwo};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
 
@@ -2201,7 +2209,7 @@
 
   FeatureVector features = {&kChromeTestFeatureFoo, &kChromeTestFeatureBar};
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
 
@@ -2234,7 +2242,7 @@
 
   FeatureVector features = {&kChromeTestFeatureFoo};
   GroupVector groups = {&kChromeTestGroupOne};
-  configuration_.LoadConfigs(features, groups);
+  LoadConfigs(features, groups);
 
   FeatureConfig foo = configuration_.GetFeatureConfig(kChromeTestFeatureFoo);
 
diff --git a/components/feature_engagement/internal/feature_config_event_storage_validator.cc b/components/feature_engagement/internal/feature_config_event_storage_validator.cc
index d50c711..c57f0c6 100644
--- a/components/feature_engagement/internal/feature_config_event_storage_validator.cc
+++ b/components/feature_engagement/internal/feature_config_event_storage_validator.cc
@@ -51,7 +51,8 @@
 }
 
 void FeatureConfigEventStorageValidator::InitializeFeatures(
-    FeatureVector features,
+    const FeatureVector& features,
+    const GroupVector& groups,
     const Configuration& configuration) {
   for (const auto* feature : features) {
     if (!base::FeatureList::IsEnabled(*feature))
@@ -59,6 +60,14 @@
 
     InitializeFeatureConfig(configuration.GetFeatureConfig(*feature));
   }
+
+  for (const auto* group : groups) {
+    if (!base::FeatureList::IsEnabled(*group)) {
+      continue;
+    }
+
+    InitializeGroupConfig(configuration.GetGroupConfig(*group));
+  }
 }
 
 void FeatureConfigEventStorageValidator::ClearForTesting() {
@@ -75,6 +84,15 @@
     InitializeEventConfig(event_config);
 }
 
+void FeatureConfigEventStorageValidator::InitializeGroupConfig(
+    const GroupConfig& group_config) {
+  InitializeEventConfig(group_config.trigger);
+
+  for (const auto& event_config : group_config.event_configs) {
+    InitializeEventConfig(event_config);
+  }
+}
+
 void FeatureConfigEventStorageValidator::InitializeEventConfig(
     const EventConfig& event_config) {
   // Minimum storage time is 1 day.
diff --git a/components/feature_engagement/internal/feature_config_event_storage_validator.h b/components/feature_engagement/internal/feature_config_event_storage_validator.h
index 4c5e6b4..783fb9be 100644
--- a/components/feature_engagement/internal/feature_config_event_storage_validator.h
+++ b/components/feature_engagement/internal/feature_config_event_storage_validator.h
@@ -11,13 +11,16 @@
 
 #include "components/feature_engagement/internal/event_storage_validator.h"
 #include "components/feature_engagement/public/feature_list.h"
+#include "components/feature_engagement/public/group_list.h"
 
 namespace feature_engagement {
 class Configuration;
 struct EventConfig;
 struct FeatureConfig;
+struct GroupConfig;
 
-// A EventStorageValidator that uses the FeatureConfig as the source of truth.
+// A EventStorageValidator that uses the FeatureConfig and GroupConfig as the
+// source of truth.
 class FeatureConfigEventStorageValidator : public EventStorageValidator {
  public:
   FeatureConfigEventStorageValidator();
@@ -35,8 +38,10 @@
                   uint32_t event_day,
                   uint32_t current_day) const override;
 
-  // Set up internal configuration required for the given |features|.
-  void InitializeFeatures(FeatureVector features,
+  // Set up internal configuration required for the given |features| and
+  // |groups|.
+  void InitializeFeatures(const FeatureVector& features,
+                          const GroupVector& groups,
                           const Configuration& configuration);
 
   // Resets the full state of this EventStorageValidator. After calling this
@@ -49,6 +54,10 @@
   void InitializeFeatureConfig(const FeatureConfig& feature_config);
 
   // Updates the internal configuration with conditions from the given
+  // |group_config|.
+  void InitializeGroupConfig(const GroupConfig& group_config);
+
+  // Updates the internal configuration with conditions from the given
   // |event_config|.
   void InitializeEventConfig(const EventConfig& event_config);
 
diff --git a/components/feature_engagement/internal/feature_config_event_storage_validator_unittest.cc b/components/feature_engagement/internal/feature_config_event_storage_validator_unittest.cc
index 40ed535b..a9575c9 100644
--- a/components/feature_engagement/internal/feature_config_event_storage_validator_unittest.cc
+++ b/components/feature_engagement/internal/feature_config_event_storage_validator_unittest.cc
@@ -25,6 +25,12 @@
 BASE_FEATURE(kEventStorageTestFeatureBar,
              "test_bar",
              base::FEATURE_DISABLED_BY_DEFAULT);
+BASE_FEATURE(kEventStorageTestGroupOne,
+             "test_group_one",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+BASE_FEATURE(kEventStorageTestGroupTwo,
+             "test_group_two",
+             base::FEATURE_DISABLED_BY_DEFAULT);
 
 FeatureConfig kNeverStored;
 FeatureConfig kStoredInUsed1Day;
@@ -37,6 +43,8 @@
 FeatureConfig kStoredInEventConfigs2Days;
 FeatureConfig kStoredInEventConfigs10Days;
 
+GroupConfig kGroupNeverStored;
+
 void InitializeStorageFeatureConfigs() {
   FeatureConfig default_config;
   default_config.valid = true;
@@ -98,6 +106,17 @@
       EventConfig("myevent", Comparator(ANY, 0), 0, 10));
   kStoredInEventConfigs10Days.event_configs.insert(
       EventConfig("unrelated_event", Comparator(ANY, 0), 0, 100));
+
+  GroupConfig default_group_config;
+  default_config.valid = true;
+  default_config.trigger = EventConfig("myevent", Comparator(ANY, 0), 0, 0);
+  default_config.event_configs.insert(
+      EventConfig("myevent", Comparator(ANY, 0), 0, 0));
+  default_config.event_configs.insert(
+      EventConfig("unrelated_event", Comparator(ANY, 0), 0, 100));
+  default_config.session_rate = Comparator(ANY, 0);
+
+  kGroupNeverStored = default_group_config;
 }
 
 class FeatureConfigEventStorageValidatorTest : public ::testing::Test {
@@ -117,7 +136,7 @@
     validator_.ClearForTesting();
     EditableConfiguration configuration;
     configuration.SetConfiguration(&kEventStorageTestFeatureFoo, foo_config);
-    validator_.InitializeFeatures(features, configuration);
+    validator_.InitializeFeatures(features, {}, configuration);
   }
 
   void UseConfigs(const FeatureConfig& foo_config,
@@ -129,7 +148,27 @@
     EditableConfiguration configuration;
     configuration.SetConfiguration(&kEventStorageTestFeatureFoo, foo_config);
     configuration.SetConfiguration(&kEventStorageTestFeatureBar, bar_config);
-    validator_.InitializeFeatures(features, configuration);
+    validator_.InitializeFeatures(features, {}, configuration);
+  }
+
+  void UseConfigs(const FeatureConfig& foo_config,
+                  const FeatureConfig& bar_config,
+                  const GroupConfig& group_one_config,
+                  const GroupConfig& group_two_config) {
+    FeatureVector features = {&kEventStorageTestFeatureFoo,
+                              &kEventStorageTestFeatureBar};
+    GroupVector groups = {&kEventStorageTestGroupOne,
+                          &kEventStorageTestGroupTwo};
+
+    validator_.ClearForTesting();
+    EditableConfiguration configuration;
+    configuration.SetConfiguration(&kEventStorageTestFeatureFoo, foo_config);
+    configuration.SetConfiguration(&kEventStorageTestFeatureBar, bar_config);
+    configuration.SetConfiguration(&kEventStorageTestGroupOne,
+                                   group_one_config);
+    configuration.SetConfiguration(&kEventStorageTestGroupTwo,
+                                   group_two_config);
+    validator_.InitializeFeatures(features, groups, configuration);
   }
 
   void VerifyNeverKeep() {
@@ -186,18 +225,27 @@
 
 TEST_F(FeatureConfigEventStorageValidatorTest,
        ShouldOnlyUseConfigFromEnabledFeatures) {
-  scoped_feature_list_.InitWithFeatures({kEventStorageTestFeatureFoo},
-                                        {kEventStorageTestFeatureBar});
+  scoped_feature_list_.InitWithFeatures(
+      {kEventStorageTestFeatureFoo, kEventStorageTestGroupOne},
+      {kEventStorageTestFeatureBar, kEventStorageTestGroupTwo});
 
   FeatureConfig foo_config = kNeverStored;
   foo_config.used = EventConfig("fooevent", Comparator(ANY, 0), 0, 1);
   FeatureConfig bar_config = kNeverStored;
   bar_config.used = EventConfig("barevent", Comparator(ANY, 0), 0, 1);
-  UseConfigs(foo_config, bar_config);
+  GroupConfig group_one_config = kGroupNeverStored;
+  group_one_config.trigger =
+      EventConfig("grouponeevent", Comparator(ANY, 0), 0, 1);
+  GroupConfig group_two_config = kGroupNeverStored;
+  group_two_config.trigger =
+      EventConfig("grouptwoevent", Comparator(ANY, 0), 0, 1);
+  UseConfigs(foo_config, bar_config, group_one_config, group_two_config);
 
   EXPECT_FALSE(validator_.ShouldStore("myevent"));
   EXPECT_TRUE(validator_.ShouldStore("fooevent"));
   EXPECT_FALSE(validator_.ShouldStore("barevent"));
+  EXPECT_TRUE(validator_.ShouldStore("grouponeevent"));
+  EXPECT_FALSE(validator_.ShouldStore("grouptwoevent"));
 }
 
 TEST_F(FeatureConfigEventStorageValidatorTest,
diff --git a/components/feature_engagement/internal/tracker_impl.cc b/components/feature_engagement/internal/tracker_impl.cc
index f8b896c..50a5bf04 100644
--- a/components/feature_engagement/internal/tracker_impl.cc
+++ b/components/feature_engagement/internal/tracker_impl.cc
@@ -106,7 +106,7 @@
     const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
     leveldb_proto::ProtoDatabaseProvider* db_provider,
     base::WeakPtr<TrackerEventExporter> event_exporter,
-    ConfigurationProviderList configuration_providers) {
+    const ConfigurationProviderList& configuration_providers) {
   DVLOG(2) << "Creating Tracker";
   if (base::FeatureList::IsEnabled(kIPHDemoMode))
     return CreateDemoModeTracker().release();
@@ -120,13 +120,14 @@
   auto event_store =
       std::make_unique<PersistentEventStore>(std::move(event_db));
 
-  auto configuration = std::make_unique<ChromeVariationsConfiguration>(
-      std::move(configuration_providers));
-  configuration->LoadConfigs(GetAllFeatures(), GetAllGroups());
+  auto configuration = std::make_unique<ChromeVariationsConfiguration>();
+  configuration->LoadConfigs(configuration_providers, GetAllFeatures(),
+                             GetAllGroups());
 
   auto event_storage_validator =
       std::make_unique<FeatureConfigEventStorageValidator>();
-  event_storage_validator->InitializeFeatures(GetAllFeatures(), *configuration);
+  event_storage_validator->InitializeFeatures(GetAllFeatures(), GetAllGroups(),
+                                              *configuration);
 
   auto raw_event_model = std::make_unique<EventModelImpl>(
       std::move(event_store), std::move(event_storage_validator));
@@ -202,9 +203,13 @@
   }
 
   FeatureConfig feature_config = configuration_->GetFeatureConfig(feature);
+  std::vector<GroupConfig> group_configs;
+  for (auto group : feature_config.groups) {
+    group_configs.push_back(configuration_->GetGroupConfigByName(group));
+  }
   ConditionValidator::Result result = condition_validator_->MeetsConditions(
-      feature, feature_config, {}, *event_model_, *availability_model_,
-      *display_lock_controller_, configuration_.get(),
+      feature, feature_config, group_configs, *event_model_,
+      *availability_model_, *display_lock_controller_, configuration_.get(),
       time_provider_->GetCurrentDay());
   if (result.NoErrors()) {
     condition_validator_->NotifyIsShowing(
@@ -256,9 +261,13 @@
   }
 
   FeatureConfig feature_config = configuration_->GetFeatureConfig(feature);
+  std::vector<GroupConfig> group_configs;
+  for (auto group : feature_config.groups) {
+    group_configs.push_back(configuration_->GetGroupConfigByName(group));
+  }
   ConditionValidator::Result result = condition_validator_->MeetsConditions(
-      feature, feature_config, {}, *event_model_, *availability_model_,
-      *display_lock_controller_, configuration_.get(),
+      feature, feature_config, group_configs, *event_model_,
+      *availability_model_, *display_lock_controller_, configuration_.get(),
       time_provider_->GetCurrentDay());
   DVLOG(2) << "Would trigger result for " << feature.name
            << ": trigger=" << result.NoErrors()
@@ -290,10 +299,15 @@
     return Tracker::TriggerState::NOT_READY;
   }
 
+  FeatureConfig feature_config = configuration_->GetFeatureConfig(feature);
+  std::vector<GroupConfig> group_configs;
+  for (auto group : feature_config.groups) {
+    group_configs.push_back(configuration_->GetGroupConfigByName(group));
+  }
   ConditionValidator::Result result = condition_validator_->MeetsConditions(
-      feature, configuration_->GetFeatureConfig(feature), {}, *event_model_,
-      *availability_model_, *display_lock_controller_, configuration_.get(),
-      time_provider_->GetCurrentDay());
+      feature, configuration_->GetFeatureConfig(feature), group_configs,
+      *event_model_, *availability_model_, *display_lock_controller_,
+      configuration_.get(), time_provider_->GetCurrentDay());
 
   if (result.trigger_ok) {
     DVLOG(2) << "TriggerState for " << feature.name << ": "
diff --git a/components/feature_engagement/internal/tracker_impl_unittest.cc b/components/feature_engagement/internal/tracker_impl_unittest.cc
index a2a982a5..8df3cb6 100644
--- a/components/feature_engagement/internal/tracker_impl_unittest.cc
+++ b/components/feature_engagement/internal/tracker_impl_unittest.cc
@@ -25,6 +25,7 @@
 #include "components/feature_engagement/internal/display_lock_controller.h"
 #include "components/feature_engagement/internal/editable_configuration.h"
 #include "components/feature_engagement/internal/event_model_impl.h"
+#include "components/feature_engagement/internal/feature_config_condition_validator.h"
 #include "components/feature_engagement/internal/in_memory_event_store.h"
 #include "components/feature_engagement/internal/never_availability_model.h"
 #include "components/feature_engagement/internal/never_event_storage_validator.h"
@@ -308,7 +309,7 @@
         std::make_unique<TestTrackerDisplayLockController>();
     display_lock_controller_ = display_lock_controller.get();
 
-    auto condition_validator = std::make_unique<OnceConditionValidator>();
+    auto condition_validator = CreateConditionValidator();
     condition_validator_ = condition_validator.get();
 
     auto time_provider = std::make_unique<TestTimeProvider>();
@@ -521,6 +522,10 @@
     return std::make_unique<TestTrackerInMemoryEventStore>(true);
   }
 
+  virtual std::unique_ptr<ConditionValidator> CreateConditionValidator() {
+    return std::make_unique<OnceConditionValidator>();
+  }
+
   virtual bool ShouldAvailabilityStoreBeReady() { return true; }
 
   base::test::SingleThreadTaskEnvironment task_environment_;
@@ -528,10 +533,10 @@
   raw_ptr<TestTrackerInMemoryEventStore> event_store_;
   raw_ptr<TestTrackerAvailabilityModel> availability_model_;
   raw_ptr<TestTrackerDisplayLockController> display_lock_controller_;
-  raw_ptr<Configuration> configuration_;
+  raw_ptr<EditableConfiguration> configuration_;
   std::unique_ptr<TestTrackerEventExporter> event_exporter_;
   base::HistogramTester histogram_tester_;
-  raw_ptr<OnceConditionValidator> condition_validator_;
+  raw_ptr<ConditionValidator> condition_validator_;
   raw_ptr<TestTimeProvider> time_provider_;
 };
 
@@ -1308,8 +1313,24 @@
   histogram_tester_.ExpectTotalCount(histogram_name, 0);
 }
 
+// Base class for any tests that specifically require a
+// |OnceConditionValidator|.
+class OnceConditionTrackerImplTest : public TrackerImplTest {
+ public:
+  OnceConditionTrackerImplTest() = default;
+  ~OnceConditionTrackerImplTest() override = default;
+
+ protected:
+  std::unique_ptr<ConditionValidator> CreateConditionValidator() override {
+    auto once_condition_validator = std::make_unique<OnceConditionValidator>();
+    once_condition_validator_ = once_condition_validator.get();
+    return once_condition_validator;
+  }
+  raw_ptr<OnceConditionValidator> once_condition_validator_;
+};
+
 // Checks that the times are logged even when multiple IPH are presented.
-TEST_F(TrackerImplTest, MultipleShownTimeLogged) {
+TEST_F(OnceConditionTrackerImplTest, MultipleShownTimeLogged) {
   // Ensure all initialization is finished.
   StoringInitializedCallback callback;
   tracker_->AddOnInitializedCallback(base::BindOnce(
@@ -1318,7 +1339,7 @@
   const char histogram_name_foo[] = "InProductHelp.ShownTime.test_foo";
   const char histogram_name_bar[] = "InProductHelp.ShownTime.test_bar";
 
-  condition_validator_->AllowMultipleFeaturesForTesting(true);
+  once_condition_validator_->AllowMultipleFeaturesForTesting(true);
 
   base::Time start = base::Time::Now();
   time_provider_->SetCurrentTime(start);
@@ -1610,6 +1631,48 @@
   tracker_->Dismissed(kTrackerTestFeatureBar);
 }
 
+// Test class for tests that require an actual
+// |FeatureConfigConditionValidator|.
+class FeatureConfigConditionValidatorTrackerTest : public TrackerImplTest {
+ public:
+  FeatureConfigConditionValidatorTrackerTest() = default;
+  ~FeatureConfigConditionValidatorTrackerTest() override = default;
+
+ protected:
+  std::unique_ptr<ConditionValidator> CreateConditionValidator() override {
+    return std::make_unique<FeatureConfigConditionValidator>();
+  }
+};
+
+TEST_F(FeatureConfigConditionValidatorTrackerTest, GroupRulesApplied) {
+  // Set up the group config to only allow 1 feature from its group to be
+  // displayed.
+  GroupConfig custom_group_config;
+  custom_group_config.valid = true;
+  custom_group_config.trigger.name = "custom_group_trigger";
+  custom_group_config.trigger.comparator = Comparator(EQUAL, 0);
+  custom_group_config.trigger.window = 1u;
+  custom_group_config.trigger.storage = 1u;
+  configuration_->SetConfiguration(&kTrackerTestGroupOne, custom_group_config);
+
+  ScopedIphFeatureList list;
+  list.InitAndEnableFeatures(
+      {kTrackerTestFeatureFoo, kTrackerTestFeatureBar, kTrackerTestGroupOne});
+
+  // Ensure all initialization is finished.
+  StoringInitializedCallback callback;
+  tracker_->AddOnInitializedCallback(base::BindOnce(
+      &StoringInitializedCallback::OnInitialized, base::Unretained(&callback)));
+  base::RunLoop().RunUntilIdle();
+  base::UserActionTester user_action_tester;
+
+  // The first feature should display, but the second one should not, as they
+  // share a group that only allows its features to be displayed once.
+  EXPECT_TRUE(tracker_->ShouldTriggerHelpUI(kTrackerTestFeatureFoo));
+  tracker_->Dismissed(kTrackerTestFeatureFoo);
+  EXPECT_FALSE(tracker_->ShouldTriggerHelpUI(kTrackerTestFeatureBar));
+}
+
 }  // namespace test
 
 }  // namespace feature_engagement
diff --git a/components/feature_engagement/public/group_configurations.cc b/components/feature_engagement/public/group_configurations.cc
index 422873ad..cfc297f 100644
--- a/components/feature_engagement/public/group_configurations.cc
+++ b/components/feature_engagement/public/group_configurations.cc
@@ -17,7 +17,7 @@
   if (kiOSFullscreenPromosGroup.name == group->name) {
     absl::optional<GroupConfig> config = GroupConfig();
     config->valid = true;
-    config->session_rate = Comparator(LESS_THAN, 0);
+    config->session_rate = Comparator(EQUAL, 0);
     // Only show a fullscreen promo once every two days.
     config->trigger = EventConfig("fullscreen_promos_group_trigger",
                                   Comparator(LESS_THAN, 1), 2, 1000);
diff --git a/components/feature_engagement/public/tracker.h b/components/feature_engagement/public/tracker.h
index 532223d..2d09352 100644
--- a/components/feature_engagement/public/tracker.h
+++ b/components/feature_engagement/public/tracker.h
@@ -153,7 +153,7 @@
       const scoped_refptr<base::SequencedTaskRunner>& background_task_runner,
       leveldb_proto::ProtoDatabaseProvider* db_provider,
       base::WeakPtr<TrackerEventExporter> event_exporter,
-      ConfigurationProviderList configuration_providers =
+      const ConfigurationProviderList& configuration_providers =
           GetDefaultConfigurationProviders());
 
   // Possibly adds a command line argument for a child browser process to
diff --git a/components/feature_engagement/test/test_tracker.cc b/components/feature_engagement/test/test_tracker.cc
index 7bfc726e..ac85a1b 100644
--- a/components/feature_engagement/test/test_tracker.cc
+++ b/components/feature_engagement/test/test_tracker.cc
@@ -23,13 +23,13 @@
 
 // static
 std::unique_ptr<Tracker> CreateTestTracker() {
-  auto configuration = std::make_unique<ChromeVariationsConfiguration>(
-      Tracker::GetDefaultConfigurationProviders());
-  configuration->LoadConfigs(GetAllFeatures(), GetAllGroups());
+  auto configuration = std::make_unique<ChromeVariationsConfiguration>();
+  configuration->LoadConfigs(Tracker::GetDefaultConfigurationProviders(),
+                             GetAllFeatures(), GetAllGroups());
 
   auto storage_validator =
       std::make_unique<FeatureConfigEventStorageValidator>();
-  storage_validator->InitializeFeatures(GetAllFeatures(), *configuration);
+  storage_validator->InitializeFeatures(GetAllFeatures(), {}, *configuration);
 
   auto raw_event_model = std::make_unique<EventModelImpl>(
       std::make_unique<InMemoryEventStore>(), std::move(storage_validator));
diff --git a/components/language/android/java/src/org/chromium/components/language/LocaleManagerDelegateImpl.java b/components/language/android/java/src/org/chromium/components/language/LocaleManagerDelegateImpl.java
index dc83bdf..36ed7b0 100644
--- a/components/language/android/java/src/org/chromium/components/language/LocaleManagerDelegateImpl.java
+++ b/components/language/android/java/src/org/chromium/components/language/LocaleManagerDelegateImpl.java
@@ -19,7 +19,7 @@
      */
     @Override
     public Locale getApplicationLocale() {
-        // TODO(https://crbug.com/1293523): Replace with calls to {@link LocaleManager} once the T
+        // TODO(https://crbug.com/1348676): Replace with calls to {@link LocaleManager} once the T
         // SDK is available.
         return null;
     }
@@ -31,7 +31,7 @@
      */
     @Override
     public void setApplicationLocale(String languageName) {
-        // TODO(https://crbug.com/1293523): Replace with calls to {@link LocaleManager} once the T
+        // TODO(https://crbug.com/1348676): Replace with calls to {@link LocaleManager} once the T
         // SDK is available.
         return;
     }
diff --git a/components/omnibox/browser/vector_icons/answer_currency_chrome_refresh.icon b/components/omnibox/browser/vector_icons/answer_currency_chrome_refresh.icon
index d75a086..b27efe2 100644
--- a/components/omnibox/browser/vector_icons/answer_currency_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/answer_currency_chrome_refresh.icon
@@ -3,41 +3,39 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 3.77f, 10.39f,
-R_ARC_TO, 5.41f, 5.41f, 0, 0, 1, -0.48f, -1.13f,
-R_ARC_TO, 4.37f, 4.37f, 0, 0, 1, -0.18f, -1.27f,
-R_CUBIC_TO, 0, -1.36f, 0.48f, -2.52f, 1.44f, -3.49f,
-R_CUBIC_TO, 0.96f, -0.96f, 2.13f, -1.43f, 3.51f, -1.39f,
-R_H_LINE_TO, 0,
-R_LINE_TO, -0.89f, -0.89f,
-R_LINE_TO, 0.89f, -0.89f,
-LINE_TO, 10.54f, 3.8f,
-LINE_TO, 8.07f, 6.27f,
-R_LINE_TO, -0.89f, -0.89f,
-R_LINE_TO, 0.89f, -0.89f,
+MOVE_TO, 3.77f, 10.6f,
+R_ARC_TO, 5.05f, 5.05f, 0, 0, 1, -0.57f, -1.23f,
+R_ARC_TO, 4.54f, 4.54f, 0, 0, 1, -0.21f, -1.39f,
+R_CUBIC_TO, 0, -1.38f, 0.49f, -2.57f, 1.46f, -3.56f,
+R_CUBIC_TO, 0.98f, -0.99f, 2.16f, -1.47f, 3.56f, -1.44f,
 R_H_LINE_TO, 0.01f,
-R_CUBIC_TO, -1.01f, -0.02f, -1.85f, 0.31f, -2.55f, 1,
-R_CUBIC_TO, -0.69f, 0.7f, -1.03f, 1.52f, -1.03f, 2.5f,
-R_CUBIC_TO, 0, 0.25f, 0.02f, 0.49f, 0.07f, 0.72f,
-R_CUBIC_TO, 0.05f, 0.23f, 0.12f, 0.45f, 0.22f, 0.67f,
+R_LINE_TO, -0.81f, -0.81f,
+R_LINE_TO, 0.95f, -0.95f,
+R_LINE_TO, 2.57f, 2.57f,
+R_LINE_TO, -2.57f, 2.57f,
+R_LINE_TO, -0.95f, -0.94f,
+R_LINE_TO, 0.81f, -0.81f,
+R_H_LINE_TO, 0.02f,
+R_CUBIC_TO, -0.97f, -0.02f, -1.77f, 0.3f, -2.43f, 0.97f,
+R_ARC_TO, 3.29f, 3.29f, 0, 0, 0, -0.98f, 2.39f,
+R_CUBIC_TO, 0, 0.27f, 0.03f, 0.52f, 0.08f, 0.75f,
+R_CUBIC_TO, 0.05f, 0.24f, 0.13f, 0.47f, 0.24f, 0.69f,
 CLOSE,
-R_MOVE_TO, 4.16f, 4.29f,
-R_LINE_TO, -2.47f, -2.47f,
-R_LINE_TO, 2.47f, -2.48f,
-R_LINE_TO, 0.89f, 0.89f,
-R_LINE_TO, -0.89f, 0.89f,
-H_LINE_TO, 7.93f,
-R_CUBIC_TO, 1.01f, 0.02f, 1.86f, -0.31f, 2.55f, -1.01f,
-R_ARC_TO, 3.41f, 3.41f, 0, 0, 0, 1.03f, -2.5f,
-R_ARC_TO, 3.6f, 3.6f, 0, 0, 0, -0.07f, -0.72f,
-R_ARC_TO, 3.51f, 3.51f, 0, 0, 0, -0.22f, -0.67f,
-R_LINE_TO, 1.01f, -1,
-R_CUBIC_TO, 0.2f, 0.36f, 0.36f, 0.73f, 0.48f, 1.13f,
-R_CUBIC_TO, 0.12f, 0.4f, 0.18f, 0.82f, 0.18f, 1.26f,
-R_CUBIC_TO, 0, 1.35f, -0.48f, 2.51f, -1.44f, 3.48f,
-R_CUBIC_TO, -0.96f, 0.97f, -2.13f, 1.44f, -3.51f, 1.41f,
-R_H_LINE_TO, 0,
-R_LINE_TO, 0.89f, 0.89f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+R_MOVE_TO, 4.07f, 4.18f,
+R_LINE_TO, -2.57f, -2.57f,
+R_LINE_TO, 2.57f, -2.58f,
+R_LINE_TO, 0.95f, 0.96f,
+R_LINE_TO, -0.81f, 0.81f,
+R_H_LINE_TO, -0.02f,
+R_CUBIC_TO, 0.97f, 0.02f, 1.77f, -0.3f, 2.43f, -0.97f,
+R_CUBIC_TO, 0.66f, -0.67f, 0.99f, -1.47f, 0.99f, -2.4f,
+R_CUBIC_TO, 0, -0.27f, -0.03f, -0.52f, -0.08f, -0.75f,
+R_ARC_TO, 2.97f, 2.97f, 0, 0, 0, -0.24f, -0.69f,
+R_LINE_TO, 1.18f, -1.16f,
+R_CUBIC_TO, 0.24f, 0.38f, 0.43f, 0.79f, 0.57f, 1.22f,
+R_CUBIC_TO, 0.14f, 0.44f, 0.21f, 0.9f, 0.21f, 1.39f,
+R_CUBIC_TO, 0, 1.37f, -0.49f, 2.55f, -1.46f, 3.55f,
+R_CUBIC_TO, -0.98f, 1, -2.16f, 1.49f, -3.56f, 1.45f,
+R_H_LINE_TO, -0.01f,
+R_LINE_TO, 0.81f, 0.8f,
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/answer_dictionary_chrome_refresh.icon b/components/omnibox/browser/vector_icons/answer_dictionary_chrome_refresh.icon
index 641335f..7260532 100644
--- a/components/omnibox/browser/vector_icons/answer_dictionary_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/answer_dictionary_chrome_refresh.icon
@@ -3,36 +3,34 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 4.44f, 14.54f,
-R_CUBIC_TO, -0.38f, 0, -0.71f, -0.13f, -0.98f, -0.4f,
-R_ARC_TO, 1.35f, 1.35f, 0, 0, 1, -0.4f, -0.98f,
-V_LINE_TO, 2.85f,
-R_CUBIC_TO, 0, -0.38f, 0.13f, -0.71f, 0.4f, -0.98f,
-R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.4f, 0.98f, -0.4f,
-R_H_LINE_TO, 7.11f,
-R_CUBIC_TO, 0.38f, 0, 0.71f, 0.13f, 0.98f, 0.4f,
-R_CUBIC_TO, 0.27f, 0.27f, 0.4f, 0.6f, 0.4f, 0.98f,
-R_V_LINE_TO, 10.31f,
-R_CUBIC_TO, 0, 0.38f, -0.13f, 0.71f, -0.4f, 0.98f,
-R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.4f, -0.98f, 0.4f,
+MOVE_TO, 4.51f, 14.72f,
+R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.47f,
+R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -0.47f, -1.16f,
+V_LINE_TO, 2.91f,
+R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.48f, -1.16f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, 1.16f, -0.47f,
+R_H_LINE_TO, 6.98f,
+R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.47f,
+R_CUBIC_TO, 0.31f, 0.32f, 0.47f, 0.7f, 0.47f, 1.16f,
+R_V_LINE_TO, 10.17f,
+R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.48f, 1.16f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, 0.47f,
 CLOSE,
-R_MOVE_TO, 0.01f, -1.38f,
-R_H_LINE_TO, 7.1f,
-V_LINE_TO, 2.85f,
-R_H_LINE_TO, -1.14f,
+R_MOVE_TO, 0, -1.63f,
+R_H_LINE_TO, 6.98f,
+V_LINE_TO, 2.91f,
+H_LINE_TO, 10.43f,
 R_V_LINE_TO, 5.2f,
 R_LINE_TO, -1.6f, -0.8f,
 R_LINE_TO, -1.6f, 0.8f,
-R_V_LINE_TO, -5.2f,
-H_LINE_TO, 4.45f,
+V_LINE_TO, 2.91f,
+H_LINE_TO, 4.51f,
 CLOSE,
 R_MOVE_TO, 0, 0,
-V_LINE_TO, 2.85f,
+V_LINE_TO, 2.91f,
 CLOSE,
-R_MOVE_TO, 2.76f, -5.11f,
+R_MOVE_TO, 2.72f, -4.97f,
 R_LINE_TO, 1.6f, -0.8f,
 R_LINE_TO, 1.6f, 0.8f,
 R_LINE_TO, -1.6f, -0.8f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/answer_finance_chrome_refresh.icon b/components/omnibox/browser/vector_icons/answer_finance_chrome_refresh.icon
index 9be85fce..e11cc49 100644
--- a/components/omnibox/browser/vector_icons/answer_finance_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/answer_finance_chrome_refresh.icon
@@ -3,25 +3,23 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 5.31f, 8.78f,
-V_LINE_TO, 4,
-LINE_TO, 3.65f, 5.66f,
-R_LINE_TO, -0.98f, -0.98f,
-LINE_TO, 6, 1.36f,
-R_LINE_TO, 3.33f, 3.33f,
-R_LINE_TO, -0.98f, 0.98f,
-R_LINE_TO, -1.66f, -1.66f,
-R_V_LINE_TO, 4.77f,
+MOVE_TO, 5.18f, 8.74f,
+V_LINE_TO, 4.14f,
+LINE_TO, 3.65f, 5.68f,
+LINE_TO, 2.5f, 4.53f,
+LINE_TO, 6, 1.02f,
+R_LINE_TO, 3.5f, 3.5f,
+LINE_TO, 8.35f, 5.68f,
+LINE_TO, 6.82f, 4.14f,
+R_V_LINE_TO, 4.6f,
 CLOSE,
-MOVE_TO, 10, 14.65f,
-R_LINE_TO, -3.33f, -3.33f,
-R_LINE_TO, 0.98f, -0.98f,
-R_LINE_TO, 1.66f, 1.66f,
-V_LINE_TO, 7.22f,
-R_H_LINE_TO, 1.38f,
-R_V_LINE_TO, 4.77f,
-R_LINE_TO, 1.66f, -1.66f,
-R_LINE_TO, 0.98f, 0.98f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+MOVE_TO, 10, 14.98f,
+R_LINE_TO, -3.5f, -3.5f,
+R_LINE_TO, 1.15f, -1.15f,
+R_LINE_TO, 1.54f, 1.54f,
+V_LINE_TO, 7.26f,
+R_H_LINE_TO, 1.63f,
+R_V_LINE_TO, 4.6f,
+R_LINE_TO, 1.54f, -1.53f,
+R_LINE_TO, 1.15f, 1.15f,
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/answer_sunrise_chrome_refresh.icon b/components/omnibox/browser/vector_icons/answer_sunrise_chrome_refresh.icon
index ee7595d..62b2ad2 100644
--- a/components/omnibox/browser/vector_icons/answer_sunrise_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/answer_sunrise_chrome_refresh.icon
@@ -3,45 +3,45 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 7.31f, 2.86f,
-V_LINE_TO, 0.68f,
-H_LINE_TO, 8.69f,
-R_V_LINE_TO, 2.18f,
+MOVE_TO, 7.18f, 2.94f,
+V_LINE_TO, 0.51f,
+R_H_LINE_TO, 1.63f,
+V_LINE_TO, 2.94f,
 CLOSE,
-R_MOVE_TO, 0, 12.46f,
-R_V_LINE_TO, -2.18f,
-H_LINE_TO, 8.69f,
-R_V_LINE_TO, 2.18f,
+R_MOVE_TO, 0, 12.55f,
+V_LINE_TO, 13.06f,
+R_H_LINE_TO, 1.63f,
+R_V_LINE_TO, 2.43f,
 CLOSE,
-R_MOVE_TO, 5.83f, -6.63f,
-V_LINE_TO, 7.31f,
-R_H_LINE_TO, 2.18f,
-V_LINE_TO, 8.69f,
+R_MOVE_TO, 5.88f, -6.68f,
+V_LINE_TO, 7.18f,
+R_H_LINE_TO, 2.43f,
+R_V_LINE_TO, 1.63f,
 CLOSE,
-R_MOVE_TO, -12.46f, 0,
-V_LINE_TO, 7.31f,
-R_H_LINE_TO, 2.18f,
-V_LINE_TO, 8.69f,
+R_MOVE_TO, -12.55f, 0,
+V_LINE_TO, 7.18f,
+H_LINE_TO, 2.94f,
+R_V_LINE_TO, 1.63f,
 CLOSE,
-MOVE_TO, 12.12f, 4.86f,
-R_LINE_TO, -0.98f, -0.98f,
-LINE_TO, 12.67f, 2.3f,
-R_LINE_TO, 1.03f, 1.03f,
+R_MOVE_TO, 11.64f, -3.8f,
+R_LINE_TO, -1.16f, -1.16f,
+R_LINE_TO, 1.71f, -1.75f,
+R_LINE_TO, 1.2f, 1.2f,
 CLOSE,
-MOVE_TO, 3.35f, 13.68f,
-LINE_TO, 2.32f, 12.65f,
-R_LINE_TO, 1.56f, -1.51f,
-R_LINE_TO, 0.98f, 0.98f,
+MOVE_TO, 3.32f, 13.88f,
+LINE_TO, 2.12f, 12.68f,
+R_LINE_TO, 1.74f, -1.7f,
+R_LINE_TO, 1.16f, 1.16f,
 CLOSE,
-R_MOVE_TO, 9.32f, 0,
-R_LINE_TO, -1.53f, -1.56f,
-R_LINE_TO, 0.98f, -0.98f,
-R_LINE_TO, 1.58f, 1.52f,
+R_MOVE_TO, 9.38f, 0,
+R_LINE_TO, -1.71f, -1.73f,
+R_LINE_TO, 1.16f, -1.16f,
+R_LINE_TO, 1.75f, 1.7f,
 CLOSE,
-MOVE_TO, 3.88f, 4.86f,
-LINE_TO, 2.32f, 3.33f,
-R_LINE_TO, 1.03f, -1.03f,
-R_LINE_TO, 1.52f, 1.58f,
+MOVE_TO, 3.85f, 5.02f,
+LINE_TO, 2.12f, 3.31f,
+LINE_TO, 3.32f, 2.1f,
+R_LINE_TO, 1.7f, 1.75f,
 CLOSE,
 MOVE_TO, 8, 12,
 R_CUBIC_TO, -1.11f, 0, -2.06f, -0.39f, -2.83f, -1.17f,
@@ -53,17 +53,13 @@
 R_CUBIC_TO, 0, 1.11f, -0.39f, 2.06f, -1.17f, 2.83f,
 CUBIC_TO, 10.06f, 11.61f, 9.11f, 12, 8, 12,
 CLOSE,
-R_MOVE_TO, 0, -1.37f,
-R_ARC_TO, 2.53f, 2.53f, 0, 0, 0, 1.86f, -0.77f,
-R_ARC_TO, 2.56f, 2.56f, 0, 0, 0, 0.76f, -1.87f,
-R_CUBIC_TO, 0, -0.73f, -0.25f, -1.35f, -0.76f, -1.85f,
-R_ARC_TO, 2.52f, 2.52f, 0, 0, 0, -1.85f, -0.76f,
-R_CUBIC_TO, -0.73f, 0, -1.35f, 0.25f, -1.86f, 0.76f,
-R_CUBIC_TO, -0.51f, 0.5f, -0.76f, 1.12f, -0.76f, 1.85f,
-R_CUBIC_TO, 0, 0.73f, 0.25f, 1.35f, 0.76f, 1.87f,
-R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 1.85f, 0.77f,
-CLOSE,
-R_MOVE_TO, 0.02f, -2.65f,
-CLOSE,
-R_MOVE_TO, 0, 0,
+R_MOVE_TO, 0, -1.62f,
+R_ARC_TO, 2.27f, 2.27f, 0, 0, 0, 1.68f, -0.7f,
+R_CUBIC_TO, 0.46f, -0.46f, 0.69f, -1.03f, 0.69f, -1.69f,
+R_CUBIC_TO, 0, -0.66f, -0.23f, -1.22f, -0.69f, -1.68f,
+R_ARC_TO, 2.28f, 2.28f, 0, 0, 0, -1.68f, -0.69f,
+R_CUBIC_TO, -0.66f, 0, -1.22f, 0.23f, -1.68f, 0.69f,
+R_ARC_TO, 2.27f, 2.27f, 0, 0, 0, -0.69f, 1.68f,
+R_CUBIC_TO, 0, 0.66f, 0.23f, 1.22f, 0.69f, 1.69f,
+R_CUBIC_TO, 0.46f, 0.47f, 1.02f, 0.7f, 1.68f, 0.7f,
 CLOSE
diff --git a/components/omnibox/browser/vector_icons/answer_translation_chrome_refresh.icon b/components/omnibox/browser/vector_icons/answer_translation_chrome_refresh.icon
index 811e770..bb8724c5 100644
--- a/components/omnibox/browser/vector_icons/answer_translation_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/answer_translation_chrome_refresh.icon
@@ -3,44 +3,42 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-R_MOVE_TO, 8.13f, 14.52f,
-R_LINE_TO, 2.91f, -7.75f,
-R_H_LINE_TO, 1.39f,
-R_LINE_TO, 2.91f, 7.75f,
-R_H_LINE_TO, -1.34f,
-R_LINE_TO, -0.69f, -1.99f,
-R_H_LINE_TO, -3.12f,
-R_LINE_TO, -0.7f, 1.99f,
+R_MOVE_TO, 8.13f, 14.69f,
+R_LINE_TO, 2.98f, -7.95f,
+R_H_LINE_TO, 1.43f,
+R_LINE_TO, 2.99f, 7.95f,
+R_H_LINE_TO, -1.38f,
+R_LINE_TO, -0.71f, -2.06f,
+R_H_LINE_TO, -3.2f,
+R_LINE_TO, -0.73f, 2.05f,
 CLOSE,
-R_MOVE_TO, 2.45f, -3.11f,
-R_H_LINE_TO, 2.31f,
-LINE_TO, 11.77f, 8.2f,
+R_MOVE_TO, 2.51f, -3.2f,
+R_H_LINE_TO, 2.37f,
+LINE_TO, 11.86f, 8.2f,
 R_H_LINE_TO, -0.07f,
 CLOSE,
-R_MOVE_TO, -7.86f, 1.07f,
-R_LINE_TO, -0.85f, -0.87f,
-R_LINE_TO, 3.27f, -3.23f,
-R_ARC_TO, 15.27f, 15.27f, 0, 0, 1, -1.14f, -1.34f,
-R_ARC_TO, 9.15f, 9.15f, 0, 0, 1, -0.91f, -1.51f,
-R_H_LINE_TO, 1.39f,
-R_CUBIC_TO, 0.21f, 0.36f, 0.44f, 0.7f, 0.7f, 1.02f,
-R_CUBIC_TO, 0.26f, 0.32f, 0.52f, 0.63f, 0.79f, 0.93f,
-ARC_TO, 15.29f, 15.29f, 0, 0, 0, 7.16f, 6,
-R_CUBIC_TO, 0.36f, -0.52f, 0.66f, -1.07f, 0.89f, -1.67f,
-H_LINE_TO, 0.66f,
-V_LINE_TO, 3.1f,
-R_H_LINE_TO, 4.69f,
-V_LINE_TO, 1.48f,
-R_H_LINE_TO, 1.22f,
-R_V_LINE_TO, 1.63f,
-R_H_LINE_TO, 4.69f,
-R_V_LINE_TO, 1.23f,
-R_H_LINE_TO, -1.93f,
-R_ARC_TO, 7.96f, 7.96f, 0, 0, 1, -1.04f, 2.16f,
-R_CUBIC_TO, -0.45f, 0.67f, -0.95f, 1.3f, -1.5f, 1.9f,
-R_LINE_TO, 1.55f, 1.53f,
-R_LINE_TO, -0.47f, 1.26f,
-R_LINE_TO, -1.91f, -1.9f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+R_MOVE_TO, -8.06f, 1.11f,
+R_LINE_TO, -0.86f, -0.89f,
+LINE_TO, 5.07f, 8.4f,
+R_CUBIC_TO, -0.42f, -0.45f, -0.82f, -0.91f, -1.17f, -1.38f,
+R_ARC_TO, 9.28f, 9.28f, 0, 0, 1, -0.93f, -1.55f,
+H_LINE_TO, 4.39f,
+R_CUBIC_TO, 0.21f, 0.37f, 0.45f, 0.72f, 0.72f, 1.04f,
+R_CUBIC_TO, 0.27f, 0.33f, 0.53f, 0.65f, 0.81f, 0.96f,
+R_CUBIC_TO, 0.45f, -0.49f, 0.86f, -1, 1.23f, -1.53f,
+R_ARC_TO, 7.79f, 7.79f, 0, 0, 0, 0.91f, -1.71f,
+H_LINE_TO, 0.48f,
+V_LINE_TO, 2.97f,
+R_H_LINE_TO, 4.8f,
+V_LINE_TO, 1.31f,
+R_H_LINE_TO, 1.26f,
+R_V_LINE_TO, 1.66f,
+R_H_LINE_TO, 4.8f,
+V_LINE_TO, 4.23f,
+H_LINE_TO, 9.38f,
+R_ARC_TO, 8.36f, 8.36f, 0, 0, 1, -1.07f, 2.22f,
+R_CUBIC_TO, -0.47f, 0.69f, -0.98f, 1.34f, -1.54f, 1.95f,
+LINE_TO, 8.36f, 9.97f,
+R_LINE_TO, -0.48f, 1.29f,
+R_LINE_TO, -1.97f, -1.95f,
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/answer_when_is_chrome_refresh.icon b/components/omnibox/browser/vector_icons/answer_when_is_chrome_refresh.icon
index b8841fb..deb09305 100644
--- a/components/omnibox/browser/vector_icons/answer_when_is_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/answer_when_is_chrome_refresh.icon
@@ -13,39 +13,37 @@
 R_CUBIC_TO, 0, 0.45f, -0.15f, 0.83f, -0.46f, 1.14f,
 ARC_TO, 1.55f, 1.55f, 0, 0, 1, 9.6f, 12,
 CLOSE,
-R_MOVE_TO, -5.96f, 2.54f,
-R_CUBIC_TO, -0.38f, 0, -0.71f, -0.14f, -0.98f, -0.41f,
-R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.97f,
-V_LINE_TO, 4.45f,
-R_CUBIC_TO, 0, -0.37f, 0.13f, -0.7f, 0.4f, -0.97f,
-R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.41f, 0.98f, -0.41f,
-R_H_LINE_TO, 1.15f,
-V_LINE_TO, 1.46f,
-H_LINE_TO, 6.09f,
-R_V_LINE_TO, 1.6f,
-R_H_LINE_TO, 3.82f,
-V_LINE_TO, 1.47f,
-R_H_LINE_TO, 1.29f,
-R_V_LINE_TO, 1.6f,
-R_H_LINE_TO, 1.15f,
-R_CUBIC_TO, 0.38f, 0, 0.71f, 0.14f, 0.98f, 0.41f,
-R_CUBIC_TO, 0.27f, 0.27f, 0.4f, 0.6f, 0.4f, 0.97f,
-R_V_LINE_TO, 8.7f,
-R_CUBIC_TO, 0, 0.38f, -0.13f, 0.7f, -0.4f, 0.97f,
-R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.41f, -0.98f, 0.41f,
+R_MOVE_TO, -5.89f, 2.72f,
+R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.48f,
+R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.48f, -1.15f,
+V_LINE_TO, 4.51f,
+R_CUBIC_TO, 0, -0.45f, 0.16f, -0.83f, 0.48f, -1.15f,
+R_CUBIC_TO, 0.32f, -0.32f, 0.7f, -0.48f, 1.16f, -0.48f,
+H_LINE_TO, 4.8f,
+V_LINE_TO, 1.28f,
+R_H_LINE_TO, 1.41f,
+V_LINE_TO, 2.88f,
+R_H_LINE_TO, 3.57f,
+V_LINE_TO, 1.28f,
+H_LINE_TO, 11.2f,
+V_LINE_TO, 2.88f,
+R_H_LINE_TO, 1.09f,
+R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f,
+R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.15f,
+R_V_LINE_TO, 8.57f,
+R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.15f,
+R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.16f, 0.48f,
 CLOSE,
-R_MOVE_TO, 0, -1.38f,
-R_H_LINE_TO, 8.7f,
+R_MOVE_TO, 0, -1.63f,
+R_H_LINE_TO, 8.57f,
 V_LINE_TO, 7.2f,
-H_LINE_TO, 3.65f,
+R_H_LINE_TO, -8.57f,
 CLOSE,
-R_MOVE_TO, 0, -7.15f,
-R_H_LINE_TO, 8.7f,
-V_LINE_TO, 4.45f,
-H_LINE_TO, 3.65f,
+R_MOVE_TO, 0, -7.09f,
+R_H_LINE_TO, 8.57f,
+V_LINE_TO, 4.51f,
+R_H_LINE_TO, -8.57f,
 CLOSE,
 R_MOVE_TO, 0, 0,
-V_LINE_TO, 4.45f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+V_LINE_TO, 4.51f,
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/arrow_down_chrome_refresh.icon b/components/omnibox/browser/vector_icons/arrow_down_chrome_refresh.icon
index c9a08ff9..d226c368 100644
--- a/components/omnibox/browser/vector_icons/arrow_down_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/arrow_down_chrome_refresh.icon
@@ -3,9 +3,7 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 8, 9.73f,
-LINE_TO, 4.58f, 6.31f,
-R_H_LINE_TO, 6.84f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+MOVE_TO, 8, 9.9f,
+LINE_TO, 4.28f, 6.18f,
+R_H_LINE_TO, 7.44f,
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/arrow_up_chrome_refresh.icon b/components/omnibox/browser/vector_icons/arrow_up_chrome_refresh.icon
index 4d456e9..28086c0 100644
--- a/components/omnibox/browser/vector_icons/arrow_up_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/arrow_up_chrome_refresh.icon
@@ -3,9 +3,7 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 4.58f, 9.69f,
-LINE_TO, 8, 6.27f,
-R_LINE_TO, 3.42f, 3.42f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+MOVE_TO, 4.28f, 9.82f,
+LINE_TO, 8, 6.1f,
+R_LINE_TO, 3.72f, 3.72f,
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/bookmark_chrome_refresh.icon b/components/omnibox/browser/vector_icons/bookmark_chrome_refresh.icon
index c8f56e67..e470d9e 100644
--- a/components/omnibox/browser/vector_icons/bookmark_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/bookmark_chrome_refresh.icon
@@ -3,29 +3,25 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 5.94f, 11.81f,
-LINE_TO, 8, 10.59f,
-R_LINE_TO, 2.07f, 1.22f,
-R_LINE_TO, -0.55f, -2.31f,
-R_LINE_TO, 1.79f, -1.53f,
-R_LINE_TO, -2.36f, -0.21f,
-LINE_TO, 8, 5.57f,
-LINE_TO, 7.05f, 7.77f,
-R_LINE_TO, -2.36f, 0.2f,
-R_LINE_TO, 1.8f, 1.52f,
+MOVE_TO, 6.05f, 11.66f,
+LINE_TO, 8, 10.51f,
+R_LINE_TO, 1.97f, 1.16f,
+LINE_TO, 9.44f, 9.48f,
+R_LINE_TO, 1.7f, -1.45f,
+R_LINE_TO, -2.24f, -0.2f,
+LINE_TO, 8, 5.75f,
+LINE_TO, 7.1f, 7.84f,
+R_LINE_TO, -2.24f, 0.19f,
+LINE_TO, 6.57f, 9.47f,
 CLOSE,
-R_MOVE_TO, -2.09f, 2.87f,
-R_LINE_TO, 1.11f, -4.66f,
-R_LINE_TO, -3.68f, -3.14f,
-R_LINE_TO, 4.83f, -0.41f,
-LINE_TO, 8, 2.06f,
-R_LINE_TO, 1.89f, 4.42f,
-R_LINE_TO, 4.83f, 0.4f,
-R_LINE_TO, -3.68f, 3.14f,
-R_LINE_TO, 1.11f, 4.66f,
-LINE_TO, 8, 12.2f,
-CLOSE,
-MOVE_TO, 8, 8.86f,
-CLOSE,
-R_MOVE_TO, 0, 0,
+R_MOVE_TO, -2.47f, 3.39f,
+R_LINE_TO, 1.18f, -4.97f,
+LINE_TO, 0.84f, 6.73f,
+R_LINE_TO, 5.15f, -0.44f,
+LINE_TO, 8, 1.6f,
+R_LINE_TO, 2.02f, 4.71f,
+R_LINE_TO, 5.15f, 0.42f,
+R_LINE_TO, -3.93f, 3.35f,
+R_LINE_TO, 1.18f, 4.97f,
+LINE_TO, 8, 12.41f,
 CLOSE
diff --git a/components/omnibox/browser/vector_icons/calculator_chrome_refresh.icon b/components/omnibox/browser/vector_icons/calculator_chrome_refresh.icon
index 76f86564..8b9a190 100644
--- a/components/omnibox/browser/vector_icons/calculator_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/calculator_chrome_refresh.icon
@@ -3,15 +3,13 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 3.11f, 11.29f,
-V_LINE_TO, 9.11f,
-R_H_LINE_TO, 9.78f,
-R_V_LINE_TO, 2.18f,
+MOVE_TO, 2.98f, 11.42f,
+V_LINE_TO, 8.98f,
+R_H_LINE_TO, 10.03f,
+R_V_LINE_TO, 2.43f,
 CLOSE,
 R_MOVE_TO, 0, -4.4f,
-V_LINE_TO, 4.71f,
-R_H_LINE_TO, 9.78f,
-R_V_LINE_TO, 2.18f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+V_LINE_TO, 4.58f,
+R_H_LINE_TO, 10.03f,
+R_V_LINE_TO, 2.43f,
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/clock_chrome_refresh.icon b/components/omnibox/browser/vector_icons/clock_chrome_refresh.icon
index 5b73c9eb..d7b745b 100644
--- a/components/omnibox/browser/vector_icons/clock_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/clock_chrome_refresh.icon
@@ -3,42 +3,40 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-R_MOVE_TO, 10.17f, 10.86f,
-R_LINE_TO, 0.94f, -0.93f,
-LINE_TO, 8.66f, 7.47f,
-R_V_LINE_TO, -3.45f,
-H_LINE_TO, 7.34f,
-R_V_LINE_TO, 4,
+R_MOVE_TO, 10.09f, 10.89f,
+R_LINE_TO, 1.07f, -1.05f,
+R_LINE_TO, -2.42f, -2.42f,
+R_V_LINE_TO, -3.38f,
+H_LINE_TO, 7.26f,
+R_V_LINE_TO, 4.01f,
 CLOSE,
-MOVE_TO, 8, 14.54f,
-R_CUBIC_TO, -0.9f, 0, -1.75f, -0.17f, -2.54f, -0.51f,
-R_ARC_TO, 6.55f, 6.55f, 0, 0, 1, -2.08f, -1.4f,
-R_ARC_TO, 6.52f, 6.52f, 0, 0, 1, -1.4f, -2.08f,
-R_ARC_TO, 6.33f, 6.33f, 0, 0, 1, -0.51f, -2.55f,
-R_CUBIC_TO, 0, -0.91f, 0.17f, -1.75f, 0.51f, -2.55f,
-R_ARC_TO, 6.4f, 6.4f, 0, 0, 1, 1.4f, -2.07f,
-ARC_TO, 6.63f, 6.63f, 0, 0, 1, 5.46f, 1.98f,
-R_ARC_TO, 6.33f, 6.33f, 0, 0, 1, 2.55f, -0.51f,
-R_ARC_TO, 6.33f, 6.33f, 0, 0, 1, 2.55f, 0.52f,
-R_ARC_TO, 6.55f, 6.55f, 0, 0, 1, 2.07f, 1.4f,
-R_ARC_TO, 6.59f, 6.59f, 0, 0, 1, 1.39f, 2.07f,
-R_CUBIC_TO, 0.34f, 0.79f, 0.51f, 1.65f, 0.51f, 2.55f,
-R_CUBIC_TO, 0, 0.9f, -0.17f, 1.75f, -0.51f, 2.54f,
-R_ARC_TO, 6.66f, 6.66f, 0, 0, 1, -1.39f, 2.08f,
-R_ARC_TO, 6.4f, 6.4f, 0, 0, 1, -2.07f, 1.4f,
-ARC_TO, 6.38f, 6.38f, 0, 0, 1, 8, 14.54f,
+MOVE_TO, 8, 14.72f,
+R_ARC_TO, 6.51f, 6.51f, 0, 0, 1, -2.62f, -0.52f,
+R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, -2.14f, -1.44f,
+R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, -1.44f, -2.14f,
+R_ARC_TO, 6.56f, 6.56f, 0, 0, 1, -0.52f, -2.62f,
+R_CUBIC_TO, 0, -0.93f, 0.17f, -1.81f, 0.52f, -2.62f,
+R_ARC_TO, 6.62f, 6.62f, 0, 0, 1, 1.44f, -2.13f,
+R_ARC_TO, 6.81f, 6.81f, 0, 0, 1, 2.14f, -1.43f,
+R_ARC_TO, 6.56f, 6.56f, 0, 0, 1, 2.63f, -0.52f,
+R_CUBIC_TO, 0.93f, 0, 1.81f, 0.18f, 2.63f, 0.53f,
+R_ARC_TO, 6.75f, 6.75f, 0, 0, 1, 2.13f, 1.43f,
+R_ARC_TO, 6.8f, 6.8f, 0, 0, 1, 1.43f, 2.13f,
+ARC_TO, 6.57f, 6.57f, 0, 0, 1, 14.72f, 8,
+R_CUBIC_TO, 0, 0.93f, -0.17f, 1.81f, -0.52f, 2.62f,
+R_ARC_TO, 6.81f, 6.81f, 0, 0, 1, -1.43f, 2.14f,
+R_ARC_TO, 6.59f, 6.59f, 0, 0, 1, -2.13f, 1.44f,
+ARC_TO, 6.57f, 6.57f, 0, 0, 1, 8, 14.72f,
 CLOSE,
 MOVE_TO, 8, 8,
 CLOSE,
-R_MOVE_TO, 0.01f, 5.15f,
-R_CUBIC_TO, 1.43f, 0, 2.64f, -0.5f, 3.64f, -1.51f,
-R_CUBIC_TO, 1, -1.01f, 1.5f, -2.22f, 1.5f, -3.65f,
-R_CUBIC_TO, 0, -1.43f, -0.5f, -2.64f, -1.5f, -3.64f,
-R_CUBIC_TO, -1, -1, -2.21f, -1.5f, -3.64f, -1.5f,
-R_CUBIC_TO, -1.43f, 0, -2.64f, 0.5f, -3.65f, 1.5f,
-R_CUBIC_TO, -1.01f, 1, -1.51f, 2.22f, -1.51f, 3.64f,
-R_CUBIC_TO, 0, 1.43f, 0.5f, 2.65f, 1.51f, 3.65f,
-R_CUBIC_TO, 1.01f, 1, 2.22f, 1.51f, 3.65f, 1.51f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+R_MOVE_TO, 0.01f, 5.09f,
+R_CUBIC_TO, 1.41f, 0, 2.61f, -0.5f, 3.59f, -1.48f,
+R_CUBIC_TO, 0.99f, -0.99f, 1.48f, -2.2f, 1.48f, -3.61f,
+R_CUBIC_TO, 0, -1.41f, -0.49f, -2.61f, -1.48f, -3.6f,
+R_CUBIC_TO, -0.99f, -0.98f, -2.19f, -1.48f, -3.59f, -1.48f,
+R_CUBIC_TO, -1.41f, 0, -2.61f, 0.49f, -3.6f, 1.48f,
+R_CUBIC_TO, -1, 0.99f, -1.49f, 2.19f, -1.49f, 3.6f,
+R_CUBIC_TO, 0, 1.41f, 0.5f, 2.62f, 1.49f, 3.61f,
+R_CUBIC_TO, 0.99f, 0.99f, 2.2f, 1.48f, 3.6f, 1.48f,
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/journeys_chrome_refresh.icon b/components/omnibox/browser/vector_icons/journeys_chrome_refresh.icon
index 9299b879..67f365b 100644
--- a/components/omnibox/browser/vector_icons/journeys_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/journeys_chrome_refresh.icon
@@ -3,45 +3,45 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 12.4f, 13.72f,
-R_CUBIC_TO, -0.49f, 0, -0.92f, -0.14f, -1.28f, -0.43f,
-R_CUBIC_TO, -0.36f, -0.29f, -0.6f, -0.64f, -0.73f, -1.06f,
+MOVE_TO, 12.4f, 13.89f,
+R_CUBIC_TO, -0.55f, 0, -1.01f, -0.16f, -1.4f, -0.47f,
+R_ARC_TO, 2.34f, 2.34f, 0, 0, 1, -0.78f, -1.14f,
 H_LINE_TO, 6.6f,
-R_ARC_TO, 2.15f, 2.15f, 0, 0, 1, -1.58f, -0.65f,
-R_ARC_TO, 2.17f, 2.17f, 0, 0, 1, -0.65f, -1.59f,
-R_CUBIC_TO, 0, -0.62f, 0.22f, -1.14f, 0.65f, -1.58f,
-R_CUBIC_TO, 0.43f, -0.43f, 0.96f, -0.65f, 1.58f, -0.65f,
+R_ARC_TO, 2.18f, 2.18f, 0, 0, 1, -1.61f, -0.66f,
+R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f,
+R_CUBIC_TO, 0, -0.63f, 0.22f, -1.17f, 0.66f, -1.61f,
+R_CUBIC_TO, 0.44f, -0.44f, 0.98f, -0.66f, 1.61f, -0.66f,
 R_H_LINE_TO, 2,
-R_CUBIC_TO, 0.38f, 0, 0.7f, -0.14f, 0.96f, -0.41f,
-R_CUBIC_TO, 0.27f, -0.26f, 0.4f, -0.59f, 0.4f, -0.97f,
-R_ARC_TO, 1.3f, 1.3f, 0, 0, 0, -0.4f, -0.96f,
-R_ARC_TO, 1.33f, 1.33f, 0, 0, 0, -0.96f, -0.4f,
-R_H_LINE_TO, -2.98f,
-R_ARC_TO, 2.09f, 2.09f, 0, 0, 1, -0.73f, 1.06f,
-R_CUBIC_TO, -0.36f, 0.29f, -0.79f, 0.43f, -1.28f, 0.43f,
-R_ARC_TO, 2.04f, 2.04f, 0, 0, 1, -1.5f, -0.62f,
-R_ARC_TO, 2.04f, 2.04f, 0, 0, 1, -0.62f, -1.5f,
-R_CUBIC_TO, 0, -0.59f, 0.21f, -1.09f, 0.62f, -1.5f,
-R_CUBIC_TO, 0.41f, -0.41f, 0.92f, -0.62f, 1.51f, -0.62f,
-R_CUBIC_TO, 0.49f, 0, 0.92f, 0.14f, 1.29f, 0.43f,
-R_CUBIC_TO, 0.36f, 0.29f, 0.61f, 0.64f, 0.73f, 1.06f,
-R_H_LINE_TO, 2.98f,
-R_CUBIC_TO, 0.73f, 0, 1.35f, 0.25f, 1.86f, 0.77f,
-R_CUBIC_TO, 0.51f, 0.52f, 0.77f, 1.13f, 0.77f, 1.86f,
-R_CUBIC_TO, 0, 0.74f, -0.25f, 1.36f, -0.76f, 1.87f,
-R_ARC_TO, 2.54f, 2.54f, 0, 0, 1, -1.86f, 0.77f,
+R_CUBIC_TO, 0.36f, 0, 0.68f, -0.13f, 0.93f, -0.39f,
+R_CUBIC_TO, 0.26f, -0.26f, 0.39f, -0.57f, 0.39f, -0.94f,
+R_CUBIC_TO, 0, -0.37f, -0.13f, -0.68f, -0.39f, -0.93f,
+R_ARC_TO, 1.27f, 1.27f, 0, 0, 0, -0.93f, -0.39f,
+R_H_LINE_TO, -2.82f,
+R_ARC_TO, 2.27f, 2.27f, 0, 0, 1, -0.77f, 1.14f,
+R_CUBIC_TO, -0.39f, 0.32f, -0.86f, 0.48f, -1.41f, 0.48f,
+R_CUBIC_TO, -0.64f, 0, -1.18f, -0.22f, -1.62f, -0.67f,
+R_ARC_TO, 2.21f, 2.21f, 0, 0, 1, -0.67f, -1.62f,
+R_CUBIC_TO, 0, -0.64f, 0.22f, -1.17f, 0.67f, -1.62f,
+R_ARC_TO, 2.21f, 2.21f, 0, 0, 1, 1.63f, -0.67f,
+R_CUBIC_TO, 0.55f, 0, 1.01f, 0.16f, 1.41f, 0.47f,
+R_CUBIC_TO, 0.39f, 0.32f, 0.64f, 0.7f, 0.77f, 1.15f,
+R_H_LINE_TO, 2.82f,
+R_CUBIC_TO, 0.75f, 0, 1.38f, 0.26f, 1.9f, 0.77f,
+R_CUBIC_TO, 0.52f, 0.52f, 0.77f, 1.15f, 0.77f, 1.9f,
+R_CUBIC_TO, 0, 0.75f, -0.26f, 1.38f, -0.77f, 1.9f,
+R_CUBIC_TO, -0.52f, 0.52f, -1.15f, 0.78f, -1.9f, 0.78f,
 R_H_LINE_TO, -2,
-R_ARC_TO, 0.93f, 0.93f, 0, 0, 0, -0.68f, 0.28f,
-R_ARC_TO, 0.93f, 0.93f, 0, 0, 0, -0.28f, 0.68f,
-R_CUBIC_TO, 0, 0.27f, 0.09f, 0.5f, 0.28f, 0.68f,
-R_ARC_TO, 0.93f, 0.93f, 0, 0, 0, 0.68f, 0.28f,
-R_H_LINE_TO, 3.78f,
-R_CUBIC_TO, 0.13f, -0.42f, 0.37f, -0.77f, 0.73f, -1.06f,
-R_CUBIC_TO, 0.36f, -0.29f, 0.79f, -0.43f, 1.29f, -0.43f,
-R_CUBIC_TO, 0.59f, 0, 1.09f, 0.21f, 1.5f, 0.62f,
-R_CUBIC_TO, 0.41f, 0.41f, 0.62f, 0.92f, 0.62f, 1.51f,
-R_CUBIC_TO, 0, 0.59f, -0.21f, 1.09f, -0.62f, 1.5f,
-R_CUBIC_TO, -0.41f, 0.41f, -0.91f, 0.62f, -1.5f, 0.62f,
+R_CUBIC_TO, -0.25f, 0, -0.47f, 0.09f, -0.65f, 0.27f,
+R_ARC_TO, 0.88f, 0.88f, 0, 0, 0, -0.27f, 0.65f,
+R_CUBIC_TO, 0, 0.25f, 0.09f, 0.47f, 0.27f, 0.65f,
+R_CUBIC_TO, 0.18f, 0.18f, 0.4f, 0.27f, 0.65f, 0.27f,
+R_H_LINE_TO, 3.62f,
+R_CUBIC_TO, 0.13f, -0.45f, 0.39f, -0.82f, 0.77f, -1.14f,
+R_CUBIC_TO, 0.39f, -0.32f, 0.86f, -0.48f, 1.41f, -0.48f,
+R_CUBIC_TO, 0.64f, 0, 1.18f, 0.22f, 1.63f, 0.67f,
+R_CUBIC_TO, 0.45f, 0.45f, 0.67f, 0.99f, 0.67f, 1.63f,
+R_CUBIC_TO, 0, 0.64f, -0.22f, 1.18f, -0.67f, 1.62f,
+R_ARC_TO, 2.21f, 2.21f, 0, 0, 1, -1.62f, 0.67f,
 CLOSE,
 MOVE_TO, 3.6f, 5.2f,
 R_ARC_TO, 0.77f, 0.77f, 0, 0, 0, 0.57f, -0.23f,
@@ -52,6 +52,4 @@
 R_ARC_TO, 0.77f, 0.77f, 0, 0, 0, -0.23f, 0.57f,
 R_CUBIC_TO, 0, 0.23f, 0.07f, 0.42f, 0.23f, 0.57f,
 R_CUBIC_TO, 0.15f, 0.16f, 0.34f, 0.23f, 0.57f, 0.23f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/page_chrome_refresh.icon b/components/omnibox/browser/vector_icons/page_chrome_refresh.icon
index 88140f0..2b44ef2 100644
--- a/components/omnibox/browser/vector_icons/page_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/page_chrome_refresh.icon
@@ -3,54 +3,54 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 8.01f, 14.54f,
-R_ARC_TO, 6.38f, 6.38f, 0, 0, 1, -2.54f, -0.51f,
-R_ARC_TO, 6.59f, 6.59f, 0, 0, 1, -2.08f, -1.41f,
-R_ARC_TO, 6.66f, 6.66f, 0, 0, 1, -1.41f, -2.09f,
-R_ARC_TO, 6.39f, 6.39f, 0, 0, 1, -0.51f, -2.54f,
-R_CUBIC_TO, 0, -0.9f, 0.17f, -1.75f, 0.51f, -2.53f,
-R_ARC_TO, 6.59f, 6.59f, 0, 0, 1, 3.49f, -3.48f,
-R_ARC_TO, 6.39f, 6.39f, 0, 0, 1, 2.54f, -0.51f,
-R_CUBIC_TO, 0.9f, 0, 1.75f, 0.17f, 2.54f, 0.51f,
-R_ARC_TO, 6.63f, 6.63f, 0, 0, 1, 3.48f, 3.49f,
-R_CUBIC_TO, 0.34f, 0.79f, 0.51f, 1.64f, 0.51f, 2.54f,
-R_ARC_TO, 6.38f, 6.38f, 0, 0, 1, -0.51f, 2.54f,
-R_ARC_TO, 6.59f, 6.59f, 0, 0, 1, -3.49f, 3.49f,
-R_CUBIC_TO, -0.79f, 0.34f, -1.63f, 0.51f, -2.53f, 0.51f,
+MOVE_TO, 8.02f, 14.72f,
+R_ARC_TO, 6.53f, 6.53f, 0, 0, 1, -2.61f, -0.52f,
+R_ARC_TO, 6.76f, 6.76f, 0, 0, 1, -3.59f, -3.59f,
+R_ARC_TO, 6.6f, 6.6f, 0, 0, 1, -0.52f, -2.61f,
+R_CUBIC_TO, 0, -0.93f, 0.18f, -1.8f, 0.52f, -2.6f,
+ARC_TO, 6.75f, 6.75f, 0, 0, 1, 3.26f, 3.25f,
+R_ARC_TO, 6.76f, 6.76f, 0, 0, 1, 2.14f, -1.44f,
+ARC_TO, 6.54f, 6.54f, 0, 0, 1, 8.02f, 1.28f,
+R_CUBIC_TO, 0.93f, 0, 1.79f, 0.17f, 2.6f, 0.52f,
+R_CUBIC_TO, 0.81f, 0.35f, 1.52f, 0.83f, 2.13f, 1.45f,
+R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, 1.45f, 2.14f,
+R_CUBIC_TO, 0.35f, 0.81f, 0.52f, 1.68f, 0.52f, 2.61f,
+R_CUBIC_TO, 0, 0.93f, -0.17f, 1.79f, -0.52f, 2.61f,
+R_ARC_TO, 6.68f, 6.68f, 0, 0, 1, -1.44f, 2.14f,
+R_ARC_TO, 6.73f, 6.73f, 0, 0, 1, -2.14f, 1.45f,
+R_ARC_TO, 6.46f, 6.46f, 0, 0, 1, -2.6f, 0.52f,
 CLOSE,
-R_MOVE_TO, -0.8f, -1.45f,
-R_V_LINE_TO, -1.13f,
-R_ARC_TO, 0.76f, 0.76f, 0, 0, 1, -0.56f, -0.23f,
-R_ARC_TO, 0.77f, 0.77f, 0, 0, 1, -0.23f, -0.56f,
-R_V_LINE_TO, -0.79f,
-R_LINE_TO, -3.45f, -3.45f,
-R_ARC_TO, 6.23f, 6.23f, 0, 0, 0, -0.09f, 0.57f,
-R_ARC_TO, 5.58f, 5.58f, 0, 0, 0, -0.02f, 0.49f,
-R_CUBIC_TO, 0, 1.27f, 0.41f, 2.39f, 1.23f, 3.36f,
-R_CUBIC_TO, 0.82f, 0.97f, 1.86f, 1.55f, 3.13f, 1.73f,
+R_MOVE_TO, -0.8f, -1.7f,
+R_V_LINE_TO, -1.12f,
+R_ARC_TO, 0.75f, 0.75f, 0, 0, 1, -0.55f, -0.22f,
+R_ARC_TO, 0.74f, 0.74f, 0, 0, 1, -0.23f, -0.54f,
+R_V_LINE_TO, -0.78f,
+LINE_TO, 3.04f, 6.93f,
+R_ARC_TO, 5.09f, 5.09f, 0, 0, 0, -0.12f, 1.05f,
+R_CUBIC_TO, 0, 1.25f, 0.41f, 2.36f, 1.22f, 3.32f,
+R_CUBIC_TO, 0.81f, 0.96f, 1.84f, 1.53f, 3.08f, 1.72f,
 CLOSE,
-R_MOVE_TO, 4.76f, -1.8f,
-R_CUBIC_TO, 0.2f, -0.23f, 0.37f, -0.47f, 0.52f, -0.73f,
-R_CUBIC_TO, 0.14f, -0.25f, 0.27f, -0.52f, 0.37f, -0.8f,
-R_ARC_TO, 5.32f, 5.32f, 0, 0, 0, 0.3f, -1.77f,
-R_CUBIC_TO, 0, -1.04f, -0.28f, -1.99f, -0.85f, -2.85f,
-R_ARC_TO, 5.05f, 5.05f, 0, 0, 0, -2.31f, -1.9f,
-R_V_LINE_TO, 0.4f,
-R_CUBIC_TO, 0, 0.32f, -0.12f, 0.61f, -0.35f, 0.84f,
-R_CUBIC_TO, -0.23f, 0.23f, -0.52f, 0.35f, -0.84f, 0.35f,
-H_LINE_TO, 7.21f,
-R_V_LINE_TO, 0.79f,
-R_ARC_TO, 0.77f, 0.77f, 0, 0, 1, -0.23f, 0.57f,
-R_ARC_TO, 0.77f, 0.77f, 0, 0, 1, -0.57f, 0.23f,
-R_H_LINE_TO, -0.78f,
-R_V_LINE_TO, 1.59f,
-H_LINE_TO, 9.59f,
-R_CUBIC_TO, 0.23f, 0, 0.41f, 0.08f, 0.57f, 0.23f,
-R_CUBIC_TO, 0.16f, 0.15f, 0.23f, 0.34f, 0.23f, 0.57f,
-R_V_LINE_TO, 1.58f,
-R_H_LINE_TO, 0.67f,
-R_ARC_TO, 0.87f, 0.87f, 0, 0, 1, 0.65f, 0.27f,
-R_CUBIC_TO, 0.18f, 0.18f, 0.26f, 0.39f, 0.26f, 0.65f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+R_MOVE_TO, 4.71f, -1.78f,
+R_CUBIC_TO, 0.2f, -0.23f, 0.37f, -0.46f, 0.51f, -0.71f,
+R_CUBIC_TO, 0.14f, -0.25f, 0.26f, -0.51f, 0.36f, -0.8f,
+R_CUBIC_TO, 0.1f, -0.28f, 0.17f, -0.57f, 0.22f, -0.86f,
+R_CUBIC_TO, 0.05f, -0.29f, 0.07f, -0.59f, 0.07f, -0.89f,
+R_CUBIC_TO, 0, -1.02f, -0.28f, -1.96f, -0.84f, -2.81f,
+R_ARC_TO, 4.93f, 4.93f, 0, 0, 0, -2.28f, -1.87f,
+R_V_LINE_TO, 0.38f,
+R_CUBIC_TO, 0, 0.32f, -0.12f, 0.6f, -0.35f, 0.83f,
+R_ARC_TO, 1.16f, 1.16f, 0, 0, 1, -0.84f, 0.34f,
+H_LINE_TO, 7.22f,
+R_V_LINE_TO, 0.77f,
+R_CUBIC_TO, 0, 0.22f, -0.08f, 0.41f, -0.23f, 0.56f,
+R_ARC_TO, 0.75f, 0.75f, 0, 0, 1, -0.56f, 0.23f,
+R_H_LINE_TO, -0.77f,
+V_LINE_TO, 7.98f,
+R_H_LINE_TO, 3.92f,
+R_CUBIC_TO, 0.22f, 0, 0.41f, 0.08f, 0.56f, 0.23f,
+R_CUBIC_TO, 0.16f, 0.15f, 0.23f, 0.34f, 0.23f, 0.56f,
+R_V_LINE_TO, 1.55f,
+R_H_LINE_TO, 0.66f,
+R_CUBIC_TO, 0.25f, 0, 0.47f, 0.09f, 0.64f, 0.27f,
+R_CUBIC_TO, 0.17f, 0.18f, 0.26f, 0.39f, 0.26f, 0.65f,
+CLOSE
\ No newline at end of file
diff --git a/components/omnibox/browser/vector_icons/trending_up_chrome_refresh.icon b/components/omnibox/browser/vector_icons/trending_up_chrome_refresh.icon
index b7c981f..102a3e3 100644
--- a/components/omnibox/browser/vector_icons/trending_up_chrome_refresh.icon
+++ b/components/omnibox/browser/vector_icons/trending_up_chrome_refresh.icon
@@ -3,19 +3,17 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-R_MOVE_TO, 2.47f, 12.09f,
-R_LINE_TO, -0.98f, -0.98f,
-R_LINE_TO, 4.82f, -4.81f,
+R_MOVE_TO, 2.5f, 12.22f,
+R_LINE_TO, -1.16f, -1.15f,
+R_LINE_TO, 5, -4.98f,
 R_LINE_TO, 2.53f, 2.53f,
-R_LINE_TO, 3.31f, -3.3f,
-R_H_LINE_TO, -1.91f,
-V_LINE_TO, 4.16f,
-R_H_LINE_TO, 4.27f,
-R_V_LINE_TO, 4.27f,
-R_H_LINE_TO, -1.38f,
-V_LINE_TO, 6.52f,
-R_LINE_TO, -4.29f, 4.28f,
+R_LINE_TO, 3.01f, -3,
+R_H_LINE_TO, -1.85f,
+V_LINE_TO, 3.98f,
+R_H_LINE_TO, 4.64f,
+R_V_LINE_TO, 4.63f,
+R_H_LINE_TO, -1.63f,
+V_LINE_TO, 6.77f,
+R_LINE_TO, -4.17f, 4.15f,
 R_LINE_TO, -2.53f, -2.53f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+CLOSE
\ No newline at end of file
diff --git a/components/password_manager/core/browser/login_database.cc b/components/password_manager/core/browser/login_database.cc
index 82057a4f..cbfe5eb 100644
--- a/components/password_manager/core/browser/login_database.cc
+++ b/components/password_manager/core/browser/login_database.cc
@@ -61,6 +61,10 @@
 
 namespace password_manager {
 
+#if BUILDFLAG(IS_IOS)
+using metrics_util::MigrationToOSCrypt;
+#endif
+
 // The current version number of the login database schema.
 constexpr int kCurrentVersionNumber = 39;
 // The oldest version of the schema such that a legacy Chrome client using that
@@ -698,29 +702,11 @@
   return true;
 }
 
-// This enum indicates migration status from Keychain to OSCrypt on iOS in the
-// version 39.
-//
-// Needs to stay in sync with PasswordManagerMatchedFormType in
-// enums.xml.
-enum class MigrationToOSCrypt {
-  kStarted,
-  kFailedToCopyPasswordColumn,
-  kFailedToDecryptFromKeychain,
-  kFailedToEncrypt,
-  kFailedToUpdate,
-  kSuccess,
-  kMaxValue = kSuccess,
-};
-
-void RecordMigrationToOSCryptStatus(MigrationToOSCrypt status) {
-  base::UmaHistogramEnumeration("PasswordManager.MigrationToOSCrypt", status);
-}
-
 // Call this after having called InitializeBuilders(), to migrate the database
 // from the current version to kCurrentVersionNumber.
 bool MigrateDatabase(unsigned current_version,
                      SQLTableBuilders builders,
+                     IsAccountStore is_account_store,
                      sql::Database* db) {
   if (!builders.logins->MigrateFrom(
           current_version, db,
@@ -823,7 +809,14 @@
 
 #if BUILDFLAG(IS_IOS)
   if (current_version < 39) {
-    RecordMigrationToOSCryptStatus(MigrationToOSCrypt::kStarted);
+    base::TimeTicks migration_start_time = base::TimeTicks::Now();
+    metrics_util::RecordMigrationToOSCryptStatus(migration_start_time,
+                                                 is_account_store.value(),
+                                                 MigrationToOSCrypt::kStarted);
+    base::OnceCallback<void(metrics_util::MigrationToOSCrypt)>
+        record_completion_metrics =
+            base::BindOnce(&metrics_util::RecordMigrationToOSCryptStatus,
+                           migration_start_time, is_account_store.value());
     // Before version 39, password_value was used to store keychain identifier
     // where the actual password is. After this version password_value is
     // encrypted password using OSCrypt. To ensure Credential Provider works as
@@ -832,8 +825,8 @@
     sql::Statement copy_keychain_identifier(db->GetUniqueStatement(
         "UPDATE logins SET keychain_identifier = password_value"));
     if (!copy_keychain_identifier.Run()) {
-      RecordMigrationToOSCryptStatus(
-          MigrationToOSCrypt::kFailedToCopyPasswordColumn);
+      std::move(record_completion_metrics)
+          .Run(MigrationToOSCrypt::kFailedToCopyPasswordColumn);
       return false;
     }
     sql::Statement get_passwords_statement(
@@ -846,8 +839,8 @@
       std::u16string plaintext_password;
       if (!GetTextFromKeychainIdentifier(
               get_passwords_statement.ColumnString(1), &plaintext_password)) {
-        RecordMigrationToOSCryptStatus(
-            MigrationToOSCrypt::kFailedToDecryptFromKeychain);
+        std::move(record_completion_metrics)
+            .Run(MigrationToOSCrypt::kFailedToDecryptFromKeychain);
         return false;
       }
       // Encrypt password using OSCrypt.
@@ -855,7 +848,8 @@
       if (LoginDatabase::EncryptedString(plaintext_password,
                                          &encrypted_password) !=
           LoginDatabase::ENCRYPTION_RESULT_SUCCESS) {
-        RecordMigrationToOSCryptStatus(MigrationToOSCrypt::kFailedToEncrypt);
+        std::move(record_completion_metrics)
+            .Run(MigrationToOSCrypt::kFailedToEncrypt);
         return false;
       }
       // Updated password_value in the database.
@@ -864,11 +858,12 @@
       password_value_update.BindBlob(0, encrypted_password);
       password_value_update.BindInt(1, id);
       if (!password_value_update.Run()) {
-        RecordMigrationToOSCryptStatus(MigrationToOSCrypt::kFailedToUpdate);
+        std::move(record_completion_metrics)
+            .Run(MigrationToOSCrypt::kFailedToUpdate);
         return false;
       }
     }
-    RecordMigrationToOSCryptStatus(MigrationToOSCrypt::kSuccess);
+    std::move(record_completion_metrics).Run(MigrationToOSCrypt::kSuccess);
   }
 #endif
 
@@ -1055,8 +1050,9 @@
 
   // If the file on disk is an older database version, bring it up to date.
   if (migration_success && current_version < kCurrentVersionNumber) {
-    migration_success = MigrateDatabase(
-        base::checked_cast<unsigned>(current_version), builders, &db_);
+    migration_success =
+        MigrateDatabase(base::checked_cast<unsigned>(current_version), builders,
+                        is_account_store_, &db_);
   }
   // Enforce that 'insecure_credentials' is created only after the 'logins'
   // table was created and migrated to the latest version. This guarantees the
diff --git a/components/password_manager/core/browser/login_database_ios_unittest.cc b/components/password_manager/core/browser/login_database_ios_unittest.cc
index cad8fa80..5bbc55c 100644
--- a/components/password_manager/core/browser/login_database_ios_unittest.cc
+++ b/components/password_manager/core/browser/login_database_ios_unittest.cc
@@ -14,10 +14,13 @@
 #include "base/apple/scoped_cftyperef.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/path_service.h"
+#include "base/strings/strcat.h"
 #include "base/strings/sys_string_conversions.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "components/password_manager/core/browser/password_form.h"
+#include "components/password_manager/core/browser/password_manager_metrics_util.h"
 #include "components/password_manager/core/common/passwords_directory_util_ios.h"
 #include "sql/database.h"
 #include "sql/statement.h"
@@ -26,9 +29,32 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "testing/platform_test.h"
 
+using base::Bucket;
 using base::UTF16ToUTF8;
 using base::apple::ScopedCFTypeRef;
+using password_manager::metrics_util::MigrationToOSCrypt;
 
+namespace {
+void ExpectSuccessMetricsRecorded(
+    const base::HistogramTester& histogram_tester,
+    password_manager::IsAccountStore is_account_store) {
+  base::StringPiece store_infix =
+      is_account_store ? "AccountStore" : "ProfileStore";
+
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples("PasswordManager.MigrationToOSCrypt"),
+      BucketsInclude(Bucket(MigrationToOSCrypt::kStarted, 1),
+                     Bucket(MigrationToOSCrypt::kSuccess, 1)));
+  EXPECT_THAT(histogram_tester.GetAllSamples(base::StrCat(
+                  {"PasswordManager.MigrationToOSCrypt.", store_infix})),
+              BucketsInclude(Bucket(MigrationToOSCrypt::kStarted, 1),
+                             Bucket(MigrationToOSCrypt::kSuccess, 1)));
+  histogram_tester.ExpectTotalCount(
+      base::StrCat({"PasswordManager.MigrationToOSCrypt.", store_infix,
+                    ".SuccessLatency"}),
+      1);
+}
+}  // namespace
 namespace password_manager {
 
 class LoginDatabaseIOSTest : public PlatformTest {
@@ -262,6 +288,15 @@
     return results;
   }
 
+  void ReplacePasswordValueWithWrongKeychainIds() {
+    sql::Database db;
+    CHECK(db.Open(get_database_path()));
+    sql::Statement set_wrong_password_value(db.GetCachedStatement(
+        SQL_FROM_HERE,
+        "UPDATE logins SET password_value = 'invalid_keychain_id'"));
+    ASSERT_TRUE(set_wrong_password_value.Run());
+  }
+
   base::FilePath get_database_path() { return database_path_; }
 
  private:
@@ -271,7 +306,7 @@
 
 // Tests the migration of the login database from version() to
 // kCurrentVersionNumber.
-TEST_F(LoginDatabaseMigrationToOSCryptTest, MigrationToVersion39) {
+TEST_F(LoginDatabaseMigrationToOSCryptTest, MigrationToVersion39ProfileStore) {
   // Keychain identifier used in the test file.
   const std::string password_keychain_identifier =
       "2572a7dc-5046-429b-b8d4-3696f87dc9c2";
@@ -286,8 +321,12 @@
   {
     // Assert that the database was successfully opened and updated
     // to current version.
+    base::HistogramTester histogram_tester;
     LoginDatabase db(get_database_path(), IsAccountStore(false));
     ASSERT_TRUE(db.Init());
+
+    ExpectSuccessMetricsRecorded(histogram_tester, IsAccountStore(false));
+
     // Delete password from the keychain to check that GetAllLogins no longer
     // needs to access it.
     DeleteEncryptedPasswordFromKeychain(password_keychain_identifier);
@@ -312,9 +351,125 @@
         LoginDatabase::EncryptedString(u"test1", &expected_encrypted_password));
     EXPECT_EQ(password_values[0], expected_encrypted_password);
   }
+
   // Clear item from the keychain to ensure this test doesn't affect other
   // tests.
   DeleteEncryptedPasswordFromKeychain(note_keychain_identifier);
 }
 
+TEST_F(LoginDatabaseMigrationToOSCryptTest,
+       MigrationToVersion39SuccessMetricsAccountStore) {
+  CreateDatabase("login_db_v38_with_keychain_id.sql");
+
+  sql::Database db;
+  CHECK(db.Open(get_database_path()));
+  // The values set in the .sql file above are already in use by the previous
+  // test. Since tests can run in parallel, the IDs need to be different to
+  // avoid collisions. The following statements replace the existing IDs with
+  // new ones.
+  sql::Statement set_password_value(
+      db.GetCachedStatement(SQL_FROM_HERE,
+                            "UPDATE logins SET password_value = "
+                            "X'"
+                            "33353732613764632D353034362D343239622D623864342D33"
+                            "3639366638376463396332'"));
+  ASSERT_TRUE(set_password_value.Run());
+
+  // Sets the keychain id matching `note_keychain_identifier` so
+  // that the lookup is successful when trying to migrate.
+  sql::Statement set_note_value(
+      db.GetCachedStatement(SQL_FROM_HERE,
+                            "UPDATE password_notes SET value = "
+                            "X'"
+                            "39646263653933652D333761392D346339662D616136612D34"
+                            "3538313263343834626333'"));
+  ASSERT_TRUE(set_note_value.Run());
+
+  // Keychain identifiers matching the updated db IDs above.
+  const std::string password_keychain_identifier =
+      "3572a7dc-5046-429b-b8d4-3696f87dc9c2";
+  const std::string note_keychain_identifier =
+      "9dbce93e-37a9-4c9f-aa6a-45812c484bc3";
+
+  // Add password and note to the keychain.
+  AddItemToKeychain(u"test1", password_keychain_identifier);
+  AddItemToKeychain(u"password note", note_keychain_identifier);
+
+  // Assert that the database was successfully opened and updated
+  // to current version.
+  base::HistogramTester histogram_tester;
+  LoginDatabase login_db(get_database_path(), IsAccountStore(true));
+  ASSERT_TRUE(login_db.Init());
+
+  ExpectSuccessMetricsRecorded(histogram_tester, IsAccountStore(true));
+
+  // Delete password from the keychain to check that GetAllLogins no longer
+  // needs to access it.
+  DeleteEncryptedPasswordFromKeychain(password_keychain_identifier);
+
+  // Clear item from the keychain to ensure this test doesn't affect other
+  // tests.
+  DeleteEncryptedPasswordFromKeychain(note_keychain_identifier);
+}
+
+TEST_F(LoginDatabaseMigrationToOSCryptTest,
+       MigrationToV39FailureMetricsProfileStore) {
+  base::HistogramTester histogram_tester;
+
+  CreateDatabase("login_db_v38_with_keychain_id.sql");
+
+  // Ensure that the password entry in the db contain invalid keychain ids
+  // so that the migration will fail.
+  ReplacePasswordValueWithWrongKeychainIds();
+
+  LoginDatabase login_db(get_database_path(), IsAccountStore(false));
+  ASSERT_FALSE(login_db.Init());
+
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples("PasswordManager.MigrationToOSCrypt"),
+      BucketsInclude(
+          Bucket(MigrationToOSCrypt::kStarted, 1),
+          Bucket(MigrationToOSCrypt::kFailedToDecryptFromKeychain, 1)));
+  EXPECT_THAT(histogram_tester.GetAllSamples(
+                  "PasswordManager.MigrationToOSCrypt.ProfileStore"),
+              BucketsInclude(
+                  Bucket(MigrationToOSCrypt::kStarted, 1),
+                  Bucket(MigrationToOSCrypt::kFailedToDecryptFromKeychain, 1)));
+
+  histogram_tester.ExpectTotalCount(
+      "PasswordManager.MigrationToOSCrypt.ProfileStore.SuccessLatency", 0);
+  histogram_tester.ExpectTotalCount(
+      "PasswordManager.MigrationToOSCrypt.ProfileStore.ErrorLatency", 1);
+}
+
+TEST_F(LoginDatabaseMigrationToOSCryptTest,
+       MigrationToV39FailureMetricsAccountStore) {
+  base::HistogramTester histogram_tester;
+
+  CreateDatabase("login_db_v38_with_keychain_id.sql");
+
+  // Ensure that the password entries in the db contain invalid keychain ids
+  // so that the migration will fail.
+  ReplacePasswordValueWithWrongKeychainIds();
+
+  LoginDatabase login_db(get_database_path(), IsAccountStore(true));
+  ASSERT_FALSE(login_db.Init());
+
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples("PasswordManager.MigrationToOSCrypt"),
+      BucketsInclude(
+          Bucket(MigrationToOSCrypt::kStarted, 1),
+          Bucket(MigrationToOSCrypt::kFailedToDecryptFromKeychain, 1)));
+  EXPECT_THAT(histogram_tester.GetAllSamples(
+                  "PasswordManager.MigrationToOSCrypt.AccountStore"),
+              BucketsInclude(
+                  Bucket(MigrationToOSCrypt::kStarted, 1),
+                  Bucket(MigrationToOSCrypt::kFailedToDecryptFromKeychain, 1)));
+
+  histogram_tester.ExpectTotalCount(
+      "PasswordManager.MigrationToOSCrypt.AccountStore.SuccessLatency", 0);
+  histogram_tester.ExpectTotalCount(
+      "PasswordManager.MigrationToOSCrypt.AccountStore.ErrorLatency", 1);
+}
+
 }  // namespace password_manager
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.cc b/components/password_manager/core/browser/password_manager_metrics_util.cc
index 91eab03..7b046d4 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.cc
+++ b/components/password_manager/core/browser/password_manager_metrics_util.cc
@@ -405,4 +405,39 @@
       interaction);
 }
 
+#if BUILDFLAG(IS_IOS)
+void RecordMigrationToOSCryptLatency(bool success,
+                                     base::TimeDelta latency,
+                                     base::StringPiece store_infix) {
+  if (success) {
+    base::UmaHistogramLongTimes(
+        base::StrCat({"PasswordManager.MigrationToOSCrypt.", store_infix,
+                      ".SuccessLatency"}),
+        latency);
+    return;
+  }
+  base::UmaHistogramLongTimes(
+      base::StrCat({"PasswordManager.MigrationToOSCrypt.", store_infix,
+                    ".ErrorLatency"}),
+      latency);
+}
+
+void RecordMigrationToOSCryptStatus(base::TimeTicks migration_start_time,
+                                    bool is_account_store,
+                                    MigrationToOSCrypt status) {
+  base::StringPiece infix_for_store =
+      is_account_store ? "AccountStore" : "ProfileStore";
+  if (status != MigrationToOSCrypt::kStarted) {
+    RecordMigrationToOSCryptLatency(
+        status == MigrationToOSCrypt::kSuccess,
+        base::TimeTicks::Now() - migration_start_time, infix_for_store);
+  }
+
+  base::UmaHistogramEnumeration("PasswordManager.MigrationToOSCrypt", status);
+  base::UmaHistogramEnumeration(
+      base::StrCat({"PasswordManager.MigrationToOSCrypt.", infix_for_store}),
+      status);
+}
+#endif  // BUILDFLAG(IS_IOS)
+
 }  // namespace password_manager::metrics_util
diff --git a/components/password_manager/core/browser/password_manager_metrics_util.h b/components/password_manager/core/browser/password_manager_metrics_util.h
index aa0e227..2bdadde 100644
--- a/components/password_manager/core/browser/password_manager_metrics_util.h
+++ b/components/password_manager/core/browser/password_manager_metrics_util.h
@@ -908,6 +908,38 @@
       histogram, base::ElapsedTimer(), std::move(callback));
 }
 
+#if BUILDFLAG(IS_IOS)
+// This enum indicates migration status from Keychain to OSCrypt on iOS in the
+// version 39.
+//
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
+//
+// Needs to stay in sync with PasswordManagerMatchedFormType in
+// enums.xml.
+enum class MigrationToOSCrypt {
+  kStarted = 0,
+  kFailedToCopyPasswordColumn = 1,
+  kFailedToDecryptFromKeychain = 2,
+  kFailedToEncrypt = 3,
+  kFailedToUpdate = 4,
+  kSuccess = 5,
+  kMaxValue = kSuccess,
+};
+
+// Records the latency of the migration to OSCrypt of the login db on iOS
+// separated by password store type and whether the migration was successful or
+// not.
+void RecordMigrationToOSCryptLatency(bool success,
+                                     base::TimeDelta latency,
+                                     base::StringPiece store_infix);
+
+// Records the status of the migration to OSCrypt of the login db on iOS
+// separated by password store type.
+void RecordMigrationToOSCryptStatus(base::TimeTicks migration_start_time,
+                                    bool is_account_store,
+                                    MigrationToOSCrypt status);
+#endif
 }  // namespace password_manager::metrics_util
 
 #endif  // COMPONENTS_PASSWORD_MANAGER_CORE_BROWSER_PASSWORD_MANAGER_METRICS_UTIL_H_
diff --git a/components/performance_manager/metrics/tab_revisit_tracker.cc b/components/performance_manager/metrics/tab_revisit_tracker.cc
index 7481dca1..7c034a5 100644
--- a/components/performance_manager/metrics/tab_revisit_tracker.cc
+++ b/components/performance_manager/metrics/tab_revisit_tracker.cc
@@ -4,8 +4,13 @@
 
 #include "components/performance_manager/public/metrics/tab_revisit_tracker.h"
 
+#include <algorithm>
+
 #include "base/check.h"
 #include "base/metrics/histogram_functions.h"
+#include "services/metrics/public/cpp/metrics_utils.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
+#include "services/metrics/public/cpp/ukm_recorder.h"
 
 namespace performance_manager {
 
@@ -13,6 +18,14 @@
 
 constexpr base::TimeDelta kMinTime = base::TimeDelta();
 constexpr base::TimeDelta kMaxTime = base::Hours(48);
+constexpr int64_t kMaxNumRevisit = 20;
+// Choosing a bucket spacing of 1.1 because it roughly matches the spacing of
+// the 200 buckets, capped at 48 hours close/revisit histograms.
+constexpr double kTimeBucketSpacing = 1.1;
+
+int64_t GetLinearCappedBucket(int64_t sample, int64_t max) {
+  return std::min(sample, max);
+}
 
 }  // namespace
 
@@ -47,6 +60,50 @@
       /*buckets=*/200);
 }
 
+void TabRevisitTracker::RecordStateChangeUkm(
+    const TabPageDecorator::TabHandle* tab_handle,
+    State new_state) {
+  ukm::builders::TabRevisitTracker_TabStateChange builder(
+      tab_handle->page_node()->GetUkmSourceID());
+
+  StateBundle& bundle = tab_states_.at(tab_handle);
+
+  if (new_state == State::kActive) {
+    ++bundle.num_revisits;
+  }
+
+  builder.SetPreviousState(StateToSample(bundle.state))
+      .SetNewState(StateToSample(new_state))
+      .SetNumTotalRevisits(
+          GetLinearCappedBucket(bundle.num_revisits, kMaxNumRevisit))
+      .SetTimeInPreviousState(ExponentiallyBucketedSeconds(
+          base::TimeTicks::Now() - bundle.last_state_change_time));
+
+  builder.Record(ukm::UkmRecorder::Get());
+
+  bundle.state = new_state;
+  bundle.last_state_change_time = base::TimeTicks::Now();
+}
+
+int64_t TabRevisitTracker::StateToSample(TabRevisitTracker::State state) {
+  // The UKM doesn't report discarded tabs, instead treating them as in the
+  // background.
+  if (state == TabRevisitTracker::State::kDiscarded) {
+    state = TabRevisitTracker::State::kBackground;
+  }
+  CHECK_LE(state, TabRevisitTracker::State::kClosed);
+  return static_cast<int64_t>(state);
+}
+
+// static
+int64_t TabRevisitTracker::ExponentiallyBucketedSeconds(base::TimeDelta time) {
+  // Cap the reported time at 48 hours, effectively making the 48 hour bucket
+  // the overflow bucket.
+  int64_t seconds = std::min(time, kMaxTime).InSeconds();
+
+  return ukm::GetExponentialBucketMin(seconds, kTimeBucketSpacing);
+}
+
 void TabRevisitTracker::OnPassedToGraph(Graph* graph) {
   TabPageDecorator* tab_page_decorator =
       graph->GetRegisteredObjectAs<TabPageDecorator>();
@@ -79,6 +136,7 @@
     // spent in the background and this tab is already in the background.
     tab_states_[tab_handle].last_active_time = base::TimeTicks::Now();
   }
+  tab_states_[tab_handle].last_state_change_time = base::TimeTicks::Now();
 }
 
 void TabRevisitTracker::OnTabAboutToBeDiscarded(
@@ -110,11 +168,13 @@
   live_state_data->RemoveObserver(this);
 
   // Don't record the histograms if this is the active tab. We only care about
-  // background tabs being closed.
+  // background tabs being closed in that histogram.
   if (!live_state_data->IsActiveTab()) {
     RecordCloseHistograms(tab_handle);
   }
 
+  RecordStateChangeUkm(tab_handle, State::kClosed);
+
   tab_states_.erase(tab_handle);
 }
 
@@ -129,12 +189,14 @@
 
   if (live_state_data->IsActiveTab()) {
     CHECK_NE(tab_states_[tab_handle].state, State::kActive);
+    RecordStateChangeUkm(tab_handle, State::kActive);
     tab_states_[tab_handle].state = State::kActive;
     RecordRevisitHistograms(tab_handle);
   } else {
     CHECK_NE(tab_states_[tab_handle].state, State::kBackground);
-    tab_states_[tab_handle].state = State::kBackground;
     tab_states_[tab_handle].last_active_time = base::TimeTicks::Now();
+    RecordStateChangeUkm(tab_handle, State::kBackground);
+    tab_states_[tab_handle].state = State::kBackground;
   }
 }
 
diff --git a/components/performance_manager/metrics/tab_revisit_tracker_unittest.cc b/components/performance_manager/metrics/tab_revisit_tracker_unittest.cc
index 50ef462..a143d37 100644
--- a/components/performance_manager/metrics/tab_revisit_tracker_unittest.cc
+++ b/components/performance_manager/metrics/tab_revisit_tracker_unittest.cc
@@ -13,9 +13,18 @@
 #include "components/performance_manager/public/graph/page_node.h"
 #include "components/performance_manager/test_support/graph_test_harness.h"
 #include "components/performance_manager/test_support/mock_graphs.h"
+#include "components/ukm/test_ukm_recorder.h"
+#include "services/metrics/public/cpp/ukm_builders.h"
 
 namespace performance_manager {
 
+// Hard-coding these constants instead of using `static_cast` on the
+// `TabRevisitTracker::State` enum to guard against changes to the enum that
+// would make it out of sync with the enums.xml entry.
+constexpr int64_t kActiveState = 0;
+constexpr int64_t kBackgroundState = 1;
+constexpr int64_t kClosedState = 2;
+
 class TabRevisitTrackerTest : public GraphTestHarness {
  protected:
   void SetUp() override {
@@ -23,6 +32,8 @@
 
     graph()->PassToGraph(std::make_unique<TabPageDecorator>());
     graph()->PassToGraph(std::make_unique<TabRevisitTracker>());
+
+    test_ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
   }
 
   void SetIsActiveTab(const PageNode* page_node, bool is_active) {
@@ -30,6 +41,30 @@
         PageLiveStateDecorator::Data::GetOrCreateForPageNode(page_node);
     data->SetIsActiveTabForTesting(is_active);
   }
+
+  void ValidateEntry(size_t entries_count,
+                     size_t entry_id,
+                     int64_t previous_state,
+                     int64_t new_state,
+                     int64_t num_total_revisits,
+                     base::TimeDelta time_in_previous_state) {
+    auto entries = test_ukm_recorder_->GetEntriesByName(
+        ukm::builders::TabRevisitTracker_TabStateChange::kEntryName);
+    EXPECT_EQ(entries.size(), entries_count);
+    EXPECT_GT(entries.size(), entry_id);
+    test_ukm_recorder_->ExpectEntryMetric(entries[entry_id], "NewState",
+                                          new_state);
+    test_ukm_recorder_->ExpectEntryMetric(entries[entry_id], "PreviousState",
+                                          previous_state);
+    test_ukm_recorder_->ExpectEntryMetric(entries[entry_id], "NumTotalRevisits",
+                                          num_total_revisits);
+    test_ukm_recorder_->ExpectEntryMetric(
+        entries[entry_id], "TimeInPreviousState",
+        TabRevisitTracker::ExponentiallyBucketedSeconds(
+            time_in_previous_state));
+  }
+
+  std::unique_ptr<ukm::TestUkmRecorder> test_ukm_recorder_;
 };
 
 TEST_F(TabRevisitTrackerTest, StartsBackgroundedThenRevisited) {
@@ -53,10 +88,22 @@
   tester.ExpectUniqueSample(TabRevisitTracker::kTimeToRevisitHistogramName,
                             base::Minutes(30).InSeconds(), 1);
 
+  ValidateEntry(/*entries_count=*/1, /*entry_id=*/0,
+                /*previous_state=*/kBackgroundState,
+                /*new_state=*/kActiveState,
+                /*num_total_revisits=*/1,
+                /*time_in_previous_state=*/base::Minutes(30));
+
   SetIsActiveTab(mock_graph.page.get(), false);
   tester.ExpectUniqueSample(TabRevisitTracker::kTimeToRevisitHistogramName,
                             base::Minutes(30).InSeconds(), 1);
 
+  ValidateEntry(/*entries_count=*/2, /*entry_id=*/1,
+                /*previous_state=*/kActiveState,
+                /*new_state=*/kBackgroundState,
+                /*num_total_revisits=*/1,
+                /*time_in_previous_state=*/base::TimeDelta());
+
   AdvanceClock(base::Minutes(10));
   // The tab became active again after 10 minutes in the background, the revisit
   // histogram should contain 2 samples: one for each revisit.
@@ -66,6 +113,12 @@
                            base::Minutes(10).InSeconds(), 1);
 
   tester.ExpectTotalCount(TabRevisitTracker::kTimeToCloseHistogramName, 0);
+
+  ValidateEntry(/*entries_count=*/3, /*entry_id=*/2,
+                /*previous_state=*/kBackgroundState,
+                /*new_state=*/kActiveState,
+                /*num_total_revisits=*/2,
+                /*time_in_previous_state=*/base::Minutes(10));
 }
 
 TEST_F(TabRevisitTrackerTest, CloseInBackgroundRecordsToCloseHistogram) {
@@ -85,8 +138,15 @@
   mock_graph.page.reset();
 
   tester.ExpectTotalCount(TabRevisitTracker::kTimeToRevisitHistogramName, 0);
+
   tester.ExpectUniqueSample(TabRevisitTracker::kTimeToCloseHistogramName,
                             base::Hours(1).InSeconds(), 1);
+
+  ValidateEntry(/*entries_count=*/1, /*entry_id=*/0,
+                /*previous_state=*/kBackgroundState,
+                /*new_state=*/kClosedState,
+                /*num_total_revisits=*/0,
+                /*time_in_previous_state=*/base::Hours(1));
 }
 
 TEST_F(TabRevisitTrackerTest, CloseWhileActiveDoesntRecordClose) {
@@ -107,6 +167,12 @@
 
   tester.ExpectTotalCount(TabRevisitTracker::kTimeToRevisitHistogramName, 0);
   tester.ExpectTotalCount(TabRevisitTracker::kTimeToCloseHistogramName, 0);
+
+  ValidateEntry(/*entries_count=*/1, /*entry_id=*/0,
+                /*previous_state=*/kActiveState,
+                /*new_state=*/kClosedState,
+                /*num_total_revisits=*/0,
+                /*time_in_previous_state=*/base::Hours(1));
 }
 
 }  // namespace performance_manager
diff --git a/components/performance_manager/public/metrics/tab_revisit_tracker.h b/components/performance_manager/public/metrics/tab_revisit_tracker.h
index 8db56ba..49bf6d1 100644
--- a/components/performance_manager/public/metrics/tab_revisit_tracker.h
+++ b/components/performance_manager/public/metrics/tab_revisit_tracker.h
@@ -31,19 +31,33 @@
   ~TabRevisitTracker() override;
 
  private:
+  friend class TabRevisitTrackerTest;
+
   enum class State {
+    // The order of the leading elements must match the one in enums.xml
+    // `TabRevisitTracker.TabState`.
     kActive,
     kBackground,
+    kClosed,
+    // The following entries aren't present in enums.xml but they are used for
+    // internal tracking
     kDiscarded,
   };
 
   struct StateBundle {
     State state;
     absl::optional<base::TimeTicks> last_active_time;
+    base::TimeTicks last_state_change_time;
+    int64_t num_revisits;
   };
 
   void RecordRevisitHistograms(const TabPageDecorator::TabHandle* tab_handle);
   void RecordCloseHistograms(const TabPageDecorator::TabHandle* tab_handle);
+  void RecordStateChangeUkm(const TabPageDecorator::TabHandle* tab_handle,
+                            State new_state);
+
+  int64_t StateToSample(TabRevisitTracker::State state);
+  static int64_t ExponentiallyBucketedSeconds(base::TimeDelta time);
 
   // GraphOwned:
   void OnPassedToGraph(Graph* graph) override;
diff --git a/components/power_bookmarks/storage/power_bookmark_backend.cc b/components/power_bookmarks/storage/power_bookmark_backend.cc
index 2ba950e..f6db588b 100644
--- a/components/power_bookmarks/storage/power_bookmark_backend.cc
+++ b/components/power_bookmarks/storage/power_bookmark_backend.cc
@@ -64,6 +64,9 @@
 
 base::WeakPtr<syncer::ModelTypeControllerDelegate>
 PowerBookmarkBackend::GetSyncControllerDelegate() {
+  if (!bridge_ && bridge_->initialized()) {
+    return nullptr;
+  }
   return bridge_->change_processor()->GetControllerDelegate();
 }
 
diff --git a/components/services/screen_ai/screen_ai_ax_tree_serializer.cc b/components/services/screen_ai/screen_ai_ax_tree_serializer.cc
index ecd8182..6f921bd 100644
--- a/components/services/screen_ai/screen_ai_ax_tree_serializer.cc
+++ b/components/services/screen_ai/screen_ai_ax_tree_serializer.cc
@@ -43,7 +43,8 @@
   tree_source_ = base::WrapUnique<ui::AXTreeSource<const ui::AXNode*>>(
       tree_->CreateTreeSource());
   DCHECK(tree_source_);
-  serializer_ = std::make_unique<ui::AXTreeSerializer<const ui::AXNode*>>(
+  serializer_ = std::make_unique<
+      ui::AXTreeSerializer<const ui::AXNode*, std::vector<const ui::AXNode*>>>(
       tree_source_.get(), /* crash_on_error */ true);
 }
 
diff --git a/components/services/screen_ai/screen_ai_ax_tree_serializer.h b/components/services/screen_ai/screen_ai_ax_tree_serializer.h
index e5226988..38fd5e2 100644
--- a/components/services/screen_ai/screen_ai_ax_tree_serializer.h
+++ b/components/services/screen_ai/screen_ai_ax_tree_serializer.h
@@ -41,7 +41,9 @@
  private:
   const std::unique_ptr<ui::AXSerializableTree> tree_;
   std::unique_ptr<ui::AXTreeSource<const ui::AXNode*>> tree_source_;
-  mutable std::unique_ptr<ui::AXTreeSerializer<const ui::AXNode*>> serializer_;
+  mutable std::unique_ptr<
+      ui::AXTreeSerializer<const ui::AXNode*, std::vector<const ui::AXNode*>>>
+      serializer_;
 };
 
 }  // namespace screen_ai
diff --git a/components/unexportable_keys/service_error.h b/components/unexportable_keys/service_error.h
index cc426ef..07a810d 100644
--- a/components/unexportable_keys/service_error.h
+++ b/components/unexportable_keys/service_error.h
@@ -10,22 +10,32 @@
 namespace unexportable_keys {
 
 // Various errors returned by this component.
+// These values are persisted to logs. Entries should not be renumbered and
+// numeric values should never be reused.
 enum class ServiceError {
+  // Reserved for histograms.
+  // kNone = 0
   // crypto:: operation returned an error.
-  kCryptoApiFailed,
+  kCryptoApiFailed = 1,
   // Provided key ID is unknown and doesn't correspond to any key.
-  kKeyNotFound,
+  kKeyNotFound = 2,
   // Newly generated key is the same as the existing one (should be extremely
   // rare).
-  kKeyCollision,
+  kKeyCollision = 3,
   // Unexportable key provider is not available on this platform.
-  kNoKeyProvider,
+  kNoKeyProvider = 4,
   // None of the requested algorithms are supported by the key provider.
-  kAlgorithmNotSupported,
+  kAlgorithmNotSupported = 5,
   // The key object hasn't been created yet. Try again later.
-  kKeyNotReady,
+  kKeyNotReady = 6,
+
+  kMaxValue = kKeyNotReady
 };
 
+// Fake `ServiceError` value that can be used for metrics to signify that no
+// error has occurred.
+constexpr ServiceError kNoServiceErrorForMetrics = static_cast<ServiceError>(0);
+
 // Return value for methods which perform unexportable keys operations that may
 // fail. Either contains a `ServiceError` or a result value of arbitrary type.
 template <class Result>
diff --git a/components/unexportable_keys/unexportable_key_task_manager.cc b/components/unexportable_keys/unexportable_key_task_manager.cc
index 748964d..82b5140 100644
--- a/components/unexportable_keys/unexportable_key_task_manager.cc
+++ b/components/unexportable_keys/unexportable_key_task_manager.cc
@@ -10,6 +10,8 @@
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/no_destructor.h"
 #include "base/task/single_thread_task_runner_thread_mode.h"
 #include "base/task/task_traits.h"
 #include "base/task/thread_pool.h"
@@ -17,6 +19,7 @@
 #include "components/unexportable_keys/background_long_task_scheduler.h"
 #include "components/unexportable_keys/background_task_priority.h"
 #include "components/unexportable_keys/ref_counted_unexportable_signing_key.h"
+#include "components/unexportable_keys/service_error.h"
 #include "components/unexportable_keys/unexportable_key_id.h"
 #include "components/unexportable_keys/unexportable_key_tasks.h"
 #include "crypto/signature_verifier.h"
@@ -26,6 +29,12 @@
 namespace unexportable_keys {
 
 namespace {
+
+constexpr std::string_view kBaseTaskResultHistogramName =
+    "Crypto.UnexportableKeys.BackgroundTaskResult";
+
+enum class TaskType { kGenerateKey, kFromWrappedKey, kSign };
+
 ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>
 MakeSigningKeyRefCounted(std::unique_ptr<crypto::UnexportableSigningKey> key) {
   if (!key) {
@@ -45,6 +54,44 @@
   return result.value();
 }
 
+std::string GetTaskResultHistogramNameForTaskType(TaskType type) {
+  std::string_view histogram_suffix;
+  switch (type) {
+    case TaskType::kGenerateKey:
+      histogram_suffix = ".GenerateKey";
+      break;
+    case TaskType::kFromWrappedKey:
+      histogram_suffix = ".FromWrappedKey";
+      break;
+    case TaskType::kSign:
+      histogram_suffix = ".Sign";
+      break;
+  }
+  return base::StrCat({kBaseTaskResultHistogramName, histogram_suffix});
+}
+
+template <class CallbackReturnType>
+ServiceErrorOr<CallbackReturnType> ReportResultMetrics(
+    TaskType task_type,
+    ServiceErrorOr<CallbackReturnType> result) {
+  ServiceError error_for_metrics =
+      result.has_value() ? kNoServiceErrorForMetrics : result.error();
+  base::UmaHistogramEnumeration(
+      GetTaskResultHistogramNameForTaskType(task_type), error_for_metrics);
+  return result;
+}
+
+// Returns a new callback that reports result metrics and then invokes the
+// original `callback`.
+template <class CallbackReturnType>
+base::OnceCallback<void(ServiceErrorOr<CallbackReturnType>)>
+WrapCallbackWithMetrics(
+    TaskType task_type,
+    base::OnceCallback<void(ServiceErrorOr<CallbackReturnType>)> callback) {
+  return base::BindOnce(&ReportResultMetrics<CallbackReturnType>, task_type)
+      .Then(std::move(callback));
+}
+
 }  // namespace
 
 UnexportableKeyTaskManager::UnexportableKeyTaskManager()
@@ -80,23 +127,28 @@
     base::OnceCallback<
         void(ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>)>
         callback) {
+  auto callback_wrapper =
+      WrapCallbackWithMetrics(TaskType::kGenerateKey, std::move(callback));
+
   std::unique_ptr<crypto::UnexportableKeyProvider> key_provider =
       GetUnexportableKeyProvider();
 
   if (!key_provider) {
-    std::move(callback).Run(base::unexpected(ServiceError::kNoKeyProvider));
+    std::move(callback_wrapper)
+        .Run(base::unexpected(ServiceError::kNoKeyProvider));
     return;
   }
 
   if (!key_provider->SelectAlgorithm(acceptable_algorithms).has_value()) {
-    std::move(callback).Run(
-        base::unexpected(ServiceError::kAlgorithmNotSupported));
+    std::move(callback_wrapper)
+        .Run(base::unexpected(ServiceError::kAlgorithmNotSupported));
     return;
   }
 
   auto task = std::make_unique<GenerateKeyTask>(
       std::move(key_provider), acceptable_algorithms, priority,
-      base::BindOnce(&MakeSigningKeyRefCounted).Then(std::move(callback)));
+      base::BindOnce(&MakeSigningKeyRefCounted)
+          .Then(std::move(callback_wrapper)));
   task_scheduler_.PostTask(std::move(task));
 }
 
@@ -106,17 +158,22 @@
     base::OnceCallback<
         void(ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>)>
         callback) {
+  auto callback_wrapper =
+      WrapCallbackWithMetrics(TaskType::kFromWrappedKey, std::move(callback));
+
   std::unique_ptr<crypto::UnexportableKeyProvider> key_provider =
       GetUnexportableKeyProvider();
 
   if (!key_provider) {
-    std::move(callback).Run(base::unexpected(ServiceError::kNoKeyProvider));
+    std::move(callback_wrapper)
+        .Run(base::unexpected(ServiceError::kNoKeyProvider));
     return;
   }
 
   auto task = std::make_unique<FromWrappedKeyTask>(
       std::move(key_provider), wrapped_key, priority,
-      base::BindOnce(&MakeSigningKeyRefCounted).Then(std::move(callback)));
+      base::BindOnce(&MakeSigningKeyRefCounted)
+          .Then(std::move(callback_wrapper)));
   task_scheduler_.PostTask(std::move(task));
 }
 
@@ -125,16 +182,22 @@
     base::span<const uint8_t> data,
     BackgroundTaskPriority priority,
     base::OnceCallback<void(ServiceErrorOr<std::vector<uint8_t>>)> callback) {
+  auto callback_wrapper =
+      WrapCallbackWithMetrics(TaskType::kSign, std::move(callback));
+
+  // TODO(alexilin): convert this to a CHECK().
   if (!signing_key) {
-    std::move(callback).Run(base::unexpected(ServiceError::kKeyNotFound));
+    std::move(callback_wrapper)
+        .Run(base::unexpected(ServiceError::kKeyNotFound));
     return;
   }
 
   // TODO(b/263249728): deduplicate tasks with the same parameters.
   // TODO(b/263249728): implement a cache of recent signings.
-  auto task = std::make_unique<SignTask>(
-      std::move(signing_key), data, priority,
-      base::BindOnce(&OptionalToServiceErrorOr).Then(std::move(callback)));
+  auto task =
+      std::make_unique<SignTask>(std::move(signing_key), data, priority,
+                                 base::BindOnce(&OptionalToServiceErrorOr)
+                                     .Then(std::move(callback_wrapper)));
   task_scheduler_.PostTask(std::move(task));
 }
 
diff --git a/components/unexportable_keys/unexportable_key_task_manager_unittest.cc b/components/unexportable_keys/unexportable_key_task_manager_unittest.cc
index 8fd6a57..7604ec2 100644
--- a/components/unexportable_keys/unexportable_key_task_manager_unittest.cc
+++ b/components/unexportable_keys/unexportable_key_task_manager_unittest.cc
@@ -5,6 +5,7 @@
 #include "components/unexportable_keys/unexportable_key_task_manager.h"
 
 #include "base/test/gmock_expected_support.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "base/token.h"
@@ -22,11 +23,23 @@
 
 namespace unexportable_keys {
 
+namespace {
+constexpr std::string_view kGenerateKeyTaskResultHistogramName =
+    "Crypto.UnexportableKeys.BackgroundTaskResult.GenerateKey";
+constexpr std::string_view kFromWrappedKeyTaskResultHistogramName =
+    "Crypto.UnexportableKeys.BackgroundTaskResult.FromWrappedKey";
+constexpr std::string_view kSignTaskResultHistogramName =
+    "Crypto.UnexportableKeys.BackgroundTaskResult.Sign";
+}  // namespace
+
 class UnexportableKeyTaskManagerTest : public testing::Test {
  public:
   UnexportableKeyTaskManagerTest() = default;
   ~UnexportableKeyTaskManagerTest() override = default;
 
+  const std::string kBaseTaskResultHistogramName =
+      "Crypto.UnexportableKeys.BackgroundTaskResult";
+
   void RunBackgroundTasks() { task_environment_.RunUntilIdle(); }
 
   UnexportableKeyTaskManager& task_manager() { return task_manager_; }
@@ -50,46 +63,65 @@
 };
 
 TEST_F(UnexportableKeyTaskManagerTest, GenerateKeyAsync) {
+  base::HistogramTester histogram_tester;
   base::test::TestFuture<
       ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>>
       future;
   auto supported_algorithm = {crypto::SignatureVerifier::ECDSA_SHA256};
+
   task_manager().GenerateSigningKeySlowlyAsync(
       supported_algorithm, BackgroundTaskPriority::kBestEffort,
       future.GetCallback());
   EXPECT_FALSE(future.IsReady());
   RunBackgroundTasks();
+
   EXPECT_TRUE(future.IsReady());
   EXPECT_THAT(future.Get(), base::test::ValueIs(::testing::NotNull()));
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples(kGenerateKeyTaskResultHistogramName),
+      testing::ElementsAre(base::Bucket(kNoServiceErrorForMetrics, 1)));
 }
 
 TEST_F(UnexportableKeyTaskManagerTest,
        GenerateKeyAsyncFailureUnsupportedAlgorithm) {
+  base::HistogramTester histogram_tester;
   base::test::TestFuture<
       ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>>
       future;
   // RSA is not supported by the mock key provider, so the key generation should
   // fail.
   auto unsupported_algorithm = {crypto::SignatureVerifier::RSA_PKCS1_SHA256};
+
   task_manager().GenerateSigningKeySlowlyAsync(
       unsupported_algorithm, BackgroundTaskPriority::kBestEffort,
       future.GetCallback());
   RunBackgroundTasks();
+
   EXPECT_EQ(future.Get(),
             base::unexpected(ServiceError::kAlgorithmNotSupported));
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples(kGenerateKeyTaskResultHistogramName),
+      testing::ElementsAre(
+          base::Bucket(ServiceError::kAlgorithmNotSupported, 1)));
 }
 
 TEST_F(UnexportableKeyTaskManagerTest, GenerateKeyAsyncFailureNoKeyProvider) {
-  DisableKeyProvider();
+  base::HistogramTester histogram_tester;
   base::test::TestFuture<
       ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>>
       future;
   auto supported_algorithm = {crypto::SignatureVerifier::ECDSA_SHA256};
+
+  DisableKeyProvider();
   task_manager().GenerateSigningKeySlowlyAsync(
       supported_algorithm, BackgroundTaskPriority::kBestEffort,
       future.GetCallback());
   RunBackgroundTasks();
+
   EXPECT_EQ(future.Get(), base::unexpected(ServiceError::kNoKeyProvider));
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples(kGenerateKeyTaskResultHistogramName),
+      testing::ElementsAre(base::Bucket(ServiceError::kNoKeyProvider, 1)));
 }
 
 TEST_F(UnexportableKeyTaskManagerTest, FromWrappedKeyAsync) {
@@ -107,14 +139,17 @@
   std::vector<uint8_t> wrapped_key = key->key().GetWrappedKey();
 
   // Second, unwrap the newly generated key.
+  base::HistogramTester histogram_tester;
   base::test::TestFuture<
       ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>>
       unwrap_key_future;
+
   task_manager().FromWrappedSigningKeySlowlyAsync(
       wrapped_key, BackgroundTaskPriority::kBestEffort,
       unwrap_key_future.GetCallback());
   EXPECT_FALSE(unwrap_key_future.IsReady());
   RunBackgroundTasks();
+
   EXPECT_TRUE(unwrap_key_future.IsReady());
   ASSERT_OK_AND_ASSIGN(auto unwrapped_key, unwrap_key_future.Get());
   EXPECT_NE(unwrapped_key, nullptr);
@@ -123,18 +158,27 @@
   // Public key should be the same for both keys.
   EXPECT_EQ(key->key().GetSubjectPublicKeyInfo(),
             unwrapped_key->key().GetSubjectPublicKeyInfo());
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples(kFromWrappedKeyTaskResultHistogramName),
+      testing::ElementsAre(base::Bucket(kNoServiceErrorForMetrics, 1)));
 }
 
 TEST_F(UnexportableKeyTaskManagerTest, FromWrappedKeyAsyncFailureEmptyKey) {
+  base::HistogramTester histogram_tester;
   base::test::TestFuture<
       ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>>
       future;
   std::vector<uint8_t> empty_wrapped_key;
+
   task_manager().FromWrappedSigningKeySlowlyAsync(
       empty_wrapped_key, BackgroundTaskPriority::kBestEffort,
       future.GetCallback());
   RunBackgroundTasks();
+
   EXPECT_EQ(future.Get(), base::unexpected(ServiceError::kCryptoApiFailed));
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples(kFromWrappedKeyTaskResultHistogramName),
+      testing::ElementsAre(base::Bucket(ServiceError::kCryptoApiFailed, 1)));
 }
 
 TEST_F(UnexportableKeyTaskManagerTest,
@@ -154,14 +198,20 @@
 
   // Second, emulate the key provider being not available and check that
   // `FromWrappedSigningKeySlowlyAsync()` returns a corresponding error.
-  DisableKeyProvider();
+  base::HistogramTester histogram_tester;
   base::test::TestFuture<
       ServiceErrorOr<scoped_refptr<RefCountedUnexportableSigningKey>>>
       future;
+
+  DisableKeyProvider();
   task_manager().FromWrappedSigningKeySlowlyAsync(
       wrapped_key, BackgroundTaskPriority::kBestEffort, future.GetCallback());
   RunBackgroundTasks();
+
   EXPECT_EQ(future.Get(), base::unexpected(ServiceError::kNoKeyProvider));
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples(kFromWrappedKeyTaskResultHistogramName),
+      testing::ElementsAre(base::Bucket(ServiceError::kNoKeyProvider, 1)));
 }
 
 TEST_F(UnexportableKeyTaskManagerTest, SignAsync) {
@@ -177,6 +227,7 @@
   ASSERT_OK_AND_ASSIGN(auto key, generate_key_future.Get());
 
   // Second, sign some data with the key.
+  base::HistogramTester histogram_tester;
   base::test::TestFuture<ServiceErrorOr<std::vector<uint8_t>>> sign_future;
   std::vector<uint8_t> data = {4, 8, 15, 16, 23, 42};
   task_manager().SignSlowlyAsync(key, data, BackgroundTaskPriority::kBestEffort,
@@ -185,6 +236,8 @@
   RunBackgroundTasks();
   EXPECT_TRUE(sign_future.IsReady());
   ASSERT_OK_AND_ASSIGN(const auto signed_data, sign_future.Get());
+  EXPECT_THAT(histogram_tester.GetAllSamples(kSignTaskResultHistogramName),
+              testing::ElementsAre(base::Bucket(kNoServiceErrorForMetrics, 1)));
 
   // Also verify that the signature was generated correctly.
   crypto::SignatureVerifier verifier;
@@ -195,13 +248,19 @@
 }
 
 TEST_F(UnexportableKeyTaskManagerTest, SignAsyncNullKey) {
+  base::HistogramTester histogram_tester;
   base::test::TestFuture<ServiceErrorOr<std::vector<uint8_t>>> sign_future;
   std::vector<uint8_t> data = {4, 8, 15, 16, 23, 42};
+
   task_manager().SignSlowlyAsync(nullptr, data,
                                  BackgroundTaskPriority::kBestEffort,
                                  sign_future.GetCallback());
   RunBackgroundTasks();
+
   EXPECT_EQ(sign_future.Get(), base::unexpected(ServiceError::kKeyNotFound));
+  EXPECT_THAT(
+      histogram_tester.GetAllSamples(kSignTaskResultHistogramName),
+      testing::ElementsAre(base::Bucket(ServiceError::kKeyNotFound, 1)));
 }
 
 }  // namespace unexportable_keys
diff --git a/components/vector_icons/history_chrome_refresh.icon b/components/vector_icons/history_chrome_refresh.icon
index a8c3f090..1defbdf25 100644
--- a/components/vector_icons/history_chrome_refresh.icon
+++ b/components/vector_icons/history_chrome_refresh.icon
@@ -3,41 +3,39 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 7.99f, 13.73f,
-R_CUBIC_TO, -1.59f, 0, -2.94f, -0.55f, -4.06f, -1.67f,
-CUBIC_TO, 2.81f, 10.95f, 2.26f, 9.59f, 2.26f, 8,
-H_LINE_TO, 3.64f,
-R_CUBIC_TO, 0, 1.2f, 0.43f, 2.22f, 1.28f, 3.07f,
-R_CUBIC_TO, 0.85f, 0.85f, 1.88f, 1.28f, 3.07f, 1.28f,
-R_CUBIC_TO, 1.2f, 0, 2.22f, -0.43f, 3.07f, -1.28f,
-R_CUBIC_TO, 0.85f, -0.85f, 1.28f, -1.87f, 1.28f, -3.07f,
-R_CUBIC_TO, 0, -1.2f, -0.43f, -2.22f, -1.28f, -3.07f,
-R_CUBIC_TO, -0.85f, -0.85f, -1.87f, -1.28f, -3.07f, -1.28f,
-R_CUBIC_TO, -0.66f, 0, -1.26f, 0.13f, -1.83f, 0.39f,
-ARC_TO, 4.16f, 4.16f, 0, 0, 0, 4.73f, 5.13f,
-R_H_LINE_TO, 1.67f,
-R_V_LINE_TO, 1.26f,
-H_LINE_TO, 2.3f,
-V_LINE_TO, 2.3f,
-R_H_LINE_TO, 1.26f,
-R_V_LINE_TO, 2.11f,
-ARC_TO, 5.75f, 5.75f, 0, 0, 1, 5.49f, 2.84f,
-R_ARC_TO, 5.51f, 5.51f, 0, 0, 1, 2.5f, -0.57f,
-R_CUBIC_TO, 0.79f, 0, 1.54f, 0.15f, 2.24f, 0.45f,
-R_CUBIC_TO, 0.7f, 0.3f, 1.3f, 0.71f, 1.82f, 1.23f,
-R_ARC_TO, 5.77f, 5.77f, 0, 0, 1, 1.23f, 1.82f,
-R_CUBIC_TO, 0.31f, 0.7f, 0.45f, 1.44f, 0.45f, 2.24f,
-R_CUBIC_TO, 0, 0.79f, -0.15f, 1.54f, -0.45f, 2.23f,
-R_CUBIC_TO, -0.3f, 0.7f, -0.71f, 1.31f, -1.23f, 1.82f,
-R_ARC_TO, 5.77f, 5.77f, 0, 0, 1, -1.82f, 1.23f,
-R_ARC_TO, 5.51f, 5.51f, 0, 0, 1, -2.23f, 0.45f,
+MOVE_TO, 7.98f, 13.92f,
+R_CUBIC_TO, -1.64f, 0, -3.04f, -0.57f, -4.19f, -1.72f,
+CUBIC_TO, 2.64f, 11.05f, 2.06f, 9.65f, 2.07f, 8,
+R_H_LINE_TO, 1.63f,
+R_CUBIC_TO, 0, 1.18f, 0.43f, 2.19f, 1.26f, 3.03f,
+R_CUBIC_TO, 0.84f, 0.84f, 1.84f, 1.26f, 3.02f, 1.26f,
+R_CUBIC_TO, 1.18f, 0, 2.19f, -0.42f, 3.03f, -1.26f,
+R_CUBIC_TO, 0.84f, -0.84f, 1.26f, -1.85f, 1.26f, -3.03f,
+R_CUBIC_TO, 0, -1.18f, -0.42f, -2.19f, -1.26f, -3.03f,
+R_CUBIC_TO, -0.84f, -0.84f, -1.85f, -1.26f, -3.03f, -1.26f,
+R_CUBIC_TO, -0.61f, 0, -1.19f, 0.11f, -1.72f, 0.34f,
+R_CUBIC_TO, -0.53f, 0.23f, -0.99f, 0.56f, -1.37f, 0.98f,
+R_H_LINE_TO, 1.52f,
+V_LINE_TO, 6.4f,
+H_LINE_TO, 2.15f,
+V_LINE_TO, 2.16f,
+R_H_LINE_TO, 1.34f,
+R_V_LINE_TO, 2.03f,
+R_ARC_TO, 5.88f, 5.88f, 0, 0, 1, 1.97f, -1.55f,
+R_ARC_TO, 5.68f, 5.68f, 0, 0, 1, 2.52f, -0.57f,
+R_CUBIC_TO, 0.82f, 0, 1.58f, 0.16f, 2.3f, 0.47f,
+R_ARC_TO, 6.04f, 6.04f, 0, 0, 1, 1.88f, 1.27f,
+R_CUBIC_TO, 0.53f, 0.53f, 0.96f, 1.16f, 1.27f, 1.88f,
+R_CUBIC_TO, 0.31f, 0.72f, 0.47f, 1.49f, 0.47f, 2.31f,
+R_CUBIC_TO, 0, 0.82f, -0.16f, 1.58f, -0.47f, 2.31f,
+R_ARC_TO, 5.96f, 5.96f, 0, 0, 1, -1.27f, 1.88f,
+R_ARC_TO, 6.04f, 6.04f, 0, 0, 1, -1.88f, 1.27f,
+R_ARC_TO, 5.74f, 5.74f, 0, 0, 1, -2.31f, 0.47f,
 CLOSE,
-R_MOVE_TO, 1.65f, -3.44f,
-LINE_TO, 7.37f, 8.03f,
-R_V_LINE_TO, -3.23f,
-R_H_LINE_TO, 1.26f,
+R_MOVE_TO, 1.62f, -3.58f,
+R_LINE_TO, -2.27f, -2.27f,
+V_LINE_TO, 4.8f,
+R_H_LINE_TO, 1.34f,
 V_LINE_TO, 7.5f,
-R_LINE_TO, 1.9f, 1.9f,
-CLOSE,
-R_MOVE_TO, 0, 0,
-CLOSE
+R_LINE_TO, 1.89f, 1.88f,
+CLOSE
\ No newline at end of file
diff --git a/components/vector_icons/info_refresh.icon b/components/vector_icons/info_refresh.icon
index 9cf55d40..063c13f6 100644
--- a/components/vector_icons/info_refresh.icon
+++ b/components/vector_icons/info_refresh.icon
@@ -3,46 +3,44 @@
 // found in the LICENSE file.
 
 CANVAS_DIMENSIONS, 16,
-MOVE_TO, 7.34f, 11.26f,
-R_H_LINE_TO, 1.32f,
+MOVE_TO, 7.26f, 11.34f,
+R_H_LINE_TO, 1.48f,
 V_LINE_TO, 7.2f,
-H_LINE_TO, 7.34f,
+H_LINE_TO, 7.26f,
 CLOSE,
-R_MOVE_TO, 0.66f, -5.18f,
-R_ARC_TO, 0.66f, 0.66f, 0, 0, 0, 0.48f, -0.19f,
-R_ARC_TO, 0.66f, 0.66f, 0, 0, 0, 0.2f, -0.48f,
-R_ARC_TO, 0.67f, 0.67f, 0, 0, 0, -0.2f, -0.48f,
-R_ARC_TO, 0.64f, 0.64f, 0, 0, 0, -0.48f, -0.2f,
-R_ARC_TO, 0.66f, 0.66f, 0, 0, 0, -0.48f, 0.2f,
-R_ARC_TO, 0.64f, 0.64f, 0, 0, 0, -0.2f, 0.48f,
-R_CUBIC_TO, 0, 0.2f, 0.07f, 0.36f, 0.2f, 0.49f,
-R_ARC_TO, 0.64f, 0.64f, 0, 0, 0, 0.48f, 0.2f,
+R_MOVE_TO, 0.74f, -5.15f,
+R_CUBIC_TO, 0.22f, 0, 0.41f, -0.07f, 0.56f, -0.23f,
+R_ARC_TO, 0.75f, 0.75f, 0, 0, 0, 0.23f, -0.56f,
+R_ARC_TO, 0.76f, 0.76f, 0, 0, 0, -0.23f, -0.56f,
+R_ARC_TO, 0.75f, 0.75f, 0, 0, 0, -0.56f, -0.23f,
+R_ARC_TO, 0.78f, 0.78f, 0, 0, 0, -0.79f, 0.78f,
+R_ARC_TO, 0.78f, 0.78f, 0, 0, 0, 0.79f, 0.79f,
 CLOSE,
-R_MOVE_TO, 0.01f, 8.46f,
-R_CUBIC_TO, -0.9f, 0, -1.75f, -0.17f, -2.54f, -0.51f,
-R_ARC_TO, 6.52f, 6.52f, 0, 0, 1, -2.08f, -1.4f,
-R_ARC_TO, 6.52f, 6.52f, 0, 0, 1, -1.4f, -2.08f,
-R_ARC_TO, 6.33f, 6.33f, 0, 0, 1, -0.51f, -2.55f,
-R_CUBIC_TO, 0, -0.91f, 0.17f, -1.75f, 0.51f, -2.54f,
-ARC_TO, 6.53f, 6.53f, 0, 0, 1, 3.38f, 3.38f,
-ARC_TO, 6.52f, 6.52f, 0, 0, 1, 5.46f, 1.98f,
-R_ARC_TO, 6.33f, 6.33f, 0, 0, 1, 2.55f, -0.51f,
-R_CUBIC_TO, 0.91f, 0, 1.75f, 0.17f, 2.54f, 0.51f,
-R_CUBIC_TO, 0.79f, 0.34f, 1.48f, 0.8f, 2.07f, 1.4f,
-R_ARC_TO, 6.5f, 6.5f, 0, 0, 1, 1.4f, 2.08f,
-R_ARC_TO, 6.29f, 6.29f, 0, 0, 1, 0.51f, 2.54f,
-R_CUBIC_TO, 0, 0.9f, -0.17f, 1.75f, -0.51f, 2.54f,
-R_ARC_TO, 6.52f, 6.52f, 0, 0, 1, -1.4f, 2.08f,
-R_ARC_TO, 6.5f, 6.5f, 0, 0, 1, -2.08f, 1.4f,
-R_ARC_TO, 6.29f, 6.29f, 0, 0, 1, -2.54f, 0.51f,
+R_MOVE_TO, 0.01f, 8.53f,
+R_CUBIC_TO, -0.93f, 0, -1.8f, -0.17f, -2.62f, -0.52f,
+R_ARC_TO, 6.67f, 6.67f, 0, 0, 1, -2.14f, -1.44f,
+R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, -1.44f, -2.14f,
+R_ARC_TO, 6.56f, 6.56f, 0, 0, 1, -0.52f, -2.62f,
+R_CUBIC_TO, 0, -0.93f, 0.17f, -1.8f, 0.52f, -2.62f,
+R_ARC_TO, 6.71f, 6.71f, 0, 0, 1, 1.44f, -2.13f,
+R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, 2.14f, -1.44f,
+R_ARC_TO, 6.56f, 6.56f, 0, 0, 1, 2.63f, -0.52f,
+R_CUBIC_TO, 0.93f, 0, 1.81f, 0.17f, 2.62f, 0.52f,
+R_CUBIC_TO, 0.81f, 0.35f, 1.52f, 0.83f, 2.13f, 1.44f,
+R_ARC_TO, 6.68f, 6.68f, 0, 0, 1, 1.44f, 2.13f,
+R_CUBIC_TO, 0.35f, 0.81f, 0.52f, 1.68f, 0.52f, 2.62f,
+R_CUBIC_TO, 0, 0.93f, -0.17f, 1.81f, -0.52f, 2.62f,
+R_ARC_TO, 6.67f, 6.67f, 0, 0, 1, -1.44f, 2.14f,
+R_ARC_TO, 6.68f, 6.68f, 0, 0, 1, -2.13f, 1.44f,
+R_ARC_TO, 6.51f, 6.51f, 0, 0, 1, -2.62f, 0.52f,
 CLOSE,
-MOVE_TO, 8, 13.15f,
-R_CUBIC_TO, 1.43f, 0, 2.65f, -0.5f, 3.65f, -1.5f,
-R_CUBIC_TO, 1, -1, 1.5f, -2.22f, 1.5f, -3.65f,
-R_CUBIC_TO, 0, -1.43f, -0.5f, -2.65f, -1.5f, -3.65f,
-CUBIC_TO_SHORTHAND, 9.43f, 2.85f, 8, 2.85f,
-R_CUBIC_TO, -1.43f, 0, -2.65f, 0.5f, -3.65f, 1.5f,
-CUBIC_TO_SHORTHAND, 2.85f, 6.57f, 2.85f, 8,
-R_CUBIC_TO, 0, 1.43f, 0.5f, 2.65f, 1.5f, 3.65f,
-R_CUBIC_TO, 1, 1, 2.22f, 1.5f, 3.65f, 1.5f,
+MOVE_TO, 8, 13.09f,
+R_CUBIC_TO, 1.42f, 0, 2.62f, -0.49f, 3.61f, -1.48f,
+R_CUBIC_TO, 0.98f, -0.99f, 1.48f, -2.19f, 1.48f, -3.61f,
+R_CUBIC_TO, 0, -1.42f, -0.49f, -2.62f, -1.48f, -3.61f,
+CUBIC_TO, 10.62f, 3.41f, 9.42f, 2.92f, 8, 2.92f,
+R_CUBIC_TO, -1.42f, 0, -2.62f, 0.49f, -3.61f, 1.48f,
+CUBIC_TO, 3.41f, 5.38f, 2.92f, 6.58f, 2.92f, 8,
+R_CUBIC_TO, 0, 1.42f, 0.49f, 2.62f, 1.48f, 3.61f,
+R_CUBIC_TO, 0.99f, 0.98f, 2.19f, 1.48f, 3.61f, 1.48f,
 CLOSE
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 367c7ff..6b185588 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
@@ -1920,7 +1920,8 @@
     }
 
 #if BUILDFLAG(IS_MAC)
-    if (features::UseGpuVsync()) {
+    if (base::FeatureList::IsEnabled(
+            features::kCVDisplayLinkBeginFrameSource)) {
       presenter_->SetVSyncDisplayID(renderer_settings_.display_id);
     }
 #endif
diff --git a/components/viz/service/frame_sinks/external_begin_frame_source_mac.cc b/components/viz/service/frame_sinks/external_begin_frame_source_mac.cc
index 8f27e98..10bc00cd 100644
--- a/components/viz/service/frame_sinks/external_begin_frame_source_mac.cc
+++ b/components/viz/service/frame_sinks/external_begin_frame_source_mac.cc
@@ -41,9 +41,12 @@
 ///////////////////////////////////////////////////////////////////////////////
 // ExternalBeginFrameSourceMac
 
-ExternalBeginFrameSourceMac::ExternalBeginFrameSourceMac(uint32_t restart_id,
-                                                         int64_t display_id)
-    : ExternalBeginFrameSource(this, restart_id) {
+ExternalBeginFrameSourceMac::ExternalBeginFrameSourceMac(
+    uint32_t restart_id,
+    int64_t display_id,
+    OutputSurface* output_surface)
+    : ExternalBeginFrameSource(this, restart_id),
+      output_surface_(output_surface) {
   if (display_id == display::kInvalidDisplayId) {
     RecordDisplayLinkCreateStatus(DisplayLinkResult::kFailedInvalidDisplayId);
     DLOG(ERROR)
@@ -77,6 +80,7 @@
   if (display_id_ == display_id) {
     return;
   }
+  output_surface_->SetVSyncDisplayID(display_id);
 
   display_id_ = display_id;
 
diff --git a/components/viz/service/frame_sinks/external_begin_frame_source_mac.h b/components/viz/service/frame_sinks/external_begin_frame_source_mac.h
index 9284dff..6382655 100644
--- a/components/viz/service/frame_sinks/external_begin_frame_source_mac.h
+++ b/components/viz/service/frame_sinks/external_begin_frame_source_mac.h
@@ -9,13 +9,16 @@
 #include <vector>
 
 #include "base/feature_list.h"
+#include "base/memory/raw_ptr.h"
 #include "components/viz/common/display/update_vsync_parameters_callback.h"
 #include "components/viz/common/frame_sinks/begin_frame_source.h"
+#include "components/viz/service/display/output_surface.h"
 #include "components/viz/service/viz_service_export.h"
 #include "ui/display/mac/display_link_mac.h"
 #include "ui/display/types/display_constants.h"
 
 namespace viz {
+class OutputSurface;
 
 // An external begin frame source for use on macOS. This listens to a
 // DisplayLinkMac in order to tick.
@@ -24,7 +27,9 @@
       public ExternalBeginFrameSourceClient,
       public DelayBasedTimeSourceClient {
  public:
-  ExternalBeginFrameSourceMac(uint32_t restart_id, int64_t display_id);
+  ExternalBeginFrameSourceMac(uint32_t restart_id,
+                              int64_t display_id,
+                              OutputSurface* output_surface);
 
   ExternalBeginFrameSourceMac(const ExternalBeginFrameSourceMac&) = delete;
   ExternalBeginFrameSourceMac& operator=(const ExternalBeginFrameSourceMac&) =
@@ -93,6 +98,7 @@
 
   bool just_started_begin_frame_ = false;
 
+  const raw_ptr<OutputSurface, DanglingUntriaged> output_surface_;
   UpdateVSyncParametersCallback update_vsync_params_callback_;
 
   base::WeakPtrFactory<ExternalBeginFrameSourceMac> weak_ptr_factory_{this};
diff --git a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
index fe0cd60b..e8df146 100644
--- a/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
+++ b/components/viz/service/frame_sinks/root_compositor_frame_sink_impl.cc
@@ -175,7 +175,8 @@
               features::kCVDisplayLinkBeginFrameSource)) {
         external_begin_frame_source =
             std::make_unique<ExternalBeginFrameSourceMac>(
-                restart_id, params->renderer_settings.display_id);
+                restart_id, params->renderer_settings.display_id,
+                output_surface.get());
       } else {
         synthetic_begin_frame_source =
             std::make_unique<DelayBasedBeginFrameSourceMac>(
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 878067e5..7dcbbbb 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -942,6 +942,8 @@
     "file_system_access/file_system_access_access_handle_host_impl.h",
     "file_system_access/file_system_access_capacity_allocation_host_impl.cc",
     "file_system_access/file_system_access_capacity_allocation_host_impl.h",
+    "file_system_access/file_system_access_change_source.cc",
+    "file_system_access/file_system_access_change_source.h",
     "file_system_access/file_system_access_data_transfer_token_impl.cc",
     "file_system_access/file_system_access_data_transfer_token_impl.h",
     "file_system_access/file_system_access_directory_handle_impl.cc",
@@ -962,10 +964,14 @@
     "file_system_access/file_system_access_manager_impl.h",
     "file_system_access/file_system_access_observer_host.cc",
     "file_system_access/file_system_access_observer_host.h",
+    "file_system_access/file_system_access_observer_observation.cc",
+    "file_system_access/file_system_access_observer_observation.h",
     "file_system_access/file_system_access_safe_move_helper.cc",
     "file_system_access/file_system_access_safe_move_helper.h",
     "file_system_access/file_system_access_transfer_token_impl.cc",
     "file_system_access/file_system_access_transfer_token_impl.h",
+    "file_system_access/file_system_access_watch_scope.cc",
+    "file_system_access/file_system_access_watch_scope.h",
     "file_system_access/file_system_access_watcher_manager.cc",
     "file_system_access/file_system_access_watcher_manager.h",
     "file_system_access/file_system_chooser.cc",
@@ -2557,6 +2563,18 @@
     ]
   }
 
+  # Watching the local file system via the File System Access API is not
+  # supported on Android or Fuchsia. Local file system access is not supported
+  # on Android at all (see https://crbug.com/1011535), whereas
+  # `base::FilePatchWatcher` is not implemented on Fuchsia (see
+  # https://crbug.com/851641)
+  if (!is_fuchsia && !is_android) {
+    sources += [
+      "file_system_access/file_system_access_local_path_watcher.cc",
+      "file_system_access/file_system_access_local_path_watcher.h",
+    ]
+  }
+
   if (is_apple) {
     sources += [
       "child_process_task_port_provider_mac.cc",
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.mm b/content/browser/accessibility/browser_accessibility_cocoa.mm
index d7a5973..9a3e04ca 100644
--- a/content/browser/accessibility/browser_accessibility_cocoa.mm
+++ b/content/browser/accessibility/browser_accessibility_cocoa.mm
@@ -504,7 +504,8 @@
 }
 
 @implementation BrowserAccessibilityCocoa {
-  raw_ptr<content::BrowserAccessibility> _owner;
+  // Dangling pointer https://crbug.com/1475830.
+  raw_ptr<content::BrowserAccessibility, DanglingUntriaged> _owner;
   // An array of children of this object. Cached to avoid re-computing.
   NSMutableArray* __strong _children;
   // Whether the children have changed and need to be updated.
diff --git a/content/browser/accessibility/browser_accessibility_manager.cc b/content/browser/accessibility/browser_accessibility_manager.cc
index eafdb26..4df4879 100644
--- a/content/browser/accessibility/browser_accessibility_manager.cc
+++ b/content/browser/accessibility/browser_accessibility_manager.cc
@@ -1645,7 +1645,8 @@
 ui::AXTreeUpdate BrowserAccessibilityManager::SnapshotAXTreeForTesting() {
   std::unique_ptr<ui::AXTreeSource<const ui::AXNode*>> tree_source(
       ax_serializable_tree()->CreateTreeSource());
-  ui::AXTreeSerializer<const ui::AXNode*> serializer(tree_source.get());
+  ui::AXTreeSerializer<const ui::AXNode*, std::vector<const ui::AXNode*>>
+      serializer(tree_source.get());
   ui::AXTreeUpdate update;
   serializer.SerializeChanges(GetRoot(), &update);
   return update;
diff --git a/content/browser/accessibility/dump_accessibility_events_browsertest.cc b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
index ec8dad9..b57fa32 100644
--- a/content/browser/accessibility/dump_accessibility_events_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_events_browsertest.cc
@@ -1169,6 +1169,11 @@
 }
 
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
+                       AccessibilityEventsAriaSelectedChangedNewSubtree) {
+  RunEventTest(FILE_PATH_LITERAL("aria-selected-changed-new-subtree.html"));
+}
+
+IN_PROC_BROWSER_TEST_P(DumpAccessibilityEventsTest,
                        AccessibilityEventsButtonClick) {
   RunEventTest(FILE_PATH_LITERAL("button-click.html"));
 }
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc
index c9ac0ec..a6058b1 100644
--- a/content/browser/accessibility/web_contents_accessibility_android.cc
+++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -816,19 +816,42 @@
       node->HasNonEmptyValue(), !node->GetTextContentUTF16().empty(),
       node->IsSeekControl(), node->IsFormDescendant());
 
-  Java_AccessibilityNodeInfoBuilder_setAccessibilityNodeInfoBaseAttributes(
-      env, obj, info, unique_id, parent_id,
-      GetCanonicalJNIString(env, node->GetClassName()),
-      GetCanonicalJNIString(env, node->GetRoleString()),
-      GetCanonicalJNIString(env, node->GetRoleDescription()),
-      base::android::ConvertUTF16ToJavaString(env, node->GetHint()),
-      base::android::ConvertUTF16ToJavaString(env, node->GetTargetUrl()),
-      node->CanOpenPopup(), node->IsMultiLine(), node->AndroidInputType(),
-      node->AndroidLiveRegionType(),
-      GetCanonicalJNIString(env, node->GetContentInvalidErrorMessage()),
-      node->ClickableScore(), GetCanonicalJNIString(env, node->GetCSSDisplay()),
-      base::android::ConvertUTF16ToJavaString(env, node->GetBrailleLabel()),
-      GetCanonicalJNIString(env, node->GetBrailleRoleDescription()));
+  // If we are not doing performance testing, then use the cache.
+  if (!base::FeatureList::IsEnabled(
+          ::features::kAccessibilityPerformanceTesting)) {
+    Java_AccessibilityNodeInfoBuilder_setAccessibilityNodeInfoBaseAttributes(
+        env, obj, info, unique_id, parent_id,
+        GetCanonicalJNIString(env, node->GetClassName()),
+        GetCanonicalJNIString(env, node->GetRoleString()),
+        GetCanonicalJNIString(env, node->GetRoleDescription()),
+        base::android::ConvertUTF16ToJavaString(env, node->GetHint()),
+        base::android::ConvertUTF16ToJavaString(env, node->GetTargetUrl()),
+        node->CanOpenPopup(), node->IsMultiLine(), node->AndroidInputType(),
+        node->AndroidLiveRegionType(),
+        GetCanonicalJNIString(env, node->GetContentInvalidErrorMessage()),
+        node->ClickableScore(),
+        GetCanonicalJNIString(env, node->GetCSSDisplay()),
+        base::android::ConvertUTF16ToJavaString(env, node->GetBrailleLabel()),
+        GetCanonicalJNIString(env, node->GetBrailleRoleDescription()));
+  } else {
+    Java_AccessibilityNodeInfoBuilder_setAccessibilityNodeInfoBaseAttributes(
+        env, obj, info, unique_id, parent_id,
+        base::android::ConvertUTF8ToJavaString(env, node->GetClassName()),
+        base::android::ConvertUTF8ToJavaString(env, node->GetRoleString()),
+        base::android::ConvertUTF16ToJavaString(env,
+                                                node->GetRoleDescription()),
+        base::android::ConvertUTF16ToJavaString(env, node->GetHint()),
+        base::android::ConvertUTF16ToJavaString(env, node->GetTargetUrl()),
+        node->CanOpenPopup(), node->IsMultiLine(), node->AndroidInputType(),
+        node->AndroidLiveRegionType(),
+        base::android::ConvertUTF16ToJavaString(
+            env, node->GetContentInvalidErrorMessage()),
+        node->ClickableScore(),
+        base::android::ConvertUTF8ToJavaString(env, node->GetCSSDisplay()),
+        base::android::ConvertUTF16ToJavaString(env, node->GetBrailleLabel()),
+        base::android::ConvertUTF16ToJavaString(
+            env, node->GetBrailleRoleDescription()));
+  }
 
   ScopedJavaLocalRef<jintArray> suggestion_starts_java;
   ScopedJavaLocalRef<jintArray> suggestion_ends_java;
@@ -849,15 +872,32 @@
         base::android::ToJavaArrayOfStrings(env, suggestion_text);
   }
 
-  Java_AccessibilityNodeInfoBuilder_setAccessibilityNodeInfoText(
-      env, obj, info,
-      base::android::ConvertUTF16ToJavaString(env, node->GetTextContentUTF16()),
-      ui::IsLink(node->GetRole()), node->IsTextField(),
-      GetCanonicalJNIString(env, node->GetInheritedString16Attribute(
-                                     ax::mojom::StringAttribute::kLanguage)),
-      suggestion_starts_java, suggestion_ends_java, suggestion_text_java,
-      base::android::ConvertUTF16ToJavaString(env,
-                                              node->GetStateDescription()));
+  // If we are not doing performance testing, then use the cache.
+  if (!base::FeatureList::IsEnabled(
+          ::features::kAccessibilityPerformanceTesting)) {
+    Java_AccessibilityNodeInfoBuilder_setAccessibilityNodeInfoText(
+        env, obj, info,
+        base::android::ConvertUTF16ToJavaString(env,
+                                                node->GetTextContentUTF16()),
+        ui::IsLink(node->GetRole()), node->IsTextField(),
+        GetCanonicalJNIString(env, node->GetInheritedString16Attribute(
+                                       ax::mojom::StringAttribute::kLanguage)),
+        suggestion_starts_java, suggestion_ends_java, suggestion_text_java,
+        base::android::ConvertUTF16ToJavaString(env,
+                                                node->GetStateDescription()));
+  } else {
+    Java_AccessibilityNodeInfoBuilder_setAccessibilityNodeInfoText(
+        env, obj, info,
+        base::android::ConvertUTF16ToJavaString(env,
+                                                node->GetTextContentUTF16()),
+        ui::IsLink(node->GetRole()), node->IsTextField(),
+        base::android::ConvertUTF16ToJavaString(
+            env, node->GetInheritedString16Attribute(
+                     ax::mojom::StringAttribute::kLanguage)),
+        suggestion_starts_java, suggestion_ends_java, suggestion_text_java,
+        base::android::ConvertUTF16ToJavaString(env,
+                                                node->GetStateDescription()));
+  }
 
   std::u16string element_id;
   if (node->GetHtmlAttribute("id", &element_id)) {
@@ -921,13 +961,24 @@
   if (obj.is_null())
     return false;
 
-  // We will always set boolean, classname, list and scroll attributes.
-  Java_WebContentsAccessibilityImpl_setAccessibilityEventBaseAttributes(
-      env, obj, event, node->IsChecked(), node->IsEnabled(),
-      node->IsPasswordField(), node->IsScrollable(), node->GetItemIndex(),
-      node->GetItemCount(), node->GetScrollX(), node->GetScrollY(),
-      node->GetMaxScrollX(), node->GetMaxScrollY(),
-      GetCanonicalJNIString(env, node->GetClassName()));
+  // If we are not doing performance testing, then use the cache.
+  if (!base::FeatureList::IsEnabled(
+          ::features::kAccessibilityPerformanceTesting)) {
+    // We will always set boolean, classname, list and scroll attributes.
+    Java_WebContentsAccessibilityImpl_setAccessibilityEventBaseAttributes(
+        env, obj, event, node->IsChecked(), node->IsEnabled(),
+        node->IsPasswordField(), node->IsScrollable(), node->GetItemIndex(),
+        node->GetItemCount(), node->GetScrollX(), node->GetScrollY(),
+        node->GetMaxScrollX(), node->GetMaxScrollY(),
+        GetCanonicalJNIString(env, node->GetClassName()));
+  } else {
+    Java_WebContentsAccessibilityImpl_setAccessibilityEventBaseAttributes(
+        env, obj, event, node->IsChecked(), node->IsEnabled(),
+        node->IsPasswordField(), node->IsScrollable(), node->GetItemIndex(),
+        node->GetItemCount(), node->GetScrollX(), node->GetScrollY(),
+        node->GetMaxScrollX(), node->GetMaxScrollY(),
+        base::android::ConvertUTF8ToJavaString(env, node->GetClassName()));
+  }
 
   switch (event_type) {
     case ANDROID_ACCESSIBILITY_EVENT_TEXT_CHANGED: {
diff --git a/content/browser/accessibility/web_contents_accessibility_android.h b/content/browser/accessibility/web_contents_accessibility_android.h
index 8eabc1fb..96d513a 100644
--- a/content/browser/accessibility/web_contents_accessibility_android.h
+++ b/content/browser/accessibility/web_contents_accessibility_android.h
@@ -16,6 +16,7 @@
 #include "base/android/scoped_java_ref.h"
 #include "base/memory/weak_ptr.h"
 #include "base/strings/utf_string_conversions.h"
+#include "content/public/common/content_features.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace ui {
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.cc b/content/browser/bluetooth/web_bluetooth_service_impl.cc
index c26243a0..7631e81 100644
--- a/content/browser/bluetooth/web_bluetooth_service_impl.cc
+++ b/content/browser/bluetooth/web_bluetooth_service_impl.cc
@@ -1334,7 +1334,7 @@
 
 void WebBluetoothServiceImpl::RequestScanningStart(
     mojo::PendingAssociatedRemote<blink::mojom::WebBluetoothAdvertisementClient>
-        client_info,
+        client_remote,
     blink::mojom::WebBluetoothRequestLEScanOptionsPtr options,
     RequestScanningStartCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -1362,10 +1362,10 @@
   if (!GetAdapter()) {
     if (BluetoothAdapterFactoryWrapper::Get().IsLowEnergySupported()) {
       BluetoothAdapterFactoryWrapper::Get().AcquireAdapter(
-          this,
-          base::BindOnce(&WebBluetoothServiceImpl::RequestScanningStartImpl,
-                         weak_ptr_factory_.GetWeakPtr(), std::move(client_info),
-                         std::move(options), std::move(callback)));
+          this, base::BindOnce(
+                    &WebBluetoothServiceImpl::RequestScanningStartImpl,
+                    weak_ptr_factory_.GetWeakPtr(), std::move(client_remote),
+                    std::move(options), std::move(callback)));
       return;
     }
     std::move(callback).Run(
@@ -1373,14 +1373,14 @@
     return;
   }
 
-  RequestScanningStartImpl(std::move(client_info), std::move(options),
+  RequestScanningStartImpl(std::move(client_remote), std::move(options),
                            std::move(callback), GetAdapter());
 }
 
 void WebBluetoothServiceImpl::WatchAdvertisementsForDevice(
     const blink::WebBluetoothDeviceId& device_id,
     mojo::PendingAssociatedRemote<blink::mojom::WebBluetoothAdvertisementClient>
-        client_info,
+        client_remote,
     WatchAdvertisementsForDeviceCallback callback) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
@@ -1402,7 +1402,7 @@
           this, base::BindOnce(
                     &WebBluetoothServiceImpl::WatchAdvertisementsForDeviceImpl,
                     weak_ptr_factory_.GetWeakPtr(), device_id,
-                    std::move(client_info), std::move(callback)));
+                    std::move(client_remote), std::move(callback)));
       return;
     }
     std::move(callback).Run(
@@ -1410,7 +1410,8 @@
     return;
   }
 
-  WatchAdvertisementsForDeviceImpl(std::move(device_id), std::move(client_info),
+  WatchAdvertisementsForDeviceImpl(std::move(device_id),
+                                   std::move(client_remote),
                                    std::move(callback), GetAdapter());
 }
 
@@ -1440,7 +1441,7 @@
 
 void WebBluetoothServiceImpl::RequestScanningStartImpl(
     mojo::PendingAssociatedRemote<blink::mojom::WebBluetoothAdvertisementClient>
-        client_info,
+        client_remote,
     blink::mojom::WebBluetoothRequestLEScanOptionsPtr options,
     RequestScanningStartCallback callback,
     scoped_refptr<BluetoothAdapter> adapter) {
@@ -1459,7 +1460,7 @@
 
   if (ble_scan_discovery_session_) {
     auto scanning_client = std::make_unique<ScanningClient>(
-        /*service=*/this, std::move(client_info), std::move(options),
+        /*service=*/this, std::move(client_remote), std::move(options),
         std::move(callback));
 
     if (AreScanFiltersAllowed(scanning_client->scan_options().filters)) {
@@ -1490,7 +1491,7 @@
       kScanClientNameRequestLeScan,
       base::BindOnce(
           &WebBluetoothServiceImpl::OnStartDiscoverySessionForScanning,
-          weak_ptr_factory_.GetWeakPtr(), std::move(client_info),
+          weak_ptr_factory_.GetWeakPtr(), std::move(client_remote),
           std::move(options)),
       base::BindOnce(
           &WebBluetoothServiceImpl::OnDiscoverySessionErrorForScanning,
@@ -1499,7 +1500,7 @@
 
 void WebBluetoothServiceImpl::OnStartDiscoverySessionForScanning(
     mojo::PendingAssociatedRemote<blink::mojom::WebBluetoothAdvertisementClient>
-        client_info,
+        client_remote,
     blink::mojom::WebBluetoothRequestLEScanOptionsPtr options,
     std::unique_ptr<BluetoothDiscoverySession> session) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -1508,7 +1509,7 @@
   ble_scan_discovery_session_ = std::move(session);
 
   auto scanning_client = std::make_unique<ScanningClient>(
-      /*service=*/this, std::move(client_info), std::move(options),
+      /*service=*/this, std::move(client_remote), std::move(options),
       std::move(request_scanning_start_callback_));
 
   if (AreScanFiltersAllowed(scanning_client->scan_options().filters)) {
@@ -1600,7 +1601,7 @@
 void WebBluetoothServiceImpl::WatchAdvertisementsForDeviceImpl(
     const blink::WebBluetoothDeviceId& device_id,
     mojo::PendingAssociatedRemote<blink::mojom::WebBluetoothAdvertisementClient>
-        client_info,
+        client_remote,
     WatchAdvertisementsForDeviceCallback callback,
     scoped_refptr<BluetoothAdapter> adapter) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
@@ -1612,7 +1613,7 @@
   }
 
   auto pending_client = std::make_unique<WatchAdvertisementsClient>(
-      /*service=*/this, std::move(client_info), std::move(device_id),
+      /*service=*/this, std::move(client_remote), std::move(device_id),
       std::move(callback));
   if (watch_advertisements_discovery_session_) {
     pending_client->RunCallback(blink::mojom::WebBluetoothResult::SUCCESS);
diff --git a/content/browser/bluetooth/web_bluetooth_service_impl.h b/content/browser/bluetooth/web_bluetooth_service_impl.h
index 66d8fc65..fb5023f6 100644
--- a/content/browser/bluetooth/web_bluetooth_service_impl.h
+++ b/content/browser/bluetooth/web_bluetooth_service_impl.h
@@ -276,13 +276,13 @@
       RemoteDescriptorWriteValueCallback callback) override;
   void RequestScanningStart(
       mojo::PendingAssociatedRemote<
-          blink::mojom::WebBluetoothAdvertisementClient> client_info,
+          blink::mojom::WebBluetoothAdvertisementClient> client_remote,
       blink::mojom::WebBluetoothRequestLEScanOptionsPtr options,
       RequestScanningStartCallback callback) override;
   void WatchAdvertisementsForDevice(
       const blink::WebBluetoothDeviceId& device_id,
       mojo::PendingAssociatedRemote<
-          blink::mojom::WebBluetoothAdvertisementClient> client_info,
+          blink::mojom::WebBluetoothAdvertisementClient> client_remote,
       WatchAdvertisementsForDeviceCallback callback) override;
 
   void RequestDeviceImpl(
@@ -296,13 +296,13 @@
   // Callbacks for BLE scanning.
   void RequestScanningStartImpl(
       mojo::PendingAssociatedRemote<
-          blink::mojom::WebBluetoothAdvertisementClient> client_info,
+          blink::mojom::WebBluetoothAdvertisementClient> client_remote,
       blink::mojom::WebBluetoothRequestLEScanOptionsPtr options,
       RequestScanningStartCallback callback,
       scoped_refptr<device::BluetoothAdapter> adapter);
   void OnStartDiscoverySessionForScanning(
       mojo::PendingAssociatedRemote<
-          blink::mojom::WebBluetoothAdvertisementClient> client_info,
+          blink::mojom::WebBluetoothAdvertisementClient> client_remote,
       blink::mojom::WebBluetoothRequestLEScanOptionsPtr options,
       std::unique_ptr<device::BluetoothDiscoverySession> session);
   void OnDiscoverySessionErrorForScanning();
@@ -311,7 +311,7 @@
   void WatchAdvertisementsForDeviceImpl(
       const blink::WebBluetoothDeviceId& device_id,
       mojo::PendingAssociatedRemote<
-          blink::mojom::WebBluetoothAdvertisementClient> client_info,
+          blink::mojom::WebBluetoothAdvertisementClient> client_remote,
       WatchAdvertisementsForDeviceCallback callback,
       scoped_refptr<device::BluetoothAdapter> adapter);
   void OnStartDiscoverySessionForWatchAdvertisements(
diff --git a/content/browser/browsing_data/clear_site_data_handler.cc b/content/browser/browsing_data/clear_site_data_handler.cc
index bcee3aab..deac3560 100644
--- a/content/browser/browsing_data/clear_site_data_handler.cc
+++ b/content/browser/browsing_data/clear_site_data_handler.cc
@@ -11,10 +11,12 @@
 #include "base/strings/stringprintf.h"
 #include "content/browser/buckets/bucket_utils.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition_config.h"
 #include "content/public/browser/web_contents.h"
 #include "net/base/load_flags.h"
 #include "net/url_request/clear_site_data.h"
 #include "services/network/public/cpp/is_potentially_trustworthy.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/features_generated.h"
 
 namespace content {
@@ -121,18 +123,19 @@
 void ClearSiteDataHandler::HandleHeader(
     base::RepeatingCallback<BrowserContext*()> browser_context_getter,
     base::RepeatingCallback<WebContents*()> web_contents_getter,
+    const StoragePartitionConfig& storage_partition_config,
     const GURL& url,
     const std::string& header_value,
     int load_flags,
-    const absl::optional<net::CookiePartitionKey>& cookie_partition_key,
-    const absl::optional<blink::StorageKey>& storage_key,
+    const absl::optional<net::CookiePartitionKey> cookie_partition_key,
+    const absl::optional<blink::StorageKey> storage_key,
     bool partitioned_state_allowed_only,
     base::OnceClosure callback) {
-  ClearSiteDataHandler handler(browser_context_getter, web_contents_getter, url,
-                               header_value, load_flags, cookie_partition_key,
-                               storage_key, partitioned_state_allowed_only,
-                               std::move(callback),
-                               std::make_unique<ConsoleMessagesDelegate>());
+  ClearSiteDataHandler handler(
+      browser_context_getter, web_contents_getter, storage_partition_config,
+      url, header_value, load_flags, cookie_partition_key, storage_key,
+      partitioned_state_allowed_only, std::move(callback),
+      std::make_unique<ConsoleMessagesDelegate>());
   handler.HandleHeaderAndOutputConsoleMessages();
 }
 
@@ -151,16 +154,18 @@
 ClearSiteDataHandler::ClearSiteDataHandler(
     base::RepeatingCallback<BrowserContext*()> browser_context_getter,
     base::RepeatingCallback<WebContents*()> web_contents_getter,
+    const StoragePartitionConfig& storage_partition_config,
     const GURL& url,
     const std::string& header_value,
     int load_flags,
-    const absl::optional<net::CookiePartitionKey>& cookie_partition_key,
-    const absl::optional<blink::StorageKey>& storage_key,
+    const absl::optional<net::CookiePartitionKey> cookie_partition_key,
+    const absl::optional<blink::StorageKey> storage_key,
     bool partitioned_state_allowed_only,
     base::OnceClosure callback,
     std::unique_ptr<ConsoleMessagesDelegate> delegate)
     : browser_context_getter_(browser_context_getter),
       web_contents_getter_(web_contents_getter),
+      storage_partition_config_(storage_partition_config),
       url_(url),
       header_value_(header_value),
       load_flags_(load_flags),
@@ -364,8 +369,7 @@
     const ClearSiteDataTypeSet clear_site_data_types,
     const std::set<std::string>& storage_buckets_to_remove,
     base::OnceClosure callback) {
-  ClearSiteData(browser_context_getter_,
-                /*storage_partition_config=*/absl::nullopt, origin,
+  ClearSiteData(browser_context_getter_, storage_partition_config_, origin,
                 clear_site_data_types, storage_buckets_to_remove,
                 /*avoid_closing_connections=*/true, cookie_partition_key_,
                 storage_key_, partitioned_state_allowed_only_,
diff --git a/content/browser/browsing_data/clear_site_data_handler.h b/content/browser/browsing_data/clear_site_data_handler.h
index 2560221..f8666365 100644
--- a/content/browser/browsing_data/clear_site_data_handler.h
+++ b/content/browser/browsing_data/clear_site_data_handler.h
@@ -13,7 +13,9 @@
 #include "base/time/time.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/clear_site_data_utils.h"
+#include "content/public/browser/storage_partition_config.h"
 #include "net/cookies/cookie_partition_key.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
 #include "third_party/blink/public/mojom/devtools/console_message.mojom.h"
 #include "url/gurl.h"
@@ -79,11 +81,12 @@
   static void HandleHeader(
       base::RepeatingCallback<BrowserContext*()> browser_context_getter,
       base::RepeatingCallback<WebContents*()> web_contents_getter,
+      const StoragePartitionConfig& storage_partition_config,
       const GURL& url,
       const std::string& header_value,
       int load_flags,
-      const absl::optional<net::CookiePartitionKey>& cookie_partition_key,
-      const absl::optional<blink::StorageKey>& storage_key,
+      const absl::optional<net::CookiePartitionKey> cookie_partition_key,
+      const absl::optional<blink::StorageKey> storage_key,
       bool partitioned_state_allowed_only,
       base::OnceClosure callback);
 
@@ -99,11 +102,12 @@
   ClearSiteDataHandler(
       base::RepeatingCallback<BrowserContext*()> browser_context_getter,
       base::RepeatingCallback<WebContents*()> web_contents_getter,
+      const StoragePartitionConfig& storage_partition_config,
       const GURL& url,
       const std::string& header_value,
       int load_flags,
-      const absl::optional<net::CookiePartitionKey>& cookie_partition_key,
-      const absl::optional<blink::StorageKey>& storage_key,
+      const absl::optional<net::CookiePartitionKey> cookie_partition_key,
+      const absl::optional<blink::StorageKey> storage_key,
       bool partitioned_state_allowed_only,
       base::OnceClosure callback,
       std::unique_ptr<ConsoleMessagesDelegate> delegate);
@@ -149,6 +153,10 @@
   // Run the callback to resume loading. No clearing actions were conducted.
   void RunCallbackNotDeferred();
 
+  const StoragePartitionConfig& StoragePartitionConfigForTesting() const {
+    return storage_partition_config_;
+  }
+
   const GURL& GetURLForTesting();
 
   const absl::optional<net::CookiePartitionKey> CookiePartitionKeyForTesting()
@@ -169,6 +177,9 @@
   base::RepeatingCallback<BrowserContext*()> browser_context_getter_;
   base::RepeatingCallback<WebContents*()> web_contents_getter_;
 
+  // The config for the target storage partition which stores the data.
+  const StoragePartitionConfig storage_partition_config_;
+
   // Target URL whose data will be cleared.
   const GURL url_;
 
diff --git a/content/browser/browsing_data/clear_site_data_handler_browsertest.cc b/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
index 4bfa013..5234400d 100644
--- a/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
+++ b/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
@@ -30,6 +30,7 @@
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/network_service_util.h"
 #include "content/public/browser/storage_partition.h"
+#include "content/public/browser/storage_partition_config.h"
 #include "content/public/browser/storage_usage_info.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
@@ -48,6 +49,7 @@
 #include "net/test/embedded_test_server/http_response.h"
 #include "storage/browser/quota/quota_settings.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/features_generated.h"
 #include "third_party/blink/public/common/storage_key/storage_key.h"
@@ -86,10 +88,12 @@
   // Sets a test expectation that a Clear-Site-Data header call from |origin|,
   // instructing to delete |cookies|, |storage|, and |cache|, will schedule
   // the corresponding BrowsingDataRemover deletion tasks.
-  void ExpectClearSiteDataCall(const url::Origin& origin,
-                               bool cookies,
-                               bool storage,
-                               bool cache) {
+  void ExpectClearSiteDataCall(
+      const StoragePartitionConfig& storage_partition_config,
+      const url::Origin& origin,
+      bool cookies,
+      bool storage,
+      bool cache) {
     const uint64_t kOriginTypeMask =
         BrowsingDataRemover::ORIGIN_TYPE_UNPROTECTED_WEB |
         BrowsingDataRemover::ORIGIN_TYPE_PROTECTED_WEB;
@@ -102,6 +106,8 @@
       BrowsingDataFilterBuilderImpl filter_builder(
           BrowsingDataFilterBuilder::Mode::kDelete);
       filter_builder.AddRegisterableDomain(origin.host());
+      filter_builder.SetStoragePartitionConfig(storage_partition_config);
+
       ExpectCall(base::Time(), base::Time::Max(), data_type_mask,
                  kOriginTypeMask, &filter_builder);
     }
@@ -117,6 +123,8 @@
       BrowsingDataFilterBuilderImpl filter_builder(
           BrowsingDataFilterBuilder::Mode::kDelete);
       filter_builder.AddOrigin(origin);
+      filter_builder.SetStoragePartitionConfig(storage_partition_config);
+
       ExpectCall(base::Time(), base::Time::Max(), data_type_mask,
                  kOriginTypeMask, &filter_builder);
     }
@@ -124,8 +132,11 @@
 
   // A shortcut for the above method, but with only cookies deleted. This is
   // useful for most tests that use |kClearCookiesHeader|.
-  void ExpectClearSiteDataCookiesCall(const url::Origin& origin) {
-    ExpectClearSiteDataCall(origin, true, false, false);
+  void ExpectClearSiteDataCookiesCall(
+      const StoragePartitionConfig& storage_partition_config,
+      const url::Origin& origin) {
+    ExpectClearSiteDataCall(storage_partition_config, origin, true, false,
+                            false);
   }
 };
 
@@ -173,6 +184,10 @@
     return browser_context()->GetDefaultStoragePartition();
   }
 
+  const StoragePartitionConfig& storage_partition_config() {
+    return storage_partition()->GetConfig();
+  }
+
   // Adds a cookie for the |url|. Used in the cookie integration tests.
   void AddCookie(const GURL& url,
                  const absl::optional<net::CookiePartitionKey>&
@@ -376,7 +391,7 @@
 
       if (mask & (1 << i))
         delegate()->ExpectClearSiteDataCookiesCall(
-            url::Origin::Create(urls[i]));
+            storage_partition_config(), url::Origin::Create(urls[i]));
     }
 
     // Set up redirects between urls 0 --> 1 --> 2.
@@ -425,7 +440,7 @@
 
       if (mask & (1 << i))
         delegate()->ExpectClearSiteDataCookiesCall(
-            url::Origin::Create(urls[i]));
+            storage_partition_config(), url::Origin::Create(urls[i]));
     }
 
     // Set up redirects between urls 0 --> 1 --> 2.
@@ -526,13 +541,15 @@
   AddQuery(&secure_page, "html", content_with_secure_image);
 
   // Secure resource on an insecure page does execute Clear-Site-Data.
-  delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(secure_image));
+  delegate()->ExpectClearSiteDataCookiesCall(storage_partition_config(),
+                                             url::Origin::Create(secure_image));
 
   EXPECT_TRUE(NavigateToURL(shell(), secure_page));
   delegate()->VerifyAndClearExpectations();
 
   // Secure resource on a secure page does execute Clear-Site-Data.
-  delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(secure_image));
+  delegate()->ExpectClearSiteDataCookiesCall(storage_partition_config(),
+                                             url::Origin::Create(secure_image));
 
   EXPECT_TRUE(NavigateToURL(shell(), secure_page));
   delegate()->VerifyAndClearExpectations();
@@ -574,10 +591,14 @@
   // but not by the "/resource_from_sw" fetch. |origin3| and |origin4| prove
   // that the number of calls is dependent on the number of network responses,
   // i.e. that it isn't always 1 as in the case of |origin1| and |origin2|.
-  delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(origin1));
-  delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(origin4));
-  delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(origin2));
-  delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(origin4));
+  delegate()->ExpectClearSiteDataCookiesCall(storage_partition_config(),
+                                             url::Origin::Create(origin1));
+  delegate()->ExpectClearSiteDataCookiesCall(storage_partition_config(),
+                                             url::Origin::Create(origin4));
+  delegate()->ExpectClearSiteDataCookiesCall(storage_partition_config(),
+                                             url::Origin::Create(origin2));
+  delegate()->ExpectClearSiteDataCookiesCall(storage_partition_config(),
+                                             url::Origin::Create(origin4));
 
   url = https_server()->GetURL("origin1.com", "/anything-in-workers-scope");
   AddQuery(&url, "origin1", origin1.spec());
@@ -647,7 +668,8 @@
     AddQuery(&page, "html", content);
 
     if (test_case.should_run)
-      delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(resource));
+      delegate()->ExpectClearSiteDataCookiesCall(storage_partition_config(),
+                                                 url::Origin::Create(resource));
 
     EXPECT_TRUE(NavigateToURL(shell(), page));
     WaitForTitle(shell(), "done");
@@ -687,7 +709,8 @@
       "</script></body></html>",
       urls[0].spec().c_str());
 
-  delegate()->ExpectClearSiteDataCookiesCall(url::Origin::Create(urls[0]));
+  delegate()->ExpectClearSiteDataCookiesCall(storage_partition_config(),
+                                             url::Origin::Create(urls[0]));
 
   GURL page = https_server()->GetURL("origin1.com", "/");
   AddQuery(&page, "html", content);
@@ -721,8 +744,9 @@
     AddQuery(&url, "header", test_case.value);
 
     delegate()->ExpectClearSiteDataCall(
-        url::Origin::Create(url), test_case.remove_cookies,
-        test_case.remove_storage, test_case.remove_cache);
+        storage_partition_config(), url::Origin::Create(url),
+        test_case.remove_cookies, test_case.remove_storage,
+        test_case.remove_cache);
 
     EXPECT_TRUE(NavigateToURL(shell(), url));
 
@@ -917,8 +941,8 @@
   GURL url = embedded_test_server()->GetURL("127.0.0.1", "/");
   AddQuery(&url, "file", "worker_test.html");
   EXPECT_TRUE(NavigateToURL(shell(), url));
-  delegate()->ExpectClearSiteDataCall(url::Origin::Create(url), false, true,
-                                      false);
+  delegate()->ExpectClearSiteDataCall(
+      storage_partition_config(), url::Origin::Create(url), false, true, false);
   SetClearSiteDataHeader("\"storage\"");
   EXPECT_FALSE(RunScriptAndGetBool("installServiceWorker()"));
   delegate()->VerifyAndClearExpectations();
@@ -944,8 +968,8 @@
   EXPECT_TRUE(RunScriptAndGetBool("installServiceWorker()"));
   delegate()->VerifyAndClearExpectations();
   // Update the service worker and send C-S-D during update.
-  delegate()->ExpectClearSiteDataCall(url::Origin::Create(url), false, true,
-                                      false);
+  delegate()->ExpectClearSiteDataCall(
+      storage_partition_config(), url::Origin::Create(url), false, true, false);
 
   base::RunLoop loop;
   auto* remover = browser_context()->GetBrowsingDataRemover();
@@ -1087,7 +1111,8 @@
   EXPECT_EQ(15, tester.GetSharedStorageTotalEntries());
 
   // Let Clear-Site-Data delete the shared storage of "origin1.com".
-  delegate()->ExpectClearSiteDataCall(kOrigin1, /*cookies=*/false,
+  delegate()->ExpectClearSiteDataCall(storage_partition_config(), kOrigin1,
+                                      /*cookies=*/false,
                                       /*storage=*/true, /*cache=*/false);
   AddQuery(&url1, "header", "\"storage\"");
   EXPECT_TRUE(NavigateToURL(shell(), url1));
diff --git a/content/browser/browsing_data/clear_site_data_handler_unittest.cc b/content/browser/browsing_data/clear_site_data_handler_unittest.cc
index a10507f..099405f 100644
--- a/content/browser/browsing_data/clear_site_data_handler_unittest.cc
+++ b/content/browser/browsing_data/clear_site_data_handler_unittest.cc
@@ -15,7 +15,9 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
+#include "content/public/browser/storage_partition_config.h"
 #include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_browser_context.h"
 #include "net/base/load_flags.h"
 #include "net/http/http_util.h"
 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
@@ -25,6 +27,7 @@
 #include "net/url_request/url_request_test_util.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/blink/public/common/features_generated.h"
 
 using ::testing::_;
@@ -46,6 +49,8 @@
   return nullptr;
 }
 
+const StoragePartitionConfig kTestStoragePartitionConfig;
+
 // A slightly modified ClearSiteDataHandler for testing with dummy clearing
 // functionality.
 class TestHandler : public ClearSiteDataHandler {
@@ -53,16 +58,18 @@
   TestHandler(
       base::RepeatingCallback<BrowserContext*()> browser_context_getter,
       base::RepeatingCallback<WebContents*()> web_contents_getter,
+      const StoragePartitionConfig& storage_partition_config,
       const GURL& url,
       const std::string& header_value,
       int load_flags,
-      const absl::optional<net::CookiePartitionKey>& cookie_partition_key,
-      const absl::optional<blink::StorageKey>& storage_key,
+      const absl::optional<net::CookiePartitionKey> cookie_partition_key,
+      const absl::optional<blink::StorageKey> storage_key,
       bool partitioned_state_allowed_only,
       base::OnceClosure callback,
       std::unique_ptr<ConsoleMessagesDelegate> delegate)
       : ClearSiteDataHandler(browser_context_getter,
                              web_contents_getter,
+                             storage_partition_config,
                              url,
                              header_value,
                              load_flags,
@@ -77,14 +84,15 @@
   // test cases.
   bool DoHandleHeader() { return HandleHeaderAndOutputConsoleMessages(); }
 
-  MOCK_METHOD7(
+  MOCK_METHOD8(
       ClearSiteData,
-      void(const url::Origin& origin,
+      void(const StoragePartitionConfig& storage_partition_config,
+           const url::Origin& origin,
            const ClearSiteDataTypeSet clear_site_data_types,
            const std::set<std::string>& storage_buckets_to_remove,
            bool avoid_closing_connections,
-           const absl::optional<net::CookiePartitionKey>& cookie_partition_key,
-           const absl::optional<blink::StorageKey>& storage_key,
+           const absl::optional<net::CookiePartitionKey> cookie_partition_key,
+           const absl::optional<blink::StorageKey> storage_key,
            bool partitioned_state_allowed_only));
 
  protected:
@@ -93,8 +101,9 @@
       const ClearSiteDataTypeSet clear_site_data_types,
       const std::set<std::string>& storage_buckets_to_remove,
       base::OnceClosure callback) override {
-    ClearSiteData(origin, clear_site_data_types, storage_buckets_to_remove,
-                  false, CookiePartitionKeyForTesting(), StorageKeyForTesting(),
+    ClearSiteData(StoragePartitionConfigForTesting(), origin,
+                  clear_site_data_types, storage_buckets_to_remove, false,
+                  CookiePartitionKeyForTesting(), StorageKeyForTesting(),
                   PartitionedStateOnlyForTesting());
 
     // NOTE: ResourceThrottle expects Resume() to be called asynchronously.
@@ -313,15 +322,16 @@
         url, net::DEFAULT_PRIORITY, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
     TestHandler handler(
         base::BindRepeating(&FakeBrowserContextGetter),
-        base::BindRepeating(&FakeWebContentsGetter), request->url(),
-        test_case.header, request->load_flags(),
+        base::BindRepeating(&FakeWebContentsGetter),
+        kTestStoragePartitionConfig, request->url(), test_case.header,
+        request->load_flags(),
         /*cookie_partition_key=*/absl::nullopt, /*storage_key=*/absl::nullopt,
         /*partitioned_state_allowed_only=*/false, base::DoNothing(),
         std::make_unique<ConsoleMessagesDelegate>());
 
-    EXPECT_CALL(handler,
-                ClearSiteData(url::Origin::Create(url), clear_site_data_types,
-                              test_case.storage_buckets_to_remove, _, _, _, _));
+    EXPECT_CALL(handler, ClearSiteData(
+                             _, url::Origin::Create(url), clear_site_data_types,
+                             test_case.storage_buckets_to_remove, _, _, _, _));
     bool defer = handler.DoHandleHeader();
     EXPECT_TRUE(defer);
 
@@ -383,13 +393,13 @@
   std::vector<Message> message_buffer;
   TestHandler handler(
       base::BindRepeating(&FakeBrowserContextGetter),
-      base::BindRepeating(&FakeWebContentsGetter), request->url(),
-      kClearCookiesHeader, request->load_flags(),
+      base::BindRepeating(&FakeWebContentsGetter), kTestStoragePartitionConfig,
+      request->url(), kClearCookiesHeader, request->load_flags(),
       /*cookie_partition_key=*/absl::nullopt, /*storage_key=*/absl::nullopt,
       /*partitioned_state_allowed_only=*/false, base::DoNothing(),
       std::make_unique<VectorConsoleMessagesDelegate>(&message_buffer));
 
-  EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _, _));
+  EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _, _, _));
   bool defer = handler.DoHandleHeader();
   EXPECT_TRUE(defer);
   EXPECT_EQ(1u, message_buffer.size());
@@ -412,13 +422,13 @@
   std::vector<Message> message_buffer;
   TestHandler handler(
       base::BindRepeating(&FakeBrowserContextGetter),
-      base::BindRepeating(&FakeWebContentsGetter), request->url(),
-      kClearCookiesHeader, request->load_flags(),
+      base::BindRepeating(&FakeWebContentsGetter), kTestStoragePartitionConfig,
+      request->url(), kClearCookiesHeader, request->load_flags(),
       /*cookie_partition_key=*/absl::nullopt, /*storage_key=*/absl::nullopt,
       /*partitioned_state_allowed_only=*/false, base::DoNothing(),
       std::make_unique<VectorConsoleMessagesDelegate>(&message_buffer));
 
-  EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _, _)).Times(0);
+  EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _, _, _)).Times(0);
   bool defer = handler.DoHandleHeader();
   EXPECT_FALSE(defer);
   EXPECT_EQ(1u, message_buffer.size());
@@ -463,13 +473,14 @@
     std::vector<Message> message_buffer;
     TestHandler handler(
         base::BindRepeating(&FakeBrowserContextGetter),
-        base::BindRepeating(&FakeWebContentsGetter), request->url(),
-        kClearCookiesHeader, request->load_flags(),
+        base::BindRepeating(&FakeWebContentsGetter),
+        kTestStoragePartitionConfig, request->url(), kClearCookiesHeader,
+        request->load_flags(),
         /*cookie_partition_key=*/absl::nullopt, /*storage_key=*/absl::nullopt,
         /*partitioned_state_allowed_only=*/false, base::DoNothing(),
         std::make_unique<VectorConsoleMessagesDelegate>(&message_buffer));
 
-    EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _, _))
+    EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _, _, _))
         .Times(test_case.expect_success ? 1 : 0);
 
     bool defer = handler.DoHandleHeader();
@@ -572,8 +583,9 @@
     for (const auto& test : kTestCases) {
       TestHandler handler(
           base::BindRepeating(&FakeBrowserContextGetter),
-          base::BindRepeating(&FakeWebContentsGetter), GURL(test.url),
-          test.header, request->load_flags(),
+          base::BindRepeating(&FakeWebContentsGetter),
+          kTestStoragePartitionConfig, GURL(test.url), test.header,
+          request->load_flags(),
           /*cookie_partition_key=*/absl::nullopt, /*storage_key=*/absl::nullopt,
           /*partitioned_state_allowed_only=*/false, base::DoNothing(),
           std::make_unique<StringConsoleMessagesDelegate>(&output_buffer));
@@ -614,12 +626,14 @@
     std::string output_buffer;
     TestHandler handler(
         base::BindRepeating(&FakeBrowserContextGetter),
-        base::BindRepeating(&FakeWebContentsGetter), kTestURL, "\"cookies\"",
+        base::BindRepeating(&FakeWebContentsGetter),
+        kTestStoragePartitionConfig, kTestURL, "\"cookies\"",
         request->load_flags(), cookie_partition_key,
         /*storage_key=*/absl::nullopt,
         /*partitioned_state_allowed_only=*/false, base::DoNothing(),
         std::make_unique<StringConsoleMessagesDelegate>(&output_buffer));
-    EXPECT_CALL(handler, ClearSiteData(_, _, _, _, cookie_partition_key, _, _));
+    EXPECT_CALL(handler,
+                ClearSiteData(_, _, _, _, _, cookie_partition_key, _, _));
     EXPECT_TRUE(handler.DoHandleHeader());
   }
 }
@@ -638,12 +652,13 @@
     std::string output_buffer;
     TestHandler handler(
         base::BindRepeating(&FakeBrowserContextGetter),
-        base::BindRepeating(&FakeWebContentsGetter), kTestURL, "\"storage\"",
+        base::BindRepeating(&FakeWebContentsGetter),
+        kTestStoragePartitionConfig, kTestURL, "\"storage\"",
         request->load_flags(), /*cookie_partition_key=*/absl::nullopt,
         storage_key,
         /*partitioned_state_allowed_only=*/false, base::DoNothing(),
         std::make_unique<StringConsoleMessagesDelegate>(&output_buffer));
-    EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, storage_key, _));
+    EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _, storage_key, _));
     EXPECT_TRUE(handler.DoHandleHeader());
   }
 }
@@ -660,15 +675,52 @@
     std::string output_buffer;
     TestHandler handler(
         base::BindRepeating(&FakeBrowserContextGetter),
-        base::BindRepeating(&FakeWebContentsGetter), kTestURL, "\"storage\"",
+        base::BindRepeating(&FakeWebContentsGetter),
+        kTestStoragePartitionConfig, kTestURL, "\"storage\"",
         request->load_flags(), /*cookie_partition_key=*/absl::nullopt,
         /*storage_key=*/absl::nullopt, partitioned_state_allowed_only,
         base::DoNothing(),
         std::make_unique<StringConsoleMessagesDelegate>(&output_buffer));
-    EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _,
+    EXPECT_CALL(handler, ClearSiteData(_, _, _, _, _, _, _,
                                        partitioned_state_allowed_only));
     EXPECT_TRUE(handler.DoHandleHeader());
   }
 }
 
+TEST_F(ClearSiteDataHandlerTest, CorrectStoragePartition) {
+  const GURL kTestURL("https://example.com");
+  TestBrowserContext test_browser_context;
+  test_browser_context.set_is_off_the_record(false);
+
+  std::vector<StoragePartitionConfig> test_cases{
+      StoragePartitionConfig::Create(&test_browser_context, "test_domain_0",
+                                     "test name 1", true),
+      StoragePartitionConfig::Create(&test_browser_context, "test_domain_1",
+                                     "test name 2", false),
+      StoragePartitionConfig::Create(&test_browser_context, "test_domain_1",
+                                     "test name 3", false),
+      StoragePartitionConfig::Create(&test_browser_context, "test_domain_1", "",
+                                     false),
+  };
+
+  for (const StoragePartitionConfig& storage_partition_config : test_cases) {
+    auto context = net::CreateTestURLRequestContextBuilder()->Build();
+    std::unique_ptr<net::URLRequest> request(
+        context->CreateRequest(kTestURL, net::DEFAULT_PRIORITY, nullptr,
+                               TRAFFIC_ANNOTATION_FOR_TESTS));
+    std::string output_buffer;
+    TestHandler handler(
+        base::BindRepeating(&FakeBrowserContextGetter),
+        base::BindRepeating(&FakeWebContentsGetter), storage_partition_config,
+        kTestURL, "\"storage\"", request->load_flags(),
+        /*cookie_partition_key=*/absl::nullopt,
+        /*storage_key=*/absl::nullopt, /*partitioned_state_allowed_only=*/false,
+        base::DoNothing(),
+        std::make_unique<StringConsoleMessagesDelegate>(&output_buffer));
+    EXPECT_CALL(handler,
+                ClearSiteData(storage_partition_config, _, _, _, _, _, _, _));
+    EXPECT_TRUE(handler.DoHandleHeader());
+  }
+}
+
 }  // namespace content
diff --git a/content/browser/file_system_access/file_system_access_change_source.cc b/content/browser/file_system_access/file_system_access_change_source.cc
new file mode 100644
index 0000000..4d79ff4
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_change_source.cc
@@ -0,0 +1,78 @@
+// 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/file_system_access/file_system_access_change_source.h"
+
+#include "base/functional/callback.h"
+
+namespace content {
+
+FileSystemAccessChangeSource::FileSystemAccessChangeSource(
+    FileSystemAccessWatchScope scope)
+    : scope_(std::move(scope)) {}
+
+FileSystemAccessChangeSource::~FileSystemAccessChangeSource() {
+  for (auto& observer : observers_) {
+    observer.OnSourceBeingDestroyed(this);
+  }
+}
+
+void FileSystemAccessChangeSource::AddObserver(RawChangeObserver* observer) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  observers_.AddObserver(observer);
+}
+void FileSystemAccessChangeSource::RemoveObserver(RawChangeObserver* observer) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  observers_.RemoveObserver(observer);
+}
+
+void FileSystemAccessChangeSource::EnsureInitialized(
+    base::OnceCallback<void(bool)> on_source_initialized) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (initialization_result_.has_value()) {
+    CHECK(initialization_callbacks_.empty());
+    std::move(on_source_initialized).Run(*initialization_result_);
+    return;
+  }
+
+  initialization_callbacks_.push_back(std::move(on_source_initialized));
+  if (initialization_callbacks_.size() > 1) {
+    return;
+  }
+
+  Initialize(base::BindOnce(&FileSystemAccessChangeSource::DidInitialize,
+                            weak_factory_.GetWeakPtr()));
+}
+
+void FileSystemAccessChangeSource::DidInitialize(bool result) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK(!initialization_result_.has_value());
+  CHECK(!initialization_callbacks_.empty());
+
+  initialization_result_ = result;
+
+  for (auto& callback : initialization_callbacks_) {
+    std::move(callback).Run(result);
+  }
+  initialization_callbacks_.clear();
+}
+
+base::WeakPtr<FileSystemAccessChangeSource>
+FileSystemAccessChangeSource::AsWeakPtr() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  return weak_factory_.GetWeakPtr();
+}
+
+void FileSystemAccessChangeSource::NotifyOfChange(
+    const base::FilePath& relative_path,
+    bool error) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  for (auto& observer : observers_) {
+    observer.OnRawChange(this, relative_path, error);
+  }
+}
+
+}  // namespace content
diff --git a/content/browser/file_system_access/file_system_access_change_source.h b/content/browser/file_system_access/file_system_access_change_source.h
new file mode 100644
index 0000000..f2ee0d35
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_change_source.h
@@ -0,0 +1,86 @@
+// 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_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_CHANGE_SOURCE_H_
+#define CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_CHANGE_SOURCE_H_
+
+#include <list>
+
+#include "base/files/file_path.h"
+#include "base/functional/callback_forward.h"
+#include "base/memory/weak_ptr.h"
+#include "base/observer_list.h"
+#include "base/observer_list_types.h"
+#include "base/sequence_checker.h"
+#include "base/thread_annotations.h"
+#include "content/browser/file_system_access/file_system_access_watch_scope.h"
+#include "content/common/content_export.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace content {
+
+// Notifies of changes to the file system within the given `scope`.
+// This class must constructed, used, and destroyed on the same sequence.
+class CONTENT_EXPORT FileSystemAccessChangeSource {
+ public:
+  class RawChangeObserver : public base::CheckedObserver {
+   public:
+    // Naively notifies of all changes from the corresponding change source.
+    // These events are _not_ safe to be consumed directly by components that
+    // forward events to JavaScript.
+    virtual void OnRawChange(FileSystemAccessChangeSource* source,
+                             const base::FilePath& relative_path,
+                             bool error) = 0;
+    virtual void OnSourceBeingDestroyed(
+        FileSystemAccessChangeSource* source) = 0;
+  };
+
+  // Constructs a change source which notifies of changes within the given
+  // `scope`, which must not be null.
+  explicit FileSystemAccessChangeSource(FileSystemAccessWatchScope scope);
+  virtual ~FileSystemAccessChangeSource();
+
+  void AddObserver(RawChangeObserver* observer);
+  void RemoveObserver(RawChangeObserver* observer);
+
+  // Ensures that this change source is ready to watch for changes within its
+  // `scope_`. This may fail if the scope cannot be watched.
+  // `on_source_initialized` is run with a bool indicating whether setting up
+  // this source succeeds.
+  // TODO(https://crbug.com/1019297): Assert that this is called before
+  // notifying of changes.
+  void EnsureInitialized(base::OnceCallback<void(bool)> on_source_initialized);
+
+  base::WeakPtr<FileSystemAccessChangeSource> AsWeakPtr();
+
+  const FileSystemAccessWatchScope& scope() const { return scope_; }
+
+ protected:
+  virtual void Initialize(
+      base::OnceCallback<void(bool)> on_source_initialized) = 0;
+
+  // Called by subclasses to record changes to watched paths.
+  void NotifyOfChange(const base::FilePath& relative_path, bool error);
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+ private:
+  void DidInitialize(bool result);
+
+  const FileSystemAccessWatchScope scope_;
+
+  absl::optional<bool> initialization_result_;
+  std::list<base::OnceCallback<void(bool)>> initialization_callbacks_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  base::ObserverList<RawChangeObserver> observers_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  base::WeakPtrFactory<FileSystemAccessChangeSource> weak_factory_
+      GUARDED_BY_CONTEXT(sequence_checker_){this};
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_CHANGE_SOURCE_H_
diff --git a/content/browser/file_system_access/file_system_access_handle_base.h b/content/browser/file_system_access/file_system_access_handle_base.h
index e7d9e00a..716ac451 100644
--- a/content/browser/file_system_access/file_system_access_handle_base.h
+++ b/content/browser/file_system_access/file_system_access_handle_base.h
@@ -56,6 +56,10 @@
   const storage::FileSystemURL& url() const { return url_; }
   const SharedHandleState& handle_state() const { return handle_state_; }
   const BindingContext& context() const { return context_; }
+  FileSystemAccessManagerImpl* manager() { return manager_; }
+  storage::FileSystemContext* file_system_context() {
+    return manager()->context();
+  }
 
   PermissionStatus GetReadPermissionStatus();
   PermissionStatus GetWritePermissionStatus();
@@ -113,11 +117,6 @@
       CallbackArgType callback_arg);
 
  protected:
-  FileSystemAccessManagerImpl* manager() { return manager_; }
-  storage::FileSystemContext* file_system_context() {
-    return manager()->context();
-  }
-
   virtual base::WeakPtr<FileSystemAccessHandleBase> AsWeakPtr() = 0;
 
   SEQUENCE_CHECKER(sequence_checker_);
diff --git a/content/browser/file_system_access/file_system_access_local_path_watcher.cc b/content/browser/file_system_access/file_system_access_local_path_watcher.cc
new file mode 100644
index 0000000..a3d0aeed
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_local_path_watcher.cc
@@ -0,0 +1,79 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/file_system_access/file_system_access_local_path_watcher.h"
+
+#include "base/files/file_path.h"
+#include "base/task/bind_post_task.h"
+#include "base/task/thread_pool.h"
+#include "content/browser/file_system_access/file_system_access_watcher_manager.h"
+#include "storage/browser/file_system/file_system_url.h"
+
+namespace content {
+
+namespace {
+
+// Creates a task runner suitable for file path watching.
+scoped_refptr<base::SequencedTaskRunner> CreateFilePathWatcherTaskRunner() {
+  return base::ThreadPool::CreateSequencedTaskRunner({
+      // Needed for file I/O.
+      base::MayBlock(),
+
+      // File path watching is likely not user visible.
+      base::TaskPriority::BEST_EFFORT,
+
+      // File path watching should not block shutdown.
+      base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN,
+  });
+}
+
+}  // namespace
+
+FileSystemAccessLocalPathWatcher::FileSystemAccessLocalPathWatcher(
+    FileSystemAccessWatchScope scope,
+    base::PassKey<FileSystemAccessWatcherManager> /*pass_key*/)
+    : FileSystemAccessChangeSource(std::move(scope)),
+      watcher_(CreateFilePathWatcherTaskRunner()) {}
+
+FileSystemAccessLocalPathWatcher::~FileSystemAccessLocalPathWatcher() = default;
+
+void FileSystemAccessLocalPathWatcher::Initialize(
+    base::OnceCallback<void(bool)> on_source_initialized) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  base::FilePathWatcher::Callback on_change_callback =
+      base::BindRepeating(&FileSystemAccessLocalPathWatcher::OnFilePathChanged,
+                          weak_factory_.GetWeakPtr());
+  watcher_.AsyncCall(&base::FilePathWatcher::WatchWithOptions)
+      .WithArgs(
+          scope().root_url().path(),
+          // TODO(https://crbug.com/1019297): Support recursive watches.
+          // TODO(https://crbug.com/1019297): Report the affected path.
+          base::FilePathWatcher::WatchOptions{
+              .type = base::FilePathWatcher::Type::kNonRecursive},
+          base::BindPostTaskToCurrentDefault(std::move(on_change_callback)))
+      .Then(std::move(on_source_initialized));
+}
+
+void FileSystemAccessLocalPathWatcher::OnFilePathChanged(
+    const base::FilePath& changed_path,
+    bool error) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  const base::FilePath& root_path = scope().root_url().path();
+
+  base::FilePath relative_path;
+  if (root_path.empty()) {
+    relative_path = changed_path;
+  } else if (root_path.IsParent(changed_path)) {
+    CHECK(root_path.AppendRelativePath(changed_path, &relative_path));
+  } else {
+    // It is illegal for a source to notify of a change outside of its scope.
+    CHECK_EQ(root_path, changed_path);
+  }
+
+  NotifyOfChange(relative_path, error);
+}
+
+}  // namespace content
diff --git a/content/browser/file_system_access/file_system_access_local_path_watcher.h b/content/browser/file_system_access/file_system_access_local_path_watcher.h
new file mode 100644
index 0000000..b429292
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_local_path_watcher.h
@@ -0,0 +1,48 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_LOCAL_PATH_WATCHER_H_
+#define CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_LOCAL_PATH_WATCHER_H_
+
+#include "base/files/file_path_watcher.h"
+#include "base/thread_annotations.h"
+#include "base/threading/sequence_bound.h"
+#include "base/types/pass_key.h"
+#include "content/browser/file_system_access/file_system_access_change_source.h"
+#include "content/browser/file_system_access/file_system_access_watch_scope.h"
+
+namespace content {
+
+class FileSystemAccessWatcherManager;
+
+// Watches a local file path and reports changes to its observers.
+// This class must constructed, used, and destroyed on the same sequence.
+class FileSystemAccessLocalPathWatcher : public FileSystemAccessChangeSource {
+ public:
+  FileSystemAccessLocalPathWatcher(
+      FileSystemAccessWatchScope scope,
+      base::PassKey<FileSystemAccessWatcherManager> pass_key);
+  FileSystemAccessLocalPathWatcher(const FileSystemAccessLocalPathWatcher&) =
+      delete;
+  FileSystemAccessLocalPathWatcher& operator=(
+      const FileSystemAccessLocalPathWatcher&) = delete;
+  ~FileSystemAccessLocalPathWatcher() override;
+
+  // FileSystemAccessChangeSource:
+  void Initialize(
+      base::OnceCallback<void(bool)> on_source_initialized) override;
+
+ private:
+  void OnFilePathChanged(const base::FilePath& changed_path, bool error);
+
+  base::SequenceBound<base::FilePathWatcher> watcher_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  base::WeakPtrFactory<FileSystemAccessLocalPathWatcher> weak_factory_
+      GUARDED_BY_CONTEXT(sequence_checker_){this};
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_LOCAL_PATH_WATCHER_H_
diff --git a/content/browser/file_system_access/file_system_access_observer_browsertest.cc b/content/browser/file_system_access/file_system_access_observer_browsertest.cc
new file mode 100644
index 0000000..8c60997
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_observer_browsertest.cc
@@ -0,0 +1,265 @@
+// 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/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "build/buildflag.h"
+#include "content/public/common/content_switches.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/file_system_chooser_test_helpers.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+// TODO(https://crbug.com/1019297): Consider making these WPTs, and adding a
+// lot more of them. For example:
+//   - change types
+//   - recursively watching a directory
+//   - watching non-local file systems
+//   - observing a handle without permission should fail
+//   - changes should not be reported to swap files
+//   - changes should not be reported if permission to the handle is lost
+//   - changes should not be reported if the page is not fully-active
+//   - moving an observed handle
+
+class FileSystemAccessObserverBrowserTestBase : public ContentBrowserTest {
+ public:
+  void SetUp() override {
+    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
+#if BUILDFLAG(IS_WIN)
+    // Convert path to long format to avoid mixing long and 8.3 formats in test.
+    ASSERT_TRUE(temp_dir_.Set(base::MakeLongFilePath(temp_dir_.Take())));
+#endif  // BUILDFLAG(IS_WIN)
+
+    ASSERT_TRUE(embedded_test_server()->Start());
+    test_url_ = embedded_test_server()->GetURL("/title1.html");
+
+    ContentBrowserTest::SetUp();
+  }
+
+  void TearDown() override {
+    ContentBrowserTest::TearDown();
+    ASSERT_TRUE(temp_dir_.Delete());
+    ui::SelectFileDialog::SetFactory(nullptr);
+  }
+
+ protected:
+  base::ScopedTempDir temp_dir_;
+  GURL test_url_;
+};
+
+class FileSystemAccessObserverDefaultBrowserTest
+    : public FileSystemAccessObserverBrowserTestBase {};
+
+IN_PROC_BROWSER_TEST_F(FileSystemAccessObserverDefaultBrowserTest,
+                       DisabledByDefault) {
+  EXPECT_TRUE(NavigateToURL(shell(), test_url_));
+
+  auto result =
+      EvalJs(shell(),
+             "(async () => {"
+             "function onChange(records, observer) {};"
+             "const observer = new FileSystemObserver(onChange); })()");
+  EXPECT_TRUE(result.error.find("not defined") != std::string::npos)
+      << result.error;
+}
+
+class FileSystemAccessObserveWithFlagBrowserTest
+    : public FileSystemAccessObserverBrowserTestBase {
+ public:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    // Enable the flag to use the FileSystemObserver interface.
+    command_line->AppendSwitchASCII(switches::kEnableBlinkFeatures,
+                                    "FileSystemObserver");
+  }
+};
+
+IN_PROC_BROWSER_TEST_F(FileSystemAccessObserveWithFlagBrowserTest,
+                       CreateObserver) {
+  EXPECT_TRUE(NavigateToURL(shell(), test_url_));
+
+  EXPECT_TRUE(
+      ExecJs(shell(),
+             "(async () => {"
+             "function onChange(records, observer) {};"
+             "const observer = new FileSystemObserver(onChange); })()"));
+}
+
+class FileSystemAccessObserverBrowserTest
+    : public FileSystemAccessObserverBrowserTestBase {
+ public:
+  void SetUpCommandLine(base::CommandLine* command_line) override {
+    // Enable experimental web platform features to enable read/write access.
+    command_line->AppendSwitch(
+        switches::kEnableExperimentalWebPlatformFeatures);
+  }
+};
+
+IN_PROC_BROWSER_TEST_F(FileSystemAccessObserverBrowserTest, CreateObserver) {
+  EXPECT_TRUE(NavigateToURL(shell(), test_url_));
+
+  EXPECT_TRUE(
+      ExecJs(shell(),
+             "(async () => {"
+             "function onChange(records, observer) {};"
+             "const observer = new FileSystemObserver(onChange); })()"));
+}
+
+// Local file system access - including the open*Picker() methods used here - is
+// not supported on Android. See https://crbug.com/1011535.
+#if !BUILDFLAG(IS_ANDROID)
+IN_PROC_BROWSER_TEST_F(FileSystemAccessObserverBrowserTest, ObserveFile) {
+  base::FilePath file_path;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    EXPECT_TRUE(
+        base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path));
+    EXPECT_TRUE(base::WriteFile(file_path, "observe me"));
+  }
+
+  ui::SelectFileDialog::SetFactory(
+      std::make_unique<FakeSelectFileDialogFactory>(
+          std::vector<base::FilePath>{file_path}));
+  EXPECT_TRUE(NavigateToURL(shell(), test_url_));
+
+// `base::FilePatchWatcher` is not implemented on Fuchsia. See
+// https://crbug.com/851641. Instead, just check that attempting to observe a
+// handle does not crash.
+#if BUILDFLAG(IS_FUCHSIA)
+  auto result = EvalJs(shell(),
+                       "(async () => {"
+                       "function onChange(records, observer) {};"
+                       "const [file] = await self.showOpenFilePicker();"
+                       "const observer = new FileSystemObserver(onChange);"
+                       "await observer.observe(file); })()");
+  EXPECT_TRUE(result.error.find("did not support") != std::string::npos)
+      << result.error;
+#else
+  EXPECT_TRUE(EvalJs(shell(),
+                     "(async () => {"
+                     "let promiseResolve, promiseReject;"
+                     "let promise = new Promise(function(resolve, reject) {"
+                     "  promiseResolve = resolve;"
+                     "  promiseReject = reject;"
+                     "});"
+                     "async function onChange(records, observer) {"
+                     "  promiseResolve(true);"
+                     "};"
+                     "const [file] = await self.showOpenFilePicker();"
+                     "const observer = new FileSystemObserver(onChange);"
+                     "await observer.observe(file);"
+                     "const writable = await file.createWritable();"
+                     "await writable.write('blah');"
+                     "await writable.close();"
+                     "return await promise; })()")
+                  .ExtractBool());
+#endif  // BUILDFLAG(IS_FUCHSIA)
+}
+
+// `base::FilePatchWatcher` is not implemented on Fuchsia. See
+// https://crbug.com/851641. This test would otherwise be the same as above, so
+// just skip it.
+#if !BUILDFLAG(IS_FUCHSIA)
+IN_PROC_BROWSER_TEST_F(FileSystemAccessObserverBrowserTest, ObserveFileRename) {
+  base::FilePath file_path;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    EXPECT_TRUE(
+        base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path));
+    EXPECT_TRUE(base::WriteFile(file_path, "observe me"));
+  }
+
+  ui::SelectFileDialog::SetFactory(
+      std::make_unique<FakeSelectFileDialogFactory>(
+          std::vector<base::FilePath>{file_path}));
+  EXPECT_TRUE(NavigateToURL(shell(), test_url_));
+
+  EXPECT_TRUE(EvalJs(shell(),
+                     "(async () => {"
+                     "let promiseResolve, promiseReject;"
+                     "let promise = new Promise(function(resolve, reject) {"
+                     "  promiseResolve = resolve;"
+                     "  promiseReject = reject;"
+                     "});"
+                     "async function onChange(records, observer) {"
+                     "  promiseResolve(true);"
+                     "};"
+                     "const [file] = await self.showOpenFilePicker();"
+                     "const observer = new FileSystemObserver(onChange);"
+                     "await observer.observe(file);"
+                     "await file.move('newName.txt');"
+                     "return await promise; })()")
+                  .ExtractBool());
+}
+#endif  // !BUILDFLAG(IS_FUCHSIA)
+
+IN_PROC_BROWSER_TEST_F(FileSystemAccessObserverBrowserTest, ObserveDirectory) {
+  base::FilePath dir_path;
+  {
+    base::ScopedAllowBlockingForTesting allow_blocking;
+    EXPECT_TRUE(base::CreateTemporaryDirInDir(
+        temp_dir_.GetPath(), FILE_PATH_LITERAL("test"), &dir_path));
+  }
+
+  ui::SelectFileDialog::SetFactory(
+      std::make_unique<FakeSelectFileDialogFactory>(
+          std::vector<base::FilePath>{dir_path}));
+  EXPECT_TRUE(NavigateToURL(shell(), test_url_));
+
+// `base::FilePatchWatcher` is not implemented on Fuchsia. See
+// https://crbug.com/851641. Instead, just check that attempting to observe a
+// handle does not crash.
+#if BUILDFLAG(IS_FUCHSIA)
+  auto result = EvalJs(shell(),
+                       "(async () => {"
+                       "function onChange(records, observer) {};"
+                       "const dir = await self.showDirectoryPicker();"
+                       "const observer = new FileSystemObserver(onChange);"
+                       "await observer.observe(dir); })()");
+  EXPECT_TRUE(result.error.find("did not support") != std::string::npos)
+      << result.error;
+#else
+  EXPECT_TRUE(EvalJs(shell(),
+                     "(async () => {"
+                     "let promiseResolve, promiseReject;"
+                     "let promise = new Promise(function(resolve, reject) {"
+                     "  promiseResolve = resolve;"
+                     "  promiseReject = reject;"
+                     "});"
+                     "async function onChange(records, observer) {"
+                     "  promiseResolve(true);"
+                     "};"
+                     "const dir = await self.showDirectoryPicker();"
+                     "const observer = new FileSystemObserver(onChange);"
+                     "await observer.observe(dir);"
+                     "await dir.getFileHandle('newFile.txt', { create:true });"
+                     "return await promise; })()")
+                  .ExtractBool());
+#endif  // BUILDFLAG(IS_FUCHSIA)
+}
+
+#endif  // !BUILDFLAG(IS_ANDROID)
+
+IN_PROC_BROWSER_TEST_F(FileSystemAccessObserverBrowserTest, ObserveBucketFS) {
+  // TODO(https://crbug.com/1019297): The BucketFS is not yet supported.
+
+  EXPECT_TRUE(NavigateToURL(shell(), test_url_));
+
+  auto result = EvalJs(shell(),
+                       "(async () => {"
+                       "function onChange(records, observer) {};"
+                       "const root = await navigator.storage.getDirectory();"
+                       "const observer = new FileSystemObserver(onChange);"
+                       "await observer.observe(root); })()");
+  EXPECT_TRUE(result.error.find("did not support") != std::string::npos)
+      << result.error;
+}
+
+}  // namespace content
diff --git a/content/browser/file_system_access/file_system_access_observer_host.cc b/content/browser/file_system_access/file_system_access_observer_host.cc
index e7f2afa..d6f1194 100644
--- a/content/browser/file_system_access/file_system_access_observer_host.cc
+++ b/content/browser/file_system_access/file_system_access_observer_host.cc
@@ -4,13 +4,20 @@
 
 #include "content/browser/file_system_access/file_system_access_observer_host.h"
 
-#include "base/feature_list.h"
+#include <memory>
+
+#include "content/browser/file_system_access/file_system_access_directory_handle_impl.h"
 #include "content/browser/file_system_access/file_system_access_error.h"
+#include "content/browser/file_system_access/file_system_access_file_handle_impl.h"
 #include "content/browser/file_system_access/file_system_access_manager_impl.h"
+#include "content/browser/file_system_access/file_system_access_observer_observation.h"
+#include "content/browser/file_system_access/file_system_access_transfer_token_impl.h"
 #include "content/browser/file_system_access/file_system_access_watcher_manager.h"
 #include "content/public/browser/file_system_access_permission_context.h"
-#include "third_party/blink/public/common/features.h"
+#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "storage/browser/file_system/file_system_url.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_observer.mojom.h"
+#include "third_party/blink/public/mojom/permissions/permission_status.mojom-shared.h"
 
 namespace content {
 
@@ -29,9 +36,8 @@
   CHECK(manager_);
   CHECK(watcher_manager_);
 
-  // TODO(https://crbug.com/1019297): Add this flag to chrome://flags.
-  CHECK(base::FeatureList::IsEnabled(blink::features::kFileSystemObserver));
-
+  // `base::Unretained` is safe here because this instance owns
+  // `host_receiver_`.
   host_receiver_.set_disconnect_handler(
       base::BindOnce(&FileSystemAccessObserverHost::OnHostReceiverDisconnect,
                      base::Unretained(this)));
@@ -48,16 +54,65 @@
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   CHECK(manager_);
 
-  mojo::PendingRemote<blink::mojom::FileSystemAccessObserver> observer_remote;
-  mojo::PendingReceiver<blink::mojom::FileSystemAccessObserver>
-      observer_receiver = observer_remote.InitWithNewPipeAndPassReceiver();
+  manager_->ResolveTransferToken(
+      std::move(token),
+      base::BindOnce(
+          &FileSystemAccessObserverHost::DidResolveTransferTokenToObserve,
+          weak_factory_.GetWeakPtr(), is_recursive, std::move(callback)));
+}
 
-  // TODO(https://crbug.com/1019297): Actually watch the file path.
+void FileSystemAccessObserverHost::DidResolveTransferTokenToObserve(
+    bool is_recursive,
+    ObserveCallback callback,
+    FileSystemAccessTransferTokenImpl* resolved_token) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  observer_remotes_.Add(std::move(observer_remote));
+  if (!resolved_token) {
+    std::move(callback).Run(
+        file_system_access_error::FromStatus(
+            blink::mojom::FileSystemAccessStatus::kInvalidArgument),
+        mojo::NullReceiver());
+    return;
+  }
 
-  std::move(callback).Run(file_system_access_error::Ok(),
-                          std::move(observer_receiver));
+  if (resolved_token->GetReadGrant()->GetStatus() !=
+      blink::mojom::PermissionStatus::GRANTED) {
+    std::move(callback).Run(
+        file_system_access_error::FromStatus(
+            blink::mojom::FileSystemAccessStatus::kPermissionDenied),
+        mojo::NullReceiver());
+    return;
+  }
+
+  if (resolved_token->url().mount_type() !=
+      storage::FileSystemType::kFileSystemTypeLocal) {
+    // TODO(https://crbug.com/1019297): Support non-local file systems.
+    std::move(callback).Run(
+        file_system_access_error::FromStatus(
+            blink::mojom::FileSystemAccessStatus::kNotSupportedError),
+        mojo::NullReceiver());
+    return;
+  }
+
+  switch (resolved_token->type()) {
+    case FileSystemAccessPermissionContext::HandleType::kDirectory:
+      watcher_manager()->GetDirectoryObservation(
+          resolved_token->url(), is_recursive,
+          base::BindOnce(
+              &FileSystemAccessObserverHost::GotObservation,
+              weak_factory_.GetWeakPtr(),
+              resolved_token->CreateDirectoryHandle(binding_context()),
+              std::move(callback)));
+      break;
+    case FileSystemAccessPermissionContext::HandleType::kFile:
+      watcher_manager()->GetFileObservation(
+          resolved_token->url(),
+          base::BindOnce(&FileSystemAccessObserverHost::GotObservation,
+                         weak_factory_.GetWeakPtr(),
+                         resolved_token->CreateFileHandle(binding_context()),
+                         std::move(callback)));
+      break;
+  }
 }
 
 void FileSystemAccessObserverHost::Unobserve(
@@ -69,9 +124,46 @@
   NOTIMPLEMENTED();
 }
 
+void FileSystemAccessObserverHost::GotObservation(
+    absl::variant<std::unique_ptr<FileSystemAccessDirectoryHandleImpl>,
+                  std::unique_ptr<FileSystemAccessFileHandleImpl>> handle,
+    ObserveCallback callback,
+    std::unique_ptr<FileSystemAccessWatcherManager::Observation> observation) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (!observation) {
+    std::move(callback).Run(
+        file_system_access_error::FromStatus(
+            blink::mojom::FileSystemAccessStatus::kNotSupportedError),
+        mojo::NullReceiver());
+    return;
+  }
+
+  mojo::PendingRemote<blink::mojom::FileSystemAccessObserver> observer_remote;
+  mojo::PendingReceiver<blink::mojom::FileSystemAccessObserver>
+      observer_receiver = observer_remote.InitWithNewPipeAndPassReceiver();
+
+  auto observer_observation =
+      std::make_unique<FileSystemAccessObserverObservation>(
+          this, std::move(observation), std::move(observer_remote),
+          std::move(handle));
+  observations_.insert(std::move(observer_observation));
+
+  std::move(callback).Run(file_system_access_error::Ok(),
+                          std::move(observer_receiver));
+}
+
+void FileSystemAccessObserverHost::RemoveObservation(
+    FileSystemAccessObserverObservation* observation) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  size_t count_removed = observations_.erase(observation);
+  CHECK_EQ(count_removed, 1u);
+}
+
 void FileSystemAccessObserverHost::OnHostReceiverDisconnect() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  observer_remotes_.Clear();
+  observations_.clear();
   host_receiver_.reset();
 
   // Destroys `this`.
diff --git a/content/browser/file_system_access/file_system_access_observer_host.h b/content/browser/file_system_access/file_system_access_observer_host.h
index 0607c3e..60cd43c 100644
--- a/content/browser/file_system_access/file_system_access_observer_host.h
+++ b/content/browser/file_system_access/file_system_access_observer_host.h
@@ -5,14 +5,17 @@
 #ifndef CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_OBSERVER_HOST_H_
 #define CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_OBSERVER_HOST_H_
 
+#include <memory>
+
+#include "base/containers/flat_set.h"
+#include "base/containers/unique_ptr_adapters.h"
 #include "base/sequence_checker.h"
 #include "content/browser/file_system_access/file_system_access_manager_impl.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
-#include "mojo/public/cpp/bindings/remote_set.h"
-#include "third_party/blink/public/mojom/file_system_access/file_system_access_observer.mojom.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_observer_host.mojom.h"
 
 namespace content {
+class FileSystemAccessObserverObservation;
 class FileSystemAccessWatcherManager;
 
 // Stores the state associated with each FileSystemAccessObserverHost mojo
@@ -48,9 +51,26 @@
       mojo::PendingRemote<blink::mojom::FileSystemAccessTransferToken> token)
       override;
 
+  void RemoveObservation(FileSystemAccessObserverObservation* observation);
+
   const BindingContext& binding_context() const { return binding_context_; }
+  FileSystemAccessManagerImpl* manager() const { return manager_; }
+  FileSystemAccessWatcherManager* watcher_manager() const {
+    return watcher_manager_;
+  }
 
  private:
+  void DidResolveTransferTokenToObserve(
+      bool is_recursive,
+      ObserveCallback callback,
+      FileSystemAccessTransferTokenImpl* resolved_token);
+
+  void GotObservation(
+      absl::variant<std::unique_ptr<FileSystemAccessDirectoryHandleImpl>,
+                    std::unique_ptr<FileSystemAccessFileHandleImpl>> handle,
+      ObserveCallback callback,
+      std::unique_ptr<FileSystemAccessWatcherManager::Observation> observation);
+
   void OnHostReceiverDisconnect();
 
   SEQUENCE_CHECKER(sequence_checker_);
@@ -61,10 +81,12 @@
   const raw_ptr<FileSystemAccessWatcherManager> watcher_manager_;
   const BindingContext binding_context_;
 
-  // Mojo pipes that send file change notifications back to the renderer.
-  // Each connection corresponds to a file system watch set up with `Observe()`.
-  mojo::RemoteSet<blink::mojom::FileSystemAccessObserver> observer_remotes_
-      GUARDED_BY_CONTEXT(sequence_checker_);
+  // Observations which maintain mojo pipes that send file change notifications
+  // back to the renderer. Each connection corresponds to a file system watch
+  // set up with `Observe()`.
+  base::flat_set<std::unique_ptr<FileSystemAccessObserverObservation>,
+                 base::UniquePtrComparator>
+      observations_;
 
   // Connection owned by a FileSystemObserver object. When the
   // FileSystemObserver is destroyed, this instance will remove itself from the
diff --git a/content/browser/file_system_access/file_system_access_observer_observation.cc b/content/browser/file_system_access/file_system_access_observer_observation.cc
new file mode 100644
index 0000000..fa44f1c
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_observer_observation.cc
@@ -0,0 +1,211 @@
+// 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/file_system_access/file_system_access_observer_observation.h"
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/files/file_path.h"
+#include "base/functional/bind.h"
+#include "build/buildflag.h"
+#include "content/browser/file_system_access/file_system_access_directory_handle_impl.h"
+#include "content/browser/file_system_access/file_system_access_file_handle_impl.h"
+#include "content/browser/file_system_access/file_system_access_handle_base.h"
+#include "content/browser/file_system_access/file_system_access_manager_impl.h"
+#include "content/browser/file_system_access/file_system_access_observer_host.h"
+#include "content/browser/file_system_access/file_system_access_transfer_token_impl.h"
+#include "content/browser/file_system_access/file_system_access_watch_scope.h"
+#include "content/browser/file_system_access/file_system_access_watcher_manager.h"
+#include "content/public/browser/file_system_access_permission_context.h"
+#include "storage/browser/file_system/file_system_context.h"
+#include "storage/browser/file_system/file_system_url.h"
+#include "third_party/blink/public/mojom/file_system_access/file_system_access_directory_handle.mojom.h"
+#include "third_party/blink/public/mojom/file_system_access/file_system_access_observer.mojom.h"
+#include "third_party/blink/public/mojom/permissions/permission_status.mojom-shared.h"
+
+#if BUILDFLAG(IS_WIN)
+#include "base/strings/utf_string_conversions.h"
+#endif  // BUILDFLAG(IS_WIN)
+
+namespace content {
+
+namespace {
+
+FileSystemAccessPermissionContext::HandleType GetHandleType(
+    const absl::variant<std::unique_ptr<FileSystemAccessDirectoryHandleImpl>,
+                        std::unique_ptr<FileSystemAccessFileHandleImpl>>&
+        handle) {
+  return absl::get_if<std::unique_ptr<FileSystemAccessDirectoryHandleImpl>>(
+             &handle)
+             ? FileSystemAccessPermissionContext::HandleType::kDirectory
+             : FileSystemAccessPermissionContext::HandleType::kFile;
+}
+
+FileSystemAccessHandleBase& AsHandleBase(
+    const absl::variant<std::unique_ptr<FileSystemAccessDirectoryHandleImpl>,
+                        std::unique_ptr<FileSystemAccessFileHandleImpl>>&
+        handle) {
+  auto* dir_handle_ptr =
+      absl::get_if<std::unique_ptr<FileSystemAccessDirectoryHandleImpl>>(
+          &handle);
+  if (dir_handle_ptr) {
+    return *static_cast<FileSystemAccessHandleBase*>(dir_handle_ptr->get());
+  }
+
+  return *absl::get<std::unique_ptr<FileSystemAccessFileHandleImpl>>(handle);
+}
+
+// TODO(https://crbug.com/1019297): Move this to a helper shared with
+// `FileSystemAccessDirectoryHandleImpl`.
+std::vector<std::string> GetRelativePathAsVectorOfStrings(
+    const base::FilePath& relative_path) {
+  CHECK(!relative_path.IsAbsolute());
+  CHECK(!relative_path.ReferencesParent());
+
+  std::vector<base::FilePath::StringType> components =
+      relative_path.GetComponents();
+#if BUILDFLAG(IS_WIN)
+  std::vector<std::string> result;
+  result.reserve(components.size());
+  for (const auto& component : components) {
+    result.push_back(base::WideToUTF8(component));
+  }
+  return result;
+#else
+  return components;
+#endif  //  BUILDFLAG(IS_WIN)
+}
+
+}  // namespace
+
+FileSystemAccessObserverObservation::FileSystemAccessObserverObservation(
+    FileSystemAccessObserverHost* host,
+    std::unique_ptr<FileSystemAccessWatcherManager::Observation> observation,
+    mojo::PendingRemote<blink::mojom::FileSystemAccessObserver> remote,
+    absl::variant<std::unique_ptr<FileSystemAccessDirectoryHandleImpl>,
+                  std::unique_ptr<FileSystemAccessFileHandleImpl>> handle)
+    : host_(host),
+      handle_(std::move(handle)),
+      observation_(std::move(observation)),
+      remote_(std::move(remote)) {
+  CHECK(host);
+  CHECK(observation_);
+
+  CHECK(observation_->scope().Contains(AsHandleBase(handle_).url()));
+
+  observation_->SetCallback(
+      base::BindRepeating(&FileSystemAccessObserverObservation::OnChanges,
+                          weak_factory_.GetWeakPtr()));
+
+  // `base::Unretained` is safe here because this instance owns
+  // `remote_`.
+  remote_.set_disconnect_handler(
+      base::BindOnce(&FileSystemAccessObserverObservation::OnReceiverDisconnect,
+                     base::Unretained(this)));
+}
+
+FileSystemAccessObserverObservation::~FileSystemAccessObserverObservation() =
+    default;
+
+void FileSystemAccessObserverObservation::OnChanges(
+    const std::list<FileSystemAccessWatcherManager::Observation::Change>&
+        changes) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  FileSystemAccessManagerImpl* manager = AsHandleBase(handle_).manager();
+  const FileSystemAccessManagerImpl::BindingContext& binding_context =
+      AsHandleBase(handle_).context();
+  const FileSystemAccessManagerImpl::SharedHandleState& handle_state =
+      AsHandleBase(handle_).handle_state();
+  const storage::FileSystemURL& handle_url = AsHandleBase(handle_).url();
+
+  // Do not relay changes if the site has lost read permission to the handle.
+  // TODO(https://crbug.com/1019297): Add tests for this.
+  if (handle_state.read_grant->GetStatus() !=
+      blink::mojom::PermissionStatus::GRANTED) {
+    // TODO(https://crbug.com/1019297): Proactively listen for permission
+    // changes, rather than (or perhaps in addition to) checking on each change.
+    return;
+  }
+
+  std::vector<blink::mojom::FileSystemAccessChangePtr> mojo_changes;
+  for (const auto& change : changes) {
+    if (change.error) {
+      // TODO(https://crbug.com/1019297): Consider destroying `observation_`...
+      // Or don't bother passing along errored changes from the WatcherManager
+      // to its Observations in the first place.
+      continue;
+    }
+
+    // TODO(https://crbug.com/1019297): Consider refactoring to keep the "scope"
+    // concept within the WatcherManager and its associated classes. This method
+    // just needs the root url.
+    //
+    // It is illegal to receive a change outside of the observed scope.
+    CHECK(observation_->scope().Contains(change.url));
+
+    blink::mojom::FileSystemAccessEntryPtr changed_entry, root_entry;
+    switch (GetHandleType(handle_)) {
+        // TODO(https://crbug.com/1425601): Don't assume the `HandleType` of the
+        // changed path is the same as `handle_`'s.
+      case FileSystemAccessPermissionContext::HandleType::kDirectory:
+        changed_entry = blink::mojom::FileSystemAccessEntry::New(
+            blink::mojom::FileSystemAccessHandle::NewDirectory(
+                manager->CreateDirectoryHandle(binding_context, change.url,
+                                               handle_state)),
+            change.url.virtual_path().BaseName().AsUTF8Unsafe());
+        root_entry = blink::mojom::FileSystemAccessEntry::New(
+            blink::mojom::FileSystemAccessHandle::NewDirectory(
+                manager->CreateDirectoryHandle(binding_context, handle_url,
+                                               handle_state)),
+            handle_url.virtual_path().BaseName().AsUTF8Unsafe());
+        break;
+      case FileSystemAccessPermissionContext::HandleType::kFile:
+        changed_entry = blink::mojom::FileSystemAccessEntry::New(
+            blink::mojom::FileSystemAccessHandle::NewFile(
+                manager->CreateFileHandle(binding_context, change.url,
+                                          handle_state)),
+            change.url.virtual_path().BaseName().AsUTF8Unsafe());
+        root_entry = blink::mojom::FileSystemAccessEntry::New(
+            blink::mojom::FileSystemAccessHandle::NewFile(
+                manager->CreateFileHandle(binding_context, handle_url,
+                                          handle_state)),
+            handle_url.virtual_path().BaseName().AsUTF8Unsafe());
+        break;
+    }
+
+    const base::FilePath& root_path = handle_url.path();
+    const base::FilePath& changed_path = change.url.path();
+
+    base::FilePath relative_path;
+    if (root_path.empty()) {
+      relative_path = changed_path;
+    } else if (root_path.IsParent(changed_path)) {
+      CHECK(root_path.AppendRelativePath(changed_path, &relative_path));
+    } else {
+      CHECK_EQ(root_path, changed_path);
+    }
+
+    mojo_changes.emplace_back(blink::mojom::FileSystemAccessChange::New(
+        blink::mojom::FileSystemAccessChangeMetadata::New(
+            std::move(root_entry), std::move(changed_entry),
+            GetRelativePathAsVectorOfStrings(relative_path)),
+        // TODO(https://crbug.com/1425601): Support change types.
+        blink::mojom::FileSystemAccessChangeType::NewModified(
+            blink::mojom::FileSystemAccessChangeTypeModified::New())));
+  }
+
+  remote_->OnFileChanges(std::move(mojo_changes));
+}
+
+void FileSystemAccessObserverObservation::OnReceiverDisconnect() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  // Destroys `this`.
+  host_->RemoveObservation(this);
+}
+
+}  // namespace content
diff --git a/content/browser/file_system_access/file_system_access_observer_observation.h b/content/browser/file_system_access/file_system_access_observer_observation.h
new file mode 100644
index 0000000..7b156e9
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_observer_observation.h
@@ -0,0 +1,78 @@
+// 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_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_OBSERVER_OBSERVATION_H_
+#define CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_OBSERVER_OBSERVATION_H_
+
+#include <memory>
+
+#include "base/sequence_checker.h"
+#include "base/thread_annotations.h"
+#include "content/browser/file_system_access/file_system_access_watcher_manager.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
+#include "third_party/abseil-cpp/absl/types/variant.h"
+#include "third_party/blink/public/mojom/file_system_access/file_system_access_observer.mojom.h"
+
+namespace content {
+class FileSystemAccessDirectoryHandleImpl;
+class FileSystemAccessFileHandleImpl;
+class FileSystemAccessObserverHost;
+
+// Browser-side representation of a successful `FileSystemObserver.observe()`
+// call from JavaScript. Forwards changes to the observed file or directory
+// to a mojo pipe whose receiver is owned by the renderer.
+//
+// TODO(https://crbug.com/1019297): Consider removing this class in favor of
+// giving the ObserverHost a FileSystemAccessObserver mojo::RemoteSet. See
+// https://chromium-review.googlesource.com/c/chromium/src/+/4809069/comment/8d90508d_74ae7891/.
+class FileSystemAccessObserverObservation {
+ public:
+  FileSystemAccessObserverObservation(
+      FileSystemAccessObserverHost* host,
+      std::unique_ptr<FileSystemAccessWatcherManager::Observation> observation,
+      mojo::PendingRemote<blink::mojom::FileSystemAccessObserver> remote,
+      absl::variant<std::unique_ptr<FileSystemAccessDirectoryHandleImpl>,
+                    std::unique_ptr<FileSystemAccessFileHandleImpl>> handle);
+  ~FileSystemAccessObserverObservation();
+
+  FileSystemAccessObserverObservation(
+      FileSystemAccessObserverObservation const&) = delete;
+  FileSystemAccessObserverObservation& operator=(
+      FileSystemAccessObserverObservation const&) = delete;
+
+ private:
+  void OnReceiverDisconnect();
+
+  // Called repeatedly by `observation_`.
+  void OnChanges(
+      const std::list<FileSystemAccessWatcherManager::Observation::Change>&
+          changes);
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  // The host which owns this instance.
+  const raw_ptr<FileSystemAccessObserverHost> host_;
+
+  // The `FileSystemHandle` being observed.
+  const absl::variant<std::unique_ptr<FileSystemAccessDirectoryHandleImpl>,
+                      std::unique_ptr<FileSystemAccessFileHandleImpl>>
+      handle_;
+
+  std::unique_ptr<FileSystemAccessWatcherManager::Observation> observation_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // Mojo pipes that send file change notifications back to the renderer.
+  // Each connection corresponds to a file system watch set up with
+  // `Observe()`.
+  mojo::Remote<blink::mojom::FileSystemAccessObserver> remote_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  base::WeakPtrFactory<FileSystemAccessObserverObservation> weak_factory_
+      GUARDED_BY_CONTEXT(sequence_checker_){this};
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_OBSERVER_OBSERVATION_H_
diff --git a/content/browser/file_system_access/file_system_access_watch_scope.cc b/content/browser/file_system_access/file_system_access_watch_scope.cc
new file mode 100644
index 0000000..63f12b2
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_watch_scope.cc
@@ -0,0 +1,73 @@
+// 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/file_system_access/file_system_access_watch_scope.h"
+
+namespace content {
+
+namespace {
+
+bool IsStrictParent(const storage::FileSystemURL& parent,
+                    const storage::FileSystemURL& child) {
+  return parent.IsParent(child) && parent.path() == child.path().DirName();
+}
+
+}  // namespace
+
+// static
+FileSystemAccessWatchScope FileSystemAccessWatchScope::GetScopeForFileWatch(
+    const storage::FileSystemURL& file_url) {
+  return {file_url, WatchType::kFile};
+}
+
+// static
+FileSystemAccessWatchScope
+FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+    const storage::FileSystemURL& directory_url,
+    bool is_recursive) {
+  return {directory_url, is_recursive ? WatchType::kDirectoryRecursive
+                                      : WatchType::kDirectoryNonRecursive};
+}
+
+FileSystemAccessWatchScope::FileSystemAccessWatchScope(
+    storage::FileSystemURL root_url,
+    WatchType watch_type)
+    : root_url_(std::move(root_url)), watch_type_(watch_type) {}
+FileSystemAccessWatchScope::~FileSystemAccessWatchScope() = default;
+
+FileSystemAccessWatchScope::FileSystemAccessWatchScope(
+    const FileSystemAccessWatchScope&) = default;
+FileSystemAccessWatchScope::FileSystemAccessWatchScope(
+    FileSystemAccessWatchScope&&) noexcept = default;
+FileSystemAccessWatchScope& FileSystemAccessWatchScope::operator=(
+    const FileSystemAccessWatchScope&) = default;
+FileSystemAccessWatchScope& FileSystemAccessWatchScope::operator=(
+    FileSystemAccessWatchScope&&) noexcept = default;
+
+bool FileSystemAccessWatchScope::Contains(
+    const storage::FileSystemURL& url) const {
+  switch (watch_type_) {
+    case WatchType::kFile:
+      return url == root_url();
+    case WatchType::kDirectoryNonRecursive:
+      return url == root_url() || IsStrictParent(root_url(), url);
+    case WatchType::kDirectoryRecursive:
+      return url == root_url() || root_url().IsParent(url);
+  }
+}
+
+bool FileSystemAccessWatchScope::Contains(
+    const FileSystemAccessWatchScope& scope) const {
+  switch (watch_type_) {
+    case WatchType::kFile:
+      return *this == scope;
+    case WatchType::kDirectoryNonRecursive:
+      return *this == scope || (scope.watch_type_ == WatchType::kFile &&
+                                IsStrictParent(root_url(), scope.root_url()));
+    case WatchType::kDirectoryRecursive:
+      return Contains(scope.root_url());
+  }
+}
+
+}  // namespace content
diff --git a/content/browser/file_system_access/file_system_access_watch_scope.h b/content/browser/file_system_access/file_system_access_watch_scope.h
new file mode 100644
index 0000000..c000d12
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_watch_scope.h
@@ -0,0 +1,71 @@
+// 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_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_WATCH_SCOPE_H_
+#define CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_WATCH_SCOPE_H_
+
+#include "content/common/content_export.h"
+#include "content/public/browser/file_system_access_permission_context.h"
+#include "storage/browser/file_system/file_system_url.h"
+
+namespace content {
+
+// Describes the extent of the file system that is being observed, which can be
+// a single file, a directory and its contents, or a directory and all its
+// subdirectories.
+class CONTENT_EXPORT FileSystemAccessWatchScope {
+ public:
+  // TODO(https://crbug.com/1019297): Consider using something like a PassKey
+  // to restrict access to these initializers.
+  static FileSystemAccessWatchScope GetScopeForFileWatch(
+      const storage::FileSystemURL& file_url);
+  static FileSystemAccessWatchScope GetScopeForDirectoryWatch(
+      const storage::FileSystemURL& directory_url,
+      bool is_recursive);
+
+  ~FileSystemAccessWatchScope();
+
+  // Copyable and movable.
+  FileSystemAccessWatchScope(const FileSystemAccessWatchScope&);
+  FileSystemAccessWatchScope(FileSystemAccessWatchScope&&) noexcept;
+  FileSystemAccessWatchScope& operator=(const FileSystemAccessWatchScope&);
+  FileSystemAccessWatchScope& operator=(FileSystemAccessWatchScope&&) noexcept;
+
+  // Returns true if `url` is contained within this `Scope`.
+  bool Contains(const storage::FileSystemURL& url) const;
+  // Returns true if `scope` is contained within this `Scope`.
+  bool Contains(const FileSystemAccessWatchScope& scope) const;
+
+  const storage::FileSystemURL& root_url() const { return root_url_; }
+  FileSystemAccessPermissionContext::HandleType handle_type() const {
+    switch (watch_type_) {
+      case WatchType::kFile:
+        return FileSystemAccessPermissionContext::HandleType::kFile;
+      case WatchType::kDirectoryNonRecursive:
+      case WatchType::kDirectoryRecursive:
+        return FileSystemAccessPermissionContext::HandleType::kDirectory;
+    }
+  }
+
+  bool operator==(const FileSystemAccessWatchScope& other) const {
+    return root_url_ == other.root_url_ && watch_type_ == other.watch_type_;
+  }
+
+ private:
+  enum class WatchType {
+    kFile,
+    kDirectoryNonRecursive,
+    kDirectoryRecursive,
+  };
+
+  FileSystemAccessWatchScope(storage::FileSystemURL root_url,
+                             WatchType watch_type);
+
+  storage::FileSystemURL root_url_;
+  WatchType watch_type_;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_WATCH_SCOPE_H_
diff --git a/content/browser/file_system_access/file_system_access_watch_scope_unittest.cc b/content/browser/file_system_access/file_system_access_watch_scope_unittest.cc
new file mode 100644
index 0000000..8948ba82
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_watch_scope_unittest.cc
@@ -0,0 +1,224 @@
+// 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/file_system_access/file_system_access_watch_scope.h"
+
+#include <list>
+
+#include "base/files/file_path.h"
+#include "base/files/safe_base_name.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/test/task_environment.h"
+#include "storage/browser/file_system/file_system_context.h"
+#include "storage/browser/file_system/file_system_url.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
+#include "storage/browser/test/test_file_system_context.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+#if BUILDFLAG(IS_WIN)
+#include "base/files/file_util.h"
+#endif  // BUILDFLAG(IS_WIN)
+
+namespace content {
+
+class FileSystemAccessWatchScopeTest : public testing::Test {
+ public:
+  FileSystemAccessWatchScopeTest()
+      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
+
+  void SetUp() override {
+    ASSERT_TRUE(dir_.CreateUniqueTempDir());
+#if BUILDFLAG(IS_WIN)
+    // Convert path to long format to avoid mixing long and 8.3 formats in test.
+    ASSERT_TRUE(dir_.Set(base::MakeLongFilePath(dir_.Take())));
+#endif  // BUILDFLAG(IS_WIN)
+
+    file_system_context_ = storage::CreateFileSystemContextForTesting(
+        /*quota_manager_proxy=*/nullptr, dir_.GetPath());
+  }
+
+  void TearDown() override { EXPECT_TRUE(dir_.Delete()); }
+
+  storage::FileSystemURL CreateFileSystemURLFromPath(
+      const base::FilePath& path) {
+    return file_system_context_->CreateCrackedFileSystemURL(
+        blink::StorageKey(), storage::kFileSystemTypeLocal, path);
+  }
+
+ protected:
+  base::test::TaskEnvironment task_environment_;
+  base::ScopedTempDir dir_;
+
+  scoped_refptr<storage::FileSystemContext> file_system_context_;
+};
+
+TEST_F(FileSystemAccessWatchScopeTest, FileScope) {
+  auto file_path = dir_.GetPath().AppendASCII("file");
+  auto file_url = CreateFileSystemURLFromPath(file_path);
+
+  auto scope = FileSystemAccessWatchScope::GetScopeForFileWatch(file_url);
+
+  EXPECT_TRUE(scope.Contains(scope));
+  EXPECT_TRUE(scope.Contains(file_url));
+
+  absl::optional<base::SafeBaseName> sibling_name =
+      base::SafeBaseName::Create(FILE_PATH_LITERAL("sibling"));
+  auto sibling_url = file_url.CreateSibling(*sibling_name);
+  EXPECT_FALSE(scope.Contains(sibling_url));
+
+  auto sibling_scope =
+      FileSystemAccessWatchScope::GetScopeForFileWatch(sibling_url);
+  EXPECT_FALSE(scope.Contains(sibling_scope));
+  EXPECT_FALSE(sibling_scope.Contains(scope));
+
+  auto parent_url = CreateFileSystemURLFromPath(file_path.DirName());
+  EXPECT_FALSE(scope.Contains(parent_url));
+
+  auto parent_non_recursive_scope =
+      FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+          parent_url, /*is_recursive=*/false);
+  EXPECT_FALSE(scope.Contains(parent_non_recursive_scope));
+  EXPECT_TRUE(parent_non_recursive_scope.Contains(scope));
+
+  auto parent_recursive_scope =
+      FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+          parent_url, /*is_recursive=*/true);
+  EXPECT_FALSE(scope.Contains(parent_recursive_scope));
+  EXPECT_TRUE(parent_recursive_scope.Contains(scope));
+
+  // A file shouldn't have a child, but... test it just in case.
+  auto child_url = CreateFileSystemURLFromPath(file_path.AppendASCII("child"));
+  EXPECT_FALSE(scope.Contains(child_url));
+
+  auto child_scope =
+      FileSystemAccessWatchScope::GetScopeForFileWatch(child_url);
+  EXPECT_FALSE(scope.Contains(child_scope));
+  EXPECT_FALSE(child_scope.Contains(scope));
+
+  // TODO(https://crbug.com/1019297): Test that URLs from different file systems
+  // return are out of scope.
+}
+
+TEST_F(FileSystemAccessWatchScopeTest, DirectoryScope) {
+  auto dir_path = dir_.GetPath().AppendASCII("dir");
+  auto dir_url = CreateFileSystemURLFromPath(dir_path);
+
+  auto scope = FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+      dir_url, /*is_recursive=*/false);
+
+  EXPECT_TRUE(scope.Contains(scope));
+  EXPECT_TRUE(scope.Contains(dir_url));
+
+  absl::optional<base::SafeBaseName> sibling_name =
+      base::SafeBaseName::Create(FILE_PATH_LITERAL("sibling"));
+  auto sibling_url = dir_url.CreateSibling(*sibling_name);
+  EXPECT_FALSE(scope.Contains(sibling_url));
+
+  auto sibling_scope =
+      FileSystemAccessWatchScope::GetScopeForFileWatch(sibling_url);
+  EXPECT_FALSE(scope.Contains(sibling_scope));
+  EXPECT_FALSE(sibling_scope.Contains(scope));
+
+  auto parent_url = CreateFileSystemURLFromPath(dir_path.DirName());
+  EXPECT_FALSE(scope.Contains(parent_url));
+
+  auto parent_non_recursive_scope =
+      FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+          parent_url, /*is_recursive=*/false);
+  EXPECT_FALSE(scope.Contains(parent_non_recursive_scope));
+  // TODO(https://crbug.com/1019297): This is unfortunate. See what can be done
+  // here.
+  EXPECT_FALSE(parent_non_recursive_scope.Contains(scope));
+
+  auto parent_recursive_scope =
+      FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+          parent_url, /*is_recursive=*/true);
+  EXPECT_FALSE(scope.Contains(parent_recursive_scope));
+  EXPECT_TRUE(parent_recursive_scope.Contains(scope));
+
+  auto child_path = dir_path.AppendASCII("child");
+  auto child_url = CreateFileSystemURLFromPath(child_path);
+  ASSERT_TRUE(dir_url.IsParent(child_url));
+  EXPECT_TRUE(scope.Contains(child_url));
+
+  auto child_scope =
+      FileSystemAccessWatchScope::GetScopeForFileWatch(child_url);
+  EXPECT_TRUE(scope.Contains(child_scope));
+  EXPECT_FALSE(child_scope.Contains(scope));
+
+  auto grandchild_url =
+      CreateFileSystemURLFromPath(child_path.AppendASCII("grand"));
+  ASSERT_TRUE(child_url.IsParent(grandchild_url));
+  EXPECT_FALSE(scope.Contains(grandchild_url));
+
+  auto grandchild_scope =
+      FileSystemAccessWatchScope::GetScopeForFileWatch(grandchild_url);
+  EXPECT_FALSE(scope.Contains(grandchild_scope));
+  EXPECT_FALSE(grandchild_scope.Contains(scope));
+
+  // TODO(https://crbug.com/1019297): Test that URLs from different file systems
+  // return are out of scope.
+}
+
+TEST_F(FileSystemAccessWatchScopeTest, RecursiveDirectoryScope) {
+  auto dir_path = dir_.GetPath().AppendASCII("dir");
+  auto dir_url = CreateFileSystemURLFromPath(dir_path);
+
+  auto scope = FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+      dir_url, /*is_recursive=*/true);
+
+  EXPECT_TRUE(scope.Contains(scope));
+  EXPECT_TRUE(scope.Contains(dir_url));
+
+  absl::optional<base::SafeBaseName> sibling_name =
+      base::SafeBaseName::Create(FILE_PATH_LITERAL("sibling"));
+  auto sibling_url = dir_url.CreateSibling(*sibling_name);
+  EXPECT_FALSE(scope.Contains(sibling_url));
+
+  auto sibling_scope =
+      FileSystemAccessWatchScope::GetScopeForFileWatch(sibling_url);
+  EXPECT_FALSE(scope.Contains(sibling_scope));
+  EXPECT_FALSE(sibling_scope.Contains(scope));
+
+  auto parent_url = CreateFileSystemURLFromPath(dir_path.DirName());
+  EXPECT_FALSE(scope.Contains(parent_url));
+
+  auto parent_non_recursive_scope =
+      FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+          parent_url, /*is_recursive=*/false);
+  EXPECT_FALSE(scope.Contains(parent_non_recursive_scope));
+  EXPECT_FALSE(parent_non_recursive_scope.Contains(scope));
+
+  auto parent_recursive_scope =
+      FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+          parent_url, /*is_recursive=*/true);
+  EXPECT_FALSE(scope.Contains(parent_recursive_scope));
+  EXPECT_TRUE(parent_recursive_scope.Contains(scope));
+
+  auto child_path = dir_path.AppendASCII("child");
+  auto child_url = CreateFileSystemURLFromPath(child_path);
+  ASSERT_TRUE(dir_url.IsParent(child_url));
+  EXPECT_TRUE(scope.Contains(child_url));
+
+  auto child_scope =
+      FileSystemAccessWatchScope::GetScopeForFileWatch(child_url);
+  EXPECT_TRUE(scope.Contains(child_scope));
+  EXPECT_FALSE(child_scope.Contains(scope));
+
+  auto grandchild_url =
+      CreateFileSystemURLFromPath(child_path.AppendASCII("grand"));
+  ASSERT_TRUE(child_url.IsParent(grandchild_url));
+  EXPECT_TRUE(scope.Contains(grandchild_url));
+
+  auto grandchild_scope =
+      FileSystemAccessWatchScope::GetScopeForFileWatch(grandchild_url);
+  EXPECT_TRUE(scope.Contains(grandchild_scope));
+  EXPECT_FALSE(grandchild_scope.Contains(scope));
+
+  // TODO(https://crbug.com/1019297): Test that URLs from different file systems
+  // return are out of scope.
+}
+
+}  // namespace content
diff --git a/content/browser/file_system_access/file_system_access_watcher_manager.cc b/content/browser/file_system_access/file_system_access_watcher_manager.cc
index b1fb9db..74a3443d 100644
--- a/content/browser/file_system_access/file_system_access_watcher_manager.cc
+++ b/content/browser/file_system_access/file_system_access_watcher_manager.cc
@@ -3,15 +3,81 @@
 // found in the LICENSE file.
 
 #include "content/browser/file_system_access/file_system_access_watcher_manager.h"
-#include <algorithm>
 
+#include <algorithm>
+#include <memory>
+
+#include "base/check.h"
+#include "base/containers/cxx20_erase_list.h"
+#include "base/functional/bind.h"
+#include "base/memory/weak_ptr.h"
+#include "base/ranges/algorithm.h"
 #include "base/sequence_checker.h"
 #include "base/types/pass_key.h"
+#include "build/buildflag.h"
+#include "components/services/storage/public/cpp/buckets/bucket_locator.h"
+#include "content/browser/file_system_access/file_system_access_change_source.h"
+#include "content/browser/file_system_access/file_system_access_manager_impl.h"
 #include "content/browser/file_system_access/file_system_access_observer_host.h"
+#include "content/browser/file_system_access/file_system_access_observer_observation.h"
+#include "content/browser/file_system_access/file_system_access_watch_scope.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "storage/browser/file_system/file_system_url.h"
+#include "storage/common/file_system/file_system_types.h"
+
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA)
+#include "content/browser/file_system_access/file_system_access_local_path_watcher.h"
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA)
 
 namespace content {
 
+namespace {
+
+FileSystemAccessWatcherManager::Observation::Change ToChange(
+    storage::FileSystemContext& context,
+    const storage::FileSystemURL& root_url,
+    const base::FilePath& relative_path,
+    bool error) {
+  CHECK(!relative_path.IsAbsolute());
+  CHECK(!relative_path.ReferencesParent());
+
+  auto result = context.CreateCrackedFileSystemURL(
+      root_url.storage_key(), root_url.mount_type(),
+      root_url.virtual_path().Append(relative_path));
+  if (root_url.bucket()) {
+    result.SetBucket(root_url.bucket().value());
+  }
+  return {std::move(result), error};
+}
+
+}  // namespace
+
+FileSystemAccessWatcherManager::Observation::Observation(
+    FileSystemAccessWatcherManager* watcher_manager,
+    FileSystemAccessWatchScope scope,
+    base::PassKey<FileSystemAccessWatcherManager> /*pass_key*/)
+    : scope_(std::move(scope)) {
+  CHECK(watcher_manager);
+  obs_.Observe(watcher_manager);
+}
+FileSystemAccessWatcherManager::Observation::~Observation() = default;
+
+void FileSystemAccessWatcherManager::Observation::SetCallback(
+    OnChangesCallback on_change_callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  CHECK(!on_change_callback_);
+  on_change_callback_ = std::move(on_change_callback);
+}
+
+void FileSystemAccessWatcherManager::Observation::NotifyOfChanges(
+    const std::list<Change>& changes,
+    base::PassKey<FileSystemAccessWatcherManager> pass_key) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  if (on_change_callback_) {
+    on_change_callback_.Run(std::move(changes));
+  }
+}
+
 FileSystemAccessWatcherManager::FileSystemAccessWatcherManager(
     FileSystemAccessManagerImpl* manager,
     base::PassKey<FileSystemAccessManagerImpl> /*pass_key*/)
@@ -37,4 +103,203 @@
   CHECK_EQ(count_removed, 1u);
 }
 
+void FileSystemAccessWatcherManager::GetFileObservation(
+    const storage::FileSystemURL& file_url,
+    GetObservationCallback get_observation_callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  auto scope = FileSystemAccessWatchScope::GetScopeForFileWatch(file_url);
+  EnsureSourceIsInitializedForScope(
+      scope, base::BindOnce(
+                 &FileSystemAccessWatcherManager::PrepareObservationForScope,
+                 weak_factory_.GetWeakPtr(), scope,
+                 std::move(get_observation_callback)));
+}
+
+void FileSystemAccessWatcherManager::GetDirectoryObservation(
+    const storage::FileSystemURL& directory_url,
+    bool is_recursive,
+    GetObservationCallback get_observation_callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  auto scope = FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+      directory_url, is_recursive);
+
+  EnsureSourceIsInitializedForScope(
+      scope, base::BindOnce(
+                 &FileSystemAccessWatcherManager::PrepareObservationForScope,
+                 weak_factory_.GetWeakPtr(), scope,
+                 std::move(get_observation_callback)));
+}
+
+void FileSystemAccessWatcherManager::OnRawChange(
+    FileSystemAccessChangeSource* source,
+    const base::FilePath& relative_path,
+    bool error) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  auto change = ToChange(*manager()->context(), source->scope().root_url(),
+                         relative_path, error);
+  const storage::FileSystemURL changed_url = change.url;
+
+  // TODO(https://crbug.com/1019297):
+  //   - Batch changes.
+  //   - Ignore changes caused by API implementation details, such as writes to
+  //     swap files.
+  //   - Discard changes corresponding to non-fully-active pages.
+
+  const std::list<Observation::Change> changes = {std::move(change)};
+  for (auto& observation : observations_) {
+    if (observation.scope().Contains(changed_url)) {
+      observation.NotifyOfChanges(
+          changes, base::PassKey<FileSystemAccessWatcherManager>());
+    }
+  }
+}
+
+void FileSystemAccessWatcherManager::OnSourceBeingDestroyed(
+    FileSystemAccessChangeSource* source) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  source_observations_.RemoveObservation(source);
+  size_t count_removed = base::Erase(all_sources_, source);
+  CHECK_EQ(count_removed, 1u);
+}
+
+void FileSystemAccessWatcherManager::RegisterSource(
+    FileSystemAccessChangeSource* source) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  source_observations_.AddObservation(source);
+  all_sources_.push_back(source);
+}
+
+void FileSystemAccessWatcherManager::AddObserver(Observation* observation) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  observations_.AddObserver(observation);
+}
+
+void FileSystemAccessWatcherManager::RemoveObserver(Observation* observation) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  const auto newly_unobserved_scope = observation->scope();
+  observations_.RemoveObserver(observation);
+
+  // Remove the respective source if we own it and it was the only observer
+  // for this scope.
+  //
+  // TODO(https://crbug.com/1019297): Handle initializing sources.
+  base::EraseIf(owned_sources_, [&](const auto& source) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return source->scope().Contains(newly_unobserved_scope) &&
+           base::ranges::none_of(
+               observations_, [&source](const auto& observation) {
+                 return source->scope().Contains(observation.scope());
+               });
+  });
+}
+
+void FileSystemAccessWatcherManager::EnsureSourceIsInitializedForScope(
+    FileSystemAccessWatchScope scope,
+    base::OnceCallback<void(bool)> on_source_initialized) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  // TODO(https://crbug.com/1019297): Handle overlapping scopes and initializing
+  // sources.
+
+  FileSystemAccessChangeSource* raw_change_source = nullptr;
+  auto it = base::ranges::find_if(
+      all_sources_, [&scope](const FileSystemAccessChangeSource* source) {
+        return source->scope().Contains(scope);
+      });
+  if (it != all_sources_.end()) {
+    raw_change_source = *it;
+  } else {
+    auto owned_change_source = CreateOwnedSourceForScope(scope);
+    if (!owned_change_source) {
+      // TODO(https://crbug.com/1019297): Watching `scope` is not supported.
+      std::move(on_source_initialized).Run(false);
+      return;
+    }
+    raw_change_source = owned_change_source.get();
+    owned_sources_.insert(std::move(owned_change_source));
+  }
+
+  CHECK(raw_change_source);
+  raw_change_source->EnsureInitialized(
+      base::BindOnce(&FileSystemAccessWatcherManager::DidInitializeSource,
+                     weak_factory_.GetWeakPtr(), raw_change_source->AsWeakPtr(),
+                     std::move(on_source_initialized)));
+}
+
+void FileSystemAccessWatcherManager::DidInitializeSource(
+    base::WeakPtr<FileSystemAccessChangeSource> source,
+    base::OnceCallback<void(bool)> on_source_initialized,
+    bool success) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (!source) {
+    std::move(on_source_initialized).Run(false);
+    return;
+  }
+
+  if (!success) {
+    // If we owned this source, remove it. A source which is not initialized
+    // will not notify of changes, so there's no use keeping it around.
+    //
+    // TODO(https://crbug.com/1019297): Decide how to handle unowned sources
+    // which fail to initialize.
+    base::EraseIf(
+        owned_sources_,
+        [&source](
+            const std::unique_ptr<FileSystemAccessChangeSource>& owned_source) {
+          return owned_source.get() == source.get();
+        });
+  }
+
+  std::move(on_source_initialized).Run(success);
+}
+
+void FileSystemAccessWatcherManager::PrepareObservationForScope(
+    FileSystemAccessWatchScope scope,
+    GetObservationCallback get_observation_callback,
+    bool success) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (!success) {
+    std::move(get_observation_callback).Run(nullptr);
+    return;
+  }
+
+  std::move(get_observation_callback)
+      .Run(std::make_unique<Observation>(
+          this, std::move(scope),
+          base::PassKey<FileSystemAccessWatcherManager>()));
+}
+
+std::unique_ptr<FileSystemAccessChangeSource>
+FileSystemAccessWatcherManager::CreateOwnedSourceForScope(
+    FileSystemAccessWatchScope scope) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  if (scope.root_url().type() != storage::kFileSystemTypeLocal) {
+    // TODO(https://crbug.com/1019297): Support non-local file systems.
+    return nullptr;
+  }
+
+  // Access to the local file system is not supported on Android. See
+  // https://crbug.com/1011535.
+  // Meanwhile, `base::FilePatchWatcher` is not implemented on Fuchsia. See
+  // https://crbug.com/851641.
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+  return nullptr;
+#else
+  auto new_source = std::make_unique<FileSystemAccessLocalPathWatcher>(
+      std::move(scope), base::PassKey<FileSystemAccessWatcherManager>());
+  RegisterSource(new_source.get());
+  return new_source;
+#endif  //  BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+}
+
 }  // namespace content
diff --git a/content/browser/file_system_access/file_system_access_watcher_manager.h b/content/browser/file_system_access/file_system_access_watcher_manager.h
index 14343f1e..087cb39 100644
--- a/content/browser/file_system_access/file_system_access_watcher_manager.h
+++ b/content/browser/file_system_access/file_system_access_watcher_manager.h
@@ -5,30 +5,93 @@
 #ifndef CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_WATCHER_MANAGER_H_
 #define CONTENT_BROWSER_FILE_SYSTEM_ACCESS_FILE_SYSTEM_ACCESS_WATCHER_MANAGER_H_
 
+#include <memory>
+
 #include "base/containers/flat_set.h"
 #include "base/containers/unique_ptr_adapters.h"
+#include "base/files/file_path.h"
+#include "base/functional/callback_forward.h"
+#include "base/scoped_multi_source_observation.h"
+#include "base/scoped_observation.h"
 #include "base/sequence_checker.h"
 #include "base/types/pass_key.h"
+#include "content/browser/file_system_access/file_system_access_change_source.h"
+#include "content/browser/file_system_access/file_system_access_watch_scope.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/file_system_access_entry_factory.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "storage/browser/file_system/file_system_context.h"
+#include "storage/browser/file_system/file_system_url.h"
 #include "third_party/blink/public/mojom/file_system_access/file_system_access_observer_host.mojom.h"
 
 namespace content {
+
 class FileSystemAccessManagerImpl;
 class FileSystemAccessObserverHost;
 
 // Manages all watches to file system changes for a StoragePartition.
-// Instances of this class must be accessed exclusively on the UI thread.
-// Owned by the FileSystemAccessManagerImpl.
-class CONTENT_EXPORT FileSystemAccessWatcherManager {
+//
+// Raw changes from the underlying file system are plumbed through this class,
+// to be filtered, batched, and transformed before being relayed to the
+// appropriate `Observer`s.
+//
+// Instances of this class must be accessed exclusively on the UI thread. Owned
+// by the FileSystemAccessManagerImpl.
+class CONTENT_EXPORT FileSystemAccessWatcherManager
+    : public FileSystemAccessChangeSource::RawChangeObserver {
  public:
+  // Notifies of changes to a file system which occur in the given `scope`.
+  // These events may be consumed by other components.
+  class CONTENT_EXPORT Observation : public base::CheckedObserver {
+   public:
+    // Describes a change to some location in a file system.
+    struct Change {
+      storage::FileSystemURL url;
+      bool error;
+      // TODO(https://crbug.com/1425601): Include the type of change.
+      // TODO(https://crbug.com/1425601): Include whether the change was to a
+      // file or directory.
+
+      bool operator==(const Change& other) const {
+        return url == other.url && error == other.error;
+      }
+    };
+
+    using OnChangesCallback =
+        base::RepeatingCallback<void(const std::list<Change>& changes)>;
+    Observation(FileSystemAccessWatcherManager* watcher_manager,
+                FileSystemAccessWatchScope scope,
+                base::PassKey<FileSystemAccessWatcherManager> pass_key);
+    ~Observation() override;
+
+    // Set the callback to which changes will be reported.
+    // It is illegal to call this method more than once.
+    void SetCallback(OnChangesCallback on_change_callback);
+
+    const FileSystemAccessWatchScope& scope() const { return scope_; }
+
+    void NotifyOfChanges(
+        const std::list<Change>& changes,
+        base::PassKey<FileSystemAccessWatcherManager> pass_key);
+
+   private:
+    SEQUENCE_CHECKER(sequence_checker_);
+
+    OnChangesCallback on_change_callback_ GUARDED_BY_CONTEXT(sequence_checker_);
+
+    const FileSystemAccessWatchScope scope_;
+    base::ScopedObservation<FileSystemAccessWatcherManager, Observation> obs_
+        GUARDED_BY_CONTEXT(sequence_checker_){this};
+  };
+
   using BindingContext = FileSystemAccessEntryFactory::BindingContext;
+  using GetObservationCallback =
+      base::OnceCallback<void(std::unique_ptr<Observation>)>;
 
   FileSystemAccessWatcherManager(
       FileSystemAccessManagerImpl* manager,
       base::PassKey<FileSystemAccessManagerImpl> pass_key);
-  ~FileSystemAccessWatcherManager();
+  ~FileSystemAccessWatcherManager() override;
 
   FileSystemAccessWatcherManager(FileSystemAccessWatcherManager const&) =
       delete;
@@ -41,7 +104,67 @@
           host_receiver);
   void RemoveObserverHost(FileSystemAccessObserverHost* host);
 
+  // Prepares to watch the given file or directory. This may create a new
+  // `FileSystemAccessChangeSource` if one does not already cover the scope of
+  // the requested observation.
+  //
+  // `get_observation_callback` returns an `Observation`, or nullptr if the
+  // given file or directory cannot be watched as requested.
+  void GetFileObservation(const storage::FileSystemURL& file_url,
+                          GetObservationCallback get_observation_callback);
+  void GetDirectoryObservation(const storage::FileSystemURL& directory_url,
+                               bool is_recursive,
+                               GetObservationCallback get_observation_callback);
+
+  // FileSystemAccessChangeSource::RawChangeObserver:
+  void OnRawChange(FileSystemAccessChangeSource* source,
+                   const base::FilePath& relative_path,
+                   bool error) override;
+  void OnSourceBeingDestroyed(FileSystemAccessChangeSource* source) override;
+
+  // Subscriber this instance to raw changes from `source`.
+  void RegisterSource(FileSystemAccessChangeSource* source);
+
+  // For use with `ScopedObservation`. Do not otherwise call these methods
+  // directly.
+  void AddObserver(Observation* observation);
+  void RemoveObserver(Observation* observation);
+
+  bool HasObservationsForTesting() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return !observations_.empty();
+  }
+  bool HasObservationForTesting(Observation* observation) const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return observations_.HasObserver(observation);
+  }
+  bool HasSourcesForTesting() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return source_observations_.IsObservingAnySource();
+  }
+  bool HasSourceForTesting(FileSystemAccessChangeSource* source) const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return source_observations_.IsObservingSource(source);
+  }
+
+  FileSystemAccessManagerImpl* manager() { return manager_; }
+
  private:
+  // Attempts to create a change source for `scope` if it does not exist.
+  void EnsureSourceIsInitializedForScope(
+      FileSystemAccessWatchScope scope,
+      base::OnceCallback<void(bool)> on_source_initialized);
+  void DidInitializeSource(base::WeakPtr<FileSystemAccessChangeSource> source,
+                           base::OnceCallback<void(bool)> on_source_initialized,
+                           bool success);
+
+  void PrepareObservationForScope(FileSystemAccessWatchScope scope,
+                                  GetObservationCallback callback,
+                                  bool success);
+
+  std::unique_ptr<FileSystemAccessChangeSource> CreateOwnedSourceForScope(
+      FileSystemAccessWatchScope scope);
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   // The manager which owns this instance.
@@ -51,6 +174,29 @@
                  base::UniquePtrComparator>
       observer_hosts_;
 
+  // TODO(https://crbug.com/1019297): Make more efficient mappings to observers
+  // and sources. For now, most actions requires iterating through lists.
+
+  // Observations to which this instance will notify of changes within their
+  // respective scope.
+  base::ObserverList<Observation> observations_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  // Sources created by this instance in response to a request to observe a
+  // scope that is not currently contained by existing sources. These
+  // sources may be removed when their scope is no longer being observed.
+  base::flat_set<std::unique_ptr<FileSystemAccessChangeSource>,
+                 base::UniquePtrComparator>
+      owned_sources_ GUARDED_BY_CONTEXT(sequence_checker_);
+  // Observations of all sources, including those not owned by this instance.
+  base::ScopedMultiSourceObservation<FileSystemAccessChangeSource,
+                                     RawChangeObserver>
+      source_observations_ GUARDED_BY_CONTEXT(sequence_checker_){this};
+  // Raw pointers to each source in `source_observations_`.
+  // Unfortunately, ScopedMultiSourceObservation does not allow for peeking
+  // inside the list. This is a workaround.
+  std::list<FileSystemAccessChangeSource*> all_sources_;
+
   base::WeakPtrFactory<FileSystemAccessWatcherManager> weak_factory_
       GUARDED_BY_CONTEXT(sequence_checker_){this};
 };
diff --git a/content/browser/file_system_access/file_system_access_watcher_manager_unittest.cc b/content/browser/file_system_access/file_system_access_watcher_manager_unittest.cc
new file mode 100644
index 0000000..420a313
--- /dev/null
+++ b/content/browser/file_system_access/file_system_access_watcher_manager_unittest.cc
@@ -0,0 +1,672 @@
+// 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/file_system_access/file_system_access_watcher_manager.h"
+
+#include <list>
+
+#include "base/files/file_path.h"
+#include "base/files/file_util.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/location.h"
+#include "base/memory/weak_ptr.h"
+#include "base/run_loop.h"
+#include "base/test/run_until.h"
+#include "base/test/task_environment.h"
+#include "base/test/test_future.h"
+#include "base/test/test_timeouts.h"
+#include "build/buildflag.h"
+#include "content/browser/blob_storage/chrome_blob_storage_context.h"
+#include "content/browser/file_system_access/file_system_access_change_source.h"
+#include "content/browser/file_system_access/file_system_access_manager_impl.h"
+#include "content/browser/file_system_access/file_system_access_watch_scope.h"
+#include "content/public/browser/web_contents.h"
+#include "content/public/test/browser_task_environment.h"
+#include "content/public/test/test_browser_context.h"
+#include "content/public/test/test_web_contents_factory.h"
+#include "content/test/test_web_contents.h"
+#include "storage/browser/file_system/file_system_context.h"
+#include "storage/browser/file_system/file_system_url.h"
+#include "storage/browser/quota/quota_manager_proxy.h"
+#include "storage/browser/test/test_file_system_context.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace content {
+
+using Change = FileSystemAccessWatcherManager::Observation::Change;
+using Observation = FileSystemAccessWatcherManager::Observation;
+
+namespace {
+
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA)
+void SpinEventLoopForABit() {
+  base::RunLoop loop;
+  base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask(
+      FROM_HERE, loop.QuitClosure(), TestTimeouts::tiny_timeout());
+  loop.Run();
+}
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA)
+
+// Accumulates changes it receives from the given `observation`.
+class ChangeAccumulator {
+ public:
+  explicit ChangeAccumulator(std::unique_ptr<Observation> observation)
+      : observation_(std::move(observation)) {
+    observation_->SetCallback(base::BindRepeating(&ChangeAccumulator::OnChanges,
+                                                  weak_factory_.GetWeakPtr()));
+  }
+  ChangeAccumulator(const ChangeAccumulator&) = delete;
+  ChangeAccumulator& operator=(const ChangeAccumulator&) = delete;
+  ~ChangeAccumulator() = default;
+
+  void OnChanges(const std::list<Change>& changes) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    for (const auto& change : changes) {
+      received_changes_.push_back(change);
+    }
+  }
+
+  Observation* observation() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return observation_.get();
+  }
+
+  const std::list<Change>& changes() const {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    return received_changes_;
+  }
+
+ private:
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  std::unique_ptr<Observation> observation_
+      GUARDED_BY_CONTEXT(sequence_checker_);
+
+  std::list<Change> received_changes_ GUARDED_BY_CONTEXT(sequence_checker_);
+
+  base::WeakPtrFactory<ChangeAccumulator> weak_factory_
+      GUARDED_BY_CONTEXT(sequence_checker_){this};
+};
+
+// Trivial implementation of a change source which allows tests to signal
+// changes.
+class FakeChangeSource : public FileSystemAccessChangeSource {
+ public:
+  explicit FakeChangeSource(FileSystemAccessWatchScope scope)
+      : FileSystemAccessChangeSource(std::move(scope)) {}
+  FakeChangeSource(const FakeChangeSource&) = delete;
+  FakeChangeSource& operator=(const FakeChangeSource&) = delete;
+  ~FakeChangeSource() override = default;
+
+  // FileSystemAccessChangeSource:
+  void Initialize(base::OnceCallback<void(bool)> on_initialized) override {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    std::move(on_initialized).Run(initialization_result_);
+  }
+
+  void Signal(base::FilePath relative_path, bool error) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    NotifyOfChange(std::move(relative_path), error);
+  }
+
+  void set_initialization_result(bool result) {
+    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+    initialization_result_ = result;
+  }
+
+ private:
+  bool initialization_result_ GUARDED_BY_CONTEXT(sequence_checker_) = true;
+};
+
+}  // namespace
+
+class FileSystemAccessWatcherManagerTest : public testing::Test {
+ public:
+  FileSystemAccessWatcherManagerTest()
+      : task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}
+
+  void SetUp() override {
+    ASSERT_TRUE(dir_.CreateUniqueTempDir());
+#if BUILDFLAG(IS_WIN)
+    // Convert path to long format to avoid mixing long and 8.3 formats in test.
+    ASSERT_TRUE(dir_.Set(base::MakeLongFilePath(dir_.Take())));
+#endif  // BUILDFLAG(IS_WIN)
+
+    web_contents_ = web_contents_factory_.CreateWebContents(&browser_context_);
+    static_cast<TestWebContents*>(web_contents_)->NavigateAndCommit(kTestUrl);
+
+    file_system_context_ = storage::CreateFileSystemContextForTesting(
+        /*quota_manager_proxy=*/nullptr, dir_.GetPath());
+
+    chrome_blob_context_ = base::MakeRefCounted<ChromeBlobStorageContext>();
+    chrome_blob_context_->InitializeOnIOThread(base::FilePath(),
+                                               base::FilePath(), nullptr);
+
+    manager_ = base::MakeRefCounted<FileSystemAccessManagerImpl>(
+        file_system_context_, chrome_blob_context_,
+        /*permission_context=*/nullptr,
+        /*off_the_record=*/false);
+  }
+
+  void TearDown() override {
+    manager_.reset();
+    task_environment_.RunUntilIdle();
+    EXPECT_TRUE(dir_.Delete());
+  }
+
+  FileSystemAccessWatcherManager& watcher_manager() const {
+    return manager_->watcher_manager();
+  }
+
+ protected:
+  const GURL kTestUrl = GURL("http://example.com/foo");
+
+  BrowserTaskEnvironment task_environment_;
+
+  base::ScopedTempDir dir_;
+
+  TestBrowserContext browser_context_;
+  TestWebContentsFactory web_contents_factory_;
+
+  scoped_refptr<storage::FileSystemContext> file_system_context_;
+  scoped_refptr<ChromeBlobStorageContext> chrome_blob_context_;
+  scoped_refptr<FileSystemAccessManagerImpl> manager_;
+
+  raw_ptr<WebContents> web_contents_;
+};
+
+// Watching the local file system is not supported on Android or Fuchsia.
+#if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA)
+TEST_F(FileSystemAccessWatcherManagerTest, BasicRegistration) {
+  base::FilePath dir_path = dir_.GetPath().AppendASCII("dir");
+  auto dir_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, dir_path);
+
+  EXPECT_FALSE(watcher_manager().HasObservationsForTesting());
+  EXPECT_FALSE(watcher_manager().HasSourcesForTesting());
+
+  {
+    base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+    watcher_manager().GetDirectoryObservation(
+        dir_url,
+        /*is_recursive=*/false, get_observation_future.GetCallback());
+    ASSERT_TRUE(get_observation_future.Get());
+
+    // An observation should have been created.
+    auto observation = get_observation_future.Take();
+    EXPECT_TRUE(watcher_manager().HasObservationForTesting(observation.get()));
+
+    // A source should have been created to cover the scope of the observation.
+    EXPECT_TRUE(watcher_manager().HasSourcesForTesting());
+  }
+
+  // Destroying an observation unregisters it with the manager and removes the
+  // respective source.
+  EXPECT_FALSE(watcher_manager().HasObservationsForTesting());
+  EXPECT_FALSE(watcher_manager().HasSourcesForTesting());
+}
+#endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA)
+
+TEST_F(FileSystemAccessWatcherManagerTest, BasicRegistrationUnownedSource) {
+  base::FilePath file_path = dir_.GetPath().AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  {
+    FakeChangeSource source(
+        FileSystemAccessWatchScope::GetScopeForFileWatch(file_url));
+    watcher_manager().RegisterSource(&source);
+    EXPECT_TRUE(watcher_manager().HasSourceForTesting(&source));
+  }
+
+  // Destroying a source unregisters it with the manager.
+  EXPECT_FALSE(watcher_manager().HasSourcesForTesting());
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, UnownedSource) {
+  base::FilePath file_path = dir_.GetPath().AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  FakeChangeSource source(
+      FileSystemAccessWatchScope::GetScopeForFileWatch(file_url));
+  watcher_manager().RegisterSource(&source);
+  EXPECT_TRUE(watcher_manager().HasSourceForTesting(&source));
+
+  // Attempting to observe a scope covered by `source` will use `source`.
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future.GetCallback());
+  ASSERT_TRUE(get_observation_future.Get());
+
+  ChangeAccumulator accumulator(get_observation_future.Take());
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator.observation()));
+
+  source.Signal(/*relative_path=*/base::FilePath(), /*error=*/false);
+
+  std::list<Change> expected_changes = {{file_url, /*error=*/false}};
+  EXPECT_TRUE(base::test::RunUntil([&]() {
+    return testing::Matches(testing::ContainerEq(expected_changes))(
+        accumulator.changes());
+  }));
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, SourceFailsInitialization) {
+  base::FilePath file_path = dir_.GetPath().AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  FakeChangeSource source(
+      FileSystemAccessWatchScope::GetScopeForFileWatch(file_url));
+  watcher_manager().RegisterSource(&source);
+  EXPECT_TRUE(watcher_manager().HasSourceForTesting(&source));
+
+  source.set_initialization_result(false);
+
+  // Attempting to observe a scope covered by `source` will use `source`.
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future.GetCallback());
+  EXPECT_FALSE(get_observation_future.Get());
+
+  // TODO(https://crbug.com/1019297): Determine what should happen on failure to
+  // initialize a source, then add better test coverage.
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, RemoveObservation) {
+  base::FilePath file_path = dir_.GetPath().AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  FakeChangeSource source(
+      FileSystemAccessWatchScope::GetScopeForFileWatch(file_url));
+  watcher_manager().RegisterSource(&source);
+  EXPECT_TRUE(watcher_manager().HasSourceForTesting(&source));
+
+  // Attempting to observe a scope covered by `source` will use `source`.
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future.GetCallback());
+  ASSERT_TRUE(get_observation_future.Get());
+
+  {
+    ChangeAccumulator accumulator(get_observation_future.Take());
+    EXPECT_TRUE(
+        watcher_manager().HasObservationForTesting(accumulator.observation()));
+
+    source.Signal(/*relative_path=*/base::FilePath(), /*error=*/false);
+
+    std::list<Change> expected_changes = {{file_url, /*error=*/false}};
+    EXPECT_TRUE(base::test::RunUntil([&]() {
+      return testing::Matches(testing::ContainerEq(expected_changes))(
+          accumulator.changes());
+    }));
+  }
+
+  // Signaling changes after the observation was removed should not crash.
+  source.Signal(/*relative_path=*/base::FilePath(), /*error=*/false);
+  EXPECT_FALSE(watcher_manager().HasObservationsForTesting());
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, UnsupportedScope) {
+  // TODO(https://crbug.com/1019297): Sandboxed backends are not yet supported.
+  auto temporary_url = storage::FileSystemURL::CreateForTest(
+      GURL("filesystem:http://chromium.org/temporary/i/has/a.bucket"));
+
+  // Attempting to observe the given file will fail.
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetFileObservation(temporary_url,
+                                       get_observation_future.GetCallback());
+  EXPECT_FALSE(get_observation_future.Get());
+}
+
+// TODO(https://crbug.com/1019297): Add tests covering more edge cases regarding
+// overlapping scopes.
+TEST_F(FileSystemAccessWatcherManagerTest, OverlappingSourceScopes) {
+  base::FilePath dir_path = dir_.GetPath().AppendASCII("dir");
+  auto dir_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, dir_path);
+  base::FilePath file_path = dir_path.AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  FakeChangeSource source_for_file(
+      FileSystemAccessWatchScope::GetScopeForFileWatch(file_url));
+  watcher_manager().RegisterSource(&source_for_file);
+  EXPECT_TRUE(watcher_manager().HasSourceForTesting(&source_for_file));
+
+  // Add another source which covers the scope of `source_for_file`, and more.
+  FakeChangeSource source_for_dir(
+      FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+          dir_url, /*is_recursive=*/true));
+  watcher_manager().RegisterSource(&source_for_dir);
+  EXPECT_TRUE(watcher_manager().HasSourceForTesting(&source_for_dir));
+
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future.GetCallback());
+  ASSERT_TRUE(get_observation_future.Get());
+
+  ChangeAccumulator accumulator(get_observation_future.Take());
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator.observation()));
+
+  source_for_file.Signal(/*relative_path=*/base::FilePath(), /*error=*/false);
+  source_for_dir.Signal(/*relative_path=*/file_path.BaseName(),
+                        /*error=*/false);
+
+  // TODO(https://crbug.com/1019297): It would be nice if the watcher manager
+  // could consolidate these changes....
+
+  std::list<Change> expected_changes = {{file_url, /*error=*/false},
+                                        {file_url, /*error=*/false}};
+  EXPECT_TRUE(base::test::RunUntil([&]() {
+    return testing::Matches(testing::ContainerEq(expected_changes))(
+        accumulator.changes());
+  }));
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, OverlappingObservationScopes) {
+  base::FilePath dir_path = dir_.GetPath().AppendASCII("dir");
+  auto dir_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, dir_path);
+  base::FilePath file_path = dir_path.AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  FakeChangeSource source(FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+      dir_url, /*is_recursive=*/true));
+  watcher_manager().RegisterSource(&source);
+  EXPECT_TRUE(watcher_manager().HasSourceForTesting(&source));
+
+  base::test::TestFuture<std::unique_ptr<Observation>>
+      get_dir_observation_future;
+  watcher_manager().GetDirectoryObservation(
+      dir_url, /*is_recursive=*/true, get_dir_observation_future.GetCallback());
+  EXPECT_TRUE(get_dir_observation_future.Get());
+
+  ChangeAccumulator dir_accumulator(get_dir_observation_future.Take());
+  EXPECT_TRUE(watcher_manager().HasObservationForTesting(
+      dir_accumulator.observation()));
+
+  base::test::TestFuture<std::unique_ptr<Observation>>
+      get_file_observation_future;
+  watcher_manager().GetFileObservation(
+      file_url, get_file_observation_future.GetCallback());
+  EXPECT_TRUE(get_file_observation_future.Get());
+
+  ChangeAccumulator file_accumulator(get_file_observation_future.Take());
+  EXPECT_TRUE(watcher_manager().HasObservationForTesting(
+      file_accumulator.observation()));
+
+  // Only observed by `dir_accumulator`.
+  source.Signal(/*relative_path=*/base::FilePath(), /*error=*/false);
+  // Observed by both accumulators.
+  source.Signal(/*relative_path=*/file_path.BaseName(), /*error=*/false);
+
+  std::list<Change> expected_dir_changes = {{dir_url, /*error=*/false},
+                                            {file_url, /*error=*/false}};
+  std::list<Change> expected_file_changes = {{file_url, /*error=*/false}};
+  EXPECT_TRUE(base::test::RunUntil([&]() {
+    return testing::Matches(testing::ContainerEq(expected_dir_changes))(
+               dir_accumulator.changes()) &&
+           testing::Matches(testing::ContainerEq(expected_file_changes))(
+               file_accumulator.changes());
+  }));
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, ErroredChange) {
+  base::FilePath file_path = dir_.GetPath().AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  FakeChangeSource source(
+      FileSystemAccessWatchScope::GetScopeForFileWatch(file_url));
+  watcher_manager().RegisterSource(&source);
+  EXPECT_TRUE(watcher_manager().HasSourceForTesting(&source));
+
+  // Attempting to observe a scope covered by `source` will use `source`.
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future.GetCallback());
+  ASSERT_TRUE(get_observation_future.Get());
+
+  ChangeAccumulator accumulator(get_observation_future.Take());
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator.observation()));
+
+  source.Signal(/*relative_path=*/base::FilePath(), /*error=*/true);
+
+  std::list<Change> expected_changes = {{file_url, /*error=*/true}};
+  EXPECT_TRUE(base::test::RunUntil([&]() {
+    return testing::Matches(testing::ContainerEq(expected_changes))(
+        accumulator.changes());
+  }));
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, ChangeAtRelativePath) {
+  base::FilePath dir_path = dir_.GetPath().AppendASCII("foo");
+  auto dir_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, dir_path);
+
+  FakeChangeSource source(FileSystemAccessWatchScope::GetScopeForDirectoryWatch(
+      dir_url, /*is_recursive=*/true));
+  watcher_manager().RegisterSource(&source);
+  EXPECT_TRUE(watcher_manager().HasSourceForTesting(&source));
+
+  // Attempting to observe a scope covered by `source` will use `source`.
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetDirectoryObservation(
+      dir_url, /*is_recursive=*/true, get_observation_future.GetCallback());
+  ASSERT_TRUE(get_observation_future.Get());
+
+  ChangeAccumulator accumulator(get_observation_future.Take());
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator.observation()));
+
+  auto relative_path =
+      base::FilePath::FromASCII("nested").AppendASCII("subdir");
+  source.Signal(relative_path, /*error=*/false);
+
+  std::list<Change> expected_changes = {
+      {manager_->CreateFileSystemURLFromPath(
+           FileSystemAccessEntryFactory::PathType::kLocal,
+           dir_path.Append(relative_path)),
+       /*error=*/false}};
+  EXPECT_TRUE(base::test::RunUntil([&]() {
+    return testing::Matches(testing::ContainerEq(expected_changes))(
+        accumulator.changes());
+  }));
+}
+
+// TODO(https://crbug.com/1019297): Consider parameterizing these tests once
+// observing changes to other backends is supported.
+
+TEST_F(FileSystemAccessWatcherManagerTest, WatchLocalDirectory) {
+  base::FilePath dir_path = dir_.GetPath().AppendASCII("dir");
+  auto dir_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, dir_path);
+
+  base::CreateDirectory(dir_path);
+  auto file_path = dir_path.AppendASCII("foo");
+  base::WriteFile(file_path, "watch me");
+
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetDirectoryObservation(
+      dir_url,
+      /*is_recursive=*/false, get_observation_future.GetCallback());
+// Watching the local file system is not supported on Android or Fuchsia.
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+  EXPECT_FALSE(get_observation_future.Get());
+#else
+  ASSERT_TRUE(get_observation_future.Get());
+  // Constructing an observation registers it with the manager.
+  ChangeAccumulator accumulator(get_observation_future.Take());
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator.observation()));
+
+  // Delete a file in the directory. This should be reported to `accumulator`.
+  base::DeleteFile(file_path);
+
+  // TODO(https://crbug.com/1019297): Report the affected path, not that of the
+  // watched directory.
+  std::list<Change> expected_changes = {{dir_url, /*error=*/false}};
+  EXPECT_TRUE(base::test::RunUntil([&]() {
+    return testing::Matches(testing::ContainerEq(expected_changes))(
+        accumulator.changes());
+  }));
+#endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, WatchLocalDirectoryRecursively) {
+  base::FilePath dir_path = dir_.GetPath().AppendASCII("dir");
+  auto dir_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, dir_path);
+
+  base::CreateDirectory(dir_path);
+  auto file_path = dir_path.AppendASCII("foo");
+  base::WriteFile(file_path, "watch me");
+
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetDirectoryObservation(
+      dir_url,
+      /*is_recursive=*/false, get_observation_future.GetCallback());
+  // Watching the local file system is not supported on Android or Fuchsia.
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+  EXPECT_FALSE(get_observation_future.Get());
+#else
+  ASSERT_TRUE(get_observation_future.Get());
+
+  ChangeAccumulator accumulator(get_observation_future.Take());
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator.observation()));
+
+  // Delete a file in the directory. This should be reported to `accumulator`.
+  base::DeleteFile(file_path);
+
+  // TODO(https://crbug.com/1019297): Report the affected path, not that of the
+  // watched directory.
+  std::list<Change> expected_changes = {{dir_url, /*error=*/false}};
+  EXPECT_TRUE(base::test::RunUntil([&]() {
+    return testing::Matches(testing::ContainerEq(expected_changes))(
+        accumulator.changes());
+  }));
+#endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, WatchLocalFile) {
+  base::FilePath file_path = dir_.GetPath().AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  // Create the file to be watched.
+  base::WriteFile(file_path, "watch me");
+
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future.GetCallback());
+  // Watching the local file system is not supported on Android or Fuchsia.
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+  EXPECT_FALSE(get_observation_future.Get());
+#else
+  ASSERT_TRUE(get_observation_future.Get());
+
+  ChangeAccumulator accumulator(get_observation_future.Take());
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator.observation()));
+
+  // Deleting the watched file should notify `accumulator`.
+  base::DeleteFile(file_path);
+
+  std::list<Change> expected_changes = {{file_url, /*error=*/false}};
+  EXPECT_TRUE(base::test::RunUntil([&]() {
+    return testing::Matches(testing::ContainerEq(expected_changes))(
+        accumulator.changes());
+  }));
+#endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest,
+       WatchLocalFileWithMultipleObservations) {
+  base::FilePath file_path = dir_.GetPath().AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  // Create the file to be watched.
+  base::WriteFile(file_path, "watch me");
+
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future1,
+      get_observation_future2, get_observation_future3;
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future1.GetCallback());
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future2.GetCallback());
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future3.GetCallback());
+  // Watching the local file system is not supported on Android or Fuchsia.
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+  EXPECT_FALSE(get_observation_future1.Get());
+  EXPECT_FALSE(get_observation_future2.Get());
+  EXPECT_FALSE(get_observation_future3.Get());
+#else
+  ASSERT_TRUE(get_observation_future1.Get());
+  ASSERT_TRUE(get_observation_future2.Get());
+  ASSERT_TRUE(get_observation_future3.Get());
+
+  ChangeAccumulator accumulator1(get_observation_future1.Take());
+  ChangeAccumulator accumulator2(get_observation_future2.Take());
+  ChangeAccumulator accumulator3(get_observation_future3.Take());
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator1.observation()));
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator2.observation()));
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator3.observation()));
+
+  // Deleting the watched file should notify each `accumulator`.
+  base::DeleteFile(file_path);
+
+  std::list<Change> expected_changes = {{file_url, /*error=*/false}};
+  const auto expected_changes_matcher = testing::ContainerEq(expected_changes);
+  EXPECT_TRUE(base::test::RunUntil([&]() {
+    return testing::Matches(expected_changes_matcher)(accumulator1.changes()) &&
+           testing::Matches(expected_changes_matcher)(accumulator2.changes()) &&
+           testing::Matches(expected_changes_matcher)(accumulator3.changes());
+  }));
+#endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+}
+
+TEST_F(FileSystemAccessWatcherManagerTest, OutOfScope) {
+  base::FilePath file_path = dir_.GetPath().AppendASCII("foo");
+  auto file_url = manager_->CreateFileSystemURLFromPath(
+      FileSystemAccessEntryFactory::PathType::kLocal, file_path);
+
+  base::test::TestFuture<std::unique_ptr<Observation>> get_observation_future;
+  watcher_manager().GetFileObservation(file_url,
+                                       get_observation_future.GetCallback());
+  // Watching the local file system is not supported on Android or Fuchsia.
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+  EXPECT_FALSE(get_observation_future.Get());
+#else
+  ASSERT_TRUE(get_observation_future.Get());
+
+  ChangeAccumulator accumulator(get_observation_future.Take());
+  EXPECT_TRUE(
+      watcher_manager().HasObservationForTesting(accumulator.observation()));
+
+  // Making a change to a sibling of the watched file should _not_ report a
+  // change to the accumulator.
+  base::FilePath sibling_path = file_path.DirName().AppendASCII("sibling");
+  base::WriteFile(sibling_path, "do not watch me");
+
+  // Give unexpected events a chance to arrive.
+  SpinEventLoopForABit();
+
+  EXPECT_THAT(accumulator.changes(), testing::IsEmpty());
+#endif  // BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
+}
+
+}  // namespace content
diff --git a/content/browser/interest_group/ad_auction_service_impl_unittest.cc b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
index f014994..fe0a9da5 100644
--- a/content/browser/interest_group/ad_auction_service_impl_unittest.cc
+++ b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
@@ -1273,7 +1273,7 @@
                              "browserSignals.reserved":-1},
 "sellerCapabilities": {"%s": ["latency-stats"],
                        "*": ["interest-group-counts", "latencyStats"]},
-"biddingLogicUrl": "%s/interest_group/new_bidding_logic.js",
+"biddingLogicURL": "%s/interest_group/new_bidding_logic.js",
 "biddingWasmHelperUrl":"%s/interest_group/new_bidding_wasm_helper_url.wasm",
 "trustedBiddingSignalsUrl":
   "%s/interest_group/new_trusted_bidding_signals_url.json",
@@ -2181,7 +2181,7 @@
     network_responder_->RegisterUpdateResponse(
         kUpdateUrlPath,
         base::StringPrintf(R"({
-"biddingLogicUrl": "%s/interest_group/new_bidding_logic.js",
+"biddingLogicURL": "%s/interest_group/new_bidding_logic.js",
 "ads": [{"renderURL": %s,
         "metadata": {"new_a": "b"},
         "allowedReportingOrigins": %s
@@ -2229,7 +2229,7 @@
   content_browser_client_.SetAllowList({kOriginG});
   network_responder_->RegisterUpdateResponse(
       kUpdateUrlPath, base::StringPrintf(R"({
-"biddingLogicUrl": "%s/interest_group/new_bidding_logic.js",
+"biddingLogicURL": "%s/interest_group/new_bidding_logic.js",
 "ads": [{"renderURL": "https://test.com",
         "metadata": {"new_a": "b"},
         "allowedReportingOrigins": ["https://a.test", "https://g.test"]
@@ -2261,7 +2261,7 @@
   network_responder_->RegisterUpdateResponse(
       kUpdateUrlPath, base::StringPrintf(R"({
 "priority": "high",
-"biddingLogicUrl": "%s/interest_group/new_bidding_logic.js"
+"biddingLogicURL": "%s/interest_group/new_bidding_logic.js"
 })",
                                          kOriginStringA));
 
@@ -6675,7 +6675,7 @@
 TEST_F(AdAuctionServiceImplRestrictedPermissionsPolicyTest,
        APICallsFromTopFrame) {
   network_responder_->RegisterUpdateResponse(
-      kUpdateUrlPath, base::StringPrintf(R"({"biddingLogicUrl": "%s%s"})",
+      kUpdateUrlPath, base::StringPrintf(R"({"biddingLogicURL": "%s%s"})",
                                          kOriginStringA, kNewBiddingUrlPath));
   blink::InterestGroup interest_group = CreateInterestGroup();
   interest_group.update_url = kUpdateUrlA;
@@ -6704,7 +6704,7 @@
 TEST_F(AdAuctionServiceImplRestrictedPermissionsPolicyTest,
        APICallsFromSameSiteIframe) {
   network_responder_->RegisterUpdateResponse(
-      kUpdateUrlPath, base::StringPrintf(R"({"biddingLogicUrl": "%s%s"})",
+      kUpdateUrlPath, base::StringPrintf(R"({"biddingLogicURL": "%s%s"})",
                                          kOriginStringA, kNewBiddingUrlPath));
   // Create a same site subframe and use it to send the interest group requests.
   content::RenderFrameHostTester* rfh_tester =
@@ -6741,7 +6741,7 @@
 TEST_F(AdAuctionServiceImplRestrictedPermissionsPolicyTest,
        APICallsFromCrossSiteIFrame) {
   network_responder_->RegisterUpdateResponse(
-      kUpdateUrlPath, base::StringPrintf(R"({"biddingLogicUrl": "%s%s"})",
+      kUpdateUrlPath, base::StringPrintf(R"({"biddingLogicURL": "%s%s"})",
                                          kOriginStringC, kNewBiddingUrlPath));
 
   NavigateAndCommit(kUrlC);
diff --git a/content/browser/interest_group/auction_metrics_recorder_unittest.cc b/content/browser/interest_group/auction_metrics_recorder_unittest.cc
index 8db73ad2..0f12968 100644
--- a/content/browser/interest_group/auction_metrics_recorder_unittest.cc
+++ b/content/browser/interest_group/auction_metrics_recorder_unittest.cc
@@ -175,6 +175,7 @@
                              base::NumberToString(distinct_worklet)})),
           /*wasm_url=*/absl::nullopt,
           /*signals_url=*/absl::nullopt,
+          /*needs_cors_for_additional_bid=*/false,
           /*experiment_group_id=*/absl::nullopt);
       recorder().ReportBidderWorkletKey(worklet_key);
     }
diff --git a/content/browser/interest_group/auction_url_loader_factory_proxy.cc b/content/browser/interest_group/auction_url_loader_factory_proxy.cc
index 37c4bc61..52f78250 100644
--- a/content/browser/interest_group/auction_url_loader_factory_proxy.cc
+++ b/content/browser/interest_group/auction_url_loader_factory_proxy.cc
@@ -63,7 +63,8 @@
     network::mojom::ClientSecurityStatePtr client_security_state,
     const GURL& script_url,
     const absl::optional<GURL>& wasm_url,
-    const absl::optional<GURL>& trusted_signals_base_url)
+    const absl::optional<GURL>& trusted_signals_base_url,
+    bool needs_cors_for_additional_bid)
     : receiver_(this, std::move(pending_receiver)),
       get_frame_url_loader_factory_(std::move(get_frame_url_loader_factory)),
       get_trusted_url_loader_factory_(
@@ -79,13 +80,17 @@
                                           url::Origin::Create(script_url))),
       script_url_(script_url),
       wasm_url_(wasm_url),
-      trusted_signals_base_url_(trusted_signals_base_url) {
+      trusted_signals_base_url_(trusted_signals_base_url),
+      needs_cors_for_additional_bid_(needs_cors_for_additional_bid) {
   DCHECK(client_security_state_);
   if (trusted_signals_base_url_) {
     std::move(preconnect_socket_callback)
         .Run(*trusted_signals_base_url_,
              isolation_info_.network_anonymization_key());
   }
+
+  // `needs_cors_for_additional_bid_` applies only to buyer stuff.
+  DCHECK(!(is_for_seller_ && needs_cors_for_additional_bid_));
 }
 
 AuctionURLLoaderFactoryProxy::~AuctionURLLoaderFactoryProxy() = default;
@@ -176,7 +181,16 @@
     new_request.load_flags = net::LOAD_BYPASS_CACHE;
   }
 
-  if (!maybe_subresource_info) {
+  if (maybe_subresource_info || needs_cors_for_additional_bid_) {
+    // CORS is needed.
+    //
+    // For subresource bundle requests, CORS is supported if the subresource
+    // URL's scheme is https and not uuid-in-package. However, unlike
+    // traditional network requests, the browser cannot read the response if
+    // kNoCors is used, even with CORS-safe methods and headers -- the response
+    // is blocked by CORB.
+    new_request.mode = network::mojom::RequestMode::kCors;
+  } else {
     // CORS is not needed.
     //
     // For bidder worklets, the requests are same origin to the InterestGroup's
@@ -190,15 +204,6 @@
     // is only made available to the same-origin script, so CORB isn't needed
     // here.
     new_request.mode = network::mojom::RequestMode::kNoCors;
-  } else {
-    // CORS is needed.
-    //
-    // For subresource bundle requests, CORS is supported if the subresource
-    // URL's scheme is https and not uuid-in-package. However, unlike
-    // traditional network requests, the browser cannot read the response if
-    // kNoCors is used, even with CORS-safe methods and headers -- the response
-    // is blocked by CORB.
-    new_request.mode = network::mojom::RequestMode::kCors;
   }
 
   GetUrlLoaderFactoryCallback url_loader_factory_getter =
@@ -230,6 +235,9 @@
       new_request.trusted_params->client_security_state =
           client_security_state_.Clone();
     }
+  } else if (needs_cors_for_additional_bid_) {
+    // For additional bid reporting, act like the frame provided it as well.
+    url_loader_factory_getter = get_frame_url_loader_factory_;
   } else {
     // Treat this as a subresource request from the owner's origin, using the
     // trusted URLLoaderFactory.
diff --git a/content/browser/interest_group/auction_url_loader_factory_proxy.h b/content/browser/interest_group/auction_url_loader_factory_proxy.h
index 706f321c..d9bd3499 100644
--- a/content/browser/interest_group/auction_url_loader_factory_proxy.h
+++ b/content/browser/interest_group/auction_url_loader_factory_proxy.h
@@ -76,6 +76,10 @@
   // for an optional WASM helper for the worklet, and `trusted_signals_url` is
   // the optional JSON url for additional input to the script. No other URLs may
   // be requested.
+  //
+  // `needs_cors_for_additional_bid` should be set if this is a bidder resource
+  // that's not been verifiably selected by the bidder itself, but indirectly
+  // via an additional bid, so additional checks are needed.
   AuctionURLLoaderFactoryProxy(
       mojo::PendingReceiver<network::mojom::URLLoaderFactory> pending_receiver,
       GetUrlLoaderFactoryCallback get_frame_url_loader_factory,
@@ -89,7 +93,8 @@
       network::mojom::ClientSecurityStatePtr client_security_state,
       const GURL& script_url,
       const absl::optional<GURL>& wasm_url,
-      const absl::optional<GURL>& trusted_signals_base_url);
+      const absl::optional<GURL>& trusted_signals_base_url,
+      bool needs_cors_for_additional_bid);
   AuctionURLLoaderFactoryProxy(const AuctionURLLoaderFactoryProxy&) = delete;
   AuctionURLLoaderFactoryProxy& operator=(const AuctionURLLoaderFactoryProxy&) =
       delete;
@@ -142,6 +147,7 @@
   const GURL script_url_;
   const absl::optional<GURL> wasm_url_;
   const absl::optional<GURL> trusted_signals_base_url_;
+  const bool needs_cors_for_additional_bid_;
 };
 
 }  // namespace content
diff --git a/content/browser/interest_group/auction_url_loader_factory_proxy_unittest.cc b/content/browser/interest_group/auction_url_loader_factory_proxy_unittest.cc
index 5cf6bcc..d4c4670 100644
--- a/content/browser/interest_group/auction_url_loader_factory_proxy_unittest.cc
+++ b/content/browser/interest_group/auction_url_loader_factory_proxy_unittest.cc
@@ -133,7 +133,7 @@
         /*force_reload=*/force_reload_, top_frame_origin_, frame_origin_,
         /*renderer_process_id=*/kRenderProcessId, is_for_seller_,
         client_security_state_.Clone(), GURL(kScriptUrl), wasm_url_,
-        trusted_signals_base_url_);
+        trusted_signals_base_url_, needs_cors_for_additional_bid_);
 
     EXPECT_EQ(preconnect_url_, trusted_signals_base_url_);
     if (trusted_signals_base_url_) {
@@ -299,18 +299,19 @@
     // The initiator should be set.
     EXPECT_EQ(frame_origin_, observed_request.request_initiator);
 
-    if (expect_bundle_request) {
+    if (expect_bundle_request || needs_cors_for_additional_bid_) {
       EXPECT_EQ(network::mojom::RequestMode::kCors, observed_request.mode);
     } else {
       EXPECT_EQ(network::mojom::RequestMode::kNoCors, observed_request.mode);
     }
 
-    if (is_for_seller_) {
+    if (is_for_seller_ || needs_cors_for_additional_bid_) {
       if (original_accept_header == kAcceptJavascript ||
-          original_accept_header == kAcceptWasm) {
+          original_accept_header == kAcceptWasm ||
+          needs_cors_for_additional_bid_) {
         // Seller worklet Javascript & WASM requests use the renderer's
         // untrusted URLLoaderFactory, so inherit security parameters from
-        // there.
+        // there. The same happens for CORS-requiring additional bid reporting.
         EXPECT_FALSE(trusted_factory_used);
         EXPECT_FALSE(observed_request.trusted_params);
       } else {
@@ -404,6 +405,7 @@
       network::mojom::ClientSecurityState::New();
   absl::optional<GURL> trusted_signals_base_url_ = GURL(kTrustedSignalsBaseUrl);
   absl::optional<GURL> wasm_url_ = GURL(kWasmUrl);
+  bool needs_cors_for_additional_bid_ = false;
 
   url::Origin top_frame_origin_ =
       url::Origin::Create(GURL("https://top.test/"));
@@ -754,4 +756,14 @@
   }
 }
 
+TEST_F(AuctionUrlLoaderFactoryProxyTest, AdditionalBidCors) {
+  is_for_seller_ = false;
+  needs_cors_for_additional_bid_ = true;
+
+  remote_url_loader_factory_.reset();
+  CreateUrlLoaderFactoryProxy();
+
+  TryMakeRequest(kScriptUrl, kAcceptJavascript, ExpectedResponse::kAllow);
+}
+
 }  // namespace content
diff --git a/content/browser/interest_group/auction_worklet_manager.cc b/content/browser/interest_group/auction_worklet_manager.cc
index 9c8e4113..142832aa 100644
--- a/content/browser/interest_group/auction_worklet_manager.cc
+++ b/content/browser/interest_group/auction_worklet_manager.cc
@@ -338,7 +338,8 @@
       rfh ? absl::optional<int>(rfh->GetProcess()->GetID()) : absl::nullopt,
       /*is_for_seller_=*/worklet_info_.type == WorkletType::kSeller,
       delegate->GetClientSecurityState(), worklet_info_.script_url,
-      worklet_info_.wasm_url, worklet_info_.signals_url);
+      worklet_info_.wasm_url, worklet_info_.signals_url,
+      worklet_info_.needs_cors_for_additional_bid);
 
   switch (worklet_info_.type) {
     case WorkletType::kBidder: {
@@ -419,11 +420,13 @@
     const GURL& script_url,
     const absl::optional<GURL>& wasm_url,
     const absl::optional<GURL>& signals_url,
+    bool needs_cors_for_additional_bid,
     absl::optional<uint16_t> experiment_group_id)
     : type(type),
       script_url(script_url),
       wasm_url(wasm_url),
       signals_url(signals_url),
+      needs_cors_for_additional_bid(needs_cors_for_additional_bid),
       experiment_group_id(experiment_group_id) {}
 
 AuctionWorkletManager::WorkletKey::WorkletKey(const WorkletKey&) = default;
@@ -447,6 +450,8 @@
   hash = CombineHash(hash,
                      signals_url ? FastHash(signals_url->spec()) : 0xbee1271e);
   hash = CombineHash(hash,
+                     needs_cors_for_additional_bid ? 0x6748ee16 : 0xc2a13cd1);
+  hash = CombineHash(hash,
                      experiment_group_id ? *experiment_group_id : 0xd60fc235);
   return hash;
 }
@@ -454,9 +459,10 @@
 bool AuctionWorkletManager::WorkletKey::WorkletKey::operator<(
     const WorkletKey& other) const {
   return std::tie(type, script_url, wasm_url, signals_url,
-                  experiment_group_id) <
+                  needs_cors_for_additional_bid, experiment_group_id) <
          std::tie(other.type, other.script_url, other.wasm_url,
-                  other.signals_url, other.experiment_group_id);
+                  other.signals_url, other.needs_cors_for_additional_bid,
+                  other.experiment_group_id);
 }
 
 AuctionWorkletManager::WorkletHandle::~WorkletHandle() {
@@ -586,10 +592,12 @@
     const GURL& bidding_logic_url,
     const absl::optional<GURL>& wasm_url,
     const absl::optional<GURL>& trusted_bidding_signals_url,
+    bool needs_cors_for_additional_bid,
     absl::optional<uint16_t> experiment_group_id) {
   return WorkletKey(WorkletType::kBidder,
                     /*script_url=*/bidding_logic_url, wasm_url,
                     /*signals_url=*/trusted_bidding_signals_url,
+                    needs_cors_for_additional_bid,
                     trusted_bidding_signals_url.has_value()
                         ? experiment_group_id
                         : absl::nullopt);
@@ -599,13 +607,14 @@
     const GURL& bidding_logic_url,
     const absl::optional<GURL>& wasm_url,
     const absl::optional<GURL>& trusted_bidding_signals_url,
+    bool needs_cors_for_additional_bid,
     absl::optional<uint16_t> experiment_group_id,
     base::OnceClosure worklet_available_callback,
     FatalErrorCallback fatal_error_callback,
     std::unique_ptr<WorkletHandle>& out_worklet_handle) {
   RequestWorkletByKey(
       BidderWorkletKey(bidding_logic_url, wasm_url, trusted_bidding_signals_url,
-                       experiment_group_id),
+                       needs_cors_for_additional_bid, experiment_group_id),
       std::move(worklet_available_callback), std::move(fatal_error_callback),
       out_worklet_handle);
 }
@@ -621,6 +630,7 @@
                           /*script_url=*/decision_logic_url,
                           /*wasm_url=*/absl::nullopt,
                           /*signals_url=*/trusted_scoring_signals_url,
+                          /*needs_cors_for_additional_bid=*/false,
                           experiment_group_id);
   RequestWorkletByKey(std::move(worklet_info),
                       std::move(worklet_available_callback),
diff --git a/content/browser/interest_group/auction_worklet_manager.h b/content/browser/interest_group/auction_worklet_manager.h
index e25e45f..1b0095f 100644
--- a/content/browser/interest_group/auction_worklet_manager.h
+++ b/content/browser/interest_group/auction_worklet_manager.h
@@ -121,6 +121,7 @@
                const GURL& script_url,
                const absl::optional<GURL>& wasm_url,
                const absl::optional<GURL>& signals_url,
+               bool needs_cors_for_additional_bid,
                absl::optional<uint16_t> experiment_group_id);
     WorkletKey(const WorkletKey&);
     WorkletKey(WorkletKey&&);
@@ -130,6 +131,10 @@
     GURL script_url;
     absl::optional<GURL> wasm_url;
     absl::optional<GURL> signals_url;
+
+    // `needs_cors_for_additional_bid` is set for buyer reporting for additional
+    // bids; those need to perform a CORS check others don't.
+    bool needs_cors_for_additional_bid;
     absl::optional<uint16_t> experiment_group_id;
 
     // Fast, non-cryptographic hash to count unique worklets for UKM.
@@ -222,6 +227,7 @@
       const GURL& bidding_logic_url,
       const absl::optional<GURL>& wasm_url,
       const absl::optional<GURL>& trusted_bidding_signals_url,
+      bool needs_cors_for_additional_bid,
       absl::optional<uint16_t> experiment_group_id);
 
   // Requests a worklet with the specified properties. The top frame origin and
@@ -255,6 +261,7 @@
       const GURL& bidding_logic_url,
       const absl::optional<GURL>& wasm_url,
       const absl::optional<GURL>& trusted_bidding_signals_url,
+      bool needs_cors_for_additional_bid,
       absl::optional<uint16_t> experiment_group_id,
       base::OnceClosure worklet_available_callback,
       FatalErrorCallback fatal_error_callback,
diff --git a/content/browser/interest_group/auction_worklet_manager_unittest.cc b/content/browser/interest_group/auction_worklet_manager_unittest.cc
index 12f23830..c790f3a7 100644
--- a/content/browser/interest_group/auction_worklet_manager_unittest.cc
+++ b/content/browser/interest_group/auction_worklet_manager_unittest.cc
@@ -721,6 +721,7 @@
   base::test::TestFuture<void> worklet_available;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle);
   ASSERT_TRUE(worklet_available.Wait());
@@ -813,6 +814,7 @@
   base::test::TestFuture<void> worklet_available;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle);
   ASSERT_TRUE(worklet_available.Wait());
@@ -867,6 +869,7 @@
     auction_worklet_manager_.RequestBidderWorklet(
         decision_logic_url, /*wasm_url=*/absl::nullopt,
         /*trusted_bidding_signals_url=*/absl::nullopt,
+        /*needs_cors_for_additional_bid=*/false,
         /*experiment_group_id=*/absl::nullopt, worklet_available.GetCallback(),
         NeverInvokedFatalErrorCallback(), handle);
     ASSERT_TRUE(worklet_available.Wait());
@@ -899,6 +902,7 @@
   std::unique_ptr<AuctionWorkletManager::WorkletHandle> handle;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available2.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle);
   EXPECT_EQ(AuctionProcessManager::kMaxBidderProcesses,
@@ -1018,6 +1022,7 @@
   base::test::TestFuture<void> worklet_available1;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available1.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle1);
   ASSERT_TRUE(worklet_available1.Wait());
@@ -1039,6 +1044,7 @@
   base::test::TestFuture<void> worklet_available2;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available2.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle2);
   ASSERT_TRUE(worklet_available2.Wait());
@@ -1060,6 +1066,7 @@
   base::test::TestFuture<void> worklet_available3;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available3.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle3);
   ASSERT_TRUE(worklet_available3.Wait());
@@ -1083,6 +1090,7 @@
   std::unique_ptr<AuctionWorkletManager::WorkletHandle> handle4;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available4.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle4);
   ASSERT_TRUE(worklet_available4.Wait());
@@ -1191,6 +1199,7 @@
   base::test::TestFuture<void> worklet_available1;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available1.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle1);
   ASSERT_TRUE(worklet_available1.Wait());
@@ -1212,6 +1221,7 @@
   base::test::TestFuture<void> worklet_available2;
   auction_worklet_manager_.RequestBidderWorklet(
       kDifferentDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available2.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle2);
   ASSERT_TRUE(worklet_available2.Wait());
@@ -1233,6 +1243,7 @@
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl,
       /*trusted_bidding_signals_url=*/absl::nullopt,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available3.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle3);
   ASSERT_TRUE(worklet_available3.Wait());
@@ -1254,6 +1265,7 @@
   base::test::TestFuture<void> worklet_available4;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, /*wasm_url=*/absl::nullopt, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available4.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle4);
   EXPECT_TRUE(handle4->GetBidderWorklet());
@@ -1278,7 +1290,8 @@
   base::test::TestFuture<void> worklet_available1;
   std::unique_ptr<AuctionWorkletManager::WorkletHandle> handle1;
   auction_worklet_manager_.RequestBidderWorklet(
-      kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl, kExperiment1,
+      kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false, kExperiment1,
       worklet_available1.GetCallback(), NeverInvokedFatalErrorCallback(),
       handle1);
   ASSERT_TRUE(worklet_available1.Wait());
@@ -1291,7 +1304,8 @@
   std::unique_ptr<AuctionWorkletManager::WorkletHandle> handle2;
   base::test::TestFuture<void> worklet_available2;
   auction_worklet_manager_.RequestBidderWorklet(
-      kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl, kExperiment2,
+      kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false, kExperiment2,
       worklet_available2.GetCallback(), NeverInvokedFatalErrorCallback(),
       handle2);
   ASSERT_TRUE(worklet_available2.Wait());
@@ -1304,7 +1318,8 @@
   std::unique_ptr<AuctionWorkletManager::WorkletHandle> handle3;
   base::test::TestFuture<void> worklet_available3;
   auction_worklet_manager_.RequestBidderWorklet(
-      kDecisionLogicUrl, kWasmUrl, kWasmUrl, kExperiment1,
+      kDecisionLogicUrl, kWasmUrl, kWasmUrl,
+      /*needs_cors_for_additional_bid=*/false, kExperiment1,
       worklet_available3.GetCallback(), NeverInvokedFatalErrorCallback(),
       handle3);
   ASSERT_TRUE(worklet_available3.Wait());
@@ -1320,7 +1335,8 @@
   base::test::TestFuture<void> worklet_available4;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl,
-      /*trusted_bidding_signals_url=*/absl::nullopt, kExperiment1,
+      /*trusted_bidding_signals_url=*/absl::nullopt,
+      /*needs_cors_for_additional_bid=*/false, kExperiment1,
       worklet_available4.GetCallback(), NeverInvokedFatalErrorCallback(),
       handle4);
   ASSERT_TRUE(worklet_available4.Wait());
@@ -1336,6 +1352,7 @@
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl,
       /*trusted_bidding_signals_url=*/absl::nullopt,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available5.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle5);
   ASSERT_TRUE(worklet_available5.Wait());
@@ -1343,6 +1360,36 @@
   EXPECT_EQ(handle5->GetBidderWorklet(), handle4->GetBidderWorklet());
 }
 
+// Test bidder worklet matching with different CORS mode.
+TEST_F(AuctionWorkletManagerTest, BidderWorkletCORSForAdditionalBid) {
+  base::test::TestFuture<void> worklet_available1;
+  std::unique_ptr<AuctionWorkletManager::WorkletHandle> handle1;
+  auction_worklet_manager_.RequestBidderWorklet(
+      kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
+      /*experiment_group_id=*/absl::nullopt, worklet_available1.GetCallback(),
+      NeverInvokedFatalErrorCallback(), handle1);
+  ASSERT_TRUE(worklet_available1.Wait());
+  EXPECT_TRUE(handle1->GetBidderWorklet());
+  std::unique_ptr<MockBidderWorklet> bidder_worklet1 =
+      auction_process_manager_.WaitForBidderWorklet();
+
+  // Request one with a different CORS setting. Should result in a different
+  // worklet.
+  std::unique_ptr<AuctionWorkletManager::WorkletHandle> handle2;
+  base::test::TestFuture<void> worklet_available2;
+  auction_worklet_manager_.RequestBidderWorklet(
+      kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/true,
+      /*experiment_group_id=*/absl::nullopt, worklet_available2.GetCallback(),
+      NeverInvokedFatalErrorCallback(), handle2);
+  ASSERT_TRUE(worklet_available2.Wait());
+  EXPECT_TRUE(handle2->GetBidderWorklet());
+  std::unique_ptr<MockBidderWorklet> bidder_worklet2 =
+      auction_process_manager_.WaitForBidderWorklet();
+  EXPECT_NE(handle1->GetBidderWorklet(), handle2->GetBidderWorklet());
+}
+
 // Make sure that worklets are not reused when parameters don't match.
 TEST_F(AuctionWorkletManagerTest, DifferentSellerWorklets) {
   // Load a seller worklet.
@@ -1490,6 +1537,7 @@
   base::test::TestFuture<void> worklet_available;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available.GetCallback(),
       load_error_helper.Callback(), handle);
   ASSERT_TRUE(worklet_available.Wait());
@@ -1518,6 +1566,7 @@
   base::test::TestFuture<void> worklet_available2;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available2.GetCallback(),
       load_error_helper.Callback(), handle2);
   ASSERT_TRUE(worklet_available2.Wait());
@@ -1546,6 +1595,7 @@
     handles.emplace_back();
     auction_worklet_manager_.RequestBidderWorklet(
         kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+        /*needs_cors_for_additional_bid=*/false,
         /*experiment_group_id=*/absl::nullopt,
         base::BindOnce(
             [](size_t* success_callbacks_ptr, size_t worklet_index) {
@@ -1590,6 +1640,7 @@
     handles.emplace_back();
     auction_worklet_manager_.RequestBidderWorklet(
         kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+        /*needs_cors_for_additional_bid=*/false,
         /*experiment_group_id=*/absl::nullopt,
         base::BindOnce(
             [](size_t* success_callbacks_ptr, size_t limit,
@@ -1665,6 +1716,7 @@
   base::test::TestFuture<void> worklet_available;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available.GetCallback(),
       load_error_helper.Callback(), handle);
   ASSERT_TRUE(worklet_available.Wait());
@@ -1695,6 +1747,7 @@
   base::test::TestFuture<void> worklet_available2;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available2.GetCallback(),
       load_error_helper.Callback(), handle2);
   ASSERT_TRUE(worklet_available2.Wait());
@@ -1760,6 +1813,7 @@
   base::test::TestFuture<void> worklet_available;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available.GetCallback(),
       base::BindLambdaForTesting(
           [&](AuctionWorkletManager::FatalErrorType fatal_error_type,
@@ -1800,6 +1854,7 @@
     handles.emplace_back();
     auction_worklet_manager_.RequestBidderWorklet(
         kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+        /*needs_cors_for_additional_bid=*/false,
         /*experiment_group_id=*/absl::nullopt,
         base::BindOnce(
             [](int worklet_index, int* worklets_received_ptr,
@@ -1881,6 +1936,7 @@
   base::test::TestFuture<void> worklet_available;
   auction_worklet_manager_.RequestBidderWorklet(
       kDecisionLogicUrl, kWasmUrl, kTrustedSignalsUrl,
+      /*needs_cors_for_additional_bid=*/false,
       /*experiment_group_id=*/absl::nullopt, worklet_available.GetCallback(),
       NeverInvokedFatalErrorCallback(), handle);
   ASSERT_TRUE(worklet_available.Wait());
@@ -2004,13 +2060,15 @@
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   AuctionWorkletManager::WorkletKey key2(
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   EXPECT_FALSE(key1 < key2);
   EXPECT_FALSE(key2 < key1);
@@ -2022,13 +2080,15 @@
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   AuctionWorkletManager::WorkletKey key2(
       AuctionWorkletManager::WorkletType::kSeller,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   EXPECT_TRUE(key1 < key2 || key2 < key1);
   EXPECT_NE(key1.GetHash(), key2.GetHash());
@@ -2039,13 +2099,15 @@
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   AuctionWorkletManager::WorkletKey key2(
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://different.example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   EXPECT_TRUE(key1 < key2 || key2 < key1);
   EXPECT_NE(key1.GetHash(), key2.GetHash());
@@ -2056,13 +2118,15 @@
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   AuctionWorkletManager::WorkletKey key2(
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://different.example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   EXPECT_TRUE(key1 < key2 || key2 < key1);
   EXPECT_NE(key1.GetHash(), key2.GetHash());
@@ -2073,12 +2137,14 @@
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   AuctionWorkletManager::WorkletKey key2(
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"), absl::nullopt,
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   EXPECT_TRUE(key1 < key2 || key2 < key1);
   EXPECT_NE(key1.GetHash(), key2.GetHash());
@@ -2089,13 +2155,15 @@
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   AuctionWorkletManager::WorkletKey key2(
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://different.example.test/signals_url"), 0x85u);
+      GURL("https://different.example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   EXPECT_TRUE(key1 < key2 || key2 < key1);
   EXPECT_NE(key1.GetHash(), key2.GetHash());
@@ -2106,12 +2174,14 @@
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   AuctionWorkletManager::WorkletKey key2(
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
-      GURL("https://example.test/wasm_url"), absl::nullopt, 0x85u);
+      GURL("https://example.test/wasm_url"), absl::nullopt,
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   EXPECT_TRUE(key1 < key2 || key2 < key1);
   EXPECT_NE(key1.GetHash(), key2.GetHash());
@@ -2122,13 +2192,15 @@
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   AuctionWorkletManager::WorkletKey key2(
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x48u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x48u);
 
   EXPECT_TRUE(key1 < key2 || key2 < key1);
   EXPECT_NE(key1.GetHash(), key2.GetHash());
@@ -2139,13 +2211,34 @@
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), 0x85u);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
 
   AuctionWorkletManager::WorkletKey key2(
       AuctionWorkletManager::WorkletType::kBidder,
       GURL("https://example.test/script_url"),
       GURL("https://example.test/wasm_url"),
-      GURL("https://example.test/signals_url"), absl::nullopt);
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, absl::nullopt);
+
+  EXPECT_TRUE(key1 < key2 || key2 < key1);
+  EXPECT_NE(key1.GetHash(), key2.GetHash());
+}
+
+TEST(WorkletKeyTest, HashIsDifferentForKeysWithDifferentCORSForAdditionalBid) {
+  AuctionWorkletManager::WorkletKey key1(
+      AuctionWorkletManager::WorkletType::kBidder,
+      GURL("https://example.test/script_url"),
+      GURL("https://example.test/wasm_url"),
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/false, 0x85u);
+
+  AuctionWorkletManager::WorkletKey key2(
+      AuctionWorkletManager::WorkletType::kBidder,
+      GURL("https://example.test/script_url"),
+      GURL("https://example.test/wasm_url"),
+      GURL("https://example.test/signals_url"),
+      /*needs_cors_for_additional_bid=*/true, 0x85u);
 
   EXPECT_TRUE(key1 < key2 || key2 < key1);
   EXPECT_NE(key1.GetHash(), key2.GetHash());
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc
index 7847f87b..fabf29b4 100644
--- a/content/browser/interest_group/interest_group_auction.cc
+++ b/content/browser/interest_group/interest_group_auction.cc
@@ -4143,6 +4143,7 @@
 AuctionWorkletManager::WorkletKey InterestGroupAuction::BidderWorkletKey(
     BidState& bid_state) {
   DCHECK(!bid_state.worklet_handle);
+  DCHECK(!bid_state.additional_bid_buyer);
 
   const blink::InterestGroup& interest_group = bid_state.bidder->interest_group;
 
@@ -4152,7 +4153,8 @@
   return AuctionWorkletManager::BidderWorkletKey(
       interest_group.bidding_url.value_or(GURL()),
       interest_group.bidding_wasm_helper_url,
-      interest_group.trusted_bidding_signals_url, experiment_group_id);
+      interest_group.trusted_bidding_signals_url,
+      /*needs_cors_for_additional_bid=*/false, experiment_group_id);
 }
 
 void InterestGroupAuction::OnDecompressedServerResponse(
diff --git a/content/browser/interest_group/interest_group_auction_reporter.cc b/content/browser/interest_group/interest_group_auction_reporter.cc
index 907950a..ee13314 100644
--- a/content/browser/interest_group/interest_group_auction_reporter.cc
+++ b/content/browser/interest_group/interest_group_auction_reporter.cc
@@ -631,7 +631,9 @@
   auction_worklet_manager_->RequestBidderWorklet(
       interest_group.bidding_url.value_or(GURL()),
       interest_group.bidding_wasm_helper_url,
-      interest_group.trusted_bidding_signals_url, experiment_group_id,
+      interest_group.trusted_bidding_signals_url,
+      /*needs_cors_for_additional_bid=*/
+      winning_bid_info_.provided_as_additional_bid, experiment_group_id,
       base::BindOnce(&InterestGroupAuctionReporter::OnBidderWorkletReceived,
                      base::Unretained(this), signals_for_winner),
       base::BindOnce(&InterestGroupAuctionReporter::OnBidderWorkletFatalError,
diff --git a/content/browser/interest_group/interest_group_browsertest.cc b/content/browser/interest_group/interest_group_browsertest.cc
index fc56185..7017206 100644
--- a/content/browser/interest_group/interest_group_browsertest.cc
+++ b/content/browser/interest_group/interest_group_browsertest.cc
@@ -751,7 +751,7 @@
              SellerCapabilitiesToDict(group.seller_capabilities,
                                       group.all_sellers_capabilities));
     if (group.bidding_url) {
-      dict.Set("biddingLogicUrl", group.bidding_url->spec());
+      dict.Set("biddingLogicURL", group.bidding_url->spec());
     }
     if (group.bidding_wasm_helper_url) {
       dict.Set("biddingWasmHelperUrl", group.bidding_wasm_helper_url->spec());
@@ -3318,7 +3318,7 @@
         {
           name: 'cars',
           owner: $1,
-          biddingLogicUrl: 'https://invalid^&',
+          biddingLogicURL: 'https://invalid^&',
         },
         /*joinDurationSec=*/1);
   } catch (e) {
@@ -7702,7 +7702,7 @@
   const ig_1= {
     owner: $1,
     name: "name_1",
-    biddingLogicUrl: $3,
+    biddingLogicURL: $3,
     ads: [{renderUrl: $1}],
   };
 
@@ -7711,7 +7711,7 @@
     name: "name_2",
     // Intentionally use invalid bidding logic URL -- this results in the bid
     // being filtered.
-    biddingLogicUrl: $1,
+    biddingLogicURL: $1,
     ads: [{renderUrl: $1}],
     enableBiddingSignalsPrioritization: true,
     trustedBiddingSignalsUrl: $1
@@ -9573,7 +9573,7 @@
     {
       name: $1,
       owner: $2,
-      biddingLogicUrl: $3,
+      biddingLogicURL: $3,
       ads: $4
     },
     /*joinDurationSec=*/ 300);
@@ -11426,7 +11426,7 @@
           owner: $1,
           trustedBiddingSignalsUrl: $2,
           trustedBiddingSignalsKeys: ['key1'],
-          biddingLogicUrl: $3,
+          biddingLogicURL: $3,
           userBiddingSignals: 1,
           ads: [{renderURL:"https://example.com/render", metadata:2}],
         },
@@ -11543,7 +11543,7 @@
         {
           name: 'cars',
           owner: $1,
-          biddingLogicUrl: $2,
+          biddingLogicURL: $2,
           ads: [{renderURL:"https://example.com/render", metadata:2}],
         },
         /*joinDurationSec=*/100);
@@ -11648,7 +11648,7 @@
         {
           name: 'cars',
           owner: $1,
-          biddingLogicUrl: $2,
+          biddingLogicURL: $2,
           ads: [{renderURL:"https://example.com/render", metadata:2}],
         },
         /*joinDurationSec=*/100);
@@ -11792,7 +11792,7 @@
         {
           name: 'cars',
           owner: $1,
-          biddingLogicUrl: $2,
+          biddingLogicURL: $2,
           ads: [{renderURL:"https://example.com/render", metadata:2}],
         },
         /*joinDurationSec=*/100);
@@ -11942,7 +11942,7 @@
         {
           name: 'cars',
           owner: $1,
-          biddingLogicUrl: $2,
+          biddingLogicURL: $2,
           ads: [{renderURL:"https://example.com/render", metadata:2}],
         },
         /*joinDurationSec=*/100);
@@ -12026,7 +12026,7 @@
   constexpr char kUpdateUrlPath[] = "/interest_group/update_partial.json";
   network_responder_->RegisterNetworkResponse(
       kUpdateUrlPath, base::StringPrintf(R"({
-"biddingLogicUrl": "%s/interest_group/new_bidding_logic.js",
+"biddingLogicURL": "%s/interest_group/new_bidding_logic.js",
 "trustedBiddingSignalsUrl":
   "%s/interest_group/new_trusted_bidding_signals_url.json",
 "trustedBiddingSignalsKeys": ["new_key"],
@@ -12114,7 +12114,7 @@
   constexpr char kUpdateUrlPath[] = "/interest_group/update_partial.json";
   network_responder_->RegisterNetworkResponse(
       kUpdateUrlPath, base::StringPrintf(R"({
-"biddingLogicUrl": "%s/interest_group/new_bidding_logic.js",
+"biddingLogicURL": "%s/interest_group/new_bidding_logic.js",
 "trustedBiddingSignalsUrl":
   "%s/interest_group/new_trusted_bidding_signals_url.json",
 "trustedBiddingSignalsKeys": ["new_key"],
@@ -12205,7 +12205,7 @@
   constexpr char kUpdateUrlPath[] = "/interest_group/update_partial.json";
   network_responder_->RegisterNetworkResponse(
       kUpdateUrlPath, base::StringPrintf(R"({
-"biddingLogicUrl": "%s/interest_group/new_bidding_logic.js",
+"biddingLogicURL": "%s/interest_group/new_bidding_logic.js",
 "trustedBiddingSignalsUrl":
   "%s/interest_group/new_trusted_bidding_signals_url.json",
 "trustedBiddingSignalsKeys": ["new_key"],
@@ -12935,11 +12935,11 @@
   GURL new_bidding_url =
       https_server_->GetURL("a.test", "/interest_group/new_bidding_logic.js");
 
-  // The server JSON updates biddingLogicUrl only.
+  // The server JSON updates biddingLogicURL only.
   network_responder_->RegisterNetworkResponse(update_url.path(),
                                               JsReplace(R"(
 {
-  "biddingLogicUrl": $1
+  "biddingLogicURL": $1
 }
                                                         )",
                                                         new_bidding_url));
@@ -13069,10 +13069,10 @@
   const GURL new_bidding_url_c =
       https_server_->GetURL("c.test", kNewBiddingPath);
 
-  // The server JSON updates biddingLogicUrl only.
+  // The server JSON updates biddingLogicURL only.
   constexpr char kUpdateContentTemplate[] = R"(
 {
-  "biddingLogicUrl": $1
+  "biddingLogicURL": $1
 }
 )";
   // a.test's response is delayed until later.
@@ -15881,27 +15881,23 @@
   ASSERT_TRUE(NavigateToURL(shell(), test_url));
   url::Origin test_origin = url::Origin::Create(test_url);
   GURL ad_url = https_server_->GetURL("c.test", "/echo?render_cars");
-  GURL additional_bid_url =
+  GURL additional_bid_ad_url =
       https_server_->GetURL("c.test", "/echo?render_horses");
 
-  EXPECT_EQ(
-      kSuccess,
-      JoinInterestGroupAndVerify(
-          blink::TestInterestGroupBuilder(
-              /*owner=*/test_origin,
-              /*name=*/"cars")
-              .SetBiddingUrl(https_server_->GetURL(
-                  "a.test", "/interest_group/bidding_logic.js"))
-              .SetTrustedBiddingSignalsUrl(https_server_->GetURL(
-                  "a.test", "/interest_group/trusted_bidding_signals.json"))
-              .SetTrustedBiddingSignalsKeys({{"key1"}})
-              .SetAds(/*ads=*/{{{ad_url, R"({"ad":"metadata","here":[1,2]})"}}})
-              .Build()));
+  EXPECT_EQ(kSuccess,
+            JoinInterestGroupAndVerify(
+                blink::TestInterestGroupBuilder(
+                    /*owner=*/test_origin,
+                    /*name=*/"cars")
+                    .SetBiddingUrl(https_server_->GetURL(
+                        "a.test", "/interest_group/bidding_logic.js"))
+                    .SetAds(/*ads=*/{{{ad_url, /*metadata=*/absl::nullopt}}})
+                    .Build()));
 
   std::string auction_nonce = CreateAuctionNonceAndWait();
 
   GURL additional_bid_logic_url = https_server_->GetURL(
-      "a.test", "/interest_group/bidding_logic_additional_bid.js");
+      "b.test", "/interest_group/bidding_logic_additional_bid.js");
 
   std::string auction_config = JsReplace(
       R"({
@@ -15925,10 +15921,11 @@
       })])})",
       test_origin,
       https_server_->GetURL("a.test", "/interest_group/decision_logic.js"),
-      auction_nonce, additional_bid_url, additional_bid_logic_url,
+      auction_nonce, additional_bid_ad_url, additional_bid_logic_url,
       url::Origin::Create(additional_bid_logic_url));
 
-  RunAuctionAndWaitForURLAndNavigateIframe(auction_config, additional_bid_url);
+  RunAuctionAndWaitForURLAndNavigateIframe(auction_config,
+                                           additional_bid_ad_url);
   WaitForUrl(https_server_->GetURL("a.test", "/echoall?report_seller"));
   WaitForUrl(
       https_server_->GetURL("a.test", "/echoall?report_bidder_additional"));
@@ -15936,6 +15933,68 @@
       https_server_->GetURL("a.test", "/echoall?report_bidder")));
 }
 
+// If additional bid's script doesn't have necessary CORS permissions, it can
+// still win, but the reporting worklet won't happen.
+IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
+                       RunAdAuctionWithWinningAdditionalBidNoCors) {
+  URLLoaderMonitor url_loader_monitor;
+
+  GURL test_url = https_server_->GetURL("a.test", "/page_with_iframe.html");
+  ASSERT_TRUE(NavigateToURL(shell(), test_url));
+  url::Origin test_origin = url::Origin::Create(test_url);
+  GURL ad_url = https_server_->GetURL("c.test", "/echo?render_cars");
+  GURL additional_bid_ad_url =
+      https_server_->GetURL("c.test", "/echo?render_horses");
+
+  EXPECT_EQ(kSuccess,
+            JoinInterestGroupAndVerify(
+                blink::TestInterestGroupBuilder(
+                    /*owner=*/test_origin,
+                    /*name=*/"cars")
+                    .SetBiddingUrl(https_server_->GetURL(
+                        "a.test", "/interest_group/bidding_logic.js"))
+                    .SetAds(/*ads=*/{{{ad_url, /*metadata=*/absl::nullopt}}})
+                    .Build()));
+
+  std::string auction_nonce = CreateAuctionNonceAndWait();
+
+  GURL additional_bid_logic_url = https_server_->GetURL(
+      "b.test", "/interest_group/bidding_logic_additional_bid_no_cors.js");
+
+  std::string auction_config = JsReplace(
+      R"({
+    seller: $1,
+    decisionLogicUrl: $2,
+    interestGroupBuyers: [$1],
+    auctionNonce: $3,
+    additionalBids: provideAdditionalBids($1, $3, [JSON.stringify({
+        interestGroup: {
+          name: 'campaign123',
+          biddingLogicURL: $5,
+          owner:$6
+        },
+        bid: {
+          ad: ['ad'],
+          bid: 1.99,
+          render: $4,
+        },
+        auctionNonce: $3,
+        seller: $1,
+      })])})",
+      test_origin,
+      https_server_->GetURL("a.test", "/interest_group/decision_logic.js"),
+      auction_nonce, additional_bid_ad_url, additional_bid_logic_url,
+      url::Origin::Create(additional_bid_logic_url));
+
+  RunAuctionAndWaitForURLAndNavigateIframe(auction_config,
+                                           additional_bid_ad_url);
+  WaitForUrl(https_server_->GetURL("a.test", "/echoall?report_seller"));
+  EXPECT_FALSE(HasServerSeenUrl(
+      https_server_->GetURL("a.test", "/echoall?report_bidder_additional")));
+  EXPECT_FALSE(HasServerSeenUrl(
+      https_server_->GetURL("a.test", "/echoall?report_bidder")));
+}
+
 IN_PROC_BROWSER_TEST_F(InterestGroupBrowserTest,
                        RunAdAuctionWithWrongCurrencyAdditionalBid) {
   URLLoaderMonitor url_loader_monitor;
@@ -15944,22 +16003,18 @@
   ASSERT_TRUE(NavigateToURL(shell(), test_url));
   url::Origin test_origin = url::Origin::Create(test_url);
   GURL ad_url = https_server_->GetURL("c.test", "/echo?render_cars");
-  GURL additional_bid_url =
+  GURL additional_bid_ad_url =
       https_server_->GetURL("c.test", "/echo?render_horses");
 
-  EXPECT_EQ(
-      kSuccess,
-      JoinInterestGroupAndVerify(
-          blink::TestInterestGroupBuilder(
-              /*owner=*/test_origin,
-              /*name=*/"cars")
-              .SetBiddingUrl(https_server_->GetURL(
-                  "a.test", "/interest_group/bidding_logic.js"))
-              .SetTrustedBiddingSignalsUrl(https_server_->GetURL(
-                  "a.test", "/interest_group/trusted_bidding_signals.json"))
-              .SetTrustedBiddingSignalsKeys({{"key1"}})
-              .SetAds(/*ads=*/{{{ad_url, R"({"ad":"metadata","here":[1,2]})"}}})
-              .Build()));
+  EXPECT_EQ(kSuccess,
+            JoinInterestGroupAndVerify(
+                blink::TestInterestGroupBuilder(
+                    /*owner=*/test_origin,
+                    /*name=*/"cars")
+                    .SetBiddingUrl(https_server_->GetURL(
+                        "a.test", "/interest_group/bidding_logic.js"))
+                    .SetAds(/*ads=*/{{{ad_url, /*metadata=*/absl::nullopt}}})
+                    .Build()));
 
   std::string auction_nonce = CreateAuctionNonceAndWait();
 
@@ -15994,7 +16049,7 @@
     ])})",
       test_origin,
       https_server_->GetURL("a.test", "/interest_group/decision_logic.js"),
-      auction_nonce, additional_bid_url, additional_bid_logic_url,
+      auction_nonce, additional_bid_ad_url, additional_bid_logic_url,
       url::Origin::Create(additional_bid_logic_url));
 
   WebContentsConsoleObserver console_observer(shell()->web_contents());
@@ -16016,22 +16071,18 @@
   ASSERT_TRUE(NavigateToURL(shell(), test_url));
   url::Origin test_origin = url::Origin::Create(test_url);
   GURL ad_url = https_server_->GetURL("c.test", "/echo?render_cars");
-  GURL additional_bid_url =
+  GURL additional_bid_ad_url =
       https_server_->GetURL("c.test", "/echo?render_horses");
 
-  EXPECT_EQ(
-      kSuccess,
-      JoinInterestGroupAndVerify(
-          blink::TestInterestGroupBuilder(
-              /*owner=*/test_origin,
-              /*name=*/"cars")
-              .SetBiddingUrl(https_server_->GetURL(
-                  "a.test", "/interest_group/bidding_logic.js"))
-              .SetTrustedBiddingSignalsUrl(https_server_->GetURL(
-                  "a.test", "/interest_group/trusted_bidding_signals.json"))
-              .SetTrustedBiddingSignalsKeys({{"key1"}})
-              .SetAds(/*ads=*/{{{ad_url, R"({"ad":"metadata","here":[1,2]})"}}})
-              .Build()));
+  EXPECT_EQ(kSuccess,
+            JoinInterestGroupAndVerify(
+                blink::TestInterestGroupBuilder(
+                    /*owner=*/test_origin,
+                    /*name=*/"cars")
+                    .SetBiddingUrl(https_server_->GetURL(
+                        "a.test", "/interest_group/bidding_logic.js"))
+                    .SetAds(/*ads=*/{{{ad_url, /*metadata=*/absl::nullopt}}})
+                    .Build()));
 
   std::string auction_nonce = CreateAuctionNonceAndWait();
 
@@ -16048,7 +16099,7 @@
       })",
       test_origin,
       https_server_->GetURL("a.test", "/interest_group/decision_logic.js"),
-      auction_nonce, additional_bid_url, additional_bid_logic_url,
+      auction_nonce, additional_bid_ad_url, additional_bid_logic_url,
       url::Origin::Create(additional_bid_logic_url));
 
   WebContentsConsoleObserver console_observer(shell()->web_contents());
@@ -16070,7 +16121,7 @@
   ASSERT_TRUE(NavigateToURL(shell(), test_url));
   url::Origin test_origin = url::Origin::Create(test_url);
   GURL ad_url = https_server_->GetURL("c.test", "/echo?render_cars");
-  GURL additional_bid_url =
+  GURL additional_bid_ad_url =
       https_server_->GetURL("c.test", "/echo?render_horses");
 
   std::string auction_nonce = CreateAuctionNonceAndWait();
@@ -16087,7 +16138,7 @@
     additionalBids: provideAdditionalBids($1, $3, [])})",
       test_origin,
       https_server_->GetURL("a.test", "/interest_group/decision_logic.js"),
-      auction_nonce, additional_bid_url, additional_bid_logic_url,
+      auction_nonce, additional_bid_ad_url, additional_bid_logic_url,
       url::Origin::Create(additional_bid_logic_url));
 
   EXPECT_EQ(nullptr, RunAuctionAndWait(auction_config));
diff --git a/content/browser/preloading/prerender/prerender_browsertest.cc b/content/browser/preloading/prerender/prerender_browsertest.cc
index dce137b..8ccf392 100644
--- a/content/browser/preloading/prerender/prerender_browsertest.cc
+++ b/content/browser/preloading/prerender/prerender_browsertest.cc
@@ -9321,6 +9321,30 @@
       PrerenderFinalStatus::kInvalidSchemeNavigation, 1);
 }
 
+IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest, EmbedderTrigger_DataUrl) {
+  const GURL initial_url = GetUrl("/empty.html");
+  ASSERT_TRUE(NavigateToURL(shell(), initial_url));
+  // The content is "<h1>Hello, World!</h1>".
+  const GURL prerendering_url(
+      "data:text/html,%3Ch1%3EHello%2C%20World%21%3C%2Fh1%3E");
+  ASSERT_FALSE(prerendering_url.SchemeIsHTTPOrHTTPS());
+
+  // Start prerendering by embedder triggered prerendering.
+  std::unique_ptr<PrerenderHandle> prerender_handle =
+      web_contents_impl()->StartPrerendering(
+          prerendering_url, PrerenderTriggerType::kEmbedder,
+          "EmbedderSuffixForTest",
+          ui::PageTransitionFromInt(ui::PAGE_TRANSITION_TYPED |
+                                    ui::PAGE_TRANSITION_FROM_ADDRESS_BAR),
+          PreloadingHoldbackStatus::kUnspecified, nullptr);
+  EXPECT_FALSE(prerender_handle);
+
+  histogram_tester().ExpectUniqueSample(
+      "Prerender.Experimental.PrerenderHostFinalStatus.Embedder_"
+      "EmbedderSuffixForTest",
+      PrerenderFinalStatus::kInvalidSchemeNavigation, 1);
+}
+
 IN_PROC_BROWSER_TEST_F(PrerenderBrowserTest,
                        EmbedderTrigger_SameOriginRedirection) {
   const GURL initial_url = GetUrl("/empty.html");
diff --git a/content/browser/renderer_host/agent_scheduling_group_host.cc b/content/browser/renderer_host/agent_scheduling_group_host.cc
index 4c90798..d857318 100644
--- a/content/browser/renderer_host/agent_scheduling_group_host.cc
+++ b/content/browser/renderer_host/agent_scheduling_group_host.cc
@@ -23,6 +23,7 @@
 #include "ipc/ipc_channel_mojo.h"
 #include "ipc/ipc_message.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom.h"
 
 namespace content {
 
@@ -332,11 +333,14 @@
 }
 
 void AgentSchedulingGroupHost::CreateSharedStorageWorkletService(
-    mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService> receiver) {
+    mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService> receiver,
+    blink::mojom::WorkletGlobalScopeCreationParamsPtr
+        global_scope_creation_params) {
   DCHECK_EQ(state_, LifecycleState::kBound);
   DCHECK(process_->IsInitializedAndNotDead());
   DCHECK(mojo_remote_.is_bound());
-  mojo_remote_.get()->CreateSharedStorageWorkletService(std::move(receiver));
+  mojo_remote_.get()->CreateSharedStorageWorkletService(
+      std::move(receiver), std::move(global_scope_creation_params));
 }
 
 void AgentSchedulingGroupHost::ReportNoBinderForInterface(
diff --git a/content/browser/renderer_host/agent_scheduling_group_host.h b/content/browser/renderer_host/agent_scheduling_group_host.h
index 3becc0a5b..5d982aa 100644
--- a/content/browser/renderer_host/agent_scheduling_group_host.h
+++ b/content/browser/renderer_host/agent_scheduling_group_host.h
@@ -29,6 +29,7 @@
 #include "third_party/blink/public/mojom/browser_interface_broker.mojom.h"
 #include "third_party/blink/public/mojom/frame/frame_replication_state.mojom-forward.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-forward.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-forward.h"
 
 namespace IPC {
 class ChannelProxy;
@@ -102,8 +103,9 @@
   void CreateFrame(mojom::CreateFrameParamsPtr params);
   void CreateView(mojom::CreateViewParamsPtr params);
   void CreateSharedStorageWorkletService(
-      mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService>
-          receiver);
+      mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService> receiver,
+      blink::mojom::WorkletGlobalScopeCreationParamsPtr
+          global_scope_creation_params);
 
   void ReportNoBinderForInterface(const std::string& error);
 
diff --git a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
index 2fe395df..1ce565b0 100644
--- a/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
+++ b/content/browser/renderer_host/media/in_process_video_capture_device_launcher.cc
@@ -99,6 +99,13 @@
 BASE_FEATURE(kScreenCaptureKitMacWindow,
              "ScreenCaptureKitMacWindow",
              base::FEATURE_DISABLED_BY_DEFAULT);
+
+// If this feature is enabled, ScreenCaptureKit will be used for screen
+// capturing even if kScreenCaptureKitMac is disabled. Please note that this
+// feature has no effect if kScreenCaptureKitMac is enabled.
+BASE_FEATURE(kScreenCaptureKitMacScreen,
+             "ScreenCaptureKitMacScreen",
+             base::FEATURE_DISABLED_BY_DEFAULT);
 #endif
 
 void IncrementDesktopCaptureCounters(const DesktopMediaID& device_id) {
@@ -185,7 +192,9 @@
   // if both fail, use the generic DesktopCaptureDevice.
   if (base::FeatureList::IsEnabled(kScreenCaptureKitMac) ||
       (desktop_id.type == DesktopMediaID::TYPE_WINDOW &&
-       base::FeatureList::IsEnabled(kScreenCaptureKitMacWindow))) {
+       base::FeatureList::IsEnabled(kScreenCaptureKitMacWindow)) ||
+      (desktop_id.type == DesktopMediaID::TYPE_SCREEN &&
+       base::FeatureList::IsEnabled(kScreenCaptureKitMacScreen))) {
     if ((device_out = CreateScreenCaptureKitDeviceMac(desktop_id)))
       return kScreenCaptureKitDeviceMac;
   }
diff --git a/content/browser/shared_storage/shared_storage_render_thread_worklet_driver.cc b/content/browser/shared_storage/shared_storage_render_thread_worklet_driver.cc
index d15c8db..4f6d1a5 100644
--- a/content/browser/shared_storage/shared_storage_render_thread_worklet_driver.cc
+++ b/content/browser/shared_storage/shared_storage_render_thread_worklet_driver.cc
@@ -8,6 +8,7 @@
 #include "content/common/renderer.mojom.h"
 #include "content/public/browser/render_process_host.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom.h"
 
 namespace content {
 
@@ -36,7 +37,9 @@
 
 void SharedStorageRenderThreadWorkletDriver::StartWorkletService(
     mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService>
-        pending_receiver) {
+        pending_receiver,
+    blink::mojom::WorkletGlobalScopeCreationParamsPtr
+        global_scope_creation_params) {
   // `StartWorkletService` will be called right after the driver is created when
   // the document is still alive, as the driver is created on-demand on the
   // first worklet operation. Thus, the `agent_scheduling_group_host_` should
@@ -44,7 +47,7 @@
   DCHECK(agent_scheduling_group_host_);
 
   agent_scheduling_group_host_->CreateSharedStorageWorkletService(
-      std::move(pending_receiver));
+      std::move(pending_receiver), std::move(global_scope_creation_params));
 }
 
 RenderProcessHost* SharedStorageRenderThreadWorkletDriver::GetProcessHost() {
diff --git a/content/browser/shared_storage/shared_storage_render_thread_worklet_driver.h b/content/browser/shared_storage/shared_storage_render_thread_worklet_driver.h
index fd9fa74..2c3421a 100644
--- a/content/browser/shared_storage/shared_storage_render_thread_worklet_driver.h
+++ b/content/browser/shared_storage/shared_storage_render_thread_worklet_driver.h
@@ -31,7 +31,9 @@
   // SharedStorageWorkletDriver overrides
   void StartWorkletService(
       mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService>
-          pending_receiver) override;
+          pending_receiver,
+      blink::mojom::WorkletGlobalScopeCreationParamsPtr
+          global_scope_creation_params) override;
   RenderProcessHost* GetProcessHost() override;
 
   // RenderProcessHostObserver overrides
diff --git a/content/browser/shared_storage/shared_storage_worklet_driver.h b/content/browser/shared_storage/shared_storage_worklet_driver.h
index 4d4c9eb..c6b8f6d 100644
--- a/content/browser/shared_storage/shared_storage_worklet_driver.h
+++ b/content/browser/shared_storage/shared_storage_worklet_driver.h
@@ -7,6 +7,7 @@
 
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-forward.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-forward.h"
 
 namespace content {
 
@@ -20,7 +21,9 @@
   // Called when starting the worklet service.
   virtual void StartWorkletService(
       mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService>
-          pending_receiver) = 0;
+          pending_receiver,
+      blink::mojom::WorkletGlobalScopeCreationParamsPtr
+          global_scope_creation_params) = 0;
 
   // Returns the process host associated with the worklet. Returns nullptr if
   // the process has gone.
diff --git a/content/browser/shared_storage/shared_storage_worklet_host.cc b/content/browser/shared_storage/shared_storage_worklet_host.cc
index 863eb09..8407c0d 100644
--- a/content/browser/shared_storage/shared_storage_worklet_host.cc
+++ b/content/browser/shared_storage/shared_storage_worklet_host.cc
@@ -15,6 +15,7 @@
 #include "components/services/storage/shared_storage/shared_storage_manager.h"
 #include "content/browser/attribution_reporting/attribution_manager.h"
 #include "content/browser/devtools/devtools_instrumentation.h"
+#include "content/browser/devtools/shared_storage_worklet_devtools_manager.h"
 #include "content/browser/fenced_frame/fenced_frame_reporter.h"
 #include "content/browser/private_aggregation/private_aggregation_budget_key.h"
 #include "content/browser/private_aggregation/private_aggregation_host.h"
@@ -34,6 +35,7 @@
 #include "third_party/blink/public/mojom/private_aggregation/private_aggregation_host.mojom.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h"
 #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom.h"
 #include "url/origin.h"
 
 namespace content {
@@ -96,6 +98,50 @@
 
 }  // namespace
 
+class SharedStorageWorkletHost::ScopedDevToolsHandle
+    : blink::mojom::WorkletDevToolsHost {
+ public:
+  explicit ScopedDevToolsHandle(SharedStorageWorkletHost& owner)
+      : owner_(owner), devtools_token_(base::UnguessableToken::Create()) {
+    SharedStorageWorkletDevToolsManager::GetInstance()->WorkletCreated(
+        owner, devtools_token_);
+  }
+
+  ScopedDevToolsHandle(const ScopedDevToolsHandle&) = delete;
+  ScopedDevToolsHandle& operator=(const ScopedDevToolsHandle&) = delete;
+
+  ~ScopedDevToolsHandle() override {
+    SharedStorageWorkletDevToolsManager::GetInstance()->WorkletDestroyed(
+        *owner_);
+  }
+
+  // blink::mojom::WorkletDevToolsHost:
+  void OnReadyForInspection(
+      mojo::PendingRemote<blink::mojom::DevToolsAgent> agent_remote,
+      mojo::PendingReceiver<blink::mojom::DevToolsAgentHost>
+          agent_host_receiver) override {
+    SharedStorageWorkletDevToolsManager::GetInstance()
+        ->WorkletReadyForInspection(*owner_, std::move(agent_remote),
+                                    std::move(agent_host_receiver));
+  }
+
+  const base::UnguessableToken& devtools_token() const {
+    return devtools_token_;
+  }
+
+  mojo::PendingRemote<blink::mojom::WorkletDevToolsHost>
+  BindNewPipeAndPassRemote() {
+    return host_.BindNewPipeAndPassRemote();
+  }
+
+ private:
+  raw_ref<SharedStorageWorkletHost> owner_;
+
+  mojo::Receiver<blink::mojom::WorkletDevToolsHost> host_{this};
+
+  const base::UnguessableToken devtools_token_;
+};
+
 SharedStorageWorkletHost::SharedStorageWorkletHost(
     std::unique_ptr<SharedStorageWorkletDriver> driver,
     SharedStorageDocumentServiceImpl& document_service)
@@ -187,6 +233,8 @@
   add_module_state_ = AddModuleState::kInitiated;
   script_source_url_ = script_source_url;
 
+  devtools_handle_ = std::make_unique<ScopedDevToolsHandle>(*this);
+
   mojo::PendingRemote<network::mojom::URLLoaderFactory> url_loader_factory;
 
   url_loader_factory_proxy_ =
@@ -907,8 +955,15 @@
     bool private_aggregation_permissions_policy_allowed =
         document_service_->render_frame_host().IsFeatureEnabled(
             blink::mojom::PermissionsPolicyFeature::kPrivateAggregation);
+
+    auto global_scope_creation_params =
+        blink::mojom::WorkletGlobalScopeCreationParams::New(
+            script_source_url_, devtools_handle_->devtools_token(),
+            devtools_handle_->BindNewPipeAndPassRemote());
+
     driver_->StartWorkletService(
-        shared_storage_worklet_service_.BindNewPipeAndPassReceiver());
+        shared_storage_worklet_service_.BindNewPipeAndPassReceiver(),
+        std::move(global_scope_creation_params));
 
     auto embedder_context = static_cast<RenderFrameHostImpl&>(
                                 document_service_->render_frame_host())
diff --git a/content/browser/shared_storage/shared_storage_worklet_host.h b/content/browser/shared_storage/shared_storage_worklet_host.h
index f2d99e45..e51954d 100644
--- a/content/browser/shared_storage/shared_storage_worklet_host.h
+++ b/content/browser/shared_storage/shared_storage_worklet_host.h
@@ -170,6 +170,8 @@
   }
 
  private:
+  class ScopedDevToolsHandle;
+
   void OnRunURLSelectionOperationOnWorkletScriptExecutionFinished(
       const GURL& urn_uuid,
       base::TimeTicks start_time,
@@ -206,6 +208,9 @@
 
   bool IsSharedStorageAllowed();
 
+  // RAII helper object for talking to `SharedStorageWorkletDevToolsManager`.
+  std::unique_ptr<ScopedDevToolsHandle> devtools_handle_;
+
   AddModuleState add_module_state_ = AddModuleState::kNotInitiated;
 
   // The URL of the module script. Set when `AddModuleOnWorklet` is invoked.
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index dd0e784..13ba6e8 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -116,6 +116,7 @@
 #include "content/public/browser/session_storage_usage_info.h"
 #include "content/public/browser/shared_cors_origin_access_list.h"
 #include "content/public/browser/storage_notification_service.h"
+#include "content/public/browser/storage_partition_config.h"
 #include "content/public/browser/storage_usage_info.h"
 #include "content/public/common/content_client.h"
 #include "content/public/common/content_constants.h"
@@ -2400,8 +2401,8 @@
           : nullptr);
 
   ClearSiteDataHandler::HandleHeader(
-      browser_context_getter, web_contents_getter, url, header_value,
-      load_flags, cookie_partition_key, storage_key,
+      browser_context_getter, web_contents_getter, GetConfig(), url,
+      header_value, load_flags, cookie_partition_key, storage_key,
       partitioned_state_allowed_only, std::move(callback));
 }
 
diff --git a/content/common/agent_scheduling_group.mojom b/content/common/agent_scheduling_group.mojom
index f58de3a..cb52ec2 100644
--- a/content/common/agent_scheduling_group.mojom
+++ b/content/common/agent_scheduling_group.mojom
@@ -11,6 +11,7 @@
 import "third_party/blink/public/mojom/frame/tree_scope_type.mojom";
 import "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom";
 import "third_party/blink/public/mojom/tokens/tokens.mojom";
+import "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom";
 
 // Interface for general communication between the renderer process's
 // AgentSchedulingGroup and the browser process's AgentSchedulingGroupHost.
@@ -72,5 +73,6 @@
   // Tells the renderer process to create a thread that exclusively hosts the
   // shared storage worklet service.
   CreateSharedStorageWorkletService(
-      pending_receiver<blink.mojom.SharedStorageWorkletService> receiver);
+      pending_receiver<blink.mojom.SharedStorageWorkletService> receiver,
+      blink.mojom.WorkletGlobalScopeCreationParams global_scope_creation_params);
 };
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
index 195ae5f7..d113c81 100644
--- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
+++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -907,8 +907,12 @@
             if (WebContentsAccessibilityImplJni.get().populateAccessibilityNodeInfo(
                         mNativeObj, info, virtualViewId)) {
                 // After successfully populating this node, add it to our cache then return.
-                mNodeInfoCache.put(virtualViewId, AccessibilityNodeInfoCompat.obtain(info));
-                mHistogramRecorder.incrementNodeWasCreatedFromScratch();
+                // If we are not doing performance testing, then use the cache.
+                if (!ContentFeatureMap.isEnabled(
+                            ContentFeatureList.ACCESSIBILITY_PERFORMANCE_TESTING)) {
+                    mNodeInfoCache.put(virtualViewId, AccessibilityNodeInfoCompat.obtain(info));
+                    mHistogramRecorder.incrementNodeWasCreatedFromScratch();
+                }
                 return info;
             } else {
                 info.recycle();
@@ -1592,8 +1596,36 @@
             return;
         }
 
-        mHistogramRecorder.incrementEnqueuedEvents();
-        mEventDispatcher.enqueueEvent(virtualViewId, eventType);
+        // If we are not doing performance testing, then use event dispatcher, otherwise send the
+        // event immediately without throttling / optimizations.
+        if (!ContentFeatureMap.isEnabled(ContentFeatureList.ACCESSIBILITY_PERFORMANCE_TESTING)) {
+            mHistogramRecorder.incrementEnqueuedEvents();
+            mEventDispatcher.enqueueEvent(virtualViewId, eventType);
+        } else {
+            sendEventSynchronously(virtualViewId, eventType);
+        }
+    }
+
+    private void sendEventSynchronously(int virtualViewId, int eventType) {
+        AccessibilityEvent event = buildAccessibilityEvent(virtualViewId, eventType);
+        if (event == null) return;
+
+        requestSendAccessibilityEvent(event);
+
+        // Always send the ENTER and then the EXIT event, to match a standard
+        // Android View.
+        if (eventType == AccessibilityEvent.TYPE_VIEW_HOVER_ENTER) {
+            AccessibilityEvent exitEvent =
+                    buildAccessibilityEvent(mLastHoverId, AccessibilityEvent.TYPE_VIEW_HOVER_EXIT);
+            if (exitEvent != null) {
+                requestSendAccessibilityEvent(exitEvent);
+                mLastHoverId = virtualViewId;
+            } else if (virtualViewId != View.NO_ID && mLastHoverId != virtualViewId) {
+                // If IDs become mismatched, or on first hover, this will sync the
+                // values again so all further hovers have correct event pairing.
+                mLastHoverId = virtualViewId;
+            }
+        }
     }
 
     private AccessibilityEvent buildAccessibilityEvent(int virtualViewId, int eventType) {
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
index ed89114..d37bb079 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java
@@ -448,6 +448,12 @@
 
     @Test
     @SmallTest
+    public void test_ariaSelectedChangedNewSubtree() {
+        performTest("aria-selected-changed-new-subtree.html", EMPTY_EXPECTATIONS_FILE);
+    }
+
+    @Test
+    @SmallTest
     public void test_ariaSetsizeChanged() {
         performTest("aria-setsize-changed.html", EMPTY_EXPECTATIONS_FILE);
     }
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
index 98e6487..b271bae2 100644
--- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
+++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityTest.java
@@ -167,11 +167,14 @@
             "Expected focus to be on a different node than it is.";
 
     // ContentFeatureList maps used for various tests.
-    private static final Map<String, Boolean> ON_DEMAND_ON_AXMODES_ON =
+    private static final Map<String, Boolean> ON_DEMAND_ON_AXMODES_ON_PERF_TEST_OFF =
             Map.of(ContentFeatureList.ON_DEMAND_ACCESSIBILITY_EVENTS, true,
-                    ContentFeatureList.ACCESSIBILITY_PERFORMANCE_FILTERING, true);
+                    ContentFeatureList.ACCESSIBILITY_PERFORMANCE_FILTERING, true,
+                    ContentFeatureList.ACCESSIBILITY_PERFORMANCE_TESTING, false);
     private static final Map<String, Boolean> AUTO_DISABLE_V2_ON =
             Map.of(ContentFeatureList.AUTO_DISABLE_ACCESSIBILITY_V2, true);
+    private static final Map<String, Boolean> PERF_TEST_OFF =
+            Map.of(ContentFeatureList.ACCESSIBILITY_PERFORMANCE_TESTING, false);
 
     // Constant values for unit tests
     private static final int UNSUPPRESSED_EXPECTED_COUNT = 15;
@@ -424,7 +427,7 @@
                 + "<p>This is a test 3</p>");
 
         // Set the relevant features and accessibility state.
-        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON);
+        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON_PERF_TEST_OFF);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             AccessibilityState.setIsScreenReaderEnabledForTesting(true);
             AccessibilityState.setIsOnlyPasswordManagersEnabledForTesting(false);
@@ -459,7 +462,7 @@
                 + "<p>This is a test 3</p>");
 
         // Set the relevant features and accessibility state.
-        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON);
+        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON_PERF_TEST_OFF);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             AccessibilityState.setIsScreenReaderEnabledForTesting(false);
             AccessibilityState.setIsOnlyPasswordManagersEnabledForTesting(true);
@@ -495,7 +498,7 @@
                 + "<p>This is a test 3</p>");
 
         // Set the relevant features and screen reader state.
-        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON);
+        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON_PERF_TEST_OFF);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             AccessibilityState.setIsScreenReaderEnabledForTesting(false);
             AccessibilityState.setIsOnlyPasswordManagersEnabledForTesting(false);
@@ -532,7 +535,7 @@
                 + "<p>This is a test 3</p>");
 
         // Set the relevant features and screen reader state, set event type masks to empty.
-        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON);
+        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON_PERF_TEST_OFF);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             AccessibilityState.setEventTypeMaskForTesting(EVENT_TYPE_MASK_NONE);
             AccessibilityState.setIsScreenReaderEnabledForTesting(true);
@@ -570,7 +573,7 @@
                 + "<p>This is a test 3</p>");
 
         // Set the relevant features and screen reader state, set event type masks to empty.
-        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON);
+        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON_PERF_TEST_OFF);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             AccessibilityState.setEventTypeMaskForTesting(EVENT_TYPE_MASK_NONE);
             AccessibilityState.setIsScreenReaderEnabledForTesting(false);
@@ -608,7 +611,7 @@
                 + "<p>This is a test 3</p>");
 
         // Set the relevant features and screen reader state, set event type masks to empty.
-        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON);
+        FeatureList.setTestFeatures(ON_DEMAND_ON_AXMODES_ON_PERF_TEST_OFF);
         TestThreadUtils.runOnUiThreadBlocking(() -> {
             AccessibilityState.setEventTypeMaskForTesting(EVENT_TYPE_MASK_NONE);
             AccessibilityState.setIsScreenReaderEnabledForTesting(false);
@@ -645,6 +648,9 @@
                 + "<p>This is a test 2</p>\n"
                 + "<p>This is a test 3</p>");
 
+        // Set the correct performance testing state so the cache is used.
+        FeatureList.setTestFeatures(PERF_TEST_OFF);
+
         var histogramWatcher =
                 HistogramWatcher.newBuilder()
                         .expectIntRecord(CACHE_MAX_NODES_HISTOGRAM, 4)
diff --git a/content/public/browser/browsing_data_remover.h b/content/public/browser/browsing_data_remover.h
index 067e45f..797edb8 100644
--- a/content/public/browser/browsing_data_remover.h
+++ b/content/public/browser/browsing_data_remover.h
@@ -176,10 +176,9 @@
 
   // Data types stored within a StoragePartition (i.e. not Profile-scoped).
   static constexpr DataType DATA_TYPE_ON_STORAGE_PARTITION =
-      DATA_TYPE_APP_CACHE_DEPRECATED | DATA_TYPE_FILE_SYSTEMS |
-      DATA_TYPE_INDEXED_DB | DATA_TYPE_LOCAL_STORAGE | DATA_TYPE_WEB_SQL |
-      DATA_TYPE_SERVICE_WORKERS | DATA_TYPE_CACHE_STORAGE |
-      DATA_TYPE_BACKGROUND_FETCH | DATA_TYPE_COOKIES | DATA_TYPE_CACHE;
+      DATA_TYPE_DOM_STORAGE | DATA_TYPE_COOKIES |
+      DATA_TYPE_AVOID_CLOSING_CONNECTIONS | DATA_TYPE_CACHE |
+      DATA_TYPE_APP_CACHE_DEPRECATED | DATA_TYPE_PRIVACY_SANDBOX;
 
   using OriginType = uint64_t;
   // Web storage origins that StoragePartition recognizes as NOT protected
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/DOMUtils.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/DOMUtils.java
index cce7aae1..4c38cc2e 100644
--- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/DOMUtils.java
+++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/DOMUtils.java
@@ -38,6 +38,8 @@
 public class DOMUtils {
     private static final long MEDIA_TIMEOUT_SECONDS = 10L;
     private static final long MEDIA_TIMEOUT_MILLISECONDS = MEDIA_TIMEOUT_SECONDS * 1000;
+    private static final String RESULT_OK = "RESULT_OK";
+    private static final String RESULT_ELEMENT_NOT_FOUND = "RESULT_ELEMENT_NOT_FOUND";
 
     /**
      * Plays the media with given {@code id}.
@@ -718,16 +720,46 @@
                     is(true));
         });
 
-        int updateSelectionListSize = inputMethodManagerWrapper.getUpdateSelectionList().size();
         ImeAdapter imeAdapter = WebContentsUtils.getImeAdapter(webContents);
         // Enter the text.
         imeAdapter.setComposingTextForTest(input, 1);
         // Wait for the input to finish. After finishing the input, it will update the selection to
         // move the cursor to the right position. This indicated that the input has finished.
-        CriteriaHelper.pollInstrumentationThread(() -> {
-            Criteria.checkThat(inputMethodManagerWrapper.getUpdateSelectionList().size(),
-                    is(updateSelectionListSize + 1));
-        });
+        waitForTextFieldValue(webContents, nodeId, input);
+    }
+
+    private static void waitForTextFieldValue(
+            WebContents webContents, String textFieldId, String value) throws TimeoutException {
+        StringBuilder func = new StringBuilder();
+        func.append("function valueCheck() {");
+        func.append("  var element = document.getElementById('" + textFieldId + "');");
+        func.append("  return element && element.value == '" + value + "';");
+        func.append("}");
+
+        func.append("new Promise(resolve => {");
+        func.append("  if (valueCheck()) {");
+        func.append("    return resolve(" + RESULT_OK + ");");
+
+        func.append("  } else {");
+        func.append("    var element = document.getElementById('" + textFieldId + "');");
+        func.append("    if (!element)");
+        func.append("      return resolve(" + RESULT_ELEMENT_NOT_FOUND + ");");
+
+        func.append("    element.oninput = function() {");
+        func.append("      if (valueCheck()) {");
+        func.append("        element.oninput = undefined;");
+        func.append("        return resolve(" + RESULT_OK + ");");
+        func.append("      }");
+        func.append("    };");
+        func.append("  }");
+        func.append("});");
+
+        String result =
+                JavaScriptUtils.executeJavaScriptAndWaitForResult(webContents, func.toString());
+        if (RESULT_ELEMENT_NOT_FOUND.equals(result)) {
+            Assert.fail("The expected value of the element with id " + textFieldId
+                    + " is different from the expected value " + value);
+        }
     }
 
     @NativeMethods
diff --git a/content/public/test/mock_browsing_data_remover_delegate.cc b/content/public/test/mock_browsing_data_remover_delegate.cc
index 88a1ab7..e882f542 100644
--- a/content/public/test/mock_browsing_data_remover_delegate.cc
+++ b/content/public/test/mock_browsing_data_remover_delegate.cc
@@ -138,6 +138,15 @@
     }
     os << "  filter_builder: " << std::endl;
     os << "    mode: " << mode_string << std::endl;
+
+    auto config = p.filter_builder_->GetStoragePartitionConfig();
+    os << "    StoragePartition: ";
+    if (config.has_value()) {
+      os << config.value();
+    } else {
+      os << "NULL";
+    }
+    os << std::endl;
   }
   return os;
 }
diff --git a/content/renderer/accessibility/render_accessibility_impl.h b/content/renderer/accessibility/render_accessibility_impl.h
index ddd8273..088edf5 100644
--- a/content/renderer/accessibility/render_accessibility_impl.h
+++ b/content/renderer/accessibility/render_accessibility_impl.h
@@ -278,7 +278,8 @@
   // Manages the automatic image annotations, if enabled.
   std::unique_ptr<AXImageAnnotator> ax_image_annotator_;
 
-  using PluginAXTreeSerializer = ui::AXTreeSerializer<const ui::AXNode*>;
+  using PluginAXTreeSerializer =
+      ui::AXTreeSerializer<const ui::AXNode*, std::vector<const ui::AXNode*>>;
   std::unique_ptr<PluginAXTreeSerializer> plugin_serializer_;
   PluginAXTreeSource* plugin_tree_source_;
 
diff --git a/content/renderer/agent_scheduling_group.cc b/content/renderer/agent_scheduling_group.cc
index 13cdba7b..489d2cba 100644
--- a/content/renderer/agent_scheduling_group.cc
+++ b/content/renderer/agent_scheduling_group.cc
@@ -27,6 +27,7 @@
 #include "third_party/blink/public/mojom/frame/frame.mojom.h"
 #include "third_party/blink/public/mojom/page/page.mojom.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom.h"
 #include "third_party/blink/public/platform/scheduler/web_thread_scheduler.h"
 #include "third_party/blink/public/web/web_remote_frame.h"
 #include "third_party/blink/public/web/web_shared_storage_worklet_thread.h"
@@ -407,9 +408,12 @@
 }
 
 void AgentSchedulingGroup::CreateSharedStorageWorkletService(
-    mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService> receiver) {
+    mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService> receiver,
+    blink::mojom::WorkletGlobalScopeCreationParamsPtr
+        global_scope_creation_params) {
   blink::WebSharedStorageWorkletThread::Start(
-      agent_group_scheduler_->DefaultTaskRunner(), std::move(receiver));
+      agent_group_scheduler_->DefaultTaskRunner(), std::move(receiver),
+      std::move(global_scope_creation_params));
 }
 
 void AgentSchedulingGroup::BindAssociatedInterfaces(
diff --git a/content/renderer/agent_scheduling_group.h b/content/renderer/agent_scheduling_group.h
index dd5d8f5a..788214f3 100644
--- a/content/renderer/agent_scheduling_group.h
+++ b/content/renderer/agent_scheduling_group.h
@@ -25,6 +25,7 @@
 #include "third_party/blink/public/mojom/browser_interface_broker.mojom.h"
 #include "third_party/blink/public/mojom/frame/frame_replication_state.mojom-forward.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-forward.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-forward.h"
 #include "third_party/blink/public/platform/scheduler/web_agent_group_scheduler.h"
 
 namespace IPC {
@@ -103,8 +104,9 @@
   void CreateView(mojom::CreateViewParamsPtr params) override;
   void CreateFrame(mojom::CreateFrameParamsPtr params) override;
   void CreateSharedStorageWorkletService(
-      mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService> receiver)
-      override;
+      mojo::PendingReceiver<blink::mojom::SharedStorageWorkletService> receiver,
+      blink::mojom::WorkletGlobalScopeCreationParamsPtr
+          global_scope_creation_params) override;
 
   // mojom::RouteProvider
   void GetRoute(
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc
index 6c20ee7..8d654400 100644
--- a/content/services/auction_worklet/bidder_worklet_unittest.cc
+++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -2291,7 +2291,7 @@
 
 TEST_F(BidderWorkletTest, GenerateBidInterestGroupBiddingLogicUrl) {
   const std::string kGenerateBidBody =
-      R"({ad: interestGroup.biddingLogicUrl, bid:1,
+      R"({ad: interestGroup.biddingLogicURL, bid:1,
         render:"https://response.test/"})";
 
   RunGenerateBidWithReturnValueExpectingResult(
diff --git a/content/shell/browser/shell_content_browser_client.cc b/content/shell/browser/shell_content_browser_client.cc
index 26acf8c..c183443 100644
--- a/content/shell/browser/shell_content_browser_client.cc
+++ b/content/shell/browser/shell_content_browser_client.cc
@@ -77,7 +77,6 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 #include "net/ssl/client_cert_identity.h"
-#include "services/device/public/cpp/geolocation/buildflags.h"
 #include "services/device/public/cpp/geolocation/location_system_permission_status.h"
 #include "services/network/public/cpp/features.h"
 #include "services/network/public/cpp/network_service_buildflags.h"
@@ -98,10 +97,13 @@
 #include "base/android/path_utils.h"
 #include "components/variations/android/variations_seed_bridge.h"
 #include "content/shell/android/shell_descriptors.h"
+#endif
+
+#if BUILDFLAG(IS_ANDROID)
 #include "components/crash/content/browser/crash_handler_host_linux.h"
 #endif
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
 #include "services/device/public/cpp/test/fake_geolocation_manager.h"
 #endif
 
@@ -253,14 +255,14 @@
 // needed should be added here so that it's shared between the instances.
 struct SharedState {
   SharedState() {
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
     location_manager = std::make_unique<device::FakeGeolocationManager>();
     location_manager->SetSystemPermission(
         device::LocationSystemPermissionStatus::kAllowed);
 #endif
   }
 
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
   std::unique_ptr<device::FakeGeolocationManager> location_manager;
 #endif
 
@@ -429,7 +431,7 @@
 }
 
 device::GeolocationManager* ShellContentBrowserClient::GetGeolocationManager() {
-#if BUILDFLAG(OS_LEVEL_GEOLOCATION_PERMISSION_SUPPORTED)
+#if BUILDFLAG(IS_MAC)
   return GetSharedState().location_manager.get();
 #elif BUILDFLAG(IS_IOS)
   // TODO(crbug.com/1431447, 1411704): Unify this to FakeGeolocationManager once
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index cd31e42..26e2f71 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -933,6 +933,7 @@
 
     "//content/test/gpu/gpu_project_config.py",
     "//content/test/gpu/run_gpu_integration_test.py",
+    "//content/test/gpu/validate_tag_consistency.py",
   ]
   data_deps = [
     # For WebGPU CTS tests.
@@ -2001,6 +2002,7 @@
       "../browser/file_system_access/file_system_access_drag_drop_browsertest.cc",
       "../browser/file_system_access/file_system_access_file_handle_impl_browsertest.cc",
       "../browser/file_system_access/file_system_access_file_writer_impl_browsertest.cc",
+      "../browser/file_system_access/file_system_access_observer_browsertest.cc",
       "../browser/file_system_access/file_system_chooser_browsertest.cc",
       "../browser/font_preferences_browsertest.cc",
       "../browser/renderer_host/clipboard_host_impl_browsertest.cc",
@@ -2349,6 +2351,8 @@
     "../browser/file_system_access/file_system_access_lock_manager_unittest.cc",
     "../browser/file_system_access/file_system_access_manager_impl_unittest.cc",
     "../browser/file_system_access/file_system_access_safe_move_helper_unittest.cc",
+    "../browser/file_system_access/file_system_access_watch_scope_unittest.cc",
+    "../browser/file_system_access/file_system_access_watcher_manager_unittest.cc",
     "../browser/file_system_access/file_system_chooser_unittest.cc",
     "../browser/first_party_sets/database/first_party_sets_database_unittest.cc",
     "../browser/first_party_sets/first_party_set_parser_unittest.cc",
@@ -3343,6 +3347,10 @@
       "//content/public/browser",
       "//testing/gtest",
     ]
+
+    if (is_ios) {
+      bundle_deps = [ ":content_shell_pak_bundle_data" ]
+    }
   }
 }
 
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist
index 7aada0e..4369fe36 100644
--- a/content/test/content_test_bundle_data.filelist
+++ b/content/test/content_test_bundle_data.filelist
@@ -2003,6 +2003,11 @@
 data/accessibility/event/aria-selected-changed-expected-android.txt
 data/accessibility/event/aria-selected-changed-expected-uia-win.txt
 data/accessibility/event/aria-selected-changed-expected-win.txt
+data/accessibility/event/aria-selected-changed-new-subtree-expected-auralinux.txt
+data/accessibility/event/aria-selected-changed-new-subtree-expected-mac.txt
+data/accessibility/event/aria-selected-changed-new-subtree-expected-uia-win.txt
+data/accessibility/event/aria-selected-changed-new-subtree-expected-win.txt
+data/accessibility/event/aria-selected-changed-new-subtree.html
 data/accessibility/event/aria-selected-changed.html
 data/accessibility/event/aria-setsize-changed-expected-uia-win.txt
 data/accessibility/event/aria-setsize-changed.html
@@ -6140,6 +6145,8 @@
 data/interest_group/bidding_logic.js.mock-http-headers
 data/interest_group/bidding_logic_additional_bid.js
 data/interest_group/bidding_logic_additional_bid.js.mock-http-headers
+data/interest_group/bidding_logic_additional_bid_no_cors.js
+data/interest_group/bidding_logic_additional_bid_no_cors.js.mock-http-headers
 data/interest_group/bidding_logic_expect_top_frame_a_test.js
 data/interest_group/bidding_logic_expect_top_frame_a_test.js.mock-http-headers
 data/interest_group/bidding_logic_invalid_ad_url.js
diff --git a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-auralinux.txt b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-auralinux.txt
index dfea3a4..234d8266 100644
--- a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-auralinux.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-auralinux.txt
@@ -4,5 +4,7 @@
 FOCUS-EVENT:TRUE role=ROLE_LIST_ITEM name='Apple' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
 PARENT-CHANGED PARENT:(role=ROLE_DOCUMENT_WEB name='(null)') role=ROLE_COMBO_BOX name='(null)' EDITABLE,ENABLED,EXPANDABLE,EXPANDED,FOCUSABLE,SENSITIVE,SHOWING,SINGLE-LINE,VISIBLE,SUPPORTS-AUTOCOMPLETION,SELECTABLE-TEXT,HAS-POPUP
 PARENT-CHANGED PARENT:(role=ROLE_DOCUMENT_WEB name='(null)') role=ROLE_LIST_BOX name='(null)' ENABLED,SENSITIVE,SHOWING,VERTICAL,VISIBLE
+SELECTION-CHANGED role=ROLE_LIST_BOX name='(null)' ENABLED,SENSITIVE,SHOWING,VERTICAL,VISIBLE
 STATE-CHANGE:FOCUSED:FALSE role=ROLE_COMBO_BOX name='(null)' EDITABLE,ENABLED,EXPANDABLE,EXPANDED,FOCUSABLE,SENSITIVE,SHOWING,SINGLE-LINE,VISIBLE,SUPPORTS-AUTOCOMPLETION,SELECTABLE-TEXT,HAS-POPUP
-STATE-CHANGE:FOCUSED:TRUE role=ROLE_LIST_ITEM name='Apple' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
\ No newline at end of file
+STATE-CHANGE:FOCUSED:TRUE role=ROLE_LIST_ITEM name='Apple' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
+STATE-CHANGE:SELECTED:TRUE role=ROLE_LIST_ITEM name='Apple' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-mac.txt b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-mac.txt
index ec33813..2da0fdf 100644
--- a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-mac.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-mac.txt
@@ -1,2 +1,3 @@
 AXFocusedUIElementChanged on AXStaticText AXValue='Apple'
-AXSelectedChildrenChanged on AXComboBox AXAutocompleteValue='list'
\ No newline at end of file
+AXSelectedChildrenChanged on AXComboBox AXAutocompleteValue='list'
+AXSelectedChildrenChanged on AXList
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-win.txt b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-win.txt
index da197e0..95e0577 100644
--- a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-win.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-win.txt
@@ -1,5 +1,8 @@
 EVENT_OBJECT_FOCUS on <li#op1> role=ROLE_SYSTEM_LISTITEM name="Apple" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=1
 EVENT_OBJECT_HIDE on <body> role=ROLE_SYSTEM_GROUPING INVISIBLE
+EVENT_OBJECT_SELECTION on <li#op1> role=ROLE_SYSTEM_LISTITEM name="Apple" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=1
+EVENT_OBJECT_SELECTIONWITHIN on <ul#list> role=ROLE_SYSTEM_LIST IA2_STATE_VERTICAL SetSize=1
+EVENT_OBJECT_STATECHANGE on <li#op1> role=ROLE_SYSTEM_LISTITEM name="Apple" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=1
 IA2_EVENT_ACTIVE_DESCENDANT_CHANGED on <input> role=ROLE_SYSTEM_COMBOBOX EXPANDED,FOCUSABLE,HASPOPUP IA2_STATE_EDITABLE,IA2_STATE_SELECTABLE_TEXT,IA2_STATE_SINGLE_LINE,IA2_STATE_SUPPORTS_AUTOCOMPLETION
 IA2_EVENT_TEXT_INSERTED on <#document> role=ROLE_SYSTEM_DOCUMENT value~=[doc-url] FOCUSABLE new_text={'<obj><obj>' start=0 end=2}
 IA2_EVENT_TEXT_REMOVED on <#document> role=ROLE_SYSTEM_DOCUMENT value~=[doc-url] FOCUSABLE old_text={'<obj>' start=0 end=1}
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/aria-combo-box-next-expected-auralinux.txt b/content/test/data/accessibility/event/aria-combo-box-next-expected-auralinux.txt
index 384ff67..8432ccce3 100644
--- a/content/test/data/accessibility/event/aria-combo-box-next-expected-auralinux.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-next-expected-auralinux.txt
@@ -3,6 +3,7 @@
 SELECTION-CHANGED role=ROLE_LIST_BOX name='(null)' ENABLED,SENSITIVE,SHOWING,VERTICAL,VISIBLE
 STATE-CHANGE:FOCUSED:FALSE role=ROLE_LIST_ITEM name='Apple' ENABLED,FOCUSABLE,SELECTABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:FOCUSED:TRUE role=ROLE_LIST_ITEM name='Orange' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
+STATE-CHANGE:SELECTED:FALSE role=ROLE_LIST_ITEM name='Apple' ENABLED,FOCUSABLE,SELECTABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:SELECTED:TRUE role=ROLE_LIST_ITEM name='Orange' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
 === Start Continuation ===
 FOCUS-EVENT:FALSE role=ROLE_LIST_ITEM name='Orange' ENABLED,FOCUSABLE,SELECTABLE,SENSITIVE,SHOWING,VISIBLE
diff --git a/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-auralinux.txt b/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-auralinux.txt
new file mode 100644
index 0000000..7fb06d1
--- /dev/null
+++ b/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-auralinux.txt
@@ -0,0 +1,11 @@
+CHILDREN-CHANGED:ADD index:2 CHILD:(role=ROLE_TABLE_CELL) role=ROLE_TABLE_ROW ENABLED,SENSITIVE,SHOWING,VISIBLE
+SELECTION-CHANGED role=ROLE_TABLE name='(null)' ENABLED,SENSITIVE,SHOWING,VISIBLE
+STATE-CHANGE:SELECTED:TRUE role=ROLE_TABLE_CELL name='Grid, GridCell3' ENABLED,FOCUSABLE,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
+=== Start Continuation ===
+CHILDREN-CHANGED:ADD index:2 CHILD:(role=ROLE_MENU_ITEM) role=ROLE_MENU ENABLED,SENSITIVE
+SELECTION-CHANGED role=ROLE_MENU name='(null)' ENABLED,SENSITIVE
+STATE-CHANGE:SELECTED:TRUE role=ROLE_MENU_ITEM name='Select, Option3' ENABLED,FOCUSABLE,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
+=== Start Continuation ===
+CHILDREN-CHANGED:ADD index:2 CHILD:(role=ROLE_LIST_ITEM) role=ROLE_LIST_BOX ENABLED,SENSITIVE,SHOWING,VERTICAL,VISIBLE
+SELECTION-CHANGED role=ROLE_LIST_BOX name='(null)' ENABLED,SENSITIVE,SHOWING,VERTICAL,VISIBLE
+STATE-CHANGE:SELECTED:TRUE role=ROLE_LIST_ITEM name='DivSelect, Option3' ENABLED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-mac.txt b/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-mac.txt
new file mode 100644
index 0000000..fca9df69
--- /dev/null
+++ b/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-mac.txt
@@ -0,0 +1,6 @@
+AXSelectedRowsChanged on AXTable
+=== Start Continuation ===
+AXSelectedChildrenChanged on AXMenu
+AXValueChanged on AXPopUpButton AXValue='Select, Option3'
+=== Start Continuation ===
+AXSelectedChildrenChanged on AXList
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-uia-win.txt b/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-uia-win.txt
new file mode 100644
index 0000000..f386b00
--- /dev/null
+++ b/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-uia-win.txt
@@ -0,0 +1,24 @@
+AriaProperties changed on role=gridcell, name=Grid, GridCell1
+AriaProperties changed on role=gridcell, name=Grid, GridCell3
+SelectionItemIsSelected changed on role=gridcell, name=Grid, GridCell1
+SelectionItemIsSelected changed on role=gridcell, name=Grid, GridCell3
+SelectionItem_ElementRemovedFromSelection on role=gridcell, name=Grid, GridCell1
+SelectionItem_ElementSelected on role=gridcell, name=Grid, GridCell3
+StructureChanged/ChildAdded on role=gridcell, name=Grid, GridCell3
+StructureChanged/ChildrenReordered on role=row
+=== Start Continuation ===
+AriaProperties changed on role=listitem, name=Select, Option3
+SelectionItemIsSelected changed on role=listitem, name=Select, Option3
+SelectionItem_ElementSelected on role=listitem, name=Select, Option3
+StructureChanged/ChildAdded on role=listitem, name=Select, Option3
+StructureChanged/ChildrenReordered on role=combobox
+Text_TextChanged on role=document
+ValueValue changed on role=combobox
+=== Start Continuation ===
+AriaProperties changed on role=option, name=DivSelect, Option1
+AriaProperties changed on role=option, name=DivSelect, Option3
+SelectionItemIsSelected changed on role=option, name=DivSelect, Option1
+SelectionItemIsSelected changed on role=option, name=DivSelect, Option3
+SelectionItem_ElementSelected on role=option, name=DivSelect, Option3
+StructureChanged/ChildAdded on role=option, name=DivSelect, Option3
+StructureChanged/ChildrenReordered on role=listbox
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-win.txt b/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-win.txt
new file mode 100644
index 0000000..cd7b873b
--- /dev/null
+++ b/content/test/data/accessibility/event/aria-selected-changed-new-subtree-expected-win.txt
@@ -0,0 +1,25 @@
+EVENT_OBJECT_LOCATIONCHANGE on <table#Grid> role=ROLE_SYSTEM_TABLE
+EVENT_OBJECT_REORDER on <tr> role=ROLE_SYSTEM_ROW
+EVENT_OBJECT_SELECTION on <td#GridCell1> role=ROLE_SYSTEM_CELL name="Grid, GridCell3" SELECTED,FOCUSABLE,SELECTABLE
+EVENT_OBJECT_SELECTIONREMOVE on <td#GridCell1> role=ROLE_SYSTEM_CELL name="Grid, GridCell1" FOCUSABLE,SELECTABLE
+EVENT_OBJECT_SELECTIONWITHIN on <table#Grid> role=ROLE_SYSTEM_TABLE
+EVENT_OBJECT_SHOW on <td#GridCell1> role=ROLE_SYSTEM_CELL name="Grid, GridCell3" SELECTED,FOCUSABLE,SELECTABLE
+EVENT_OBJECT_STATECHANGE on <td#GridCell1> role=ROLE_SYSTEM_CELL name="Grid, GridCell1" FOCUSABLE,SELECTABLE
+EVENT_OBJECT_STATECHANGE on <td#GridCell1> role=ROLE_SYSTEM_CELL name="Grid, GridCell3" SELECTED,FOCUSABLE,SELECTABLE
+IA2_EVENT_TEXT_INSERTED on <tr> role=ROLE_SYSTEM_ROW new_text={'<obj>' start=2 end=3}
+=== Start Continuation ===
+EVENT_OBJECT_REORDER on role=ROLE_SYSTEM_LIST INVISIBLE SetSize=3
+EVENT_OBJECT_SELECTION on <option#Option3> role=ROLE_SYSTEM_LISTITEM name="Select, Option3" SELECTED,FOCUSABLE,SELECTABLE PosInSet=3 SetSize=3
+EVENT_OBJECT_SELECTIONWITHIN on role=ROLE_SYSTEM_LIST INVISIBLE SetSize=3
+EVENT_OBJECT_SHOW on <option#Option3> role=ROLE_SYSTEM_LISTITEM name="Select, Option3" SELECTED,FOCUSABLE,SELECTABLE PosInSet=3 SetSize=3
+EVENT_OBJECT_STATECHANGE on <option#Option3> role=ROLE_SYSTEM_LISTITEM name="Select, Option3" SELECTED,FOCUSABLE,SELECTABLE PosInSet=3 SetSize=3
+EVENT_OBJECT_VALUECHANGE on <select#Select> role=ROLE_SYSTEM_COMBOBOX value="Select, Option3" COLLAPSED,FOCUSABLE,HASPOPUP SetSize=3
+IA2_EVENT_TEXT_INSERTED on role=ROLE_SYSTEM_LIST INVISIBLE SetSize=3 new_text={'l' start=2 end=3}
+=== Start Continuation ===
+EVENT_OBJECT_REORDER on <div#DivSelect> role=ROLE_SYSTEM_LIST IA2_STATE_VERTICAL SetSize=3
+EVENT_OBJECT_SELECTION on <div#Option3> role=ROLE_SYSTEM_LISTITEM name="DivSelect, Option3" SELECTED,FOCUSED,SELECTABLE PosInSet=3 SetSize=3
+EVENT_OBJECT_SELECTIONWITHIN on <div#DivSelect> role=ROLE_SYSTEM_LIST IA2_STATE_VERTICAL SetSize=3
+EVENT_OBJECT_SHOW on <div#Option3> role=ROLE_SYSTEM_LISTITEM name="DivSelect, Option3" SELECTED,FOCUSED,SELECTABLE PosInSet=3 SetSize=3
+EVENT_OBJECT_STATECHANGE on <div#Option1> role=ROLE_SYSTEM_LISTITEM name="DivSelect, Option1" SELECTABLE PosInSet=1 SetSize=3
+EVENT_OBJECT_STATECHANGE on <div#Option3> role=ROLE_SYSTEM_LISTITEM name="DivSelect, Option3" SELECTED,FOCUSED,SELECTABLE PosInSet=3 SetSize=3
+IA2_EVENT_TEXT_INSERTED on <div#DivSelect> role=ROLE_SYSTEM_LIST IA2_STATE_VERTICAL SetSize=3 new_text={'<obj>' start=2 end=3}
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/aria-selected-changed-new-subtree.html b/content/test/data/accessibility/event/aria-selected-changed-new-subtree.html
new file mode 100644
index 0000000..6db9b0c
--- /dev/null
+++ b/content/test/data/accessibility/event/aria-selected-changed-new-subtree.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<table id='Grid' role='grid' aria-multiselectable='false'><tbody>
+  <tr>
+    <td id='GridCell1' role='gridcell' aria-selected='true' tabindex='0'
+        onclick='tdclick(this, event)'>Grid, GridCell1</td>
+    <td id='GridCell2' role='gridcell' aria-selected='false' tabindex='0'
+        onclick='tdclick(this, event)'>Grid, GridCell2</td>
+  </tr>
+</tbody></table>
+<select id='Select'>
+  <option id='Option1' value='1' selected
+          onclick='option_click(this, event)'>Select, Option1</option>
+  <option id='Option2' value='2'
+          onclick='option_click(this, event)'>Select, Option2</option>
+</select>
+<div id='DivSelect' role='listbox'>
+  <div id='Option1' role='option' aria-selected='true'
+       onclick='div_option_click(this, event)'>DivSelect, Option1</div>
+  <div id='Option2' role='option' aria-selected='false'
+       onclick='div_option_click(this, event)'>DivSelect, Option2</div>
+</div>
+<script>
+  function grid_select() {
+    var selected = document.querySelector('td#GridCell1');
+    var new_selection = selected.cloneNode(true);
+    selected.setAttribute('aria-selected', false);
+    new_selection.innerHTML = 'Grid, GridCell3';
+    new_selection.id - 'GridCell3'
+    selected.parentElement.appendChild(new_selection);
+  }
+
+  function option_select() {
+    var selected = document.querySelector('option#Option1');
+    var new_selection = selected.cloneNode(true);
+    selected.selected = false;
+    new_selection.value = '3';
+    new_selection.innerHTML = 'Select, Option3';
+    new_selection.id = 'Option3';
+    selected.parentElement.appendChild(new_selection);
+  }
+
+  function div_select() {
+    var selected = document.querySelector('div#Option1');
+    var new_selection = selected.cloneNode(true);
+    selected.setAttribute('aria-selected', false);
+    new_selection.innerHTML = 'DivSelect, Option3';
+    new_selection.id = 'Option3';
+    selected.parentElement.appendChild(new_selection);
+  }
+
+  const go_passes = [
+    () => grid_select(),
+    () => option_select(),
+    () => div_select(),
+  ];
+
+  var current_pass = 0;
+  function go() {
+    go_passes[current_pass++].call();
+    return current_pass < go_passes.length;
+  }
+</script>
diff --git a/content/test/data/accessibility/event/button-click-expected-android.txt b/content/test/data/accessibility/event/button-click-expected-android.txt
index ce189461..9a8630ac 100644
--- a/content/test/data/accessibility/event/button-click-expected-android.txt
+++ b/content/test/data/accessibility/event/button-click-expected-android.txt
@@ -1,7 +1,7 @@
+TYPE_VIEW_ACCESSIBILITY_FOCUSED
 TYPE_VIEW_CLICKED
 TYPE_VIEW_CLICKED
 TYPE_VIEW_CLICKED
 TYPE_VIEW_CLICKED
 TYPE_VIEW_CLICKED
 TYPE_VIEW_CLICKED
-TYPE_VIEW_ACCESSIBILITY_FOCUSED
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/focus-listbox-expected-auralinux.txt b/content/test/data/accessibility/event/focus-listbox-expected-auralinux.txt
index 852871a2..d38c6eb 100644
--- a/content/test/data/accessibility/event/focus-listbox-expected-auralinux.txt
+++ b/content/test/data/accessibility/event/focus-listbox-expected-auralinux.txt
@@ -3,4 +3,5 @@
 SELECTION-CHANGED role=ROLE_LIST_BOX name='(null)' ENABLED,FOCUSABLE,SENSITIVE,SHOWING,VERTICAL,VISIBLE
 STATE-CHANGE:FOCUSED:FALSE role=ROLE_DOCUMENT_WEB name='(null)' ENABLED,FOCUSABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:FOCUSED:TRUE role=ROLE_LIST_ITEM name='%C3%A7' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
+STATE-CHANGE:SELECTED:FALSE role=ROLE_LIST_ITEM name='b' ENABLED,FOCUSABLE,SELECTABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:SELECTED:TRUE role=ROLE_LIST_ITEM name='%C3%A7' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
diff --git a/content/test/data/accessibility/event/focus-listbox-multiselect-expected-auralinux.txt b/content/test/data/accessibility/event/focus-listbox-multiselect-expected-auralinux.txt
index 9c1c347..ee9ecdf2 100644
--- a/content/test/data/accessibility/event/focus-listbox-multiselect-expected-auralinux.txt
+++ b/content/test/data/accessibility/event/focus-listbox-multiselect-expected-auralinux.txt
@@ -3,4 +3,5 @@
 SELECTION-CHANGED role=ROLE_LIST_BOX name='(null)' ENABLED,FOCUSABLE,MULTISELECTABLE,SENSITIVE,SHOWING,VERTICAL,VISIBLE
 STATE-CHANGE:FOCUSED:FALSE role=ROLE_DOCUMENT_WEB name='(null)' ENABLED,FOCUSABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:FOCUSED:TRUE role=ROLE_LIST_ITEM name='c' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
+STATE-CHANGE:SELECTED:FALSE role=ROLE_LIST_ITEM name='b' ENABLED,FOCUSABLE,SELECTABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:SELECTED:TRUE role=ROLE_LIST_ITEM name='c' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
diff --git a/content/test/data/accessibility/event/listbox-next-expected-auralinux.txt b/content/test/data/accessibility/event/listbox-next-expected-auralinux.txt
index b043c26..eab0f68 100644
--- a/content/test/data/accessibility/event/listbox-next-expected-auralinux.txt
+++ b/content/test/data/accessibility/event/listbox-next-expected-auralinux.txt
@@ -3,4 +3,5 @@
 SELECTION-CHANGED role=ROLE_LIST_BOX name='(null)' ENABLED,FOCUSABLE,SENSITIVE,SHOWING,VERTICAL,VISIBLE
 STATE-CHANGE:FOCUSED:FALSE role=ROLE_LIST_ITEM name='Apple' ENABLED,FOCUSABLE,SELECTABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:FOCUSED:TRUE role=ROLE_LIST_ITEM name='Orange' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
+STATE-CHANGE:SELECTED:FALSE role=ROLE_LIST_ITEM name='Apple' ENABLED,FOCUSABLE,SELECTABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:SELECTED:TRUE role=ROLE_LIST_ITEM name='Orange' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
diff --git a/content/test/data/accessibility/event/menulist-with-optgroup-next-expected-auralinux.txt b/content/test/data/accessibility/event/menulist-with-optgroup-next-expected-auralinux.txt
index 13e84e41..d9f45d1 100644
--- a/content/test/data/accessibility/event/menulist-with-optgroup-next-expected-auralinux.txt
+++ b/content/test/data/accessibility/event/menulist-with-optgroup-next-expected-auralinux.txt
@@ -8,5 +8,6 @@
 STATE-CHANGE:FOCUSED:FALSE role=ROLE_MENU_ITEM name='Lemon' ENABLED,FOCUSABLE,SELECTABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:FOCUSED:TRUE role=ROLE_MENU_ITEM name='Lemon' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:FOCUSED:TRUE role=ROLE_MENU_ITEM name='Orange' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
+STATE-CHANGE:SELECTED:FALSE role=ROLE_MENU_ITEM name='Lemon' ENABLED,FOCUSABLE,SELECTABLE,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:SELECTED:TRUE role=ROLE_MENU_ITEM name='Orange' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
 STATE-CHANGE:SELECTED:TRUE role=ROLE_MENU_ITEM name='Orange' ENABLED,FOCUSABLE,FOCUSED,SELECTABLE,SELECTED,SENSITIVE,SHOWING,VISIBLE
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/same-page-link-navigation-expected-android.txt b/content/test/data/accessibility/event/same-page-link-navigation-expected-android.txt
index b020e58..ea43b076 100644
--- a/content/test/data/accessibility/event/same-page-link-navigation-expected-android.txt
+++ b/content/test/data/accessibility/event/same-page-link-navigation-expected-android.txt
@@ -1,3 +1,3 @@
 TYPE_VIEW_SCROLLED
+TYPE_VIEW_ACCESSIBILITY_FOCUSED
 TYPE_VIEW_CLICKED
-TYPE_VIEW_ACCESSIBILITY_FOCUSED
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/selectlist-expected-mac.txt b/content/test/data/accessibility/event/selectlist-expected-mac.txt
index 02bb6ca..21e43e0 100644
--- a/content/test/data/accessibility/event/selectlist-expected-mac.txt
+++ b/content/test/data/accessibility/event/selectlist-expected-mac.txt
@@ -1,5 +1,7 @@
 AXExpandedChanged on AXComboBox AXDescription='Combobox A' AXValue='Option 1'
 AXFocusedUIElementChanged on AXStaticText AXValue='Option 1'
+AXSelectedChildrenChanged on AXList
 === Start Continuation ===
 AXExpandedChanged on AXComboBox AXDescription='Combobox B' AXValue='Option 4'
 AXFocusedUIElementChanged on AXStaticText AXValue='Option 4'
+AXSelectedChildrenChanged on AXList
diff --git a/content/test/data/accessibility/event/selectlist-expected-win.txt b/content/test/data/accessibility/event/selectlist-expected-win.txt
index 4351a24f..8ac753a 100644
--- a/content/test/data/accessibility/event/selectlist-expected-win.txt
+++ b/content/test/data/accessibility/event/selectlist-expected-win.txt
@@ -1,8 +1,10 @@
 EVENT_OBJECT_FOCUS on <option> role=ROLE_SYSTEM_LISTITEM name="Option 1" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=3
 EVENT_OBJECT_SHOW on <div> role=ROLE_SYSTEM_LIST IA2_STATE_VERTICAL SetSize=3
 EVENT_OBJECT_STATECHANGE on <div#ButtonA> role=ROLE_SYSTEM_COMBOBOX name="Combobox A" value="Option 1" EXPANDED,HASPOPUP
+EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Option 1" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=3
 === Start Continuation ===
 EVENT_OBJECT_FOCUS on <option> role=ROLE_SYSTEM_LISTITEM name="Option 4" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=3
 EVENT_OBJECT_HIDE on <div> role=ROLE_SYSTEM_LIST IA2_STATE_VERTICAL SetSize=3
 EVENT_OBJECT_SHOW on <div> role=ROLE_SYSTEM_LIST IA2_STATE_VERTICAL SetSize=3
 EVENT_OBJECT_STATECHANGE on <div#ButtonB> role=ROLE_SYSTEM_COMBOBOX name="Combobox B" value="Option 4" EXPANDED,HASPOPUP
+EVENT_OBJECT_STATECHANGE on <option> role=ROLE_SYSTEM_LISTITEM name="Option 4" SELECTED,FOCUSED,FOCUSABLE,SELECTABLE PosInSet=1 SetSize=3
diff --git a/content/test/data/accessibility/readme.md b/content/test/data/accessibility/readme.md
index ba4bb22..2732e80 100644
--- a/content/test/data/accessibility/readme.md
+++ b/content/test/data/accessibility/readme.md
@@ -14,18 +14,18 @@
 
 `Tree tests` are designed to test accessible tree. It loads an HTML file, waits
 for it to load, then dumps the accessible tree. The dumped tree is compared
-to an expectation file. The tests are driven by `DumpAccessibilityTree` testing
-class.
+to an expectation file. The tests are driven by `DumpAccessibilityTreeTest`
+testing class.
 
 `Node tests` are used to run a test for a single node, for example, to check
 a specific property. The test loads an HTML file, waits for it to load, then
 dump a single accessible node for a DOM element whose `id` or `class` attribute
 is `test`. There is no support for multiple "test" nodes and the output will be
-for the first match located. The tests are driven by `DumpAccessibilityNode`
+for the first match located. The tests are driven by `DumpAccessibilityNodeTest`
 testing class.
 
 `Script tests` are used to run a script and test its output against
-expectations. The tests is driven by `DumpAccessibilityScript` testing
+expectations. The tests is driven by `DumpAccessibilityScriptTest` testing
 class.
 
 `Event tests` tests use a similar format but the events are dumped after
@@ -399,9 +399,9 @@
 If you are adding a new events test, remember to add a corresponding test case
 for Android, see more info below.
 
-## More details on DumpAccessibilityEvents tests
+## More details on DumpAccessibilityEventsTest tests
 
-These tests are similar to `DumpAccessibilityTree` tests in that they first
+These tests are similar to `DumpAccessibilityTreeTest` tests in that they first
 load an HTML document, then dump something, then compare the output to
 an expectation file. The difference is that what's dumped is accessibility
 events that are fired.
@@ -425,7 +425,7 @@
 
 ### Including Tests for Android
 
-The Android DumpAccessibilityEvents tests work differently than the other
+The Android `DumpAccessibilityEventsTests` tests work differently than the other
 platforms and are driven by the Java-side code. The tests all reside in the
 [WebContentsAccessibilityEventsTest.java](https://source.chromium.org/chromium/chromium/src/+/main:content/public/android/javatests/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityEventsTest.java)
 class. The tests are controlled from the Java code so that they can leverage the
@@ -468,4 +468,4 @@
 same directory as the others (content/test/data/accessibility/event).
 
 A PRESUBMIT check will give a non-blocking warning if you are adding, renaming,
-or deleting an events test without a corresponding change for Android.
\ No newline at end of file
+or deleting an events test without a corresponding change for Android.
diff --git a/content/test/data/interest_group/bidding_logic_additional_bid.js.mock-http-headers b/content/test/data/interest_group/bidding_logic_additional_bid.js.mock-http-headers
index 4ee0b2a1..88dea3b 100644
--- a/content/test/data/interest_group/bidding_logic_additional_bid.js.mock-http-headers
+++ b/content/test/data/interest_group/bidding_logic_additional_bid.js.mock-http-headers
@@ -2,3 +2,4 @@
 Content-Type: Application/Javascript
 Ad-Auction-Allowed: true
 Cache-Control: max-age=60
+Access-Control-Allow-Origin: *
diff --git a/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.js b/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.js
new file mode 100644
index 0000000..b75c4f4
--- /dev/null
+++ b/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.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.
+
+function reportWin(auctionSignals, perBuyerSignals, sellerSignals,
+                   browserSignals) {
+  sendReportTo(browserSignals.interestGroupOwner +
+      '/echoall?report_bidder_additional');
+}
diff --git a/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.js.mock-http-headers b/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.js.mock-http-headers
new file mode 100644
index 0000000..f9fd5179
--- /dev/null
+++ b/content/test/data/interest_group/bidding_logic_additional_bid_no_cors.js.mock-http-headers
@@ -0,0 +1,5 @@
+HTTP/1.1 200 OK
+Content-Type: Application/Javascript
+Ad-Auction-Allowed: true
+Cache-Control: max-age=60
+
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 93eea54..fa35bad 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 34161dd..ce6275d 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
diff --git a/content/test/gpu/gpu_tests/test_expectations/expected_color_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/expected_color_expectations.txt
index 3555774..350a976 100644
--- a/content/test/gpu/gpu_tests/test_expectations/expected_color_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/expected_color_expectations.txt
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 dc6299f..54d40d3 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 95b4beb..199daf5 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 92a5d07..4c6c1b8 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 9ff2da84..5cf72b4a 100644
--- a/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/mediapipe_expectations.txt
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 cc9d92d..c3a344d 100644
--- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 95b4beb..199daf5 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 f67270c..4763fdeb 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 7a920ec2..b44bda1 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 142d8576..5242baed 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webcodecs_expectations.txt
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 971586f..087693f 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
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 cd53fd9..d1a9892 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
@@ -18,11 +18,14 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
+# tags: [ android-chromium
+#         android-webview-instrumentation
 #         debug debug-x64
 #         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+#         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-apple-m2
@@ -31,7 +34,7 @@
 #         arm
 #         google google-0xffff google-0xc0de
 #         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
+#             intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
 #         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
 #         qualcomm ]
 # Architecture
@@ -608,8 +611,8 @@
 crbug.com/1276552 [ android-pixel-4 android-r passthrough qualcomm renderer-skia-gl target-cpu-32 ] conformance/canvas/render-after-resize-test.html [ Failure ]
 
 # Failing test when experiment DrDc is enabled via fieldtrial_testing_config.json.
-crbug.com/1289303 [ android angle-disabled no-passthrough qualcomm renderer-skia-gl target-cpu-32 ] conformance/textures/misc/texture-video-transparent.html [ Failure ]
-crbug.com/1289303 [ android-pixel-4 android-r ] conformance/textures/misc/texture-video-transparent.html [ Failure ]
+crbug.com/1289303 [ android android-sm-a235m ] conformance/textures/misc/texture-video-transparent.html [ Failure ]
+crbug.com/1289303 [ android-r android-pixel-4 ] conformance/textures/misc/texture-video-transparent.html [ Failure ]
 
 ## Samsung failures ##
 
diff --git a/content/test/gpu/gpu_tests/test_expectations_unittest.py b/content/test/gpu/gpu_tests/test_expectations_unittest.py
index ef2e772..e5aa0d5 100644
--- a/content/test/gpu/gpu_tests/test_expectations_unittest.py
+++ b/content/test/gpu/gpu_tests/test_expectations_unittest.py
@@ -3,15 +3,15 @@
 # found in the LICENSE file.
 
 import inspect
-import itertools
 import os
 import re
 import sys
-from typing import Iterable, List, Optional, Set, Type
+from typing import Dict, List, Optional, Type
 import unittest
 import unittest.mock as mock
 
 import gpu_project_config
+import validate_tag_consistency
 
 from gpu_tests import gpu_helper
 from gpu_tests import gpu_integration_test
@@ -28,40 +28,6 @@
 from typ import expectations_parser
 from typ import json_results
 
-OS_CONDITIONS = ['win', 'mac', 'android']
-GPU_CONDITIONS = [
-    'amd',
-    'arm',
-    'broadcom',
-    'hisilicon',
-    'intel',
-    'imagination',
-    'nvidia',
-    'qualcomm',
-    'vivante',
-]
-WIN_CONDITIONS = ['xp', 'vista', 'win7', 'win8', 'win10']
-MAC_CONDITIONS = [
-    'leopard',
-    'snowleopard',
-    'lion',
-    'mountainlion',
-    'mavericks',
-    'yosemite',
-    'sierra',
-    'highsierra',
-    'mojave',
-]
-ANDROID_CONDITIONS = [
-    'android-lollipop',
-    'android-marshmallow',
-    'anroid-nougat',
-    'android-oreo',
-    'android-pie',
-    'android-10',
-    'android-kitkat',
-]
-GENERIC_CONDITIONS = OS_CONDITIONS + GPU_CONDITIONS
 
 VALID_BUG_REGEXES = [
     re.compile(r'crbug\.com\/\d+'),
@@ -72,11 +38,19 @@
     re.compile(r'skbug\.com\/\d+'),
 ]
 
-_map_specific_to_generic = {sos: 'win' for sos in WIN_CONDITIONS}
-_map_specific_to_generic.update({sos: 'mac' for sos in MAC_CONDITIONS})
-_map_specific_to_generic.update({sos: 'android' for sos in ANDROID_CONDITIONS})
-_map_specific_to_generic['debug-x64'] = 'debug'
-_map_specific_to_generic['release-x64'] = 'release'
+
+# Handled in a helper function to avoid polluting the global scope with
+# variable names that will potentially be used elsewhere.
+def _CreateSpecificToGenericMapping() -> Dict[str, str]:
+  _specific_to_generic = {}
+  for _, tag_set in validate_tag_consistency.TAG_SPECIALIZATIONS.items():
+    for general_tag, specific_tags in tag_set.items():
+      for tag in specific_tags:
+        _specific_to_generic[tag] = general_tag
+  return _specific_to_generic
+
+
+_map_specific_to_generic = _CreateSpecificToGenericMapping()
 
 _get_generic = lambda tags: set(
     _map_specific_to_generic.get(tag, tag) for tag in tags)
@@ -107,17 +81,6 @@
   return True
 
 
-def _MapGpuDevicesToVendors(tag_sets: Iterable[Set[str]]) -> None:
-  for tag_set in tag_sets:
-    if any(gpu in tag_set for gpu in GPU_CONDITIONS):
-      _map_specific_to_generic.update({
-          t[0]: t[1]
-          for t in itertools.permutations(tag_set, 2)
-          if t[0].startswith(t[1] + '-')
-      })
-      break
-
-
 # No good way to reduce the number of return statements to the required level
 # without harming readability.
 # pylint: disable=too-many-return-statements,too-many-branches
@@ -229,7 +192,6 @@
   test_expectations = expectations_parser.TestExpectations()
   test_expectations.parse_tagged_list(
       expectations, file_name=file_name, tags_conflict=_DoTagsConflict)
-  _MapGpuDevicesToVendors(test_expectations.tag_sets)
   return test_expectations.check_test_expectations_patterns_for_conflicts()
 
 
@@ -443,11 +405,11 @@
 
   def testConflictBetweenTestExpectationsWithOsNameAndOSVersionTags(self
                                                                     ) -> None:
-    test_expectations = """# tags: [ mac win linux xp ]
+    test_expectations = """# tags: [ mac win linux win10 ]
     # tags: [ intel amd nvidia ]
     # tags: [ debug release ]
     # results: [ Failure Skip ]
-    [ intel xp ] a/b/c/d [ Failure ]
+    [ intel win10 ] a/b/c/d [ Failure ]
     [ intel win debug ] a/b/c/d [ Skip ]
     """
     errors = CheckTestExpectationPatternsForConflicts(test_expectations,
@@ -468,10 +430,10 @@
 
   def testConflictBetweenGpuVendorAndGpuDeviceIdTags(self) -> None:
     test_expectations = """# tags: [ mac win linux xp win7 ]
-    # tags: [ intel amd nvidia nvidia-0x01 nvidia-0x02 ]
+    # tags: [ intel amd nvidia nvidia-0x1cb3 nvidia-0x2184 ]
     # tags: [ debug release ]
     # results: [ Failure Skip ]
-    [ nvidia-0x01 ] a/b/c/d [ Failure ]
+    [ nvidia-0x1cb3 ] a/b/c/d [ Failure ]
     [ nvidia debug ] a/b/c/d [ Skip ]
     """
     errors = CheckTestExpectationPatternsForConflicts(test_expectations,
diff --git a/content/test/gpu/validate_tag_consistency.py b/content/test/gpu/validate_tag_consistency.py
index 3dba4939..5480cf5 100755
--- a/content/test/gpu/validate_tag_consistency.py
+++ b/content/test/gpu/validate_tag_consistency.py
@@ -9,17 +9,164 @@
 import argparse
 import logging
 import os
+import textwrap
+from typing import Dict, List
 import sys
 
+# Constants for tag set generation.
+LINE_START = '# '
+TAG_SET_START = 'tags: [ '
+TAG_SET_END = ' ]'
+DEFAULT_LINE_LENGTH = 80 - len(LINE_START) - len(TAG_SET_START)
+BREAK_INDENTATION = ' ' * 4
+
+# Certain tags are technically subsets of other tags, e.g. win10 falls under the
+# general win umbrella. We take this into account when checking for conflicting
+# expectations, so we store the source of truth here and generate the resulting
+# strings for the tag header.
+TAG_SPECIALIZATIONS = {
+    'OS_TAGS': {
+        'android': [
+            'android-lollipop',
+            'android-marshmallow',
+            'android-nougat',
+            'android-oreo',
+            'android-pie',
+            'android-r',
+            'android-s',
+            'android-t',
+        ],
+        'chromeos': [],
+        'fuchsia': [],
+        'linux': [
+            'ubuntu',
+        ],
+        'mac': [
+            'highsierra',
+            'mojave',
+            'catalina',
+            'bigsur',
+            'monterey',
+            'ventura',
+        ],
+        'win': [
+            'win8',
+            'win10',
+        ],
+    },
+    'BROWSER_TAGS': {
+        'android-chromium': [],
+        'android-webview-instrumentation': [],
+        'debug': [
+            'debug-x64',
+        ],
+        'release': [
+            'release-x64',
+        ],
+        # These two are both Fuchsia-related.
+        'fuchsia-chrome': [],
+        'web-engine-shell': [],
+        # These two are both ChromeOS-related.
+        'lacros-chrome': [],
+        'cros-chrome': [],
+    },
+    'GPU_TAGS': {
+        'amd': [
+            'amd-0x6613',
+            'amd-0x679e',
+            'amd-0x67ef',
+            'amd-0x6821',
+            'amd-0x7340',
+        ],
+        'apple': [
+            'apple-apple-m1',
+            'apple-apple-m2',
+            'apple-angle-metal-renderer:-apple-m1',
+            'apple-angle-metal-renderer:-apple-m2',
+        ],
+        'arm': [],
+        'google': [
+            'google-0xffff',
+            'google-0xc0de',
+        ],
+        'intel': [
+            # Individual GPUs should technically fit under intel-gen-X, but we
+            # only support one level of nesting, so treat the generation tags as
+            # individual GPUs.
+            'intel-gen-9',
+            'intel-gen-12',
+            'intel-0xa2e',
+            'intel-0xd26',
+            'intel-0xa011',
+            'intel-0x3e92',
+            'intel-0x3e9b',
+            'intel-0x5912',
+            'intel-0x9bc5',
+        ],
+        'nvidia': [
+            'nvidia-0xfe9',
+            'nvidia-0x1cb3',
+            'nvidia-0x2184',
+        ],
+        'qualcomm': [],
+    },
+}
+
+
+def _GenerateTagSpecializationStrings() -> Dict[str, str]:
+  """Generates string a string representation of |TAG_SPECIALIZATIONS|.
+
+  The resulting dictionary can be fed directly into string.format().
+
+  Returns:
+    A dict mapping tag_set_name to tag_set_string. |tag_set_string| is the
+    formatted, expectation parser-compatible string for the information
+    contained within TAG_SPECIALIZATIONS[tag_set_name].
+  """
+  tag_specialization_strings = {}
+  for tag_set_name, tag_set in TAG_SPECIALIZATIONS.items():
+    # Create an appropriately wrapped set of lines for each group, join them,
+    # and add the necessary bits to make them a parseable tag set.
+    wrapped_tag_lines = []
+    num_groups = len(tag_set)
+    current_group = 0
+    for general_tag, specialized_tags in tag_set.items():
+      current_group += 1
+      wrapped_tag_lines.extend(
+          _CreateWrappedLinesForTagGroup([general_tag] + specialized_tags,
+                                         current_group == num_groups))
+
+    wrapped_tags_string = '\n'.join(wrapped_tag_lines)
+    tag_set_string = ''
+    for i, line in enumerate(wrapped_tags_string.splitlines(True)):
+      tag_set_string += LINE_START
+      if i == 0:
+        tag_set_string += TAG_SET_START
+      else:
+        tag_set_string += (' ' * len(TAG_SET_START))
+      tag_set_string += line
+    tag_set_string += TAG_SET_END
+    tag_specialization_strings[tag_set_name] = tag_set_string
+  return tag_specialization_strings
+
+
+def _CreateWrappedLinesForTagGroup(tag_group: List[str],
+                                   is_last_group: bool) -> List[str]:
+  tag_line = ' '.join(tag_group)
+  line_length = DEFAULT_LINE_LENGTH
+  # If this will be the last group, we have to make sure we wrap such that
+  # there will be enough room for the closing bracket of the tag set.
+  if is_last_group:
+    line_length -= len(TAG_SET_END)
+  return textwrap.wrap(tag_line,
+                       width=line_length,
+                       subsequent_indent=BREAK_INDENTATION,
+                       break_on_hyphens=False)
+
+
 TAG_HEADER = """\
 # OS
-# tags: [ android android-lollipop android-marshmallow android-nougat
-#             android-oreo android-pie android-r android-s android-t
-#         chromeos
-#         fuchsia
-#         linux ubuntu
-#         mac highsierra mojave catalina bigsur monterey ventura
-#         win win8 win10 ]
+{OS_TAGS}
 # Devices
 # tags: [ android-nexus-5x android-pixel-2 android-pixel-4
 #             android-pixel-6 android-shield-android-tv android-sm-a135m
@@ -31,22 +178,9 @@
 # tags: [ desktop
 #         mobile ]
 # Browser
-# tags: [ android-chromium android-webview-instrumentation
-#         debug debug-x64
-#         release release-x64
-#         fuchsia-chrome web-engine-shell
-#         lacros-chrome cros-chrome ]
+{BROWSER_TAGS}
 # GPU
-# tags: [ amd amd-0x6613 amd-0x679e amd-0x67ef amd-0x6821 amd-0x7340
-#         apple apple-apple-m1 apple-apple-m2
-#             apple-angle-metal-renderer:-apple-m1
-#             apple-angle-metal-renderer:-apple-m2
-#         arm
-#         google google-0xffff google-0xc0de
-#         intel intel-gen-9 intel-gen-12 intel-0xa2e intel-0xd26 intel-0xa011
-#               intel-0x3e92 intel-0x3e9b intel-0x5912 intel-0x9bc5
-#         nvidia nvidia-0xfe9 nvidia-0x1cb3 nvidia-0x2184
-#         qualcomm ]
+{GPU_TAGS}
 # Architecture
 # tags: [ mac-arm64 mac-x86_64 ]
 # Decoder
@@ -85,7 +219,7 @@
 # Skia Graphite
 # tags: [ graphite-enabled graphite-disabled ]
 # results: [ Failure RetryOnFailure Skip Slow ]
-"""
+""".format(**_GenerateTagSpecializationStrings())
 
 TAG_HEADER_BEGIN =\
     '# BEGIN TAG HEADER (autogenerated, see validate_tag_consistency.py)'
diff --git a/docs/website b/docs/website
index 49c12ab..fcd9e70 160000
--- a/docs/website
+++ b/docs/website
@@ -1 +1 @@
-Subproject commit 49c12aba2275832dc5d645c12defc3e41f076392
+Subproject commit fcd9e704410cd8801f923e24aa9cbbd9cb5ed58a
diff --git a/extensions/browser/api/management/management_api.cc b/extensions/browser/api/management/management_api.cc
index f1b8733..39fbc1f1 100644
--- a/extensions/browser/api/management/management_api.cc
+++ b/extensions/browser/api/management/management_api.cc
@@ -50,6 +50,7 @@
 #include "extensions/common/permissions/permission_message.h"
 #include "extensions/common/permissions/permissions_data.h"
 #include "extensions/common/url_pattern.h"
+#include "services/data_decoder/public/cpp/data_decoder.h"
 #include "url/gurl.h"
 #include "url/url_constants.h"
 
@@ -342,16 +343,10 @@
       management::GetPermissionWarningsByManifest::Params::Create(args());
   EXTENSION_FUNCTION_VALIDATE(params);
 
-  const ManagementAPIDelegate* delegate = ManagementAPI::GetFactoryInstance()
-                                              ->Get(browser_context())
-                                              ->GetDelegate();
-  if (!delegate) {
-    // TODO(lfg) add error string
-    return RespondNow(Error(kUnknownErrorDoNotUse));
-  }
-
-  delegate->GetPermissionWarningsByManifestFunctionDelegate(
-      this, params->manifest_str);
+  data_decoder::DataDecoder::ParseJsonIsolated(
+      params->manifest_str,
+      base::BindOnce(
+          &ManagementGetPermissionWarningsByManifestFunction::OnParse, this));
 
   // Matched with a Release() in OnParse().
   AddRef();
diff --git a/extensions/browser/api/management/management_api_delegate.h b/extensions/browser/api/management/management_api_delegate.h
index 45829f1..41aa495e 100644
--- a/extensions/browser/api/management/management_api_delegate.h
+++ b/extensions/browser/api/management/management_api_delegate.h
@@ -25,7 +25,6 @@
 class ExtensionPrefs;
 class ManagementCreateAppShortcutFunction;
 class ManagementGenerateAppForLinkFunction;
-class ManagementGetPermissionWarningsByManifestFunction;
 class ManagementUninstallFunctionBase;
 
 // Manages the lifetime of the install prompt.
@@ -75,12 +74,6 @@
   virtual LaunchType GetLaunchType(const ExtensionPrefs* prefs,
                                    const Extension* extension) const = 0;
 
-  // Parses the manifest and calls back the
-  // ManagementGetPermissionWarningsByManifestFunction.
-  virtual void GetPermissionWarningsByManifestFunctionDelegate(
-      ManagementGetPermissionWarningsByManifestFunction* function,
-      const std::string& manifest_str) const = 0;
-
   // Used to show a dialog prompt in chrome when management.setEnabled extension
   // function is called.
   virtual std::unique_ptr<InstallPromptDelegate> SetEnabledFunctionDelegate(
diff --git a/extensions/browser/api/web_request/extension_web_request_event_router.cc b/extensions/browser/api/web_request/extension_web_request_event_router.cc
index 7533376..572b42f 100644
--- a/extensions/browser/api/web_request/extension_web_request_event_router.cc
+++ b/extensions/browser/api/web_request/extension_web_request_event_router.cc
@@ -533,7 +533,8 @@
 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does
 // not play well with event pages. See downloads.onDeterminingFilename and
 // ExtensionDownloadsEventRouter for an alternative approach.
-ExtensionWebRequestEventRouter::EventListener::EventListener(ID id) : id(id) {}
+ExtensionWebRequestEventRouter::EventListener::EventListener(ID id)
+    : id(std::move(id)) {}
 ExtensionWebRequestEventRouter::EventListener::~EventListener() = default;
 
 // Contains info about requests that are blocked waiting for a response from
@@ -825,6 +826,40 @@
     BrowserContextData&&) = default;
 ExtensionWebRequestEventRouter::BrowserContextData::~BrowserContextData() =
     default;
+
+ExtensionWebRequestEventRouter::EventListener::ID::ID(
+    content::BrowserContext* browser_context,
+    const std::string& extension_id,
+    const std::string& sub_event_name,
+    int render_process_id,
+    int web_view_instance_id,
+    int worker_thread_id,
+    int64_t service_worker_version_id)
+    : browser_context(browser_context),
+      extension_id(extension_id),
+      sub_event_name(sub_event_name),
+      render_process_id(render_process_id),
+      web_view_instance_id(web_view_instance_id),
+      worker_thread_id(worker_thread_id),
+      service_worker_version_id(service_worker_version_id) {}
+
+ExtensionWebRequestEventRouter::EventListener::ID::ID(const ID& source) =
+    default;
+ExtensionWebRequestEventRouter::EventListener::ID::ID(ID&& source) = default;
+
+bool ExtensionWebRequestEventRouter::EventListener::ID::operator==(
+    const ID& that) const {
+  // Since EventListeners are segmented by browser_context, check that
+  // last, as it is exceedingly unlikely to be different.
+  return extension_id == that.extension_id &&
+         sub_event_name == that.sub_event_name &&
+         web_view_instance_id == that.web_view_instance_id &&
+         render_process_id == that.render_process_id &&
+         worker_thread_id == that.worker_thread_id &&
+         service_worker_version_id == that.service_worker_version_id &&
+         browser_context == that.browser_context;
+}
+
 //
 // ExtensionWebRequestEventRouter
 //
@@ -1541,7 +1576,7 @@
     int web_view_instance_id,
     int worker_thread_id,
     int64_t service_worker_version_id,
-    EventResponse* response) {
+    std::unique_ptr<EventResponse> response) {
   BrowserContextData& context_data =
       data_[GetBrowserContextID(browser_context)];
   EventListener::ID id(browser_context, extension_id, sub_event_name,
@@ -1571,7 +1606,7 @@
 
   listener->blocked_requests.erase(request_id);
   DecrementBlockCount(browser_context, extension_id, event_name, request_id,
-                      response, listener->extra_info_spec);
+                      std::move(response), listener->extra_info_spec);
 }
 
 bool ExtensionWebRequestEventRouter::AddEventListener(
@@ -1602,7 +1637,8 @@
     return false;
   }
 
-  std::unique_ptr<EventListener> listener(new EventListener(id));
+  std::unique_ptr<EventListener> listener =
+      std::make_unique<EventListener>(std::move(id));
   listener->extension_name = extension_name;
   listener->histogram_value = GetEventHistogramValue(event_name);
   listener->filter = std::move(filter);
@@ -2153,10 +2189,8 @@
     const std::string& extension_id,
     const std::string& event_name,
     uint64_t request_id,
-    EventResponse* response,
+    std::unique_ptr<EventResponse> response,
     int extra_info_spec) {
-  std::unique_ptr<EventResponse> response_scoped(response);
-
   // It's possible that this request was deleted, or cancelled by a previous
   // event handler or handled by Declarative Net Request API. If so, ignore this
   // response.
@@ -2176,7 +2210,7 @@
 
   if (response) {
     helpers::EventResponseDelta delta = CalculateDelta(
-        browser_context, blocked_request, response, extra_info_spec);
+        browser_context, blocked_request, response.get(), extra_info_spec);
 
     activity_monitor::OnWebRequestApiUsed(
         static_cast<content::BrowserContext*>(browser_context), extension_id,
diff --git a/extensions/browser/api/web_request/extension_web_request_event_router.h b/extensions/browser/api/web_request/extension_web_request_event_router.h
index 792a690d..dc4472a 100644
--- a/extensions/browser/api/web_request/extension_web_request_event_router.h
+++ b/extensions/browser/api/web_request/extension_web_request_event_router.h
@@ -55,17 +55,6 @@
 
   struct BlockedRequest;
 
-  // Identifier for a `BrowserContext` to scope the lifetime for references.
-  // `BrowserContextID` is derived from `BrowserContext*`, used in comparison
-  // only, and are never deferenced.
-  using BrowserContextID = std::uintptr_t;
-
-  static BrowserContextID GetBrowserContextID(
-      content::BrowserContext* browser_context) {
-    return reinterpret_cast<BrowserContextID>(
-        static_cast<void*>(browser_context));
-  }
-
   // The events denoting the lifecycle of a given network request.
   enum EventTypes {
     kInvalidEvent = 0,
@@ -269,7 +258,7 @@
                       int web_view_instance_id,
                       int worker_thread_id,
                       int64_t service_worker_version_id,
-                      EventResponse* response);
+                      std::unique_ptr<EventResponse> response);
 
   // Adds a listener to the given event. |event_name| specifies the event being
   // listened to. |sub_event_name| is an internal event uniquely generated in
@@ -346,6 +335,17 @@
   }
 
  private:
+  // Identifier for a `BrowserContext` to scope the lifetime for references.
+  // `BrowserContextID` is derived from `BrowserContext*`, used in comparison
+  // only, and are never deferenced.
+  using BrowserContextID = std::uintptr_t;
+
+  static BrowserContextID GetBrowserContextID(
+      content::BrowserContext* browser_context) {
+    return reinterpret_cast<BrowserContextID>(
+        static_cast<void*>(browser_context));
+  }
+
   friend class WebRequestAPI;
   friend class base::NoDestructor<ExtensionWebRequestEventRouter>;
 
@@ -360,6 +360,7 @@
          int64_t service_worker_version_id);
 
       ID(const ID& source);
+      ID(ID&& source);
 
       bool operator==(const ID& that) const;
 
@@ -526,13 +527,12 @@
   // Decrements the count of event handlers blocking the given request. When the
   // count reaches 0, we stop blocking the request and proceed it using the
   // method requested by the extension with the highest precedence. Precedence
-  // is decided by extension install time. If |response| is non-NULL, this
-  // method assumes ownership.
+  // is decided by extension install time.
   void DecrementBlockCount(content::BrowserContext* browser_context,
                            const std::string& extension_id,
                            const std::string& event_name,
                            uint64_t request_id,
-                           EventResponse* response,
+                           std::unique_ptr<EventResponse> response,
                            int extra_info_spec);
 
   // Processes the generated deltas from blocked_requests_ on the specified
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
index 1066900..9ed1cc0f 100644
--- a/extensions/browser/api/web_request/web_request_api.cc
+++ b/extensions/browser/api/web_request/web_request_api.cc
@@ -780,7 +780,7 @@
   ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
       browser_context(), extension_id_safe(), event_name, sub_event_name,
       request_id, render_process_id, web_view_instance_id, worker_thread_id(),
-      service_worker_version_id(), response.release());
+      service_worker_version_id(), std::move(response));
 }
 
 ExtensionFunction::ResponseAction
@@ -925,7 +925,7 @@
   ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
       browser_context(), extension_id_safe(), event_name, sub_event_name,
       request_id, render_process_id, web_view_instance_id, worker_thread_id(),
-      service_worker_version_id(), response.release());
+      service_worker_version_id(), std::move(response));
 
   return RespondNow(NoArguments());
 }
@@ -958,36 +958,4 @@
   return RespondNow(NoArguments());
 }
 
-ExtensionWebRequestEventRouter::EventListener::ID::ID(
-    content::BrowserContext* browser_context,
-    const std::string& extension_id,
-    const std::string& sub_event_name,
-    int render_process_id,
-    int web_view_instance_id,
-    int worker_thread_id,
-    int64_t service_worker_version_id)
-    : browser_context(browser_context),
-      extension_id(extension_id),
-      sub_event_name(sub_event_name),
-      render_process_id(render_process_id),
-      web_view_instance_id(web_view_instance_id),
-      worker_thread_id(worker_thread_id),
-      service_worker_version_id(service_worker_version_id) {}
-
-ExtensionWebRequestEventRouter::EventListener::ID::ID(const ID& source) =
-    default;
-
-bool ExtensionWebRequestEventRouter::EventListener::ID::operator==(
-    const ID& that) const {
-  // Since EventListeners are segmented by browser_context, check that
-  // last, as it is exceedingly unlikely to be different.
-  return extension_id == that.extension_id &&
-         sub_event_name == that.sub_event_name &&
-         web_view_instance_id == that.web_view_instance_id &&
-         render_process_id == that.render_process_id &&
-         worker_thread_id == that.worker_thread_id &&
-         service_worker_version_id == that.service_worker_version_id &&
-         browser_context == that.browser_context;
-}
-
 }  // namespace extensions
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.h b/gpu/ipc/service/image_transport_surface_overlay_mac.h
index ee83f9e..879113fd 100644
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.h
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.h
@@ -22,6 +22,9 @@
 // third_party/mesa_headers/GL/glext.h
 #if BUILDFLAG(IS_MAC)
 #include "gpu/ipc/service/gpu_vsync_mac.h"
+
+#include "ui/display/mac/display_link_mac.h"
+#include "ui/display/types/display_constants.h"
 #endif
 
 @class CAContext;
@@ -60,11 +63,11 @@
 
   void SetCALayerErrorCode(gfx::CALayerResult ca_layer_error_code) override;
 
-  // GLSurface override
 #if BUILDFLAG(IS_MAC)
-  bool SupportsGpuVSync() const override;
+  // GLSurface override
   void SetVSyncDisplayID(int64_t display_id) override;
-  void SetGpuVSyncEnabled(bool enabled) override;
+
+  void OnVSyncPresentation(ui::VSyncParamsMac params);
 #endif
 
  private:
@@ -76,6 +79,7 @@
   void ApplyBackpressure();
   void BufferPresented(gl::GLSurface::PresentationCallback callback,
                        const gfx::PresentationFeedback& feedback);
+  void PopulateCALayerParameters();
 
   base::WeakPtr<ImageTransportSurfaceDelegate> delegate_;
 
@@ -92,9 +96,19 @@
   uint64_t previous_frame_fence_ = 0;
 
 #if BUILDFLAG(IS_MAC)
-  std::unique_ptr<GpuVSyncMac> gpu_vsync_mac_;
+  // CGDirectDisplayID of the current monitor used for Creating CVDisplayLink.
+  int64_t display_id_ = display::kInvalidDisplayId;
+  scoped_refptr<ui::DisplayLinkMac> display_link_mac_;
+  std::unique_ptr<ui::VSyncCallbackMac> vsync_callback_mac_;
 #endif
 
+  SwapCompletionCallback completion_callback_;
+  PresentationCallback presentation_callback_;
+  // The number of CALayerTree that is committed but not yet populated. This
+  // number is increased in Present() and decreased in
+  // PopulateCALayerParameters();
+  int num_committed_ca_layer_trees_ = 0;
+
   base::WeakPtrFactory<ImageTransportSurfaceOverlayMacEGL> weak_ptr_factory_;
 };
 
diff --git a/gpu/ipc/service/image_transport_surface_overlay_mac.mm b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
index bd2f1d8..40212e8 100644
--- a/gpu/ipc/service/image_transport_surface_overlay_mac.mm
+++ b/gpu/ipc/service/image_transport_surface_overlay_mac.mm
@@ -14,6 +14,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
+#include "components/viz/common/features.h"
 #include "gpu/command_buffer/common/swap_buffers_complete_params.h"
 #include "gpu/ipc/service/gpu_channel_manager.h"
 #include "gpu/ipc/service/gpu_channel_manager_delegate.h"
@@ -85,13 +86,6 @@
 #endif
     ca_context_.layer = ca_layer_tree_coordinator_->GetCALayerForDisplay();
   }
-
-#if BUILDFLAG(IS_MAC)
-  if (features::UseGpuVsync()) {
-    gpu_vsync_mac_ =
-        std::make_unique<GpuVSyncMac>(delegate->GetGpuVSyncCallback());
-  }
-#endif
 }
 
 ImageTransportSurfaceOverlayMacEGL::~ImageTransportSurfaceOverlayMacEGL() {
@@ -123,6 +117,14 @@
     gfx::FrameData data) {
   TRACE_EVENT0("gpu", "ImageTransportSurfaceOverlayMac::Present");
 
+  // Only one commited CALayer tree is permitted. Populate the last frame if
+  // there is already a commited CALayer tree waiting to be populated. At the
+  // end of this function, another commited CALayer tree will be produced.
+  if (num_committed_ca_layer_trees_ >= 1) {
+    PopulateCALayerParameters();
+  }
+  DCHECK_EQ(num_committed_ca_layer_trees_, 0);
+
   constexpr base::TimeDelta kHistogramMinTime = base::Microseconds(5);
   constexpr base::TimeDelta kHistogramMaxTime = base::Milliseconds(16);
   constexpr int kHistogramTimeBuckets = 50;
@@ -170,6 +172,31 @@
         kHistogramMinTime, kHistogramMaxTime, kHistogramTimeBuckets);
   }
 
+  // Delay PopulateCALayerParameters until the next Vsync on Mac. No delay if
+  // kCVDisplayLinkBeginFrameSource feature is off or DisplayLink fails.
+  completion_callback_ = std::move(completion_callback);
+  presentation_callback_ = std::move(presentation_callback);
+  num_committed_ca_layer_trees_++;
+
+#if BUILDFLAG(IS_MAC)
+  if (display_link_mac_ && !vsync_callback_mac_) {
+    vsync_callback_mac_ = display_link_mac_->RegisterCallback(
+        base::BindRepeating(
+            &ImageTransportSurfaceOverlayMacEGL::OnVSyncPresentation,
+            weak_ptr_factory_.GetWeakPtr()),
+        /*do_callback_on_register_thread=*/true);
+  }
+
+  if (vsync_callback_mac_) {
+    // PopulateCALayerParameters will be called in OnVSyncPresentation.
+    return;
+  }
+#endif
+
+  PopulateCALayerParameters();
+}
+
+void ImageTransportSurfaceOverlayMacEGL::PopulateCALayerParameters() {
   // Populate the CA layer parameters to send to the browser.
   gfx::CALayerParams params;
   {
@@ -191,14 +218,15 @@
   }
 
   // Send the swap parameters to the browser.
-  if (completion_callback) {
+  if (completion_callback_) {
     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
         FROM_HERE,
-        base::BindOnce(std::move(completion_callback),
+        base::BindOnce(std::move(completion_callback_),
                        gfx::SwapCompletionResult(
                            gfx::SwapResult::SWAP_ACK,
                            std::make_unique<gfx::CALayerParams>(params))));
   }
+
   gfx::PresentationFeedback feedback(base::TimeTicks::Now(), base::Hertz(60),
                                      /*flags=*/0);
   feedback.ca_layer_error_code = ca_layer_error_code_;
@@ -207,7 +235,9 @@
       FROM_HERE,
       base::BindOnce(&ImageTransportSurfaceOverlayMacEGL::BufferPresented,
                      weak_ptr_factory_.GetWeakPtr(),
-                     std::move(presentation_callback), feedback));
+                     std::move(presentation_callback_), feedback));
+
+  num_committed_ca_layer_trees_--;
 }
 
 bool ImageTransportSurfaceOverlayMacEGL::ScheduleOverlayPlane(
@@ -269,24 +299,33 @@
 }
 
 #if BUILDFLAG(IS_MAC)
-bool ImageTransportSurfaceOverlayMacEGL::SupportsGpuVSync() const {
-  return features::UseGpuVsync();
-}
-
 void ImageTransportSurfaceOverlayMacEGL::SetVSyncDisplayID(int64_t display_id) {
-  if (!features::UseGpuVsync()) {
+  if (!base::FeatureList::IsEnabled(features::kCVDisplayLinkBeginFrameSource)) {
     return;
   }
 
-  gpu_vsync_mac_->SetVSyncDisplayID(display_id);
+  if ((!display_link_mac_ || display_id != display_id_) &&
+      display_id != display::kInvalidDisplayId) {
+    if (vsync_callback_mac_) {
+      OnVSyncPresentation(ui::VSyncParamsMac());
+      DCHECK(!vsync_callback_mac_);
+    }
+    display_link_mac_ = ui::DisplayLinkMac::GetForDisplay(display_id);
+  }
+
+  display_id_ = display_id;
 }
 
-void ImageTransportSurfaceOverlayMacEGL::SetGpuVSyncEnabled(bool enabled) {
-  if (!features::UseGpuVsync()) {
-    return;
+void ImageTransportSurfaceOverlayMacEGL::OnVSyncPresentation(
+    ui::VSyncParamsMac params) {
+  if (num_committed_ca_layer_trees_) {
+    PopulateCALayerParameters();
   }
 
-  gpu_vsync_mac_->SetGpuVSyncEnabled(enabled);
+  // No more pending frames. Now stop the vsync callback.
+  if (!num_committed_ca_layer_trees_) {
+    vsync_callback_mac_ = nullptr;
+  }
 }
 #endif
 
diff --git "a/infra/config/generated/builders/ci/Linux Builder \050j-500\051 \050reclient\051/properties.json" "b/infra/config/generated/builders/ci/Linux Builder \050j-500\051 \050reclient\051/properties.json"
deleted file mode 100644
index 0566edee..0000000
--- "a/infra/config/generated/builders/ci/Linux Builder \050j-500\051 \050reclient\051/properties.json"
+++ /dev/null
@@ -1,61 +0,0 @@
-{
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Linux Builder (j-500) (reclient)",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-fyi-archive",
-              "builder_group": "chromium.fyi",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage"
-                ],
-                "config": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "Linux Builder (j-500) (reclient)",
-          "project": "chromium"
-        }
-      ]
-    }
-  },
-  "$build/reclient": {
-    "instance": "rbe-chromium-trusted",
-    "jobs": 500,
-    "metrics_project": "chromium-reclient-metrics",
-    "rewrapper_env": {
-      "RBE_platform": "container-image=docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:b4dad0bfc4951d619229ab15343a311f2415a16ef83bcaa55b44f4e2bf1cf635,pool=linux-e2-custom_0"
-    },
-    "scandeps_server": true
-  },
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "chromium.fyi",
-  "recipe": "chromium"
-}
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Linux Builder \050j-500\051 \050reclient\051/shadow-properties.json" "b/infra/config/generated/builders/ci/Linux Builder \050j-500\051 \050reclient\051/shadow-properties.json"
deleted file mode 100644
index 586276d..0000000
--- "a/infra/config/generated/builders/ci/Linux Builder \050j-500\051 \050reclient\051/shadow-properties.json"
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "$build/reclient": {
-    "instance": "rbe-chromium-untrusted",
-    "jobs": 500,
-    "metrics_project": "chromium-reclient-metrics",
-    "rewrapper_env": {
-      "RBE_platform": "container-image=docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:b4dad0bfc4951d619229ab15343a311f2415a16ef83bcaa55b44f4e2bf1cf635,pool=linux-e2-custom_0"
-    },
-    "scandeps_server": true
-  }
-}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-blink-dbg-fyi/properties.json b/infra/config/generated/builders/ci/ios-blink-dbg-fyi/properties.json
index 91ad62d..a8a81ca 100644
--- a/infra/config/generated/builders/ci/ios-blink-dbg-fyi/properties.json
+++ b/infra/config/generated/builders/ci/ios-blink-dbg-fyi/properties.json
@@ -60,5 +60,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-device/properties.json b/infra/config/generated/builders/ci/ios-device/properties.json
index ea9975e0..885ef05c 100644
--- a/infra/config/generated/builders/ci/ios-device/properties.json
+++ b/infra/config/generated/builders/ci/ios-device/properties.json
@@ -64,5 +64,5 @@
     "chromium",
     "ios"
   ],
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json b/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json
index 99653bc4..ff1b0b8 100644
--- a/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json
+++ b/infra/config/generated/builders/ci/ios-fieldtrial-rel/properties.json
@@ -59,5 +59,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json b/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json
index 3847dec..c5ac701 100644
--- a/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json
+++ b/infra/config/generated/builders/ci/ios-m1-simulator-cronet/properties.json
@@ -59,5 +59,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-m1-simulator/properties.json b/infra/config/generated/builders/ci/ios-m1-simulator/properties.json
index b0a640a..00122fd 100644
--- a/infra/config/generated/builders/ci/ios-m1-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios-m1-simulator/properties.json
@@ -59,5 +59,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json b/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json
index 3135d64..7acbfb6d 100644
--- a/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-code-coverage/properties.json
@@ -72,5 +72,5 @@
   },
   "builder_group": "chromium.coverage",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json b/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json
index a599567..198ea95 100644
--- a/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-cronet/properties.json
@@ -60,5 +60,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json b/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json
index 88571ec..05894b1 100644
--- a/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-full-configs/properties.json
@@ -67,5 +67,5 @@
     "chromium",
     "ios"
   ],
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json b/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json
index e0b3e38..d2de7f05 100644
--- a/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-multi-window/properties.json
@@ -60,5 +60,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json b/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json
index 6eaeac39..2eb0d467 100644
--- a/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator-noncq/properties.json
@@ -64,5 +64,5 @@
     "chromium",
     "ios"
   ],
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-simulator/properties.json b/infra/config/generated/builders/ci/ios-simulator/properties.json
index b99856c..b6c26af 100644
--- a/infra/config/generated/builders/ci/ios-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios-simulator/properties.json
@@ -71,5 +71,5 @@
     "chromium",
     "ios"
   ],
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios-wpt-fyi-rel/properties.json b/infra/config/generated/builders/ci/ios-wpt-fyi-rel/properties.json
index b32402f..fd18fb4 100644
--- a/infra/config/generated/builders/ci/ios-wpt-fyi-rel/properties.json
+++ b/infra/config/generated/builders/ci/ios-wpt-fyi-rel/properties.json
@@ -59,5 +59,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json b/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json
index 0d145cc0..04a0fbe7 100644
--- a/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios16-beta-simulator/properties.json
@@ -60,5 +60,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/ios17-beta-simulator/properties.json b/infra/config/generated/builders/ci/ios17-beta-simulator/properties.json
index d1c592a..da8b227 100644
--- a/infra/config/generated/builders/ci/ios17-beta-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios17-beta-simulator/properties.json
@@ -60,5 +60,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-asan/properties.json b/infra/config/generated/builders/try/ios-asan/properties.json
index bfa4a88..b143106 100644
--- a/infra/config/generated/builders/try/ios-asan/properties.json
+++ b/infra/config/generated/builders/try/ios-asan/properties.json
@@ -58,5 +58,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-blink-dbg-fyi/properties.json b/infra/config/generated/builders/try/ios-blink-dbg-fyi/properties.json
index 9a5fd4e03..d15974b 100644
--- a/infra/config/generated/builders/try/ios-blink-dbg-fyi/properties.json
+++ b/infra/config/generated/builders/try/ios-blink-dbg-fyi/properties.json
@@ -53,5 +53,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-device/properties.json b/infra/config/generated/builders/try/ios-device/properties.json
index ba96edf3..be84a633 100644
--- a/infra/config/generated/builders/try/ios-device/properties.json
+++ b/infra/config/generated/builders/try/ios-device/properties.json
@@ -54,5 +54,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json b/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json
index 14f9a535..0e7d154f 100644
--- a/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json
+++ b/infra/config/generated/builders/try/ios-fieldtrial-rel/properties.json
@@ -52,5 +52,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json b/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json
index 1874d22..d9592c8 100644
--- a/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json
+++ b/infra/config/generated/builders/try/ios-m1-simulator-cronet/properties.json
@@ -53,5 +53,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-m1-simulator/properties.json b/infra/config/generated/builders/try/ios-m1-simulator/properties.json
index 1d77a74..4bb00cb5 100644
--- a/infra/config/generated/builders/try/ios-m1-simulator/properties.json
+++ b/infra/config/generated/builders/try/ios-m1-simulator/properties.json
@@ -52,5 +52,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-code-coverage/properties.json b/infra/config/generated/builders/try/ios-simulator-code-coverage/properties.json
index fa8c954..f0251b7 100644
--- a/infra/config/generated/builders/try/ios-simulator-code-coverage/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-code-coverage/properties.json
@@ -56,5 +56,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-compilator/properties.json b/infra/config/generated/builders/try/ios-simulator-compilator/properties.json
index 3db9ff42..5b12216 100644
--- a/infra/config/generated/builders/try/ios-simulator-compilator/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-compilator/properties.json
@@ -69,5 +69,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium/compilator",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-cronet/properties.json b/infra/config/generated/builders/try/ios-simulator-cronet/properties.json
index f88e8a9..2e814ba 100644
--- a/infra/config/generated/builders/try/ios-simulator-cronet/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-cronet/properties.json
@@ -59,5 +59,5 @@
   "builder_group": "tryserver.chromium.mac",
   "cq": "path-based",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json b/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json
index a00935c..17b3d5b4 100644
--- a/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-full-configs/properties.json
@@ -70,5 +70,5 @@
   "builder_group": "tryserver.chromium.mac",
   "cq": "path-based",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json b/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json
index 1655f43..86eb81c 100644
--- a/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-inverse-fieldtrials-fyi/properties.json
@@ -56,5 +56,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json b/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json
index d9307d5..49028a6 100644
--- a/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-multi-window/properties.json
@@ -53,5 +53,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-simulator-noncq/properties.json b/infra/config/generated/builders/try/ios-simulator-noncq/properties.json
index cfdd638..605625fe 100644
--- a/infra/config/generated/builders/try/ios-simulator-noncq/properties.json
+++ b/infra/config/generated/builders/try/ios-simulator-noncq/properties.json
@@ -59,5 +59,5 @@
   "builder_group": "tryserver.chromium.mac",
   "cq": "path-based",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios-wpt-fyi-rel/properties.json b/infra/config/generated/builders/try/ios-wpt-fyi-rel/properties.json
index a16accc..14b4c10 100644
--- a/infra/config/generated/builders/try/ios-wpt-fyi-rel/properties.json
+++ b/infra/config/generated/builders/try/ios-wpt-fyi-rel/properties.json
@@ -52,5 +52,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios16-beta-simulator/properties.json b/infra/config/generated/builders/try/ios16-beta-simulator/properties.json
index f894c97..a74b27c 100644
--- a/infra/config/generated/builders/try/ios16-beta-simulator/properties.json
+++ b/infra/config/generated/builders/try/ios16-beta-simulator/properties.json
@@ -54,5 +54,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios17-beta-simulator/properties.json b/infra/config/generated/builders/try/ios17-beta-simulator/properties.json
index fd5fcb2..bb4b496 100644
--- a/infra/config/generated/builders/try/ios17-beta-simulator/properties.json
+++ b/infra/config/generated/builders/try/ios17-beta-simulator/properties.json
@@ -53,5 +53,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "15a5219j"
+  "xcode_build_version": "15a5229h"
 }
\ No newline at end of file
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 00b481f..6d16717 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -5173,13 +5173,13 @@
         '  },'
         '  "builder_group": "chromium.fyi",'
         '  "recipe": "reclient_reclient_comparison",'
-        '  "xcode_build_version": "15a5219j"'
+        '  "xcode_build_version": "15a5229h"'
         '}'
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -5284,13 +5284,13 @@
         '  },'
         '  "builder_group": "chromium.fyi",'
         '  "recipe": "reclient_reclient_comparison",'
-        '  "xcode_build_version": "15a5219j"'
+        '  "xcode_build_version": "15a5229h"'
         '}'
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -14056,98 +14056,6 @@
       }
     }
     builders {
-      name: "Linux Builder (j-500) (reclient)"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:8"
-      dimensions: "cpu:x86-64"
-      dimensions: "free_space:standard"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      dimensions: "ssd:0"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/ci/Linux Builder (j-500) (reclient)/properties.json",'
-        '    "shadow_properties_file": "infra/config/generated/builders/ci/Linux Builder (j-500) (reclient)/shadow-properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "chromium.fyi",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium_swarming.expose_merge_script_failures"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://chrome/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*blink_wpt_tests/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        dimensions: "free_space:"
-        dimensions: "pool:luci.chromium.try"
-      }
-    }
-    builders {
       name: "Linux Builder (reclient compare)"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -37181,8 +37089,8 @@
       priority: 35
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -37375,8 +37283,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -37468,8 +37376,8 @@
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -37562,8 +37470,8 @@
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -37656,8 +37564,8 @@
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -37753,8 +37661,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -37849,8 +37757,8 @@
       priority: 35
       execution_timeout_secs: 72000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -37941,8 +37849,8 @@
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -38038,8 +37946,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -38131,8 +38039,8 @@
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -38228,8 +38136,8 @@
         '}'
       execution_timeout_secs: 10800
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -38415,8 +38323,8 @@
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -38509,8 +38417,8 @@
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -38791,8 +38699,8 @@
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -78000,8 +77908,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -78092,8 +78000,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -78276,8 +78184,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -78368,8 +78276,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -78460,8 +78368,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -78552,8 +78460,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -78739,8 +78647,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -78831,8 +78739,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -78925,8 +78833,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -79018,8 +78926,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -79110,8 +79018,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -79202,8 +79110,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -79295,8 +79203,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -79387,8 +79295,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -79479,8 +79387,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -79663,8 +79571,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_15a5219j"
-        path: "xcode_ios_15a5219j.app"
+        name: "xcode_ios_15a5229h"
+        path: "xcode_ios_15a5229h.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 013b6c67..8b2f379 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -9555,11 +9555,6 @@
     short_name: "lk"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/Linux Builder (j-500) (reclient)"
-    category: "linux"
-    short_name: "re"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/Linux Builder (reclient compare)"
     category: "linux"
     short_name: "re"
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg
index d1e1256..1182780 100644
--- a/infra/config/generated/luci/luci-scheduler.cfg
+++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -1500,16 +1500,6 @@
   }
 }
 job {
-  id: "Linux Builder (j-500) (reclient)"
-  realm: "ci"
-  schedule: "triggered"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "Linux Builder (j-500) (reclient)"
-  }
-}
-job {
   id: "Linux Builder (reclient compare)"
   realm: "ci"
   buildbucket {
@@ -6403,7 +6393,6 @@
   triggers: "Linux Builder"
   triggers: "Linux Builder (Wayland)"
   triggers: "Linux Builder (dbg)"
-  triggers: "Linux Builder (j-500) (reclient)"
   triggers: "Linux Builder (reclient compare)"
   triggers: "Linux CFI"
   triggers: "Linux Chromium OS ASan LSan Builder"
diff --git a/infra/config/generated/testing/mixins.pyl b/infra/config/generated/testing/mixins.pyl
index 8ec6e0d..97f6dba0 100644
--- a/infra/config/generated/testing/mixins.pyl
+++ b/infra/config/generated/testing/mixins.pyl
@@ -1234,12 +1234,12 @@
   'xcode_15_main': {
     'args': [
       '--xcode-build-version',
-      '15a5219j',
+      '15a5229h',
     ],
     'swarming': {
       'named_caches': [
         {
-          'name': 'xcode_ios_15a5219j',
+          'name': 'xcode_ios_15a5229h',
           'path': 'Xcode.app',
         },
       ],
diff --git a/infra/config/generated/testing/variants.pyl b/infra/config/generated/testing/variants.pyl
index 5922ed2..4ca98f8 100644
--- a/infra/config/generated/testing/variants.pyl
+++ b/infra/config/generated/testing/variants.pyl
@@ -16,16 +16,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 118.0.5969.0',
+    'description': 'Run with ash-chrome version 118.0.5970.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v118.0.5969.0',
-          'revision': 'version:118.0.5969.0',
+          'location': 'lacros_version_skew_tests_v118.0.5970.0',
+          'revision': 'version:118.0.5970.0',
         },
       ],
     },
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star
index 1eaf4ac..d65262a 100644
--- a/infra/config/lib/builders.star
+++ b/infra/config/lib/builders.star
@@ -174,7 +174,7 @@
     # A newer Xcode 14 RC  used on beta bots.
     x14betabots = xcode_enum("14e222b"),
     # Default Xcode 15 for chromium iOS
-    x15main = xcode_enum("15a5219j"),
+    x15main = xcode_enum("15a5229h"),
     # A newer Xcode 15 version used on beta bots.
     x15betabots = xcode_enum("15a5229h"),
     # in use by ios-webkit-tot
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star
index 051ff5e..c22100c 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -1637,33 +1637,6 @@
 )
 
 ci.builder(
-    name = "Linux Builder (j-500) (reclient)",
-    schedule = "triggered",
-    builder_spec = builder_config.builder_spec(
-        gclient_config = builder_config.gclient_config(
-            config = "chromium",
-            apply_configs = ["use_clang_coverage"],
-        ),
-        chromium_config = builder_config.chromium_config(
-            config = "chromium",
-            apply_configs = ["mb"],
-            build_config = builder_config.build_config.RELEASE,
-            target_bits = 64,
-        ),
-        build_gs_bucket = "chromium-fyi-archive",
-    ),
-    os = os.LINUX_DEFAULT,
-    console_view_entry = consoles.console_view_entry(
-        category = "linux",
-        short_name = "re",
-    ),
-    reclient_jobs = 500,
-    reclient_rewrapper_env = {
-        "RBE_platform": "container-image=docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:b4dad0bfc4951d619229ab15343a311f2415a16ef83bcaa55b44f4e2bf1cf635,pool=linux-e2-custom_0",
-    },
-)
-
-ci.builder(
     name = "Linux Builder (reclient compare)",
     builder_spec = builder_config.copy_from(
         "ci/Linux Builder",
diff --git a/infra/config/targets/lacros-version-skew-variants.json b/infra/config/targets/lacros-version-skew-variants.json
index d210533..45f8f7a4 100644
--- a/infra/config/targets/lacros-version-skew-variants.json
+++ b/infra/config/targets/lacros-version-skew-variants.json
@@ -1,16 +1,16 @@
 {
   "LACROS_VERSION_SKEW_CANARY": {
     "args": [
-      "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+      "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
     ],
-    "description": "Run with ash-chrome version 118.0.5969.0",
+    "description": "Run with ash-chrome version 118.0.5970.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_v118.0.5969.0",
-          "revision": "version:118.0.5969.0"
+          "location": "lacros_version_skew_tests_v118.0.5970.0",
+          "revision": "version:118.0.5970.0"
         }
       ]
     }
diff --git a/infra/config/targets/mixins.star b/infra/config/targets/mixins.star
index a36a16d..d278173 100644
--- a/infra/config/targets/mixins.star
+++ b/infra/config/targets/mixins.star
@@ -1567,12 +1567,12 @@
     name = "xcode_15_main",
     args = [
         "--xcode-build-version",
-        "15a5219j",
+        "15a5229h",
     ],
     swarming = targets.swarming(
         named_caches = [
             swarming.cache(
-                name = "xcode_ios_15a5219j",
+                name = "xcode_ios_15a5229h",
                 path = "Xcode.app",
             ),
         ],
diff --git a/internal b/internal
index ad00a6b..74f0023 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit ad00a6b3a52005a50d149f0a84a8fc4b216e9839
+Subproject commit 74f00236c1468c95c957abbe7ee5801388cf6529
diff --git a/ios/chrome/browser/autocomplete/BUILD.gn b/ios/chrome/browser/autocomplete/model/BUILD.gn
similarity index 98%
rename from ios/chrome/browser/autocomplete/BUILD.gn
rename to ios/chrome/browser/autocomplete/model/BUILD.gn
index 7001b41..a4505fb 100644
--- a/ios/chrome/browser/autocomplete/BUILD.gn
+++ b/ios/chrome/browser/autocomplete/model/BUILD.gn
@@ -2,7 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-source_set("autocomplete") {
+source_set("model") {
   sources = [
     "autocomplete_classifier_factory.cc",
     "autocomplete_classifier_factory.h",
diff --git a/ios/chrome/browser/autocomplete/DEPS b/ios/chrome/browser/autocomplete/model/DEPS
similarity index 100%
rename from ios/chrome/browser/autocomplete/DEPS
rename to ios/chrome/browser/autocomplete/model/DEPS
diff --git a/ios/chrome/browser/autocomplete/OWNERS b/ios/chrome/browser/autocomplete/model/OWNERS
similarity index 100%
rename from ios/chrome/browser/autocomplete/OWNERS
rename to ios/chrome/browser/autocomplete/model/OWNERS
diff --git a/ios/chrome/browser/autocomplete/autocomplete_classifier_factory.cc b/ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.cc
similarity index 86%
rename from ios/chrome/browser/autocomplete/autocomplete_classifier_factory.cc
rename to ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.cc
index b56f106..93cc663 100644
--- a/ios/chrome/browser/autocomplete/autocomplete_classifier_factory.cc
+++ b/ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h"
+#include "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h"
 
 #include "base/functional/bind.h"
 #include "base/memory/ptr_util.h"
@@ -10,10 +10,10 @@
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
 #include "components/omnibox/browser/autocomplete_classifier.h"
 #include "components/omnibox/browser/autocomplete_controller.h"
-#include "ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h"
-#include "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
-#include "ios/chrome/browser/autocomplete/in_memory_url_index_factory.h"
-#include "ios/chrome/browser/autocomplete/shortcuts_backend_factory.h"
+#include "ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h"
+#include "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
+#include "ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.h"
+#include "ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.h"
 #include "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #include "ios/chrome/browser/shared/model/browser_state/browser_state_otr_helper.h"
 #include "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
diff --git a/ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h b/ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h
similarity index 86%
rename from ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h
rename to ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h
index d32c75ac..c457072 100644
--- a/ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h
+++ b/ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.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_AUTOCOMPLETE_AUTOCOMPLETE_CLASSIFIER_FACTORY_H_
-#define IOS_CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CLASSIFIER_FACTORY_H_
+#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_CLASSIFIER_FACTORY_H_
+#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_CLASSIFIER_FACTORY_H_
 
 #include <memory>
 
@@ -46,4 +46,4 @@
 
 }  // namespace ios
 
-#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CLASSIFIER_FACTORY_H_
+#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_CLASSIFIER_FACTORY_H_
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h b/ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h
similarity index 91%
rename from ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h
rename to ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h
index 478a0ffd..13ad40f 100644
--- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h
+++ b/ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_PROVIDER_CLIENT_IMPL_H_
-#define IOS_CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_PROVIDER_CLIENT_IMPL_H_
+#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_PROVIDER_CLIENT_IMPL_H_
+#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_PROVIDER_CLIENT_IMPL_H_
 
 #include "components/omnibox/browser/actions/omnibox_pedal.h"
 #include "components/omnibox/browser/autocomplete_provider_client.h"
-#include "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
-#include "ios/chrome/browser/autocomplete/tab_matcher_impl.h"
+#include "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
+#include "ios/chrome/browser/autocomplete/model/tab_matcher_impl.h"
 
 class ChromeBrowserState;
 class AutocompleteScoringModelService;
@@ -110,4 +110,4 @@
   std::unique_ptr<OmniboxPedalProvider> pedal_provider_;
 };
 
-#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_PROVIDER_CLIENT_IMPL_H_
+#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_PROVIDER_CLIENT_IMPL_H_
diff --git a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm b/ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.mm
similarity index 93%
rename from ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm
rename to ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.mm
index be509aff..f23779b 100644
--- a/ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.mm
+++ b/ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h"
 
 #import "base/notreached.h"
 #import "base/strings/utf_string_conversions.h"
@@ -18,13 +18,13 @@
 #import "components/signin/public/identity_manager/identity_manager.h"
 #import "components/sync/service/sync_service.h"
 #import "components/unified_consent/url_keyed_data_collection_consent_helper.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h"
-#import "ios/chrome/browser/autocomplete/in_memory_url_index_factory.h"
-#import "ios/chrome/browser/autocomplete/omnibox_pedal_implementation.h"
-#import "ios/chrome/browser/autocomplete/remote_suggestions_service_factory.h"
-#import "ios/chrome/browser/autocomplete/shortcuts_backend_factory.h"
-#import "ios/chrome/browser/autocomplete/tab_matcher_impl.h"
-#import "ios/chrome/browser/autocomplete/zero_suggest_cache_service_factory.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h"
+#import "ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.h"
+#import "ios/chrome/browser/autocomplete/model/omnibox_pedal_implementation.h"
+#import "ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.h"
+#import "ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.h"
+#import "ios/chrome/browser/autocomplete/model/tab_matcher_impl.h"
+#import "ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.h"
 #import "ios/chrome/browser/bookmarks/model/account_bookmark_model_factory.h"
 #import "ios/chrome/browser/bookmarks/model/local_or_syncable_bookmark_model_factory.h"
 #import "ios/chrome/browser/history/history_service_factory.h"
diff --git a/ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h b/ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h
similarity index 76%
rename from ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h
rename to ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h
index 2310c39..7acb9dd 100644
--- a/ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h
+++ b/ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.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_AUTOCOMPLETE_AUTOCOMPLETE_SCHEME_CLASSIFIER_IMPL_H_
-#define IOS_CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_SCHEME_CLASSIFIER_IMPL_H_
+#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_SCHEME_CLASSIFIER_IMPL_H_
+#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_SCHEME_CLASSIFIER_IMPL_H_
 
 #include "components/omnibox/browser/autocomplete_scheme_classifier.h"
 
@@ -25,4 +25,4 @@
       const std::string& scheme) const override;
 };
 
-#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_SCHEME_CLASSIFIER_IMPL_H_
+#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_AUTOCOMPLETE_SCHEME_CLASSIFIER_IMPL_H_
diff --git a/ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.mm b/ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.mm
similarity index 90%
rename from ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.mm
rename to ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.mm
index 5bbdaf5..25fc69a 100644
--- a/ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.mm
+++ b/ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
 
 #import "base/check_op.h"
 #import "base/strings/string_util.h"
diff --git a/ios/chrome/browser/autocomplete/in_memory_url_index_factory.cc b/ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.cc
similarity index 97%
rename from ios/chrome/browser/autocomplete/in_memory_url_index_factory.cc
rename to ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.cc
index dbb17f1..3a5baa0c 100644
--- a/ios/chrome/browser/autocomplete/in_memory_url_index_factory.cc
+++ b/ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ios/chrome/browser/autocomplete/in_memory_url_index_factory.h"
+#include "ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.h"
 
 #include <utility>
 
diff --git a/ios/chrome/browser/autocomplete/in_memory_url_index_factory.h b/ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.h
similarity index 86%
rename from ios/chrome/browser/autocomplete/in_memory_url_index_factory.h
rename to ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.h
index 375fd53..fc3ae3c 100644
--- a/ios/chrome/browser/autocomplete/in_memory_url_index_factory.h
+++ b/ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.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_AUTOCOMPLETE_IN_MEMORY_URL_INDEX_FACTORY_H_
-#define IOS_CHROME_BROWSER_AUTOCOMPLETE_IN_MEMORY_URL_INDEX_FACTORY_H_
+#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_IN_MEMORY_URL_INDEX_FACTORY_H_
+#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_IN_MEMORY_URL_INDEX_FACTORY_H_
 
 #include <memory>
 
@@ -45,4 +45,4 @@
 
 }  // namespace ios
 
-#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_IN_MEMORY_URL_INDEX_FACTORY_H_
+#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_IN_MEMORY_URL_INDEX_FACTORY_H_
diff --git a/ios/chrome/browser/autocomplete/omnibox_pedal_implementation.h b/ios/chrome/browser/autocomplete/model/omnibox_pedal_implementation.h
similarity index 69%
rename from ios/chrome/browser/autocomplete/omnibox_pedal_implementation.h
rename to ios/chrome/browser/autocomplete/model/omnibox_pedal_implementation.h
index 3ba8f33..6bbe5ad0 100644
--- a/ios/chrome/browser/autocomplete/omnibox_pedal_implementation.h
+++ b/ios/chrome/browser/autocomplete/model/omnibox_pedal_implementation.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_AUTOCOMPLETE_OMNIBOX_PEDAL_IMPLEMENTATION_H_
-#define IOS_CHROME_BROWSER_AUTOCOMPLETE_OMNIBOX_PEDAL_IMPLEMENTATION_H_
+#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_OMNIBOX_PEDAL_IMPLEMENTATION_H_
+#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_OMNIBOX_PEDAL_IMPLEMENTATION_H_
 
 #include <unordered_map>
 
@@ -15,4 +15,4 @@
 std::unordered_map<OmniboxPedalId, scoped_refptr<OmniboxPedal>>
 GetPedalImplementations(bool incognito, bool testing);
 
-#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_OMNIBOX_PEDAL_IMPLEMENTATION_H_
+#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_OMNIBOX_PEDAL_IMPLEMENTATION_H_
diff --git a/ios/chrome/browser/autocomplete/omnibox_pedal_implementation.mm b/ios/chrome/browser/autocomplete/model/omnibox_pedal_implementation.mm
similarity index 99%
rename from ios/chrome/browser/autocomplete/omnibox_pedal_implementation.mm
rename to ios/chrome/browser/autocomplete/model/omnibox_pedal_implementation.mm
index d37cd6d0..bb0c8fe 100644
--- a/ios/chrome/browser/autocomplete/omnibox_pedal_implementation.mm
+++ b/ios/chrome/browser/autocomplete/model/omnibox_pedal_implementation.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/autocomplete/omnibox_pedal_implementation.h"
+#import "ios/chrome/browser/autocomplete/model/omnibox_pedal_implementation.h"
 
 #import "components/omnibox/browser/actions/omnibox_pedal.h"
 #import "components/omnibox/browser/autocomplete_input.h"
diff --git a/ios/chrome/browser/autocomplete/remote_suggestions_service_factory.h b/ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.h
similarity index 82%
rename from ios/chrome/browser/autocomplete/remote_suggestions_service_factory.h
rename to ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.h
index 504d797..73a38353 100644
--- a/ios/chrome/browser/autocomplete/remote_suggestions_service_factory.h
+++ b/ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.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_AUTOCOMPLETE_REMOTE_SUGGESTIONS_SERVICE_FACTORY_H_
-#define IOS_CHROME_BROWSER_AUTOCOMPLETE_REMOTE_SUGGESTIONS_SERVICE_FACTORY_H_
+#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_REMOTE_SUGGESTIONS_SERVICE_FACTORY_H_
+#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_REMOTE_SUGGESTIONS_SERVICE_FACTORY_H_
 
 #include "base/no_destructor.h"
 #include "components/keyed_service/ios/browser_state_keyed_service_factory.h"
@@ -36,4 +36,4 @@
       const RemoteSuggestionsServiceFactory&) = delete;
 };
 
-#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_REMOTE_SUGGESTIONS_SERVICE_FACTORY_H_
+#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_REMOTE_SUGGESTIONS_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/autocomplete/remote_suggestions_service_factory.mm b/ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.mm
similarity index 94%
rename from ios/chrome/browser/autocomplete/remote_suggestions_service_factory.mm
rename to ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.mm
index 988477f..32fe04d 100644
--- a/ios/chrome/browser/autocomplete/remote_suggestions_service_factory.mm
+++ b/ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/autocomplete/remote_suggestions_service_factory.h"
+#import "ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.h"
 
 #import "base/no_destructor.h"
 #import "components/keyed_service/ios/browser_state_dependency_manager.h"
diff --git a/ios/chrome/browser/autocomplete/shortcuts_backend_factory.h b/ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.h
similarity index 85%
rename from ios/chrome/browser/autocomplete/shortcuts_backend_factory.h
rename to ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.h
index 92da407..bfef56e 100644
--- a/ios/chrome/browser/autocomplete/shortcuts_backend_factory.h
+++ b/ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.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_AUTOCOMPLETE_SHORTCUTS_BACKEND_FACTORY_H_
-#define IOS_CHROME_BROWSER_AUTOCOMPLETE_SHORTCUTS_BACKEND_FACTORY_H_
+#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_SHORTCUTS_BACKEND_FACTORY_H_
+#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_SHORTCUTS_BACKEND_FACTORY_H_
 
 #include "base/memory/ref_counted.h"
 #include "base/no_destructor.h"
@@ -41,4 +41,4 @@
 
 }  // namespace ios
 
-#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_SHORTCUTS_BACKEND_FACTORY_H_
+#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_SHORTCUTS_BACKEND_FACTORY_H_
diff --git a/ios/chrome/browser/autocomplete/shortcuts_backend_factory.mm b/ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.mm
similarity index 97%
rename from ios/chrome/browser/autocomplete/shortcuts_backend_factory.mm
rename to ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.mm
index 52737c5..4db9ab5 100644
--- a/ios/chrome/browser/autocomplete/shortcuts_backend_factory.mm
+++ b/ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/autocomplete/shortcuts_backend_factory.h"
+#import "ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.h"
 
 #import <memory>
 
diff --git a/ios/chrome/browser/autocomplete/tab_matcher_impl.h b/ios/chrome/browser/autocomplete/model/tab_matcher_impl.h
similarity index 71%
rename from ios/chrome/browser/autocomplete/tab_matcher_impl.h
rename to ios/chrome/browser/autocomplete/model/tab_matcher_impl.h
index 293b6ca9..d19936f 100644
--- a/ios/chrome/browser/autocomplete/tab_matcher_impl.h
+++ b/ios/chrome/browser/autocomplete/model/tab_matcher_impl.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_AUTOCOMPLETE_TAB_MATCHER_IMPL_H_
-#define IOS_CHROME_BROWSER_AUTOCOMPLETE_TAB_MATCHER_IMPL_H_
+#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_TAB_MATCHER_IMPL_H_
+#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_TAB_MATCHER_IMPL_H_
 
 #include "components/omnibox/browser/tab_matcher.h"
 
@@ -20,4 +20,4 @@
   ChromeBrowserState* browser_state_{};
 };
 
-#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_TAB_MATCHER_IMPL_H_
+#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_TAB_MATCHER_IMPL_H_
diff --git a/ios/chrome/browser/autocomplete/tab_matcher_impl.mm b/ios/chrome/browser/autocomplete/model/tab_matcher_impl.mm
similarity index 94%
rename from ios/chrome/browser/autocomplete/tab_matcher_impl.mm
rename to ios/chrome/browser/autocomplete/model/tab_matcher_impl.mm
index 5867450..6292ae91 100644
--- a/ios/chrome/browser/autocomplete/tab_matcher_impl.mm
+++ b/ios/chrome/browser/autocomplete/model/tab_matcher_impl.mm
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#import "ios/chrome/browser/autocomplete/tab_matcher_impl.h"
+#import "ios/chrome/browser/autocomplete/model/tab_matcher_impl.h"
 
 #import <set>
 
diff --git a/ios/chrome/browser/autocomplete/zero_suggest_cache_service_factory.cc b/ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.cc
similarity index 94%
rename from ios/chrome/browser/autocomplete/zero_suggest_cache_service_factory.cc
rename to ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.cc
index fc62c0a..95be669 100644
--- a/ios/chrome/browser/autocomplete/zero_suggest_cache_service_factory.cc
+++ b/ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "ios/chrome/browser/autocomplete/zero_suggest_cache_service_factory.h"
+#include "ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.h"
 
 #include "base/no_destructor.h"
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
diff --git a/ios/chrome/browser/autocomplete/zero_suggest_cache_service_factory.h b/ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.h
similarity index 84%
rename from ios/chrome/browser/autocomplete/zero_suggest_cache_service_factory.h
rename to ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.h
index ff0692d..182e3aa 100644
--- a/ios/chrome/browser/autocomplete/zero_suggest_cache_service_factory.h
+++ b/ios/chrome/browser/autocomplete/model/zero_suggest_cache_service_factory.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_AUTOCOMPLETE_ZERO_SUGGEST_CACHE_SERVICE_FACTORY_H_
-#define IOS_CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_CACHE_SERVICE_FACTORY_H_
+#ifndef IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_ZERO_SUGGEST_CACHE_SERVICE_FACTORY_H_
+#define IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_ZERO_SUGGEST_CACHE_SERVICE_FACTORY_H_
 
 #include "memory.h"
 
@@ -42,4 +42,4 @@
 };
 }  // namespace ios
 
-#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_CACHE_SERVICE_FACTORY_H_
+#endif  // IOS_CHROME_BROWSER_AUTOCOMPLETE_MODEL_ZERO_SUGGEST_CACHE_SERVICE_FACTORY_H_
diff --git a/ios/chrome/browser/browser_state/BUILD.gn b/ios/chrome/browser/browser_state/BUILD.gn
index 3eb1990..90b1afa 100644
--- a/ios/chrome/browser/browser_state/BUILD.gn
+++ b/ios/chrome/browser/browser_state/BUILD.gn
@@ -71,7 +71,7 @@
     "//components/user_prefs",
     "//components/variations/service",
     "//google_apis",
-    "//ios/chrome/browser/autocomplete",
+    "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/autofill",
     "//ios/chrome/browser/bookmarks/model",
     "//ios/chrome/browser/bring_android_tabs",
diff --git a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
index 85a37b65..3b47ae3 100644
--- a/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
+++ b/ios/chrome/browser/browser_state/browser_state_keyed_service_factories.mm
@@ -5,9 +5,9 @@
 #import "ios/chrome/browser/browser_state/browser_state_keyed_service_factories.h"
 
 #import "base/feature_list.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h"
-#import "ios/chrome/browser/autocomplete/in_memory_url_index_factory.h"
-#import "ios/chrome/browser/autocomplete/shortcuts_backend_factory.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h"
+#import "ios/chrome/browser/autocomplete/model/in_memory_url_index_factory.h"
+#import "ios/chrome/browser/autocomplete/model/shortcuts_backend_factory.h"
 #import "ios/chrome/browser/autofill/personal_data_manager_factory.h"
 #import "ios/chrome/browser/bookmarks/model/account_bookmark_model_factory.h"
 #import "ios/chrome/browser/bookmarks/model/bookmark_undo_service_factory.h"
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index 99b43eda..837e8714 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -368,20 +368,30 @@
 const FeatureEntry::FeatureParam kMagicStackMostVisitedModule[] = {
     {kMagicStackMostVisitedModuleParam, "true"},
     {kReducedSpaceParam, "-80"}};
+const FeatureEntry::FeatureParam
+    kMagicStackMostVisitedModuleHideIrrelevantModules[] = {
+        {kMagicStackMostVisitedModuleParam, "true"},
+        {kReducedSpaceParam, "-80"},
+        {kHideIrrelevantModulesParam, "true"}};
 const FeatureEntry::FeatureParam kMagicStackPushedDown[] = {
     {kMagicStackMostVisitedModuleParam, "false"},
     {kReducedSpaceParam, "-30"}};
-const FeatureEntry::FeatureParam kMagicStackReducedNTPTopSpace[] = {
+const FeatureEntry::FeatureParam kMagicStackPushedDownHidIrrelevantModules[] = {
     {kMagicStackMostVisitedModuleParam, "false"},
-    {kReducedSpaceParam, "20"}};
+    {kReducedSpaceParam, "-30"},
+    {kHideIrrelevantModulesParam, "true"}};
 
 const FeatureEntry::FeatureVariation kMagicStackVariations[]{
     {"Most Visited Tiles in Magic Stack", kMagicStackMostVisitedModule,
      std::size(kMagicStackMostVisitedModule), nullptr},
+    {"Most Visited Tiles in Magic Stack and hide irrelevant modules",
+     kMagicStackMostVisitedModuleHideIrrelevantModules,
+     std::size(kMagicStackMostVisitedModuleHideIrrelevantModules), nullptr},
     {"Magic Stack with more NTP Top Space", kMagicStackPushedDown,
      std::size(kMagicStackPushedDown), nullptr},
-    {"Magic Stack with Reduced NTP Top Space", kMagicStackReducedNTPTopSpace,
-     std::size(kMagicStackReducedNTPTopSpace), nullptr},
+    {"Magic Stack with more NTP Top Space and hide irrelevant modules",
+     kMagicStackPushedDownHidIrrelevantModules,
+     std::size(kMagicStackPushedDownHidIrrelevantModules), nullptr},
 };
 
 const FeatureEntry::FeatureParam kEnableDefaultModel[] = {
diff --git a/ios/chrome/browser/intents/BUILD.gn b/ios/chrome/browser/intents/BUILD.gn
new file mode 100644
index 0000000..fb5c2614
--- /dev/null
+++ b/ios/chrome/browser/intents/BUILD.gn
@@ -0,0 +1,16 @@
+source_set("intents_donation_helper") {
+  sources = [
+    "intents_donation_helper.h",
+    "intents_donation_helper.mm",
+  ]
+  deps = [
+    "//base",
+    "//ios/chrome/app/strings:ios_strings",
+    "//ios/chrome/common/intents",
+    "//ui/base",
+  ]
+  frameworks = [
+    "Intents.framework",
+    "Foundation.framework",
+  ]
+}
diff --git a/ios/chrome/browser/intents/intents_donation_helper.h b/ios/chrome/browser/intents/intents_donation_helper.h
new file mode 100644
index 0000000..c80e1145
--- /dev/null
+++ b/ios/chrome/browser/intents/intents_donation_helper.h
@@ -0,0 +1,24 @@
+// 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_INTENTS_INTENTS_DONATION_HELPER_H_
+#define IOS_CHROME_BROWSER_INTENTS_INTENTS_DONATION_HELPER_H_
+
+#import <Foundation/Foundation.h>
+
+// All intent types available for donation.
+enum IntentType {
+  INTENT_SEARCH_IN_CHROME,  //< SearchInChromeIntent
+  INTENT_TYPE_COUNT,
+};
+
+/// Set of utils for donating INInteractions matching INIntents.
+@interface IntentDonationHelper : NSObject
+
+/// Donate the intent of given type to IntentKit.
++ (void)donateIntent:(IntentType)intentType;
+
+@end
+
+#endif  // IOS_CHROME_BROWSER_INTENTS_INTENTS_DONATION_HELPER_H_
diff --git a/ios/chrome/browser/intents/intents_donation_helper.mm b/ios/chrome/browser/intents/intents_donation_helper.mm
new file mode 100644
index 0000000..27d897c
--- /dev/null
+++ b/ios/chrome/browser/intents/intents_donation_helper.mm
@@ -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.
+
+#import "ios/chrome/browser/intents/intents_donation_helper.h"
+
+#import "base/notreached.h"
+#import "base/task/thread_pool.h"
+#import "ios/chrome/common/intents/SearchInChromeIntent.h"
+#import "ios/chrome/grit/ios_strings.h"
+#import "ui/base/l10n/l10n_util.h"
+
+@implementation IntentDonationHelper
+
++ (void)donateIntent:(IntentType)intentType {
+  base::ThreadPool::PostTask(
+      FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
+      base::BindOnce(^{
+        INInteraction* interaction = [self interactionForIntentType:intentType];
+        [interaction donateInteractionWithCompletion:nil];
+      }));
+}
+
++ (INInteraction*)interactionForIntentType:(IntentType)intentType {
+  switch (intentType) {
+    case INTENT_SEARCH_IN_CHROME: {
+      SearchInChromeIntent* searchInChromeIntent =
+          [[SearchInChromeIntent alloc] init];
+
+      // SiriKit requires the intent parameter to be set to a non-empty
+      // string in order to accept the intent donation. Set it to a single
+      // space, to be later trimmed by the intent handler, which will result
+      // in the shortcut being treated as if no search phrase was supplied.
+      searchInChromeIntent.searchPhrase = @" ";
+      searchInChromeIntent.suggestedInvocationPhrase = l10n_util::GetNSString(
+          IDS_IOS_INTENTS_SEARCH_IN_CHROME_INVOCATION_PHRASE);
+      INInteraction* interaction =
+          [[INInteraction alloc] initWithIntent:searchInChromeIntent
+                                       response:nil];
+      return interaction;
+    }
+    default: {
+      NOTREACHED();
+      return nil;
+    }
+  }
+}
+
+@end
diff --git a/ios/chrome/browser/safety_check/BUILD.gn b/ios/chrome/browser/safety_check/BUILD.gn
index d9ecc6a..703c427 100644
--- a/ios/chrome/browser/safety_check/BUILD.gn
+++ b/ios/chrome/browser/safety_check/BUILD.gn
@@ -23,6 +23,8 @@
     "//components/version_info",
     "//ios/chrome/browser/omaha",
     "//ios/chrome/browser/shared/model/prefs:pref_names",
+    "//ios/chrome/browser/ui/content_suggestions:constants",
+    "//ios/chrome/browser/ui/ntp/metrics:home_metrics",
     "//ios/chrome/browser/upgrade",
     "//ios/chrome/browser/upgrade:public",
     "//ios/chrome/common",
@@ -98,6 +100,7 @@
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/sync:test_support",
     "//ios/chrome/browser/upgrade",
+    "//ios/chrome/test:test_support",
     "//ios/web/public/test",
     "//testing/gtest",
   ]
diff --git a/ios/chrome/browser/safety_check/DEPS b/ios/chrome/browser/safety_check/DEPS
index cc75970..270fdb1 100644
--- a/ios/chrome/browser/safety_check/DEPS
+++ b/ios/chrome/browser/safety_check/DEPS
@@ -2,4 +2,6 @@
   "+ios/chrome/browser/passwords",
   "+ios/chrome/browser/upgrade",
   "+ios/chrome/browser/omaha",
+  "+ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h",
+  "+ios/chrome/browser/ui/ntp/metrics/home_metrics.h",
 ]
diff --git a/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager.mm b/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager.mm
index 06cee15ab..eb617fc 100644
--- a/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager.mm
+++ b/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager.mm
@@ -16,6 +16,8 @@
 #import "ios/chrome/browser/omaha/omaha_service.h"
 #import "ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_utils.h"
 #import "ios/chrome/browser/shared/model/prefs/pref_names.h"
+#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_constants.h"
+#import "ios/chrome/browser/ui/ntp/metrics/home_metrics.h"
 #import "ios/chrome/browser/upgrade/upgrade_recommended_details.h"
 #import "ios/chrome/browser/upgrade/upgrade_utils.h"
 #import "ios/chrome/common/channel_info.h"
@@ -271,6 +273,9 @@
 
   safe_browsing_check_state_ = state;
 
+  // The safe browsing state changed, log a freshness signal for Safety Check.
+  RecordModuleFreshnessSignal(ContentSuggestionsModuleType::kSafetyCheck);
+
   local_pref_service_->SetString(
       prefs::kIosSafetyCheckManagerSafeBrowsingCheckResult,
       NameForSafetyCheckState(state));
@@ -330,6 +335,15 @@
     return;
   }
 
+  // Only log that there was a freshness signal if the new state has a different
+  // end result (a password issue, safe).
+  if (state == PasswordSafetyCheckState::kUnmutedCompromisedPasswords ||
+      state == PasswordSafetyCheckState::kReusedPasswords ||
+      state == PasswordSafetyCheckState::kWeakPasswords ||
+      state == PasswordSafetyCheckState::kSafe) {
+    RecordModuleFreshnessSignal(ContentSuggestionsModuleType::kSafetyCheck);
+  }
+
   password_check_state_ = state;
 
   local_pref_service_->SetString(
@@ -352,6 +366,13 @@
     return;
   }
 
+  // Only log that there was a freshness signal if the new state has a different
+  // end result (out of date, up to date).
+  if (state == UpdateChromeSafetyCheckState::kOutOfDate ||
+      state == UpdateChromeSafetyCheckState::kUpToDate) {
+    RecordModuleFreshnessSignal(ContentSuggestionsModuleType::kSafetyCheck);
+  }
+
   update_chrome_check_state_ = state;
 
   local_pref_service_->SetString(prefs::kIosSafetyCheckManagerUpdateCheckResult,
diff --git a/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_unittest.mm b/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_unittest.mm
index 08c14aa..6a994b3 100644
--- a/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_unittest.mm
+++ b/ios/chrome/browser/safety_check/ios_chrome_safety_check_manager_unittest.mm
@@ -29,6 +29,7 @@
 #import "ios/chrome/browser/sync/sync_setup_service_factory.h"
 #import "ios/chrome/browser/sync/sync_setup_service_mock.h"
 #import "ios/chrome/browser/upgrade/upgrade_recommended_details.h"
+#import "ios/chrome/test/testing_application_context.h"
 #import "ios/web/public/test/web_task_environment.h"
 #import "testing/gtest/include/gtest/gtest.h"
 #import "testing/platform_test.h"
@@ -43,6 +44,9 @@
 
     registry->RegisterBooleanPref(prefs::kSafeBrowsingEnabled, false);
     registry->RegisterBooleanPref(prefs::kSafeBrowsingEnhanced, false);
+    registry->RegisterIntegerPref(
+        prefs::kIosMagicStackSegmentationSafetyCheckImpressionsSinceFreshness,
+        -1);
 
     local_pref_service_ = std::make_unique<TestingPrefServiceSimple>();
     PrefRegistrySimple* local_registry = local_pref_service_->registry();
@@ -75,6 +79,7 @@
                 web::BrowserState, password_manager::TestPasswordStore>));
 
     browser_state_ = builder.Build();
+    TestingApplicationContext::GetGlobal()->SetLocalState(pref_service_.get());
 
     password_check_manager_ =
         IOSChromePasswordCheckManagerFactory::GetForBrowserState(
@@ -88,6 +93,7 @@
   void TearDown() override {
     safety_check_manager_->StopSafetyCheck();
     safety_check_manager_->Shutdown();
+    TestingApplicationContext::GetGlobal()->SetLocalState(nullptr);
   }
 
  protected:
diff --git a/ios/chrome/browser/synced_sessions/OWNERS b/ios/chrome/browser/synced_sessions/OWNERS
new file mode 100644
index 0000000..89c87a6d
--- /dev/null
+++ b/ios/chrome/browser/synced_sessions/OWNERS
@@ -0,0 +1 @@
+file://ios/chrome/browser/ui/recent_tabs/OWNERS
diff --git a/ios/chrome/browser/ui/content_suggestions/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
index 8483f79..fc3bc2f 100644
--- a/ios/chrome/browser/ui/content_suggestions/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/BUILD.gn
@@ -17,7 +17,7 @@
     "//components/keyed_service/ios",
     "//components/prefs",
     "//components/search:start_suggest",
-    "//ios/chrome/browser/autocomplete",
+    "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/search_engines",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/browser_state",
@@ -318,6 +318,7 @@
     "//ios/chrome/browser/shared/model/prefs:pref_names",
     "//ios/chrome/browser/shared/model/web_state_list",
     "//ios/chrome/browser/shared/public/commands",
+    "//ios/chrome/browser/shared/public/features",
     "//ios/chrome/browser/signin",
     "//ios/chrome/browser/signin:test_support",
     "//ios/chrome/browser/sync",
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h b/ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h
index 7fbf194..73060282 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h
@@ -33,6 +33,10 @@
 // is negative, it will increase the top space margin.
 extern const char kReducedSpaceParam[];
 
+// A parameter representing whether modules should not be added to the Magic
+// Stack if their content is irrelevant.
+extern const char kHideIrrelevantModulesParam[];
+
 // A parameter to indicate whether the native UI is enabled for the discover
 // feed.
 // TODO(crbug.com/1385512): Remove this.
@@ -55,6 +59,10 @@
 // How much the NTP top margin should be reduced by for the Magic Stack design.
 double ReducedNTPTopMarginSpaceForMagicStack();
 
+// Whether modules should not be added to the Magic Stack if their content is
+// irrelevant.
+bool ShouldHideIrrelevantModules();
+
 // Whether the Most Visited Tiles should be hidden.
 bool ShouldHideMVT();
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.mm
index 265335e..be19f88 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.mm
@@ -32,6 +32,8 @@
 
 const char kReducedSpaceParam[] = "ReducedNTPTopSpace";
 
+const char kHideIrrelevantModulesParam[] = "HideIrrelevantModules";
+
 // A parameter to indicate whether the native UI is enabled for the discover
 // feed.
 const char kDiscoverFeedIsNativeUIEnabled[] = "DiscoverFeedIsNativeUIEnabled";
@@ -57,6 +59,11 @@
                                                    kReducedSpaceParam, 0);
 }
 
+bool ShouldHideIrrelevantModules() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      kMagicStack, kHideIrrelevantModulesParam, false);
+}
+
 bool ShouldHideMVT() {
   return base::GetFieldTrialParamByFeatureAsBool(
       kHideContentSuggestionsTiles,
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
index f71b27f..998ad55 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator.mm
@@ -991,6 +991,12 @@
     } else if (label == segmentation_platform::kShortcuts) {
       [magicStackOrder
           addObject:@(int(ContentSuggestionsModuleType::kShortcuts))];
+    } else if (label == segmentation_platform::kSafetyCheck) {
+      // If ShouldHideIrrelevantModules() is enabled and it is not the first
+      // ranked module, do not add it to the Magic Stack.
+      if (!ShouldHideIrrelevantModules() || [magicStackOrder count] == 0) {
+        [self addSafetyCheckToMagicStackOrder:magicStackOrder];
+      }
     }
   }
   [self.consumer setMagicStackOrder:magicStackOrder];
@@ -1015,25 +1021,16 @@
 - (void)addSafetyCheckToMagicStackOrder:(NSMutableArray*)order {
   CHECK(IsSafetyCheckMagicStackEnabled());
 
-  // TODO(crbug.com/1472382): In a follow-up CL, the module will be placed at
-  // different places in the Magic Stack depending on the Safety Check state(s).
-  // However, for now, the module will simply be inserted at the front of the
-  // Magic Stack.
-  int moduleIndex = 0;
-
   int checkIssuesCount = CheckIssuesCount(_safetyCheckState);
 
   if (checkIssuesCount > 2) {
-    [order insertObject:@(int(ContentSuggestionsModuleType::
-                                  kSafetyCheckMultiRowOverflow))
-                atIndex:moduleIndex];
+    [order addObject:@(int(ContentSuggestionsModuleType::
+                               kSafetyCheckMultiRowOverflow))];
   } else if (checkIssuesCount > 1) {
     [order
-        insertObject:@(int(ContentSuggestionsModuleType::kSafetyCheckMultiRow))
-             atIndex:moduleIndex];
+        addObject:@(int(ContentSuggestionsModuleType::kSafetyCheckMultiRow))];
   } else {
-    [order insertObject:@(int(ContentSuggestionsModuleType::kSafetyCheck))
-                atIndex:moduleIndex];
+    [order addObject:@(int(ContentSuggestionsModuleType::kSafetyCheck))];
   }
 }
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm
index 3b9a2c5..fbc25910 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_mediator_unittest.mm
@@ -41,6 +41,7 @@
 #import "ios/chrome/browser/shared/model/web_state_list/web_state_opener.h"
 #import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h"
 #import "ios/chrome/browser/shared/public/commands/snackbar_commands.h"
+#import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/signin/authentication_service.h"
 #import "ios/chrome/browser/signin/authentication_service_factory.h"
 #import "ios/chrome/browser/signin/fake_authentication_service_delegate.h"
@@ -362,14 +363,18 @@
       {{segmentation_platform::features::kSegmentationPlatformFeature, {}},
        {segmentation_platform::features::kSegmentationPlatformIosModuleRanker,
         {{segmentation_platform::kDefaultModelEnabledParam, "true"}}},
-       {kMagicStack, {}}},
+       {kMagicStack, {}},
+       {kSafetyCheckMagicStack, {}}},
       {});
   OCMExpect(
       [consumer_ setMagicStackOrder:[OCMArg checkWithBlock:^BOOL(id value) {
                    NSArray<NSNumber*>* magicStackOrder = (NSArray*)value;
-                   return [magicStackOrder count] == 2 &&
+                   // Ensure MVT, Shortcuts, and Safety Check are returned in
+                   // that order.
+                   return [magicStackOrder count] == 3 &&
                           0 == [magicStackOrder[0] intValue] &&
-                          1 == [magicStackOrder[1] intValue];
+                          1 == [magicStackOrder[1] intValue] &&
+                          7 == [magicStackOrder[2] intValue];
                  }]]);
   mediator_.consumer = consumer_;
 
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm
index 6c164bf..9b3c5c07 100644
--- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm
+++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_metrics_recorder.mm
@@ -69,14 +69,28 @@
       }
       break;
     }
+
+    case ContentSuggestionsModuleType::kSafetyCheck:
+    case ContentSuggestionsModuleType::kSafetyCheckMultiRow:
+    case ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow: {
+      if (_localState) {
+        // Increment freshness pref since it is an impression of
+        // the latest Safety Check results as the top module.
+        int freshness_impression_count = _localState->GetInteger(
+            prefs::
+                kIosMagicStackSegmentationSafetyCheckImpressionsSinceFreshness);
+        _localState->SetInteger(
+            prefs::
+                kIosMagicStackSegmentationSafetyCheckImpressionsSinceFreshness,
+            freshness_impression_count + 1);
+      }
+      break;
+    }
     case ContentSuggestionsModuleType::kSetUpListSync:
     case ContentSuggestionsModuleType::kSetUpListDefaultBrowser:
     case ContentSuggestionsModuleType::kSetUpListAutofill:
     case ContentSuggestionsModuleType::kCompactedSetUpList:
     case ContentSuggestionsModuleType::kSetUpListAllSet:
-    case ContentSuggestionsModuleType::kSafetyCheck:
-    case ContentSuggestionsModuleType::kSafetyCheckMultiRow:
-    case ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow:
       break;
   }
   UMA_HISTOGRAM_ENUMERATION(kMagicStackTopModuleImpressionHistogram, type);
diff --git a/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_icon.mm b/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_icon.mm
index 090ea8f4..9e27578 100644
--- a/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_icon.mm
+++ b/ios/chrome/browser/ui/content_suggestions/set_up_list/set_up_list_item_icon.mm
@@ -10,6 +10,7 @@
 #import "components/sync/base/features.h"
 #import "ios/chrome/browser/ntp/set_up_list_item_type.h"
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
+#import "ios/chrome/browser/ui/content_suggestions/content_suggestions_feature.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
 
@@ -17,10 +18,13 @@
 
 // Constants related to icon sizing.
 constexpr CGFloat kIconSize = 36;
+constexpr CGFloat kMagicStackIconSize = 30;
 constexpr CGFloat kCompactIconSize = 26;
 constexpr CGFloat kSymbolPointSize = 18;
 constexpr CGFloat kSparkleSize = 72;
 constexpr CGFloat kSparkleOffset = (kSparkleSize - kIconSize) / 2;
+constexpr CGFloat kMagicStackSparkleOffset =
+    (kSparkleSize - kMagicStackIconSize) / 2;
 constexpr CGFloat kIconSquareContainerRadius = 7.0f;
 
 // The amount of rotation for the icons, during the animation.
@@ -45,9 +49,11 @@
   UIImage* image = DefaultSymbolWithConfiguration(symbol, config);
   UIImageView* icon = [[UIImageView alloc] initWithImage:image];
   icon.translatesAutoresizingMaskIntoConstraints = NO;
-  CGFloat icon_width = compact_layout ? kCompactIconSize : kIconSize;
+  CGFloat nonCompactIconWidth =
+      IsMagicStackEnabled() ? kMagicStackIconSize : kIconSize;
+  CGFloat iconWidth = compact_layout ? kCompactIconSize : nonCompactIconWidth;
   [NSLayoutConstraint activateConstraints:@[
-    [icon.widthAnchor constraintEqualToConstant:icon_width],
+    [icon.widthAnchor constraintEqualToConstant:iconWidth],
     [icon.heightAnchor constraintEqualToAnchor:icon.widthAnchor],
   ]];
   return icon;
@@ -61,8 +67,9 @@
 
   [square_view addSubview:icon];
   AddSameCenterConstraints(icon, square_view);
+  CGFloat iconWidth = IsMagicStackEnabled() ? kMagicStackIconSize : kIconSize;
   [NSLayoutConstraint activateConstraints:@[
-    [square_view.widthAnchor constraintEqualToConstant:kIconSize],
+    [square_view.widthAnchor constraintEqualToConstant:iconWidth],
     [square_view.heightAnchor constraintEqualToAnchor:square_view.widthAnchor],
   ]];
   return square_view;
@@ -90,7 +97,9 @@
   [container addSubview:icon];
   AddSameConstraints(icon, container);
   // Set the widths.
-  CGFloat icon_width = compact_layout ? kCompactIconSize : kIconSize;
+  CGFloat nonCompactIconWidth =
+      IsMagicStackEnabled() ? kMagicStackIconSize : kIconSize;
+  CGFloat icon_width = compact_layout ? kCompactIconSize : nonCompactIconWidth;
   // The white background circle must be smaller so that the edges don't show.
   CGFloat white_background_width = icon_width - 2;
   [NSLayoutConstraint activateConstraints:@[
@@ -154,8 +163,9 @@
   symbol_view.translatesAutoresizingMaskIntoConstraints = NO;
   [square_view addSubview:symbol_view];
   AddSameCenterConstraints(symbol_view, square_view);
+  CGFloat iconWidth = IsMagicStackEnabled() ? kMagicStackIconSize : kIconSize;
   [NSLayoutConstraint activateConstraints:@[
-    [square_view.widthAnchor constraintEqualToConstant:kIconSize],
+    [square_view.widthAnchor constraintEqualToConstant:iconWidth],
     [square_view.heightAnchor constraintEqualToAnchor:square_view.widthAnchor],
   ]];
   return square_view;
@@ -273,7 +283,7 @@
       }
 
       UIImageView* iconImage = IconForSymbol(
-          kSyncCircleSymbol, _compactLayout || _inSquare,
+          kSyncCircleSymbol, _compactLayout,
           @[ [UIColor whiteColor], [UIColor colorNamed:kGreen500Color] ]);
       return _inSquare ? IconInSquareContainer(iconImage, kGreen500Color)
                        : iconImage;
@@ -308,8 +318,10 @@
   // This image view does not initially have an image. The animation frames
   // are loaded on demand.
   UIImageView* imageView = [[UIImageView alloc] initWithImage:nil];
+  CGFloat sparkleOffset =
+      IsMagicStackEnabled() ? kMagicStackSparkleOffset : kSparkleOffset;
   imageView.frame =
-      CGRectMake(-kSparkleOffset, -kSparkleOffset, kSparkleSize, kSparkleSize);
+      CGRectMake(-sparkleOffset, -sparkleOffset, kSparkleSize, kSparkleSize);
   return imageView;
 }
 
diff --git a/ios/chrome/browser/ui/content_suggestions/start_suggest_service_factory.mm b/ios/chrome/browser/ui/content_suggestions/start_suggest_service_factory.mm
index 11a477c..ebc3bc1 100644
--- a/ios/chrome/browser/ui/content_suggestions/start_suggest_service_factory.mm
+++ b/ios/chrome/browser/ui/content_suggestions/start_suggest_service_factory.mm
@@ -5,7 +5,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/start_suggest_service_factory.h"
 
 #import "components/keyed_service/ios/browser_state_dependency_manager.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
 #import "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
diff --git a/ios/chrome/browser/ui/location_bar/BUILD.gn b/ios/chrome/browser/ui/location_bar/BUILD.gn
index b14c3bc..3ee9811 100644
--- a/ios/chrome/browser/ui/location_bar/BUILD.gn
+++ b/ios/chrome/browser/ui/location_bar/BUILD.gn
@@ -32,7 +32,7 @@
     "//components/strings",
     "//ios/chrome/app/strings",
     "//ios/chrome/app/theme",
-    "//ios/chrome/browser/autocomplete",
+    "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/browser_state_metrics:browser_state_metrics",
     "//ios/chrome/browser/default_browser:utils",
     "//ios/chrome/browser/drag_and_drop",
@@ -114,7 +114,7 @@
     "//components/omnibox/browser",
     "//components/prefs",
     "//components/security_state/ios",
-    "//ios/chrome/browser/autocomplete",
+    "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/reading_list",
     "//ios/chrome/browser/search_engines:template_url_service_factory",
     "//ios/chrome/browser/shared/model/browser_state",
@@ -155,7 +155,7 @@
     "//components/variations",
     "//components/variations:test_support",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/autocomplete",
+    "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/history",
     "//ios/chrome/browser/overlays",
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
index e29530b..debcd5d 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator.mm
@@ -19,7 +19,7 @@
 #import "components/profile_metrics/browser_profile_type.h"
 #import "components/search_engines/util.h"
 #import "components/strings/grit/components_strings.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
 #import "ios/chrome/browser/browser_state_metrics/browser_state_metrics.h"
 #import "ios/chrome/browser/default_browser/utils.h"
 #import "ios/chrome/browser/drag_and_drop/drag_item_util.h"
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_coordinator_unittest.mm b/ios/chrome/browser/ui/location_bar/location_bar_coordinator_unittest.mm
index e3c4d2d1..51b57f3 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_coordinator_unittest.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_coordinator_unittest.mm
@@ -11,7 +11,7 @@
 #import "components/omnibox/browser/test_location_bar_model.h"
 #import "components/variations/scoped_variations_ids_provider.h"
 #import "components/variations/variations_ids_provider.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.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/favicon/ios_chrome_large_icon_service_factory.h"
diff --git a/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm b/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm
index ae1e92c..af49b63 100644
--- a/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm
+++ b/ios/chrome/browser/ui/location_bar/location_bar_model_delegate_ios.mm
@@ -10,7 +10,7 @@
 #import "components/omnibox/browser/autocomplete_match.h"
 #import "components/prefs/pref_service.h"
 #import "components/security_state/ios/security_state_utils.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
 #import "ios/chrome/browser/reading_list/offline_page_tab_helper.h"
 #import "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
diff --git a/ios/chrome/browser/ui/ntp/metrics/home_metrics.mm b/ios/chrome/browser/ui/ntp/metrics/home_metrics.mm
index 0a55346..a4129f1 100644
--- a/ios/chrome/browser/ui/ntp/metrics/home_metrics.mm
+++ b/ios/chrome/browser/ui/ntp/metrics/home_metrics.mm
@@ -32,6 +32,17 @@
           base::UserMetricsAction("IOSMagicStackShortcutsFreshSignal"));
       break;
     }
+    case ContentSuggestionsModuleType::kSafetyCheck:
+    case ContentSuggestionsModuleType::kSafetyCheckMultiRow:
+    case ContentSuggestionsModuleType::kSafetyCheckMultiRowOverflow: {
+      PrefService* local_state = GetApplicationContext()->GetLocalState();
+      local_state->SetInteger(
+          prefs::kIosMagicStackSegmentationSafetyCheckImpressionsSinceFreshness,
+          0);
+      base::RecordAction(
+          base::UserMetricsAction("IOSMagicStackSafetyCheckFreshSignal"));
+      break;
+    }
     default:
       break;
   }
diff --git a/ios/chrome/browser/ui/omnibox/BUILD.gn b/ios/chrome/browser/ui/omnibox/BUILD.gn
index a56d559..533d0dd 100644
--- a/ios/chrome/browser/ui/omnibox/BUILD.gn
+++ b/ios/chrome/browser/ui/omnibox/BUILD.gn
@@ -127,13 +127,14 @@
     "//components/security_state/core",
     "//components/strings",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/autocomplete",
+    "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/bookmarks/model",
     "//ios/chrome/browser/bookmarks/model:model_utils",
     "//ios/chrome/browser/default_browser:utils",
     "//ios/chrome/browser/favicon",
     "//ios/chrome/browser/feature_engagement",
     "//ios/chrome/browser/https_upgrades",
+    "//ios/chrome/browser/intents:intents_donation_helper",
     "//ios/chrome/browser/net",
     "//ios/chrome/browser/ntp",
     "//ios/chrome/browser/prerender",
@@ -166,7 +167,6 @@
     "//ios/chrome/browser/ui/toolbar/public:constants",
     "//ios/chrome/browser/url_loading",
     "//ios/chrome/common",
-    "//ios/chrome/common/intents",
     "//ios/chrome/common/ui/colors",
     "//ios/chrome/common/ui/favicon:favicon",
     "//ios/chrome/common/ui/favicon:favicon_constants",
@@ -214,7 +214,7 @@
     "//components/omnibox/browser",
     "//components/search_engines",
     "//components/variations:variations",
-    "//ios/chrome/browser/autocomplete",
+    "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/history",
     "//ios/chrome/browser/search_engines",
     "//ios/chrome/browser/search_engines:template_url_service_factory",
diff --git a/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.h b/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.h
index c832bcca..ee0c005 100644
--- a/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.h
+++ b/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.h
@@ -8,7 +8,7 @@
 #include <memory>
 
 #include "components/omnibox/browser/omnibox_client.h"
-#include "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#include "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
 
 class ChromeBrowserState;
 class WebLocationBar;
diff --git a/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.mm b/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.mm
index 4740756..4bdbc61 100644
--- a/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.mm
+++ b/ios/chrome/browser/ui/omnibox/chrome_omnibox_client_ios.mm
@@ -17,12 +17,13 @@
 #import "components/omnibox/browser/omnibox_log.h"
 #import "components/omnibox/common/omnibox_features.h"
 #import "components/search_engines/template_url_service.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_provider_client_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_classifier_factory.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_provider_client_impl.h"
 #import "ios/chrome/browser/bookmarks/model/bookmarks_utils.h"
 #import "ios/chrome/browser/bookmarks/model/local_or_syncable_bookmark_model_factory.h"
 #import "ios/chrome/browser/default_browser/utils.h"
 #import "ios/chrome/browser/https_upgrades/https_upgrade_service_factory.h"
+#import "ios/chrome/browser/intents/intents_donation_helper.h"
 #import "ios/chrome/browser/prerender/prerender_service.h"
 #import "ios/chrome/browser/prerender/prerender_service_factory.h"
 #import "ios/chrome/browser/search_engines/template_url_service_factory.h"
@@ -30,7 +31,6 @@
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h"
 #import "ios/chrome/browser/ui/omnibox/web_location_bar.h"
-#import "ios/chrome/common/intents/SearchInChromeIntent.h"
 #import "ios/chrome/grit/ios_strings.h"
 #import "ios/web/public/navigation/navigation_manager.h"
 #import "ios/web/public/web_state.h"
@@ -209,25 +209,7 @@
   if (!browser_state_->IsOffTheRecord() &&
       (log->input_type == metrics::OmniboxInputType::QUERY ||
        log->input_type == metrics::OmniboxInputType::UNKNOWN)) {
-    base::ThreadPool::PostTask(
-        FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT},
-        base::BindOnce(^{
-          SearchInChromeIntent* searchInChromeIntent =
-              [[SearchInChromeIntent alloc] init];
-
-          // SiriKit requires the intent parameter to be set to a non-empty
-          // string in order to accept the intent donation. Set it to a single
-          // space, to be later trimmed by the intent handler, which will result
-          // in the shortcut being treated as if no search phrase was supplied.
-          searchInChromeIntent.searchPhrase = @" ";
-          searchInChromeIntent.suggestedInvocationPhrase =
-              l10n_util::GetNSString(
-                  IDS_IOS_INTENTS_SEARCH_IN_CHROME_INVOCATION_PHRASE);
-          INInteraction* interaction =
-              [[INInteraction alloc] initWithIntent:searchInChromeIntent
-                                           response:nil];
-          [interaction donateInteractionWithCompletion:nil];
-        }));
+    [IntentDonationHelper donateIntent:INTENT_SEARCH_IN_CHROME];
   }
 
   engagement_tracker_->NotifyEvent(
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_app_interface.mm b/ios/chrome/browser/ui/omnibox/omnibox_app_interface.mm
index fa98a3d..6229909c 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_app_interface.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_app_interface.mm
@@ -13,7 +13,7 @@
 #import "components/history/core/browser/top_sites.h"
 #import "components/search_engines/template_url_service.h"
 #import "components/variations/variations_ids_provider.h"
-#import "ios/chrome/browser/autocomplete/remote_suggestions_service_factory.h"
+#import "ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.h"
 #import "ios/chrome/browser/history/top_sites_factory.h"
 #import "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_experimental.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_experimental.mm
index 8f74513..8067f61 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_experimental.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_experimental.mm
@@ -14,7 +14,7 @@
 #import "base/strings/sys_string_conversions.h"
 #import "components/grit/components_scaled_resources.h"
 #import "components/omnibox/browser/autocomplete_input.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/public/features/system_flags.h"
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
index 2880d7e..04c8038 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_ios.mm
@@ -14,7 +14,7 @@
 #import "base/strings/sys_string_conversions.h"
 #import "components/grit/components_scaled_resources.h"
 #import "components/omnibox/browser/autocomplete_input.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/public/features/system_flags.h"
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_text_field_legacy.mm b/ios/chrome/browser/ui/omnibox/omnibox_text_field_legacy.mm
index 0518f40..3ca3d21 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_text_field_legacy.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_text_field_legacy.mm
@@ -14,7 +14,7 @@
 #import "base/strings/sys_string_conversions.h"
 #import "components/grit/components_scaled_resources.h"
 #import "components/omnibox/browser/autocomplete_input.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
 #import "ios/chrome/browser/shared/model/application_context/application_context.h"
 #import "ios/chrome/browser/shared/public/features/features.h"
 #import "ios/chrome/browser/shared/public/features/system_flags.h"
diff --git a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
index f60622a..378eb8b 100644
--- a/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
+++ b/ios/chrome/browser/ui/omnibox/omnibox_view_ios.mm
@@ -23,7 +23,7 @@
 #import "components/omnibox/browser/omnibox_edit_model.h"
 #import "components/omnibox/common/omnibox_focus_state.h"
 #import "components/open_from_clipboard/clipboard_recent_content.h"
-#import "ios/chrome/browser/autocomplete/autocomplete_scheme_classifier_impl.h"
+#import "ios/chrome/browser/autocomplete/model/autocomplete_scheme_classifier_impl.h"
 #import "ios/chrome/browser/feature_engagement/tracker_factory.h"
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
diff --git a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
index bc72e4a..22fefef 100644
--- a/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
+++ b/ios/chrome/browser/ui/omnibox/popup/BUILD.gn
@@ -68,7 +68,7 @@
     "//components/strings:components_strings_grit",
     "//components/variations",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/autocomplete",
+    "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/default_browser",
     "//ios/chrome/browser/default_browser:utils",
     "//ios/chrome/browser/favicon",
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
index 6e65e60..0e4256977 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_coordinator.mm
@@ -12,7 +12,7 @@
 #import "components/omnibox/browser/autocomplete_result.h"
 #import "components/omnibox/common/omnibox_features.h"
 #import "components/search_engines/template_url_service.h"
-#import "ios/chrome/browser/autocomplete/remote_suggestions_service_factory.h"
+#import "ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.h"
 #import "ios/chrome/browser/favicon/ios_chrome_favicon_loader_factory.h"
 #import "ios/chrome/browser/favicon/ios_chrome_large_icon_cache_factory.h"
 #import "ios/chrome/browser/favicon/ios_chrome_large_icon_service_factory.h"
diff --git a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
index 8deb680..4197bb64 100644
--- a/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
+++ b/ios/chrome/browser/ui/omnibox/popup/omnibox_popup_presenter.mm
@@ -49,6 +49,7 @@
 
 // The layout guide center to use to refer to the omnibox.
 @property(nonatomic, strong) LayoutGuideCenter* layoutGuideCenter;
+@property(nonatomic, strong) UILayoutGuide* topOmniboxGuide;
 
 @end
 
@@ -233,12 +234,15 @@
                                   constant:kPopupBottomPaddingTablet];
 
   // Install in the superview the guide tracking the top omnibox.
-  UILayoutGuide* topOmniboxGuide =
+  if (self.topOmniboxGuide) {
+    [[popup superview] removeLayoutGuide:self.topOmniboxGuide];
+  }
+  self.topOmniboxGuide =
       [self.layoutGuideCenter makeLayoutGuideNamed:kTopOmniboxGuide];
-  [[popup superview] addLayoutGuide:topOmniboxGuide];
+  [[popup superview] addLayoutGuide:self.topOmniboxGuide];
   // Position the top anchor of the popup relatively to that layout guide.
   NSLayoutConstraint* topConstraint =
-      [popup.topAnchor constraintEqualToAnchor:topOmniboxGuide.bottomAnchor
+      [popup.topAnchor constraintEqualToAnchor:self.topOmniboxGuide.bottomAnchor
                                       constant:kVerticalOffset];
 
   NSMutableArray<NSLayoutConstraint*>* constraintsToActivate =
@@ -248,9 +252,9 @@
       IsRegularXRegularSizeClass(self.popupContainerView)) {
     [constraintsToActivate addObjectsFromArray:@[
       [popup.leadingAnchor
-          constraintEqualToAnchor:topOmniboxGuide.leadingAnchor],
+          constraintEqualToAnchor:self.topOmniboxGuide.leadingAnchor],
       [popup.trailingAnchor
-          constraintEqualToAnchor:topOmniboxGuide.trailingAnchor],
+          constraintEqualToAnchor:self.topOmniboxGuide.trailingAnchor],
     ]];
   } else {
     [constraintsToActivate addObjectsFromArray:@[
diff --git a/ios/chrome/browser/ui/omnibox/test_fake_suggestions_service.cc b/ios/chrome/browser/ui/omnibox/test_fake_suggestions_service.cc
index 1415866..396ad2a23 100644
--- a/ios/chrome/browser/ui/omnibox/test_fake_suggestions_service.cc
+++ b/ios/chrome/browser/ui/omnibox/test_fake_suggestions_service.cc
@@ -5,7 +5,7 @@
 #include "ios/chrome/browser/ui/omnibox/test_fake_suggestions_service.h"
 
 #import "components/search_engines/template_url_service.h"
-#import "ios/chrome/browser/autocomplete/remote_suggestions_service_factory.h"
+#import "ios/chrome/browser/autocomplete/model/remote_suggestions_service_factory.h"
 #import "ios/chrome/browser/search_engines/template_url_service_factory.h"
 #import "ios/chrome/browser/ui/omnibox/fake_suggestions_database.h"
 #import "services/network/public/cpp/resource_request.h"
diff --git a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm
index 001aa745..c9bbe2b 100644
--- a/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_coordinator.mm
@@ -128,6 +128,9 @@
             initForWarningType:warningType
       baseNavigationController:self.baseNavigationController
                        browser:self.browser];
+  // No need to authenticate the user before showing password issues as the user
+  // was already authenticated when opening the password manager.
+  _passwordIssuesCoordinator.skipAuthenticationOnStart = YES;
   _passwordIssuesCoordinator.delegate = self;
   _passwordIssuesCoordinator.reauthModule = _reauthModule;
   [_passwordIssuesCoordinator start];
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn
index 77c9573..029a21c 100644
--- a/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn
+++ b/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn
@@ -29,8 +29,10 @@
     "//ios/chrome/browser/shared/ui/table_view:utils",
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/ui/settings/password:common",
+    "//ios/chrome/browser/ui/settings/password:features",
     "//ios/chrome/browser/ui/settings/password/password_checkup:password_checkup_constants",
     "//ios/chrome/browser/ui/settings/password/password_details",
+    "//ios/chrome/browser/ui/settings/password/reauthentication",
     "//ios/chrome/browser/ui/settings/utils",
     "//ios/chrome/common/ui/favicon:favicon_constants",
     "//ios/chrome/common/ui/reauthentication",
@@ -74,6 +76,7 @@
   testonly = true
   sources = [
     "password_issue_unittest.mm",
+    "password_issues_coordinator_unittest.mm",
     "password_issues_mediator_unittest.mm",
     "password_issues_table_view_controller_unittest.mm",
   ]
@@ -93,17 +96,25 @@
     "//ios/chrome/browser/passwords",
     "//ios/chrome/browser/passwords:password_checkup_utils",
     "//ios/chrome/browser/passwords:store_factory",
+    "//ios/chrome/browser/shared/coordinator/scene:scene_state_browser_agent",
+    "//ios/chrome/browser/shared/coordinator/scene:scene_state_header",
     "//ios/chrome/browser/shared/model/application_context",
     "//ios/chrome/browser/shared/model/browser/test:test_support",
     "//ios/chrome/browser/shared/model/browser_state:test_support",
+    "//ios/chrome/browser/shared/public/commands",
     "//ios/chrome/browser/shared/ui/table_view:test_support",
     "//ios/chrome/browser/shared/ui/table_view/cells",
     "//ios/chrome/browser/sync",
     "//ios/chrome/browser/sync:test_support",
+    "//ios/chrome/browser/ui/settings/password:features",
     "//ios/chrome/browser/ui/settings/password/password_checkup:password_checkup_constants",
+    "//ios/chrome/browser/ui/settings/password/reauthentication:reauthentication_ui",
+    "//ios/chrome/test:test_support",
+    "//ios/chrome/test/app:test_support",
     "//ios/web/public/test",
     "//testing/gmock",
     "//testing/gtest",
+    "//third_party/ocmock",
     "//ui/base",
   ]
 }
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h
index 0a95ac9..dbab80a 100644
--- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h
+++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h
@@ -42,6 +42,14 @@
 
 @property(nonatomic, weak) id<ApplicationCommands> dispatcher;
 
+// Whether Local Authentication should be skipped when the coordinator is
+// started. Defaults to NO. Authentication should be required when starting the
+// coordinator unless it was already required by the starting coordinator or
+// another ancestor higher in the ancestor chain. This property is most likely
+// used only by coordinators for other password manager subpages as the password
+// manager requires authentication upon entry.
+@property(nonatomic) BOOL skipAuthenticationOnStart;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_SETTINGS_PASSWORD_PASSWORD_ISSUES_PASSWORD_ISSUES_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm
index 86b73a63..2cfa737 100644
--- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.mm
@@ -25,6 +25,8 @@
 #import "ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator.h"
 #import "ios/chrome/browser/ui/settings/password/password_issues/password_issues_presenter.h"
 #import "ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.h"
+#import "ios/chrome/browser/ui/settings/password/password_manager_ui_features.h"
+#import "ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_coordinator.h"
 #import "ios/chrome/browser/ui/settings/utils/password_utils.h"
 #import "ios/chrome/common/ui/reauthentication/reauthentication_protocol.h"
 #import "ui/base/l10n/l10n_util.h"
@@ -53,7 +55,8 @@
 
 @interface PasswordIssuesCoordinator () <PasswordDetailsCoordinatorDelegate,
                                          PasswordIssuesCoordinatorDelegate,
-                                         PasswordIssuesPresenter> {
+                                         PasswordIssuesPresenter,
+                                         ReauthenticationCoordinatorDelegate> {
   // Password check manager to power mediator.
   IOSChromePasswordCheckManager* _manager;
 
@@ -71,6 +74,12 @@
   // there are child coordinators, this flag is used to dismiss the view
   // controller after the children are dismissed.
   BOOL _shouldDismissAfterChildCoordinatorRemoved;
+
+  // Coordinator for blocking Password Issues until Local Authentication is
+  // passed. Used for requiring authentication when opening Password Issues
+  // from outside the Password Manager and when the app is
+  // backgrounded/foregrounded with Password Issues opened.
+  ReauthenticationCoordinator* _reauthCoordinator;
 }
 
 // Main view controller for this coordinator.
@@ -98,6 +107,7 @@
     _baseNavigationController = navigationController;
     _dispatcher = HandlerForProtocol(self.browser->GetCommandDispatcher(),
                                      ApplicationCommands);
+    _skipAuthenticationOnStart = NO;
   }
   return self;
 }
@@ -132,8 +142,12 @@
   self.mediator.consumer = self.viewController;
   self.viewController.presenter = self;
 
+  // Disable animation when content will be blocked for reauth to prevent
+  // flickering in navigation bar.
   [self.baseNavigationController pushViewController:self.viewController
-                                           animated:YES];
+                                           animated:_skipAuthenticationOnStart];
+
+  [self startReauthCoordinatorWithAuthOnStart:!_skipAuthenticationOnStart];
 }
 
 - (void)stop {
@@ -146,6 +160,7 @@
   self.passwordDetails = nil;
 
   [self stopDismissedPasswordIssuesCoordinator];
+  [self stopReauthenticationCoordinator];
 }
 
 #pragma mark - PasswordIssuesPresenter
@@ -162,6 +177,9 @@
 
 - (void)presentPasswordIssueDetails:(PasswordIssue*)password {
   DCHECK(!self.passwordDetails);
+
+  [self stopReauthCoordinatorBeforeStartingChildCoordinator];
+
   self.passwordDetails = [[PasswordDetailsCoordinator alloc]
       initWithBaseNavigationController:self.baseNavigationController
                                browser:self.browser
@@ -175,11 +193,15 @@
 
 - (void)presentDismissedCompromisedCredentials {
   CHECK(!_dismissedPasswordIssuesCoordinator);
+
+  [self stopReauthCoordinatorBeforeStartingChildCoordinator];
+
   _dismissedPasswordIssuesCoordinator = [[PasswordIssuesCoordinator alloc]
             initForWarningType:password_manager::WarningType::
                                    kDismissedWarningsWarning
       baseNavigationController:self.baseNavigationController
                        browser:self.browser];
+  _dismissedPasswordIssuesCoordinator.skipAuthenticationOnStart = YES;
   _dismissedPasswordIssuesCoordinator.reauthModule = self.reauthModule;
   _dismissedPasswordIssuesCoordinator.delegate = self;
   [_dismissedPasswordIssuesCoordinator start];
@@ -215,6 +237,17 @@
   [self onChildCoordinatorDidRemove];
 }
 
+#pragma mark - ReauthenticationCoordinatorDelegate
+
+- (void)successfulReauthenticationWithCoordinator:
+    (ReauthenticationCoordinator*)coordinator {
+  // No-op.
+}
+
+- (void)willPushReauthenticationViewController {
+  // No-op.
+}
+
 #pragma mark - Private
 
 - (void)stopDismissedPasswordIssuesCoordinator {
@@ -224,6 +257,12 @@
   _dismissedPasswordIssuesCoordinator = nil;
 }
 
+- (void)stopReauthenticationCoordinator {
+  [_reauthCoordinator stop];
+  _reauthCoordinator.delegate = nil;
+  _reauthCoordinator = nil;
+}
+
 // Called after the view controller of a child coordinator of `self` was removed
 // from the navigation stack.
 - (void)onChildCoordinatorDidRemove {
@@ -237,6 +276,59 @@
     dispatch_async(dispatch_get_main_queue(), ^{
       [self.baseNavigationController popViewControllerAnimated:NO];
     });
+  } else {
+    // Otherwise restart scene monitoring so authentication is required when the
+    // scene is backgrounded/foregrounded.
+    [self restartReauthCoordinator];
+  }
+}
+
+// Starts reauthCoordinator.
+// - authOnStart: Pass `YES` to cover Password Issues with an empty view
+// controller until successful Local Authentication when reauthCoordinator
+// starts.
+//
+// Local authentication is required every time the current
+// scene is backgrounded and foregrounded until reauthCoordinator is stopped.
+- (void)startReauthCoordinatorWithAuthOnStart:(BOOL)authOnStart {
+  // No-op if Auth on Entry is not enabled for the password manager.
+  if (!password_manager::features::IsAuthOnEntryV2Enabled()) {
+    return;
+  }
+
+  DCHECK(!_reauthCoordinator);
+
+  _reauthCoordinator = [[ReauthenticationCoordinator alloc]
+      initWithBaseNavigationController:_baseNavigationController
+                               browser:self.browser
+                reauthenticationModule:_reauthModule
+                           authOnStart:authOnStart];
+
+  _reauthCoordinator.delegate = self;
+
+  [_reauthCoordinator start];
+}
+
+// Stop reauth coordinator when a child coordinator will be started.
+//
+// Needed so reauth coordinator doesn't block for reauth if the scene state
+// changes while the child coordinator is presenting its content. The child
+// coordinator will add its own reauth coordinator to block its content for
+// reauth.
+- (void)stopReauthCoordinatorBeforeStartingChildCoordinator {
+  // See PasswordsCoordinator
+  // stopReauthCoordinatorBeforeStartingChildCoordinator.
+  [_reauthCoordinator stopAndPopViewController];
+  _reauthCoordinator.delegate = nil;
+  _reauthCoordinator = nil;
+}
+
+// Starts reauthCoordinator after a child coordinator content was dismissed.
+- (void)restartReauthCoordinator {
+  // Restart reauth coordinator so it monitors scene state changes and requests
+  // local authentication after the scene goes to the background.
+  if (password_manager::features::IsAuthOnEntryV2Enabled()) {
+    [self startReauthCoordinatorWithAuthOnStart:NO];
   }
 }
 
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator_unittest.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator_unittest.mm
new file mode 100644
index 0000000..c3cc61b0
--- /dev/null
+++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator_unittest.mm
@@ -0,0 +1,175 @@
+// 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 <UIKit/UIKit.h>
+
+#import "base/memory/scoped_refptr.h"
+#import "base/test/bind.h"
+#import "base/test/ios/wait_util.h"
+#import "base/test/scoped_feature_list.h"
+#import "components/password_manager/core/browser/password_manager_test_utils.h"
+#import "components/password_manager/core/browser/test_password_store.h"
+#import "ios/chrome/browser/passwords/ios_chrome_password_check_manager.h"
+#import "ios/chrome/browser/passwords/ios_chrome_password_check_manager_factory.h"
+#import "ios/chrome/browser/passwords/ios_chrome_password_store_factory.h"
+#import "ios/chrome/browser/passwords/password_checkup_utils.h"
+#import "ios/chrome/browser/shared/coordinator/scene/scene_state.h"
+#import "ios/chrome/browser/shared/coordinator/scene/scene_state_browser_agent.h"
+#import "ios/chrome/browser/shared/model/browser/test/test_browser.h"
+#import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h"
+#import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h"
+#import "ios/chrome/browser/shared/public/commands/application_commands.h"
+#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h"
+#import "ios/chrome/browser/sync/mock_sync_service_utils.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
+#import "ios/chrome/browser/ui/settings/password/password_issues/password_issues_coordinator.h"
+#import "ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.h"
+#import "ios/chrome/browser/ui/settings/password/password_manager_ui_features.h"
+#import "ios/chrome/browser/ui/settings/password/reauthentication/reauthentication_view_controller.h"
+#import "ios/chrome/test/app/mock_reauthentication_module.h"
+#import "ios/chrome/test/scoped_key_window.h"
+#import "ios/web/public/test/web_task_environment.h"
+#import "testing/gtest/include/gtest/gtest.h"
+#import "testing/platform_test.h"
+#import "third_party/ocmock/OCMock/OCMock.h"
+#import "third_party/ocmock/gtest_support.h"
+
+namespace password_manager {
+
+// Test fixture for PasswordIssuesCoordinator.
+class PasswordIssuesCoordinatorTest : public PlatformTest {
+ protected:
+  void SetUp() override {
+    PlatformTest::SetUp();
+
+    scoped_feature_list_.InitAndEnableFeature(
+        password_manager::features::kIOSPasswordAuthOnEntryV2);
+
+    TestChromeBrowserState::Builder builder;
+    // Add test password store. Used by the mediator.
+    builder.AddTestingFactory(
+        IOSChromePasswordStoreFactory::GetInstance(),
+        base::BindRepeating(
+            &password_manager::BuildPasswordStore<
+                web::BrowserState, password_manager::TestPasswordStore>));
+
+    builder.AddTestingFactory(SyncServiceFactory::GetInstance(),
+                              base::BindRepeating(&CreateMockSyncService));
+
+    browser_state_ = builder.Build();
+    browser_ = std::make_unique<TestBrowser>(browser_state_.get());
+
+    // Keep a scoped reference to IOSChromePasswordCheckManager until the test
+    // finishes, otherwise it gets destroyed as soon as PasswordIssuesMediator
+    // init goes out of scope.
+    password_check_manager_ =
+        IOSChromePasswordCheckManagerFactory::GetForBrowserState(
+            browser_state_.get());
+
+    // Mock ApplicationCommands. Since ApplicationCommands conforms to
+    // ApplicationSettingsCommands, it must be mocked as well.
+    mocked_application_commands_handler_ =
+        OCMStrictProtocolMock(@protocol(ApplicationCommands));
+    [browser_->GetCommandDispatcher()
+        startDispatchingToTarget:mocked_application_commands_handler_
+                     forProtocol:@protocol(ApplicationCommands)];
+    id mocked_application_settings_command_handler =
+        OCMProtocolMock(@protocol(ApplicationSettingsCommands));
+    [browser_->GetCommandDispatcher()
+        startDispatchingToTarget:mocked_application_settings_command_handler
+                     forProtocol:@protocol(ApplicationSettingsCommands)];
+
+    // Init navigation controller with a root vc.
+    base_navigation_controller_ = [[UINavigationController alloc]
+        initWithRootViewController:[[UIViewController alloc] init]];
+    mock_reauth_module_ = [[MockReauthenticationModule alloc] init];
+    // Delay auth result so auth doesn't pass right after starting coordinator.
+    // Needed for verifying behavior when auth is required.
+    mock_reauth_module_.shouldReturnSynchronously = NO;
+    mock_reauth_module_.expectedResult = ReauthenticationResult::kSuccess;
+
+    coordinator_ = [[PasswordIssuesCoordinator alloc]
+              initForWarningType:password_manager::WarningType::
+                                     kCompromisedPasswordsWarning
+        baseNavigationController:base_navigation_controller_
+                         browser:browser_.get()];
+
+    coordinator_.reauthModule = mock_reauth_module_;
+
+    // Create scene state for reauthentication coordinator.
+    scene_state_ = [[SceneState alloc] initWithAppState:nil];
+    scene_state_.activationLevel = SceneActivationLevelForegroundActive;
+    SceneStateBrowserAgent::CreateForBrowser(browser_.get(), scene_state_);
+
+    scoped_window_.Get().rootViewController = base_navigation_controller_;
+  }
+
+  void TearDown() override {
+    [coordinator_ stop];
+    PlatformTest::TearDown();
+  }
+
+  // Starts the coordinator.
+  //  - skip_auth_on_start: Whether to skip local authentication when the
+  //  coordinator is started.
+  void StartCoordinatorSkippingAuth(BOOL skip_auth_on_start) {
+    coordinator_.skipAuthenticationOnStart = skip_auth_on_start;
+
+    [coordinator_ start];
+
+    // Wait for presentation animation of the coordinator's view controller.
+    base::test::ios::SpinRunLoopWithMaxDelay(
+        base::test::ios::kWaitForUIElementTimeout);
+  }
+
+  // Verifies that the PasswordIssuesTableViewController was pushed in the
+  // navigation controller.
+  void CheckPasswordIssuesIsPresented() {
+    ASSERT_TRUE([base_navigation_controller_.topViewController
+        isKindOfClass:[PasswordIssuesTableViewController class]]);
+  }
+
+  // Verifies that the PasswordIssuesTableViewController is not on top of the
+  // navigation controller.
+  void CheckPasswordIssuesIsNotPresented() {
+    ASSERT_FALSE([base_navigation_controller_.topViewController
+        isKindOfClass:[PasswordIssuesTableViewController class]]);
+  }
+
+  web::WebTaskEnvironment task_environment_;
+  std::unique_ptr<ChromeBrowserState> browser_state_;
+  std::unique_ptr<TestBrowser> browser_;
+  // IOSChromePasswordCheckManager must be destroyed before browser otherwise it
+  // crashes when unregistering itself as an observer of a keyed service.
+  scoped_refptr<IOSChromePasswordCheckManager> password_check_manager_;
+  SceneState* scene_state_;
+  ScopedKeyWindow scoped_window_;
+  UINavigationController* base_navigation_controller_ = nil;
+  MockReauthenticationModule* mock_reauth_module_ = nil;
+  base::test::ScopedFeatureList scoped_feature_list_;
+  id mocked_application_commands_handler_;
+  PasswordIssuesCoordinator* coordinator_ = nil;
+};
+
+// Tests that Password Issues is presented without authentication required.
+TEST_F(PasswordIssuesCoordinatorTest, PasswordIssuesPresentedWithoutAuth) {
+  StartCoordinatorSkippingAuth(/*skip_auth_on_start=*/YES);
+
+  CheckPasswordIssuesIsPresented();
+}
+
+// Tests that Password Issues is presented only after passing authentication
+TEST_F(PasswordIssuesCoordinatorTest, PasswordIssuesPresentedWithAuth) {
+  StartCoordinatorSkippingAuth(/*skip_auth_on_start=*/NO);
+
+  // Password Issues should be covered until auth is passed.
+  CheckPasswordIssuesIsNotPresented();
+
+  [mock_reauth_module_ returnMockedReathenticationResult];
+
+  // Successful auth should leave Password Issues visible.
+  CheckPasswordIssuesIsPresented();
+}
+
+}  // namespace password_manager
diff --git a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm
index 2542f487..cbe88076 100644
--- a/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm
+++ b/ios/chrome/browser/ui/settings/password/passwords_coordinator.mm
@@ -259,9 +259,10 @@
             initForWarningType:WarningType::kCompromisedPasswordsWarning
       baseNavigationController:self.baseNavigationController
                        browser:self.browser];
-  self.passwordIssuesCoordinator.delegate = self;
-  self.passwordIssuesCoordinator.reauthModule = self.reauthModule;
-  [self.passwordIssuesCoordinator start];
+  _passwordIssuesCoordinator.skipAuthenticationOnStart = YES;
+  _passwordIssuesCoordinator.delegate = self;
+  _passwordIssuesCoordinator.reauthModule = self.reauthModule;
+  [_passwordIssuesCoordinator start];
 }
 
 - (void)showDetailedViewForCredential:
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn
index f5c5a15..0346728 100644
--- a/ios/chrome/browser/ui/toolbar/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -34,7 +34,7 @@
     "//components/segmentation_platform/public",
     "//components/strings",
     "//ios/chrome/app/strings",
-    "//ios/chrome/browser/autocomplete",
+    "//ios/chrome/browser/autocomplete/model",
     "//ios/chrome/browser/bookmarks/model",
     "//ios/chrome/browser/feature_engagement",
     "//ios/chrome/browser/first_run",
diff --git a/ios/chrome/browser/voice/speech_input_locale_config_impl.mm b/ios/chrome/browser/voice/speech_input_locale_config_impl.mm
index aea6575..e20c352 100644
--- a/ios/chrome/browser/voice/speech_input_locale_config_impl.mm
+++ b/ios/chrome/browser/voice/speech_input_locale_config_impl.mm
@@ -10,6 +10,7 @@
 #import "base/apple/foundation_util.h"
 #import "base/apple/scoped_cftyperef.h"
 #import "base/containers/contains.h"
+#import "base/debug/dump_without_crashing.h"
 #import "base/strings/string_split.h"
 #import "base/strings/sys_string_conversions.h"
 #import "ios/chrome/browser/voice/speech_input_locale_match.h"
@@ -127,12 +128,23 @@
   NSString* language = [lang_pref_locale objectForKey:NSLocaleLanguageCode];
   if (!language.length)
     language = [current_locale objectForKey:NSLocaleLanguageCode];
-  DCHECK(language.length);
+  // In production, in very rare cases the language cannot be detected. Default
+  // to en-US.
+  if (!language.length) {
+    base::debug::DumpWithoutCrashing();
+    return GetCanonicalLocaleForLocale(@"en-US");
+  }
   // Prioritize the country portion of `current_locale`.
   NSString* country = [current_locale objectForKey:NSLocaleCountryCode];
   if (!country.length)
     country = [lang_pref_locale objectForKey:NSLocaleCountryCode];
-  DCHECK(country.length);
+  // In production, in very rare cases the country code cannot be detected.
+  // Default to en-US.
+  if (!country.length) {
+    base::debug::DumpWithoutCrashing();
+    return GetCanonicalLocaleForLocale(@"en-US");
+  }
+
   return GetCanonicalLocaleForLocale(
       [NSString stringWithFormat:@"%@-%@", language, country]);
 }
diff --git a/ios/chrome/common/BUILD.gn b/ios/chrome/common/BUILD.gn
index cc7c3f3e..5b01bd6 100644
--- a/ios/chrome/common/BUILD.gn
+++ b/ios/chrome/common/BUILD.gn
@@ -33,12 +33,6 @@
   frameworks = [ "UIKit.framework" ]
 }
 
-# TODO(crbug.com/1471650): Remove this once AppStore stops blocking
-# __availability_version_check.
-source_set("os_version_check") {
-  sources = [ "third_party/compiler-rt/os_version_check.c" ]
-}
-
 source_set("constants") {
   sources = [
     "constants.h",
diff --git a/ios/chrome/common/app_group/BUILD.gn b/ios/chrome/common/app_group/BUILD.gn
index 8994caa..6f118dd 100644
--- a/ios/chrome/common/app_group/BUILD.gn
+++ b/ios/chrome/common/app_group/BUILD.gn
@@ -38,7 +38,7 @@
 
     # TODO(crbug.com/1471650): Remove this once AppStore stops blocking
     # __availability_version_check.
-    "//ios/chrome/common:os_version_check",
+    "//ios/components/third_party/compiler-rt:os_version_check",
   ]
 }
 
diff --git a/ios/components/third_party/compiler-rt/BUILD.gn b/ios/components/third_party/compiler-rt/BUILD.gn
new file mode 100644
index 0000000..55cb21b
--- /dev/null
+++ b/ios/components/third_party/compiler-rt/BUILD.gn
@@ -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.
+
+# TODO(crbug.com/1471650): Remove this once AppStore stops blocking
+# __availability_version_check.
+source_set("os_version_check") {
+  sources = [ "os_version_check.c" ]
+}
diff --git a/ios/chrome/common/third_party/compiler-rt/os_version_check.c b/ios/components/third_party/compiler-rt/os_version_check.c
similarity index 100%
rename from ios/chrome/common/third_party/compiler-rt/os_version_check.c
rename to ios/components/third_party/compiler-rt/os_version_check.c
diff --git a/ios/web_view/BUILD.gn b/ios/web_view/BUILD.gn
index 9946c599..bedebae 100644
--- a/ios/web_view/BUILD.gn
+++ b/ios/web_view/BUILD.gn
@@ -379,6 +379,10 @@
   "//ios/components/security_interstitials/lookalikes",
   "//ios/components/security_interstitials/safe_browsing",
   "//ios/components/security_interstitials/safe_browsing:util",
+
+  # TODO(crbug.com/1471650): Remove this once AppStore stops blocking
+  # __availability_version_check.
+  "//ios/components/third_party/compiler-rt:os_version_check",
   "//ios/components/webui:provider",
   "//ios/components/webui:url_constants",
   "//ios/components/webui/sync_internals",
diff --git a/ios_internal b/ios_internal
index 90b6ca5..cbf06b1 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 90b6ca5bc5942ca1b25e4504339f80716d2dadbe
+Subproject commit cbf06b1a54baf999a39e40de680dba54cba14166
diff --git a/media/gpu/OWNERS b/media/gpu/OWNERS
index 2530348a..0fc3f40 100644
--- a/media/gpu/OWNERS
+++ b/media/gpu/OWNERS
@@ -8,5 +8,5 @@
 frkoenig@chromium.org
 hiroh@chromium.org
 jcliang@chromium.org
-jkardatzke@chromium.org
+jkardatzke@google.com
 mcasas@chromium.org
diff --git a/media/gpu/chromeos/chromeos_status.h b/media/gpu/chromeos/chromeos_status.h
index c29eead..8852b3a8 100644
--- a/media/gpu/chromeos/chromeos_status.h
+++ b/media/gpu/chromeos/chromeos_status.h
@@ -21,6 +21,8 @@
   kInvalidLayoutSize = 8,
   kFailedToChangeResolution = 9,
   kInsufficientFramePoolSize = 10,
+  kUnableToAllocateSecureBuffer = 11,
+  kSecureBufferPoolEmpty = 12,
 };
 
 struct CroStatusTraits {
diff --git a/media/gpu/chromeos/decoder_buffer_transcryptor.cc b/media/gpu/chromeos/decoder_buffer_transcryptor.cc
index 9924233e..b9a6c03e 100644
--- a/media/gpu/chromeos/decoder_buffer_transcryptor.cc
+++ b/media/gpu/chromeos/decoder_buffer_transcryptor.cc
@@ -6,7 +6,9 @@
 
 #include "base/functional/callback.h"
 #include "base/task/bind_post_task.h"
+#include "base/task/sequenced_task_runner.h"
 #include "chromeos/components/cdm_factory_daemon/chromeos_cdm_context.h"
+#include "media/gpu/chromeos/video_decoder_pipeline.h"
 
 namespace media {
 DecoderBufferTranscryptor::TranscryptTask::TranscryptTask(
@@ -21,9 +23,11 @@
 
 DecoderBufferTranscryptor::DecoderBufferTranscryptor(
     CdmContext* cdm_context,
+    VideoDecoderMixin& decoder,
     OnBufferTranscryptedCB transcrypt_callback,
     WaitingCB waiting_callback)
-    : transcrypt_callback_(std::move(transcrypt_callback)),
+    : decoder_(decoder),
+      transcrypt_callback_(std::move(transcrypt_callback)),
       waiting_callback_(std::move(waiting_callback)) {
   weak_this_ = weak_this_factory_.GetWeakPtr();
 
@@ -39,6 +43,15 @@
   Reset(DecoderStatus::Codes::kAborted);
 }
 
+void DecoderBufferTranscryptor::SecureBuffersMayBeAvailable() {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  // Re-post this so we don't need to worry about re-entrancy issues.
+  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
+      FROM_HERE,
+      base::BindOnce(&DecoderBufferTranscryptor::DecryptPendingBuffer,
+                     weak_this_));
+}
+
 void DecoderBufferTranscryptor::EnqueueBuffer(
     scoped_refptr<DecoderBuffer> buffer,
     VideoDecoder::DecodeCB decode_cb) {
@@ -87,6 +100,32 @@
     OnBufferTranscrypted(Decryptor::kSuccess, current_transcrypt_task_->buffer);
     return;
   }
+
+  // If we've already attached a secure buffer, don't do it again.
+  if (!current_transcrypt_task_->buffer->has_side_data() ||
+      !current_transcrypt_task_->buffer->side_data()->secure_handle) {
+    auto status =
+        decoder_->AttachSecureBuffer(current_transcrypt_task_->buffer);
+    if (status == CroStatus::Codes::kSecureBufferPoolEmpty) {
+      // We are currently out of secure buffers, so wait until this gets invoked
+      // again.
+      return;
+    } else if (!status.is_ok()) {
+      LOG(ERROR) << "Failure in attaching secure buffer";
+      OnBufferTranscrypted(Decryptor::kError, nullptr);
+      return;
+    }
+
+    if (current_transcrypt_task_->buffer->has_side_data() &&
+        current_transcrypt_task_->buffer->side_data()->secure_handle) {
+      // Wrap the callback so we can release the secure buffer when decoding is
+      // done.
+      current_transcrypt_task_->decode_done_cb = base::BindOnce(
+          &DecoderBufferTranscryptor::OnSecureBufferRelease, weak_this_,
+          current_transcrypt_task_->buffer->side_data()->secure_handle,
+          std::move(current_transcrypt_task_->decode_done_cb));
+    }
+  }
   transcrypt_pending_ = true;
   cdm_context_ref_->GetCdmContext()->GetDecryptor()->Decrypt(
       Decryptor::kVideo, current_transcrypt_task_->buffer,
@@ -150,4 +189,13 @@
     DecryptPendingBuffer();
 }
 
+void DecoderBufferTranscryptor::OnSecureBufferRelease(
+    uint64_t secure_handle,
+    VideoDecoder::DecodeCB decode_cb,
+    DecoderStatus status) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  decoder_->ReleaseSecureBuffer(secure_handle);
+  std::move(decode_cb).Run(status);
+}
+
 }  // namespace media
diff --git a/media/gpu/chromeos/decoder_buffer_transcryptor.h b/media/gpu/chromeos/decoder_buffer_transcryptor.h
index 6ead301d5..67ebc2fe 100644
--- a/media/gpu/chromeos/decoder_buffer_transcryptor.h
+++ b/media/gpu/chromeos/decoder_buffer_transcryptor.h
@@ -9,6 +9,7 @@
 
 #include "base/containers/queue.h"
 #include "base/functional/callback_forward.h"
+#include "base/memory/raw_ref.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "media/base/callback_registry.h"
@@ -21,6 +22,8 @@
 
 namespace media {
 
+class VideoDecoderMixin;
+
 // This is used to send buffers to the CdmContext's Decryptor prior to sending
 // them into the decoder for VideoDecoderPipeline. This is used in AMD
 // implementations for protected content where the Decryptor normalizes the
@@ -34,6 +37,7 @@
   // The |transcrypt_callback| is invoked upon transcryption of a buffer. It
   // will be called with a nullptr in the event of failure.
   DecoderBufferTranscryptor(CdmContext* cdm_context,
+                            VideoDecoderMixin& decoder,
                             OnBufferTranscryptedCB transcrypt_callback,
                             WaitingCB waiting_callback);
   DecoderBufferTranscryptor(const DecoderBufferTranscryptor&) = delete;
@@ -50,6 +54,11 @@
   // callbacks with the passed in |status|.
   void Reset(DecoderStatus status);
 
+  // Invoked when more secure buffers might be available. When we have pending
+  // tasks that are stalled due to secure buffer exhaustion, this is the
+  // mechanism by which we will retry them.
+  void SecureBuffersMayBeAvailable();
+
  private:
   // Transcrypt task holding single transcrypt request.
   struct TranscryptTask {
@@ -75,6 +84,11 @@
   void OnBufferTranscrypted(Decryptor::Status status,
                             scoped_refptr<DecoderBuffer> transcrypted_buffer);
 
+  void OnSecureBufferRelease(uint64_t secure_handle,
+                             VideoDecoder::DecodeCB decode_cb,
+                             DecoderStatus status);
+
+  const raw_ref<VideoDecoderMixin> decoder_;  // Not owned.
   OnBufferTranscryptedCB transcrypt_callback_;
   WaitingCB waiting_callback_;
 
diff --git a/media/gpu/chromeos/video_decoder_pipeline.cc b/media/gpu/chromeos/video_decoder_pipeline.cc
index d318b5ad0..4f4e0e6 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline.cc
@@ -180,6 +180,13 @@
   return false;
 }
 
+CroStatus VideoDecoderMixin::AttachSecureBuffer(
+    scoped_refptr<DecoderBuffer>& buffer) {
+  return CroStatus::Codes::kOk;
+}
+
+void VideoDecoderMixin::ReleaseSecureBuffer(uint64_t secure_handle) {}
+
 size_t VideoDecoderMixin::GetMaxOutputFramePoolSize() const {
   return std::numeric_limits<size_t>::max();
 }
@@ -414,10 +421,12 @@
   // instead.
   frame_converter_.reset();
   main_frame_pool_.reset();
-  decoder_.reset();
 #if BUILDFLAG(IS_CHROMEOS)
+  // We must release |buffer_transcryptor_| before the decoder because it holds
+  // a raw pointer to |decoder_|.
   buffer_transcryptor_.reset();
 #endif  // BUILDFLAG(IS_CHROMEOS)
+  decoder_.reset();
 }
 
 // static
@@ -650,7 +659,12 @@
     if (frame_converter_) {
       frame_converter_->set_unwrap_frame_cb(base::NullCallback());
     }
-    decoder_ = nullptr;
+#if BUILDFLAG(IS_CHROMEOS)
+    // We always need to destroy |buffer_transcryptor_| if it exists before
+    // |decoder_|.
+    buffer_transcryptor_.reset();
+#endif  // BUILDFLAG(IS_CHROMEOS)
+    decoder_.reset();
   }
   MEDIA_LOG(INFO, media_log_)
       << "VideoDecoderPipeline |decoder_| Initialize() successful";
@@ -662,12 +676,15 @@
       if (frame_converter_) {
         frame_converter_->set_unwrap_frame_cb(base::NullCallback());
       }
-      decoder_ = nullptr;
+      // We always need to destroy |buffer_transcryptor_| if it exists before
+      // |decoder_|.
+      buffer_transcryptor_.reset();
+      decoder_.reset();
       status = DecoderStatus::Codes::kUnsupportedEncryptionMode;
     } else {
       // We need to enable transcryption for protected content.
       buffer_transcryptor_ = std::make_unique<DecoderBufferTranscryptor>(
-          cdm_context,
+          cdm_context, *decoder_,
           base::BindRepeating(&VideoDecoderPipeline::OnBufferTranscrypted,
                               decoder_weak_this_),
           base::BindRepeating(&VideoDecoderPipeline::OnDecoderWaiting,
@@ -801,6 +818,13 @@
   DVLOGF(4);
   TRACE_EVENT1("media,gpu", "VideoDecoderPipeline::OnFrameDecoded", "timestamp",
                (frame ? frame->timestamp().InMicroseconds() : 0));
+
+#if BUILDFLAG(IS_CHROMEOS)
+  if (buffer_transcryptor_) {
+    buffer_transcryptor_->SecureBuffersMayBeAvailable();
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS)
+
   if (uses_oop_video_decoder_) {
     oop_decoder_can_read_without_stalling_.store(
         decoder_->CanReadWithoutStalling(), std::memory_order_seq_cst);
diff --git a/media/gpu/chromeos/video_decoder_pipeline.h b/media/gpu/chromeos/video_decoder_pipeline.h
index f1a03ecc..d0cc87fe 100644
--- a/media/gpu/chromeos/video_decoder_pipeline.h
+++ b/media/gpu/chromeos/video_decoder_pipeline.h
@@ -115,10 +115,19 @@
   virtual void ApplyResolutionChange() = 0;
 
   // For protected content implementations that require transcryption of the
-  // content before being sent into the HW decoders. (Currently only used by
-  // AMD). Default implementation returns false.
+  // content before being sent into the HW decoders. (Currently used by AMD and
+  // ARM). Default implementation returns false.
   virtual bool NeedsTranscryption();
 
+  // For protected content implementations that decrypt to a secure memory
+  // buffer (i.e. TrustZone on ARM), this is used to attach the appropriate
+  // handle for the secure buffer to the DecoderBuffer.
+  virtual CroStatus AttachSecureBuffer(scoped_refptr<DecoderBuffer>& buffer);
+  // Counterpart to AttachSecureBuffer, this should be invoked when the
+  // DecoderBuffer is no longer in use and the attached secure buffer can be
+  // released.
+  virtual void ReleaseSecureBuffer(uint64_t secure_handle);
+
   // Set the DMA coherency of the video decoder buffers. Only relevant for
   // V4L2.
   virtual void SetDmaIncoherentV4L2(bool incoherent) {}
diff --git a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
index 9dc6046..f68e25fd 100644
--- a/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
+++ b/media/gpu/chromeos/video_decoder_pipeline_unittest.cc
@@ -93,12 +93,15 @@
   MOCK_METHOD1(Reset, void(base::OnceClosure));
   MOCK_METHOD0(ApplyResolutionChange, void());
   MOCK_METHOD0(NeedsTranscryption, bool());
+  MOCK_METHOD1(AttachSecureBuffer, CroStatus(scoped_refptr<DecoderBuffer>&));
+  MOCK_METHOD1(ReleaseSecureBuffer, void(uint64_t));
   MOCK_CONST_METHOD0(GetDecoderType, VideoDecoderType());
 };
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 constexpr uint8_t kEncryptedData[] = {1, 8, 9};
 constexpr uint8_t kTranscryptedData[] = {9, 2, 4};
+constexpr uint64_t kFakeSecureHandle = 75;
 class MockChromeOsCdmContext : public chromeos::ChromeOsCdmContext {
  public:
   MockChromeOsCdmContext() : chromeos::ChromeOsCdmContext() {}
@@ -133,7 +136,7 @@
   CdmContext* GetCdmContext() override { return cdm_context_; }
 
  private:
-  CdmContext* cdm_context_;
+  raw_ptr<CdmContext> cdm_context_;
 };
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
@@ -473,6 +476,9 @@
   // First send in a DecoderBuffer.
   {
     InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(encrypted_buffer_))
+        .WillOnce(Return(CroStatus::Codes::kOk));
     EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
         .WillOnce([this](Decryptor::StreamType stream_type,
                          scoped_refptr<DecoderBuffer> encrypted,
@@ -523,8 +529,14 @@
       &kEncryptedData[1], std::size(kEncryptedData) - 1);
   // Send in a buffer, but don't invoke the Decrypt callback so it stays as
   // pending. Then send in 2 more buffers so they are in the queue.
-  EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
-      .Times(1);
+  {
+    InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(encrypted_buffer_))
+        .WillOnce(Return(CroStatus::Codes::kOk));
+    EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
+        .Times(1);
+  }
   decoder_->Decode(encrypted_buffer_,
                    base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                   base::Unretained(this)));
@@ -535,6 +547,8 @@
                    base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                   base::Unretained(this)));
   task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(
+      reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()));
   testing::Mock::VerifyAndClearExpectations(&decryptor_);
 
   // Now when we reset, we should see 3 decode callbacks occur as well as the
@@ -561,17 +575,25 @@
   // First send in a buffer, which will go to the decryptor and hold on to that
   // callback.
   Decryptor::DecryptCB saved_decrypt_cb;
-  EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
-      .WillOnce([&saved_decrypt_cb](Decryptor::StreamType stream_type,
-                                    scoped_refptr<DecoderBuffer> encrypted,
-                                    Decryptor::DecryptCB decrypt_cb) {
-        saved_decrypt_cb =
-            base::BindPostTaskToCurrentDefault(std::move(decrypt_cb));
-      });
+  {
+    InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(encrypted_buffer_))
+        .WillOnce(Return(CroStatus::Codes::kOk));
+    EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
+        .WillOnce([&saved_decrypt_cb](Decryptor::StreamType stream_type,
+                                      scoped_refptr<DecoderBuffer> encrypted,
+                                      Decryptor::DecryptCB decrypt_cb) {
+          saved_decrypt_cb =
+              base::BindPostTaskToCurrentDefault(std::move(decrypt_cb));
+        });
+  }
   decoder_->Decode(encrypted_buffer_,
                    base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                   base::Unretained(this)));
   task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(
+      reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()));
   testing::Mock::VerifyAndClearExpectations(&decryptor_);
 
   // Now we invoke the CDM callback to indicate there is a new key available.
@@ -583,6 +605,9 @@
   // that should go through decoding. This should not invoke the waiting CB.
   {
     InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(encrypted_buffer_))
+        .WillOnce(Return(CroStatus::Codes::kOk));
     EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
         .WillOnce([this](Decryptor::StreamType stream_type,
                          scoped_refptr<DecoderBuffer> encrypted,
@@ -603,6 +628,75 @@
   task_environment_.RunUntilIdle();
 }
 
+// Verifies that if we have a condition where we need to retry a pending
+// transcrypt task that it doesn't try to reacquire a secure buffer if it
+// already has one.
+TEST_F(VideoDecoderPipelineTest, RetryDoesntReattachSecureBuffer) {
+  InitializeForTranscrypt();
+  // First send in a buffer, which will go to the decryptor and hold on to that
+  // callback.
+  Decryptor::DecryptCB saved_decrypt_cb;
+  {
+    InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(encrypted_buffer_))
+        .WillOnce([](scoped_refptr<DecoderBuffer>& buffer) {
+          buffer->WritableSideData().secure_handle = kFakeSecureHandle;
+          return CroStatus::Codes::kOk;
+        });
+    EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
+        .WillOnce([&saved_decrypt_cb](Decryptor::StreamType stream_type,
+                                      scoped_refptr<DecoderBuffer> encrypted,
+                                      Decryptor::DecryptCB decrypt_cb) {
+          saved_decrypt_cb =
+              base::BindPostTaskToCurrentDefault(std::move(decrypt_cb));
+        });
+  }
+  decoder_->Decode(encrypted_buffer_,
+                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
+                                  base::Unretained(this)));
+  task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(
+      reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()));
+  testing::Mock::VerifyAndClearExpectations(&decryptor_);
+
+  // Now we invoke the CDM callback to indicate there is a new key available.
+  event_callbacks_.Notify(CdmContext::Event::kHasAdditionalUsableKey);
+  task_environment_.RunUntilIdle();
+
+  // Now we have the decryptor callback return with kNoKey which should then
+  // cause another call into the decryptor which we will have succeed and then
+  // that should go through decoding. This should not invoke the call to attach
+  // a secure buffer, but after it's done decoding it should invoke the call to
+  // release the secure buffer.
+  {
+    InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(_))
+        .Times(0);
+    EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
+        .WillOnce([this](Decryptor::StreamType stream_type,
+                         scoped_refptr<DecoderBuffer> encrypted,
+                         Decryptor::DecryptCB decrypt_cb) {
+          std::move(decrypt_cb).Run(Decryptor::kSuccess, transcrypted_buffer_);
+        });
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                Decode(transcrypted_buffer_, _))
+        .WillOnce([](scoped_refptr<DecoderBuffer> transcrypted,
+                     VideoDecoderMixin::DecodeCB decode_cb) {
+          std::move(decode_cb).Run(DecoderStatus::Codes::kOk);
+        });
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                ReleaseSecureBuffer(kFakeSecureHandle))
+        .Times(1);
+    EXPECT_CALL(*this,
+                OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kOk)));
+  }
+  EXPECT_CALL(*this, OnWaiting(_)).Times(0);
+  std::move(saved_decrypt_cb).Run(Decryptor::kNoKey, nullptr);
+  task_environment_.RunUntilIdle();
+}
+
 // Verifies that if we don't have the key during transcrypt, the WaitingCB is
 // invoked and then it retries again when we notify it of the new key.
 TEST_F(VideoDecoderPipelineTest, TranscryptNoKeyWaitRetry) {
@@ -611,6 +705,9 @@
   // is no key. This should also invoke the WaitingCB.
   {
     InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(encrypted_buffer_))
+        .WillOnce(Return(CroStatus::Codes::kOk));
     EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
         .WillOnce([](Decryptor::StreamType stream_type,
                      scoped_refptr<DecoderBuffer> encrypted,
@@ -623,6 +720,8 @@
                    base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
                                   base::Unretained(this)));
   task_environment_.RunUntilIdle();
+  testing::Mock::VerifyAndClearExpectations(
+      reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()));
   testing::Mock::VerifyAndClearExpectations(&decryptor_);
   testing::Mock::VerifyAndClearExpectations(this);
 
@@ -631,6 +730,9 @@
   // complete the decode operation.
   {
     InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(encrypted_buffer_))
+        .WillOnce(Return(CroStatus::Codes::kOk));
     EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
         .WillOnce([this](Decryptor::StreamType stream_type,
                          scoped_refptr<DecoderBuffer> encrypted,
@@ -654,6 +756,9 @@
   InitializeForTranscrypt();
   {
     InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(encrypted_buffer_))
+        .WillOnce(Return(CroStatus::Codes::kOk));
     EXPECT_CALL(decryptor_, Decrypt(Decryptor::kVideo, encrypted_buffer_, _))
         .WillOnce([](Decryptor::StreamType stream_type,
                      scoped_refptr<DecoderBuffer> encrypted,
@@ -668,6 +773,22 @@
                                   base::Unretained(this)));
   task_environment_.RunUntilIdle();
 }
+
+TEST_F(VideoDecoderPipelineTest, SecureBufferFailure) {
+  InitializeForTranscrypt();
+  {
+    InSequence sequence;
+    EXPECT_CALL(*reinterpret_cast<MockDecoder*>(GetUnderlyingDecoder()),
+                AttachSecureBuffer(encrypted_buffer_))
+        .WillOnce(Return(CroStatus::Codes::kUnableToAllocateSecureBuffer));
+    EXPECT_CALL(*this,
+                OnDecodeDone(MatchesStatusCode(DecoderStatus::Codes::kFailed)));
+  }
+  decoder_->Decode(encrypted_buffer_,
+                   base::BindOnce(&VideoDecoderPipelineTest::OnDecodeDone,
+                                  base::Unretained(this)));
+  task_environment_.RunUntilIdle();
+}
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 // Verifies the algorithm for choosing formats in PickDecoderOutputFormat works
diff --git a/mojo/public/tools/bindings/BUILD.gn b/mojo/public/tools/bindings/BUILD.gn
index 815d7d9..d7c2281 100644
--- a/mojo/public/tools/bindings/BUILD.gn
+++ b/mojo/public/tools/bindings/BUILD.gn
@@ -8,6 +8,7 @@
 action("precompile_templates") {
   sources = mojom_generator_sources
   sources += [
+    "$mojom_generator_root/generators/cpp_templates/cpp_macros.tmpl",
     "$mojom_generator_root/generators/cpp_templates/enum_macros.tmpl",
     "$mojom_generator_root/generators/cpp_templates/enum_serialization_declaration.tmpl",
     "$mojom_generator_root/generators/cpp_templates/interface_declaration.tmpl",
@@ -27,7 +28,6 @@
     "$mojom_generator_root/generators/cpp_templates/module-test-utils.h.tmpl",
     "$mojom_generator_root/generators/cpp_templates/module.cc.tmpl",
     "$mojom_generator_root/generators/cpp_templates/module.h.tmpl",
-    "$mojom_generator_root/generators/cpp_templates/namespace_macros.tmpl",
     "$mojom_generator_root/generators/cpp_templates/struct_data_view_declaration.tmpl",
     "$mojom_generator_root/generators/cpp_templates/struct_data_view_definition.tmpl",
     "$mojom_generator_root/generators/cpp_templates/struct_declaration.tmpl",
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/cpp_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/cpp_macros.tmpl
new file mode 100644
index 0000000..30c51159
--- /dev/null
+++ b/mojo/public/tools/bindings/generators/cpp_templates/cpp_macros.tmpl
@@ -0,0 +1,51 @@
+{# Opens a C++ namespace built from `namespaces` and `variant`.
+   - if `variant` is not supplied, or empty/false then only `namespaces`
+       is used.
+   - if an empty namespace would result, then nothing is emitted. #}
+{%- macro namespace_begin(namespaces, variant) %}
+{%- set full_namespace = namespaces|join("::") %}
+{%- if namespaces|length and variant %}
+{%-   set full_namespace = (full_namespace, variant)|join("::") %}
+{%- elif variant %}
+{%-   set full_namespace = variant %}
+{%- endif %}
+{%- if full_namespace %}
+namespace {{full_namespace}} {
+{%- endif %}
+{%- endmacro -%}
+
+{# Closes a C++ namespace using the same rules as namespace_begin() #}
+{%- macro namespace_end(namespaces, variant) %}
+{%- set full_namespace = namespaces|join("::") %}
+{%- if namespaces|length and variant %}
+{%-   set full_namespace = (full_namespace, variant)|join("::") %}
+{%- elif variant %}
+{%-   set full_namespace = variant %}
+{%- endif %}
+{%- if full_namespace %}
+}  // {{full_namespace}}
+{%- endif %}
+{%- endmacro -%}
+
+{# Creates a string path matching the module and variant, includes the
+ module name, and can be suffixed with '.h', '-forward.h' etc. #}
+{%- macro variant_path(path, variant) -%}
+{%- if variant -%}
+{%-   set variant_path = "%s-%s"|format(path, variant) -%}
+{%- else -%}
+{%-   set variant_path = path -%}
+{%- endif -%}
+{{variant_path}}
+{%- endmacro -%}
+
+{# Creates a string matching the file's path for include guards #}
+{%- macro include_guard(type, path, variant) -%}
+{%- set upper_path = variant_path(path, variant)
+ |upper|replace("/","_")|replace(".","_")|replace("-", "_") -%}
+{%- if type -%}
+{%- set header_guard = "%s_%s_H_"|format(upper_path, type) -%}
+{%- else -%}
+{%- set header_guard = "%s_H_"|format(upper_path) -%}
+{%- endif -%}
+{{header_guard}}
+{%- endmacro -%}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
index d85ad15..943cec9f 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-forward.h.tmpl
@@ -2,17 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- from 'namespace_macros.tmpl' import namespace_begin, namespace_end %}
+{%- from 'cpp_macros.tmpl' import
+  include_guard, namespace_begin, namespace_end %}
 
-{%- if variant -%}
-{%-   set variant_path = "%s-%s"|format(module.path, variant) -%}
-{%- else -%}
-{%-   set variant_path = module.path -%}
-{%- endif -%}
-
-{%- set header_guard = "%s_FORWARD_H_"|format(
-        variant_path|upper|replace("/","_")|replace(".","_")|
-            replace("-", "_")) %}
+{%- set header_guard = include_guard('FORWARD', module.path, variant) %}
 
 {%- macro kythe_annotation(name) %}
 {%- if enable_kythe_annotations %}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-import-headers.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-import-headers.h.tmpl
index fa2df99..e0f6e85 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-import-headers.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-import-headers.h.tmpl
@@ -2,27 +2,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- if variant -%}
-{%-   set variant_path = "%s-%s"|format(module.path, variant) -%}
-{%- else -%}
-{%-   set variant_path = module.path -%}
-{%- endif -%}
+{%- from 'cpp_macros.tmpl' import include_guard, variant_path %}
 
-{%- set header_guard = "%s_IMPORT_HEADERS_H_"|format(
-        variant_path|upper|replace("/","_")|replace(".","_")|
-            replace("-", "_")) %}
+{%- set header_guard = include_guard('IMPORT_HEADERS', module.path, variant) %}
 
 #ifndef {{header_guard}}
 #define {{header_guard}}
 
 {%- for import in imports %}
-{%-   if variant %}
-#include "{{"%s-%s.h"|format(import.path, variant)}}"
-#include "{{"%s-%s-import-headers.h"|format(import.path, variant)}}"
-{%-   else %}
-#include "{{import.path}}.h"
-#include "{{import.path}}-import-headers.h"
-{%-   endif %}
+#include "{{variant_path(import.path, variant)}}.h"
+#include "{{variant_path(import.path, variant)}}-import-headers.h"
 {%- endfor %}
 
 #endif  // {{header_guard}}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
index d1688f1..2589cd1 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-params-data.h.tmpl
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- set header_guard = "%s_PARAMS_DATA_H_"|format(
-        module.path|upper|replace("/","_")|replace(".","_")|
-            replace("-", "_")) %}
+{%- from 'cpp_macros.tmpl' import
+  include_guard, namespace_begin, namespace_end %}
+
+{%- set header_guard = include_guard('PARAMS_DATA', module.path, variant) %}
 
 #ifndef {{header_guard}}
 #define {{header_guard}}
@@ -21,9 +22,7 @@
 class ValidationContext;
 }
 
-{%- for namespace in namespaces_as_array %}
-namespace {{namespace}} {
-{%- endfor %}
+{{namespace_begin(namespaces_as_array)}}
 namespace internal {
 
 {#--- Interface parameter definitions #}
@@ -63,9 +62,7 @@
 {%-   endfor %}
 {%- endfor %}
 
-{%- for namespace in namespaces_as_array|reverse %}
-}  // namespace {{namespace}}
-{%- endfor %}
+{{namespace_end(namespaces_as_array)}}
 
 #if defined(__clang__)
 #pragma clang diagnostic pop
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
index 1791c37..c57d8a8 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-shared-internal.h.tmpl
@@ -2,9 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- set header_guard = "%s_SHARED_INTERNAL_H_"|format(
-        module.path|upper|replace("/","_")|replace(".","_")|
-            replace("-", "_")) %}
+{%- from 'cpp_macros.tmpl' import
+  include_guard, namespace_begin, namespace_end %}
+
+{%- set header_guard = include_guard("SHARED_INTERNAL", module.path) %}
 
 #ifndef {{header_guard}}
 #define {{header_guard}}
@@ -41,9 +42,7 @@
 }
 }
 
-{%- for namespace in namespaces_as_array %}
-namespace {{namespace}} {
-{%- endfor %}
+{{namespace_begin(namespaces_as_array)}}
 namespace internal {
 
 {#--- Internal forward declarations #}
@@ -89,8 +88,6 @@
 #pragma pack(pop)
 
 }  // namespace internal
-{%- for namespace in namespaces_as_array|reverse %}
-}  // namespace {{namespace}}
-{%- endfor %}
+{{namespace_end(namespaces_as_array)}}
 
 #endif  // {{header_guard}}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-shared-message-ids.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-shared-message-ids.h.tmpl
index 1229ffb..f3e2d31 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-shared-message-ids.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-shared-message-ids.h.tmpl
@@ -2,19 +2,17 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- set header_guard = "%s_SHARED_MESSAGE_IDS_H_"|format(
-        module.path|upper|replace("/","_")|replace(".","_")|
-            replace("-", "_")) %}
+{%- from 'cpp_macros.tmpl' import
+  include_guard, namespace_begin, namespace_end %}
+
+{%- set header_guard = include_guard("SHARED_MESSAGE_IDS", module.path) %}
 
 #ifndef {{header_guard}}
 #define {{header_guard}}
 
 #include <stdint.h>
 
-{%- for namespace in namespaces_as_array %}
-namespace {{namespace}} {
-{%- endfor %}
-
+{{namespace_begin(namespaces_as_array)}}
 namespace internal {
 
 {% for interface in interfaces -%}
@@ -28,8 +26,6 @@
 {%- endfor %}
 
 }  // namespace internal
-{%- for namespace in namespaces_as_array|reverse %}
-}  // namespace {{namespace}}
-{%- endfor %}
+{{namespace_end(namespaces_as_array)}}
 
 #endif  // {{header_guard}}
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
index 4a6ef0b..2eded47 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-shared.h.tmpl
@@ -2,11 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- from 'namespace_macros.tmpl' import namespace_begin, namespace_end %}
+{%- from 'cpp_macros.tmpl' import
+  namespace_begin, namespace_end, include_guard %}
 
-{%- set header_guard = "%s_SHARED_H_"|format(
-        module.path|upper|replace("/","_")|replace(".","_")|
-            replace("-", "_")) %}
+{%- set header_guard = include_guard("SHARED", module.path) %}
 
 {%- macro mojom_type_traits(kind) %}
 template <>
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module-test-utils.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module-test-utils.h.tmpl
index 1da8ab78..e3ce589 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module-test-utils.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module-test-utils.h.tmpl
@@ -2,22 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- from 'namespace_macros.tmpl' import namespace_begin, namespace_end %}
+{%- from 'cpp_macros.tmpl' import
+    namespace_begin, namespace_end, include_guard, variant_path %}
 
-{%- if variant -%}
-{%-   set variant_path = "%s-%s"|format(module.path, variant) -%}
-{%- else -%}
-{%-   set variant_path = module.path -%}
-{%- endif -%}
-
-{%- set header_guard = "%s_TEST_UTILS_H_"|format(
-        variant_path|upper|replace("/","_")|replace(".","_")|
-            replace("-", "_")) %}
+{%- set header_guard = include_guard("TEST_UTILS", module.path, variant) %}
 
 #ifndef {{header_guard}}
 #define {{header_guard}}
 
-#include "{{variant_path}}.h"
+#include "{{variant_path(module.path, variant)}}.h"
 
 {%- if export_header %}
 #include "{{export_header}}"
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
index f19a9728..b3bbbab 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.cc.tmpl
@@ -2,20 +2,15 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- from 'namespace_macros.tmpl' import namespace_begin, namespace_end %}
-
-{%- if variant -%}
-{%-   set variant_path = "%s-%s"|format(module.path, variant) -%}
-{%- else -%}
-{%-   set variant_path = module.path -%}
-{%- endif %}
+{%- from 'cpp_macros.tmpl' import
+    namespace_begin, namespace_end, variant_path %}
 
 #if defined(__clang__)
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wunused-private-field"
 #endif
 
-#include "{{variant_path}}.h"
+#include "{{variant_path(module.path, variant)}}.h"
 
 #include <math.h>
 #include <stdint.h>
@@ -44,8 +39,8 @@
 #include "{{module.path}}-params-data.h"
 #include "{{module.path}}-shared-message-ids.h"
 
-#include "{{variant_path}}-import-headers.h"
-#include "{{variant_path}}-test-utils.h"
+#include "{{variant_path(module.path, variant)}}-import-headers.h"
+#include "{{variant_path(module.path, variant)}}-test-utils.h"
 
 {%- if for_blink %}
 #include "mojo/public/cpp/bindings/lib/wtf_serialization.h"
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
index 8803256..bc0c1ace 100644
--- a/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
+++ b/mojo/public/tools/bindings/generators/cpp_templates/module.h.tmpl
@@ -2,17 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-{%- from 'namespace_macros.tmpl' import namespace_begin, namespace_end %}
+{%- from 'cpp_macros.tmpl' import
+ namespace_begin, namespace_end, include_guard, variant_path %}
 
-{%- if variant -%}
-{%-   set variant_path = "%s-%s"|format(module.path, variant) -%}
-{%- else -%}
-{%-   set variant_path = module.path -%}
-{%- endif -%}
-
-{%- set header_guard = "%s_H_"|format(
-        variant_path|upper|replace("/","_")|replace(".","_")|
-            replace("-", "_")) %}
+{%- set header_guard = include_guard('', module.path, variant) %}
 
 {%- macro kythe_annotation(name) %}
 {%- if enable_kythe_annotations %}
@@ -45,21 +38,13 @@
 #include "third_party/perfetto/include/perfetto/tracing/traced_value_forward.h"
 
 #include "{{module.path}}-shared.h"
-#include "{{variant_path}}-forward.h"
+#include "{{variant_path(module.path, variant)}}-forward.h"
 
 {%- for import in imports %}
 {%-   if import|is_full_header_required_for_import %}
-{%-     if variant %}
-#include "{{"%s-%s.h"|format(import.path, variant)}}"
-{%-     else %}
-#include "{{import.path}}.h"
-{%-     endif %}
+#include "{{variant_path(import.path, variant)}}.h"
 {%-   else %}
-{%-     if variant %}
-#include "{{"%s-%s-forward.h"|format(import.path, variant)}}"
-{%-     else %}
-#include "{{import.path}}-forward.h"
-{%-     endif %}
+#include "{{variant_path(import.path, variant)}}-forward.h"
 {%-   endif %}
 {%- endfor %}
 
diff --git a/mojo/public/tools/bindings/generators/cpp_templates/namespace_macros.tmpl b/mojo/public/tools/bindings/generators/cpp_templates/namespace_macros.tmpl
deleted file mode 100644
index 5a1e9b0..0000000
--- a/mojo/public/tools/bindings/generators/cpp_templates/namespace_macros.tmpl
+++ /dev/null
@@ -1,28 +0,0 @@
-{# Opens a C++ namespace built from `namespaces` and `variant`.
-   - if `variant` is not supplied, or empty/false then only `namespaces`
-       is used.
-   - if an empty namespace would result, then nothing is emitted. #}
-{%- macro namespace_begin(namespaces, variant) %}
-{%- set full_namespace = namespaces|join("::") %}
-{%- if namespaces|length and variant %}
-{%-   set full_namespace = (full_namespace, variant)|join("::") %}
-{%- elif variant %}
-{%-   set full_namespace = variant %}
-{%- endif %}
-{%- if full_namespace %}
-namespace {{full_namespace}} {
-{%- endif %}
-{%- endmacro -%}
-
-{# Closes a C++ namespace using the same rules as namespace_begin() #}
-{%- macro namespace_end(namespaces, variant) %}
-{%- set full_namespace = namespaces|join("::") %}
-{%- if namespaces|length and variant %}
-{%-   set full_namespace = (full_namespace, variant)|join("::") %}
-{%- elif variant %}
-{%-   set full_namespace = variant %}
-{%- endif %}
-{%- if full_namespace %}
-}  // {{full_namespace}}
-{%- endif %}
-{%- endmacro -%}
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins
index c92ab9e..f7078bb 100644
--- a/net/http/transport_security_state_static.pins
+++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@
 #   hash function for preloaded entries again (we have already done so once).
 #
 
-# Last updated: 2023-08-24 12:54 UTC
+# Last updated: 2023-08-25 12:59 UTC
 PinsListTimestamp
-1692881695
+1692968350
 
 TestSPKI
 sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json
index 35b9b00..f734e8b6 100644
--- a/net/http/transport_security_state_static_pins.json
+++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@
 // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets'
 // refer to, and the timestamp at which the pins list was last updated.
 //
-// Last updated: 2023-08-24 12:54 UTC
+// Last updated: 2023-08-25 12:59 UTC
 //
 {
   "pinsets": [
diff --git a/services/accessibility/android/ax_tree_source_android.h b/services/accessibility/android/ax_tree_source_android.h
index de3a897..5620086 100644
--- a/services/accessibility/android/ax_tree_source_android.h
+++ b/services/accessibility/android/ax_tree_source_android.h
@@ -30,7 +30,8 @@
 class AXTreeSourceAndroidTest;
 
 using AXTreeAndroidSerializer =
-    ui::AXTreeSerializer<AccessibilityInfoDataWrapper*>;
+    ui::AXTreeSerializer<AccessibilityInfoDataWrapper*,
+                         std::vector<AccessibilityInfoDataWrapper*>>;
 
 // This class represents the accessibility tree from the focused ARC window.
 class AXTreeSourceAndroid
diff --git a/services/device/public/cpp/geolocation/BUILD.gn b/services/device/public/cpp/geolocation/BUILD.gn
index e31fa58..ef1e79a 100644
--- a/services/device/public/cpp/geolocation/BUILD.gn
+++ b/services/device/public/cpp/geolocation/BUILD.gn
@@ -37,10 +37,11 @@
   }
 
   public_deps = [
-    ":buildflags",
     "//base",
     "//services/device/public/mojom",
     "//services/device/public/mojom:geolocation_internals",
     "//third_party/abseil-cpp:absl",
   ]
+
+  deps = [ ":buildflags" ]
 }
diff --git a/services/device/public/cpp/geolocation/geolocation_manager.h b/services/device/public/cpp/geolocation/geolocation_manager.h
index a9be30e2..206bb34 100644
--- a/services/device/public/cpp/geolocation/geolocation_manager.h
+++ b/services/device/public/cpp/geolocation/geolocation_manager.h
@@ -35,10 +35,6 @@
   // Sets the global instance of the Geolocation Manager.
   static void SetInstance(std::unique_ptr<GeolocationManager> manager);
 
-  GeolocationManager(const GeolocationManager&) = delete;
-  GeolocationManager& operator=(const GeolocationManager&) = delete;
-  virtual ~GeolocationManager();
-
   void TrackGeolocationAttempted();
   void TrackGeolocationRelinquished();
   void RequestSystemPermission();
@@ -49,7 +45,6 @@
   // operation systems for which we don't support system-level geolocation. A
   // separate class (as opposed to nullptr) makes sure no unsupported calls are
   // made in such context.
-
 };  // class GeolocationManager
 
 #else
@@ -75,6 +70,9 @@
 
   explicit GeolocationManager(
       std::unique_ptr<SystemGeolocationSource> system_geolocation_source);
+  GeolocationManager(const GeolocationManager&) = delete;
+  GeolocationManager& operator=(const GeolocationManager&) = delete;
+  virtual ~GeolocationManager();
 
   // Synchronously retrieves the current system permission status.
   LocationSystemPermissionStatus GetSystemPermission() const;
diff --git a/services/device/public/cpp/test/fake_geolocation_manager.h b/services/device/public/cpp/test/fake_geolocation_manager.h
index 1b592f38..400368e 100644
--- a/services/device/public/cpp/test/fake_geolocation_manager.h
+++ b/services/device/public/cpp/test/fake_geolocation_manager.h
@@ -15,7 +15,6 @@
   ~FakeGeolocationManager() override = default;
 
   void SetSystemPermission(LocationSystemPermissionStatus status);
-
 #if BUILDFLAG(IS_APPLE)
   bool watching_position();
   void FakePositionUpdated(device::mojom::GeopositionResultPtr result);
diff --git a/skia/BUILD.gn b/skia/BUILD.gn
index cf225d6..c8a80ba5 100644
--- a/skia/BUILD.gn
+++ b/skia/BUILD.gn
@@ -622,15 +622,6 @@
     public_deps += [ ":skia_graphite_public" ]
     deps += [ ":skia_graphite_private" ]
 
-    # Even though we only use Dawn and Metal with Graphite, we need to build the
-    # Ganesh sources, since both Ganesh and Graphite use the same defines for
-    # enabling backends, otherwise we'll get undefined symbol errors in Ganesh.
-    if (skia_use_dawn) {
-      # It's ok to not make these public since they aren't meant to be used
-      # outside of Skia.
-      sources += skia_gpu_dawn_public
-      sources += skia_gpu_dawn_private
-    }
     if (skia_use_metal) {
       deps += [ ":skia_ganesh_metal" ]
     }
diff --git a/testing/buildbot/chromium.angle.json b/testing/buildbot/chromium.angle.json
index 1ab48a8..fc774e3 100644
--- a/testing/buildbot/chromium.angle.json
+++ b/testing/buildbot/chromium.angle.json
@@ -61,7 +61,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_profile_data": true,
@@ -90,7 +90,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -115,7 +115,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_profile_data": true,
@@ -144,7 +144,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -169,7 +169,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_profile_data": true,
@@ -198,7 +198,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -223,7 +223,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_profile_data": true,
@@ -252,7 +252,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 684ba59..a54a893 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -4827,9 +4827,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -4839,8 +4839,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -4974,9 +4974,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -4986,8 +4986,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -5106,9 +5106,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -5118,8 +5118,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.clang.json b/testing/buildbot/chromium.clang.json
index 7675fdf..35bc1f23 100644
--- a/testing/buildbot/chromium.clang.json
+++ b/testing/buildbot/chromium.clang.json
@@ -2042,7 +2042,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -2068,7 +2068,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -2110,7 +2110,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -2138,7 +2138,7 @@
           "expiration": 21600,
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             }
           ],
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 00d63f9..160a94d 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -9111,7 +9111,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -9138,7 +9138,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9161,7 +9161,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -9188,7 +9188,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9211,7 +9211,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -9238,7 +9238,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9261,7 +9261,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -9288,7 +9288,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9311,7 +9311,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9338,7 +9338,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9361,7 +9361,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9388,7 +9388,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9411,7 +9411,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9438,7 +9438,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9461,7 +9461,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9488,7 +9488,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9511,7 +9511,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9538,7 +9538,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9561,7 +9561,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9588,7 +9588,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9611,7 +9611,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9638,7 +9638,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9661,7 +9661,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9688,7 +9688,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9711,7 +9711,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9738,7 +9738,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9761,7 +9761,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9788,7 +9788,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9811,7 +9811,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -9838,7 +9838,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9861,7 +9861,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -9888,7 +9888,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9911,7 +9911,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -9938,7 +9938,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9961,7 +9961,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -9988,7 +9988,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10011,7 +10011,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -10038,7 +10038,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10061,7 +10061,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -10088,7 +10088,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10111,7 +10111,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -10138,7 +10138,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10161,7 +10161,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -10188,7 +10188,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10211,7 +10211,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -10238,7 +10238,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10261,7 +10261,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10288,7 +10288,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10311,7 +10311,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10338,7 +10338,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10361,7 +10361,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10388,7 +10388,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10411,7 +10411,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10438,7 +10438,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10461,7 +10461,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10488,7 +10488,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10511,7 +10511,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10538,7 +10538,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10561,7 +10561,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10588,7 +10588,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10611,7 +10611,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10638,7 +10638,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10661,7 +10661,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10688,7 +10688,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10711,7 +10711,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10738,7 +10738,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10761,7 +10761,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -10788,7 +10788,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10811,7 +10811,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -10838,7 +10838,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10861,7 +10861,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -10888,7 +10888,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10911,7 +10911,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -10938,7 +10938,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10961,7 +10961,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -10988,7 +10988,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11011,7 +11011,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -11038,7 +11038,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11061,7 +11061,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -11088,7 +11088,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11111,7 +11111,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -11138,7 +11138,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11161,7 +11161,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -11188,7 +11188,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11211,7 +11211,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11238,7 +11238,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11261,7 +11261,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11288,7 +11288,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11311,7 +11311,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11338,7 +11338,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11361,7 +11361,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11388,7 +11388,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11411,7 +11411,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11438,7 +11438,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11461,7 +11461,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11488,7 +11488,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11511,7 +11511,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11538,7 +11538,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11561,7 +11561,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11588,7 +11588,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11611,7 +11611,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11638,7 +11638,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11661,7 +11661,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11688,7 +11688,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11711,7 +11711,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -11738,7 +11738,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11761,7 +11761,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -11788,7 +11788,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11811,7 +11811,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -11838,7 +11838,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11861,7 +11861,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -11888,7 +11888,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11911,7 +11911,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -11938,7 +11938,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11961,7 +11961,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -11989,7 +11989,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12012,7 +12012,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12040,7 +12040,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12063,7 +12063,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12091,7 +12091,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12114,7 +12114,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12142,7 +12142,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12165,7 +12165,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12193,7 +12193,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12216,7 +12216,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12244,7 +12244,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12267,7 +12267,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12295,7 +12295,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12318,7 +12318,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12346,7 +12346,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12369,7 +12369,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12399,7 +12399,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12423,7 +12423,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12453,7 +12453,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12477,7 +12477,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12507,7 +12507,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12531,7 +12531,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12561,7 +12561,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12585,7 +12585,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12615,7 +12615,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12639,7 +12639,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12669,7 +12669,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12693,7 +12693,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12723,7 +12723,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12747,7 +12747,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12777,7 +12777,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12801,7 +12801,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12831,7 +12831,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12855,7 +12855,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12885,7 +12885,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12909,7 +12909,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12939,7 +12939,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12963,7 +12963,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12993,7 +12993,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13017,7 +13017,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13047,7 +13047,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13071,7 +13071,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13101,7 +13101,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13125,7 +13125,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13155,7 +13155,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13179,7 +13179,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13209,7 +13209,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13233,7 +13233,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13261,7 +13261,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13285,7 +13285,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13313,7 +13313,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13337,7 +13337,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13365,7 +13365,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13389,7 +13389,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13417,7 +13417,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13441,7 +13441,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13469,7 +13469,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13493,7 +13493,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13521,7 +13521,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13545,7 +13545,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13573,7 +13573,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13597,7 +13597,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13625,7 +13625,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13649,7 +13649,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13677,7 +13677,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13700,7 +13700,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13728,7 +13728,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13751,7 +13751,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13779,7 +13779,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13802,7 +13802,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13830,7 +13830,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13853,7 +13853,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13881,7 +13881,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13904,7 +13904,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13932,7 +13932,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13955,7 +13955,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13983,7 +13983,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14006,7 +14006,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -14034,7 +14034,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14057,7 +14057,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -14087,7 +14087,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14111,7 +14111,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -14141,7 +14141,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14165,7 +14165,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -14195,7 +14195,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14219,7 +14219,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -14249,7 +14249,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14273,7 +14273,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -14303,7 +14303,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14327,7 +14327,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -14357,7 +14357,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14381,7 +14381,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -14411,7 +14411,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14435,7 +14435,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -14465,7 +14465,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14489,7 +14489,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14516,7 +14516,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14539,7 +14539,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14566,7 +14566,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14589,7 +14589,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14616,7 +14616,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14639,7 +14639,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14666,7 +14666,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14689,7 +14689,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14716,7 +14716,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14739,7 +14739,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14766,7 +14766,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14789,7 +14789,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14816,7 +14816,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14839,7 +14839,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14866,7 +14866,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14889,7 +14889,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14916,7 +14916,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14939,7 +14939,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14966,7 +14966,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14989,7 +14989,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -15016,7 +15016,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15039,7 +15039,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15067,7 +15067,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15091,7 +15091,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15119,7 +15119,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15143,7 +15143,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15171,7 +15171,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15195,7 +15195,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15223,7 +15223,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15247,7 +15247,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15275,7 +15275,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15299,7 +15299,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15327,7 +15327,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15351,7 +15351,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15379,7 +15379,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15403,7 +15403,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15431,7 +15431,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15455,7 +15455,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -15482,7 +15482,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15505,7 +15505,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -15532,7 +15532,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15555,7 +15555,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -15582,7 +15582,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15605,7 +15605,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -15632,7 +15632,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15655,7 +15655,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -15682,7 +15682,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15706,7 +15706,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -15733,7 +15733,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15757,7 +15757,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -15784,7 +15784,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15808,7 +15808,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -15835,7 +15835,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15859,7 +15859,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -15886,7 +15886,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15909,7 +15909,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -15936,7 +15936,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15959,7 +15959,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -15986,7 +15986,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16009,7 +16009,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -16036,7 +16036,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16059,7 +16059,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16087,7 +16087,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16110,7 +16110,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16138,7 +16138,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16161,7 +16161,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16189,7 +16189,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16212,7 +16212,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16240,7 +16240,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16263,7 +16263,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16291,7 +16291,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16314,7 +16314,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16342,7 +16342,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16365,7 +16365,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16393,7 +16393,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16416,7 +16416,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16444,7 +16444,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16467,7 +16467,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -16494,7 +16494,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16517,7 +16517,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -16544,7 +16544,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16567,7 +16567,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -16594,7 +16594,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16617,7 +16617,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -16644,7 +16644,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16667,7 +16667,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -16694,7 +16694,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16717,7 +16717,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -16744,7 +16744,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16767,7 +16767,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -16794,7 +16794,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16817,7 +16817,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -16844,7 +16844,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16867,7 +16867,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -16894,7 +16894,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16917,7 +16917,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -16944,7 +16944,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16967,7 +16967,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -16994,7 +16994,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17017,7 +17017,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -17044,7 +17044,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17067,7 +17067,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -17094,7 +17094,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17117,7 +17117,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -17144,7 +17144,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17167,7 +17167,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -17194,7 +17194,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17217,7 +17217,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -17245,7 +17245,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17268,7 +17268,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -17296,7 +17296,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17319,7 +17319,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -17347,7 +17347,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17370,7 +17370,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -17398,7 +17398,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17421,7 +17421,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -17449,7 +17449,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17472,7 +17472,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -17500,7 +17500,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17523,7 +17523,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -17551,7 +17551,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17574,7 +17574,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -17602,7 +17602,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17625,7 +17625,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -17652,7 +17652,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17675,7 +17675,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -17702,7 +17702,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17725,7 +17725,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -17752,7 +17752,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17775,7 +17775,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -17802,7 +17802,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17825,7 +17825,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -17852,7 +17852,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17875,7 +17875,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -17902,7 +17902,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17925,7 +17925,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -17952,7 +17952,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17975,7 +17975,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -18002,7 +18002,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18025,7 +18025,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -18052,7 +18052,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18075,7 +18075,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -18102,7 +18102,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18125,7 +18125,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -18152,7 +18152,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18175,7 +18175,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18202,7 +18202,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18225,7 +18225,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18252,7 +18252,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18275,7 +18275,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18302,7 +18302,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18325,7 +18325,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18352,7 +18352,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18375,7 +18375,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18402,7 +18402,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18425,7 +18425,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18452,7 +18452,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18475,7 +18475,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18502,7 +18502,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18525,7 +18525,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18552,7 +18552,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18575,7 +18575,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18602,7 +18602,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18625,7 +18625,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18652,7 +18652,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18675,7 +18675,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -18702,7 +18702,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18725,7 +18725,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -18752,7 +18752,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18775,7 +18775,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -18802,7 +18802,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18825,7 +18825,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -18852,7 +18852,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18875,7 +18875,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -18902,7 +18902,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18925,7 +18925,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -18952,7 +18952,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18975,7 +18975,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -19002,7 +19002,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19025,7 +19025,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -19052,7 +19052,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19075,7 +19075,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -19102,7 +19102,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19125,7 +19125,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -19152,7 +19152,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19175,7 +19175,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -19202,7 +19202,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19225,7 +19225,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -19252,7 +19252,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19275,7 +19275,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -19302,7 +19302,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19325,7 +19325,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -19352,7 +19352,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19375,7 +19375,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -19402,7 +19402,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19425,7 +19425,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -19452,7 +19452,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19475,7 +19475,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -19502,7 +19502,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19525,7 +19525,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -19552,7 +19552,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19575,7 +19575,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -19602,7 +19602,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19625,7 +19625,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -19652,7 +19652,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19675,7 +19675,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -19702,7 +19702,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19725,7 +19725,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -19752,7 +19752,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19775,7 +19775,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -19802,7 +19802,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19825,7 +19825,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -19852,7 +19852,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19875,7 +19875,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -19902,7 +19902,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19925,7 +19925,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -19952,7 +19952,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19975,7 +19975,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -20002,7 +20002,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20025,7 +20025,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -20052,7 +20052,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20075,7 +20075,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -20102,7 +20102,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20125,7 +20125,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -20152,7 +20152,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20175,7 +20175,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -20202,7 +20202,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20225,7 +20225,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -20252,7 +20252,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20275,7 +20275,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -20302,7 +20302,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20325,7 +20325,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -20352,7 +20352,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20375,7 +20375,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -20402,7 +20402,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20425,7 +20425,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20452,7 +20452,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20475,7 +20475,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20502,7 +20502,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20525,7 +20525,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20552,7 +20552,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20575,7 +20575,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20602,7 +20602,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20625,7 +20625,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20652,7 +20652,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20675,7 +20675,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20702,7 +20702,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20725,7 +20725,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20752,7 +20752,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20775,7 +20775,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20802,7 +20802,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20825,7 +20825,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20852,7 +20852,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20875,7 +20875,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20902,7 +20902,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20925,7 +20925,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -20952,7 +20952,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20975,7 +20975,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -21002,7 +21002,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21025,7 +21025,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -21052,7 +21052,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21075,7 +21075,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -21102,7 +21102,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21125,7 +21125,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -21152,7 +21152,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -25055,9 +25055,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25067,8 +25067,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -25202,9 +25202,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25214,8 +25214,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -25334,9 +25334,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -25346,8 +25346,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 19464c3..da70a422 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -46,11 +46,6 @@
       "all"
     ]
   },
-  "Linux Builder (j-500) (reclient)": {
-    "additional_compile_targets": [
-      "all"
-    ]
-  },
   "Linux Viz": {
     "additional_compile_targets": [
       "all"
@@ -4739,6 +4734,54 @@
           "15a5229h",
           "--xctest"
         ],
+        "isolate_name": "content_nocompile_tests",
+        "merge": {
+          "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
+        },
+        "name": "content_nocompile_tests iPhone 14 17.0",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "cipd_packages": [
+            {
+              "cipd_package": "infra/tools/mac_toolchain/${platform}",
+              "location": ".",
+              "revision": "git_revision:59ddedfe3849abf560cbe0b41bb8e431041cd2bb"
+            }
+          ],
+          "dimensions": {
+            "cpu": "arm64",
+            "os": "Mac-13.4"
+          },
+          "named_caches": [
+            {
+              "name": "xcode_ios_15a5229h",
+              "path": "Xcode.app"
+            },
+            {
+              "name": "runtime_ios_17_0",
+              "path": "Runtime-ios-17.0"
+            }
+          ],
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test_id_prefix": "ninja://content/test:content_nocompile_tests/",
+        "variant_id": "iPhone 14 17.0"
+      },
+      {
+        "args": [
+          "--platform",
+          "iPhone 14",
+          "--version",
+          "17.0",
+          "--out-dir",
+          "${ISOLATED_OUTDIR}",
+          "--xcode-build-version",
+          "15a5229h",
+          "--xctest"
+        ],
         "isolate_name": "content_unittests",
         "merge": {
           "script": "//testing/merge_scripts/standard_isolated_script_merge.py"
@@ -6469,7 +6512,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6498,7 +6541,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6520,7 +6563,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6549,7 +6592,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6571,7 +6614,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6600,7 +6643,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6623,7 +6666,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6652,7 +6695,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6675,7 +6718,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6704,7 +6747,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6727,7 +6770,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6756,7 +6799,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6779,7 +6822,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6808,7 +6851,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6831,7 +6874,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6860,7 +6903,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6883,7 +6926,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6912,7 +6955,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6934,7 +6977,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -6963,7 +7006,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -6985,7 +7028,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -7014,7 +7057,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7037,7 +7080,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -7066,7 +7109,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7089,7 +7132,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -7118,7 +7161,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7141,7 +7184,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -7170,7 +7213,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7193,7 +7236,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -7222,7 +7265,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7244,7 +7287,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -7273,7 +7316,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7295,7 +7338,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -7324,7 +7367,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7346,7 +7389,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--extra-app-args=--disable-field-trial-config"
@@ -7375,7 +7418,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7404,7 +7447,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -7430,7 +7473,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7452,7 +7495,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -7478,7 +7521,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7500,7 +7543,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -7526,7 +7569,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7548,7 +7591,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -7574,7 +7617,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7596,7 +7639,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -7622,7 +7665,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7644,7 +7687,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -7670,7 +7713,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7692,7 +7735,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -7718,7 +7761,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7740,7 +7783,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -7766,7 +7809,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7788,7 +7831,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -7814,7 +7857,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7836,7 +7879,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -7862,7 +7905,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7884,7 +7927,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -7910,7 +7953,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7932,7 +7975,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -7958,7 +8001,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7980,7 +8023,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -8006,7 +8049,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8028,7 +8071,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -8054,7 +8097,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8076,7 +8119,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8102,7 +8145,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8124,7 +8167,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8150,7 +8193,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8172,7 +8215,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8198,7 +8241,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8220,7 +8263,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8246,7 +8289,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8268,7 +8311,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8294,7 +8337,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8316,7 +8359,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8342,7 +8385,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8364,7 +8407,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8390,7 +8433,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8412,7 +8455,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8438,7 +8481,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8460,7 +8503,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -8486,7 +8529,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8508,7 +8551,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -8534,7 +8577,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8556,7 +8599,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -8582,7 +8625,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8604,7 +8647,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -8630,7 +8673,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8652,7 +8695,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8678,7 +8721,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8700,7 +8743,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8726,7 +8769,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8748,7 +8791,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8774,7 +8817,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8796,7 +8839,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8822,7 +8865,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8844,7 +8887,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8870,7 +8913,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8892,7 +8935,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8918,7 +8961,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8940,7 +8983,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8966,7 +9009,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8988,7 +9031,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -9014,7 +9057,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9036,7 +9079,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -9062,7 +9105,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9084,7 +9127,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -9110,7 +9153,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9132,7 +9175,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9161,7 +9204,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9183,7 +9226,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9212,7 +9255,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9234,7 +9277,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9263,7 +9306,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9286,7 +9329,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9315,7 +9358,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9338,7 +9381,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9367,7 +9410,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9390,7 +9433,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9419,7 +9462,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9442,7 +9485,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9471,7 +9514,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9494,7 +9537,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9523,7 +9566,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9546,7 +9589,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9575,7 +9618,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9598,7 +9641,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9627,7 +9670,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9650,7 +9693,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9679,7 +9722,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9702,7 +9745,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9731,7 +9774,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9754,7 +9797,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9783,7 +9826,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9806,7 +9849,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9835,7 +9878,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9858,7 +9901,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9887,7 +9930,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9909,7 +9952,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9938,7 +9981,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9960,7 +10003,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -9989,7 +10032,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10012,7 +10055,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -10041,7 +10084,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10064,7 +10107,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -10090,7 +10133,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10112,7 +10155,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -10138,7 +10181,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10160,7 +10203,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -10186,7 +10229,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10208,7 +10251,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -10234,7 +10277,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10256,7 +10299,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -10282,7 +10325,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10304,7 +10347,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -10330,7 +10373,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10352,7 +10395,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -10378,7 +10421,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10400,7 +10443,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -10426,7 +10469,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10448,7 +10491,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -10477,7 +10520,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10500,7 +10543,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -10529,7 +10572,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10552,7 +10595,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -10578,7 +10621,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10600,7 +10643,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -10626,7 +10669,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10648,7 +10691,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -10674,7 +10717,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10697,7 +10740,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -10723,7 +10766,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10746,7 +10789,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -10772,7 +10815,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10794,7 +10837,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -10820,7 +10863,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10842,7 +10885,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -10871,7 +10914,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10893,7 +10936,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -10922,7 +10965,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10944,7 +10987,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -10970,7 +11013,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10992,7 +11035,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -11018,7 +11061,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11040,7 +11083,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -11066,7 +11109,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11088,7 +11131,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -11114,7 +11157,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11136,7 +11179,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -11162,7 +11205,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11184,7 +11227,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -11210,7 +11253,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11232,7 +11275,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -11258,7 +11301,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11280,7 +11323,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -11306,7 +11349,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11328,7 +11371,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -11354,7 +11397,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11376,7 +11419,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -11402,7 +11445,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11424,7 +11467,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -11453,7 +11496,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11475,7 +11518,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -11504,7 +11547,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11526,7 +11569,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -11555,7 +11598,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11577,7 +11620,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -11606,7 +11649,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11628,7 +11671,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -11657,7 +11700,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11679,7 +11722,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -11708,7 +11751,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11730,7 +11773,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -11759,7 +11802,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11781,7 +11824,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -11810,7 +11853,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11832,7 +11875,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -11858,7 +11901,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11880,7 +11923,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -11906,7 +11949,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11928,7 +11971,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -11954,7 +11997,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11976,7 +12019,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -12002,7 +12045,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12024,7 +12067,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -12050,7 +12093,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12072,7 +12115,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -12098,7 +12141,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12120,7 +12163,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -12146,7 +12189,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12168,7 +12211,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -12194,7 +12237,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12216,7 +12259,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -12242,7 +12285,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12264,7 +12307,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -12290,7 +12333,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12312,7 +12355,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -12338,7 +12381,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12360,7 +12403,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -12386,7 +12429,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12408,7 +12451,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -12434,7 +12477,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12456,7 +12499,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -12482,7 +12525,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12504,7 +12547,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -12530,7 +12573,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12552,7 +12595,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -12578,7 +12621,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12600,7 +12643,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -12626,7 +12669,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12648,7 +12691,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -12674,7 +12717,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12696,7 +12739,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -12722,7 +12765,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12744,7 +12787,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -12770,7 +12813,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12792,7 +12835,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -12818,7 +12861,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12840,7 +12883,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -12866,7 +12909,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12888,7 +12931,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -12914,7 +12957,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12936,7 +12979,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -12962,7 +13005,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12984,7 +13027,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -13010,7 +13053,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13032,7 +13075,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -13058,7 +13101,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13080,7 +13123,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -13106,7 +13149,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13128,7 +13171,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -13154,7 +13197,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13176,7 +13219,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -13202,7 +13245,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13224,7 +13267,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -13250,7 +13293,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13272,7 +13315,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -13298,7 +13341,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13320,7 +13363,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -13346,7 +13389,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13368,7 +13411,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -13394,7 +13437,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13416,7 +13459,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -13442,7 +13485,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13464,7 +13507,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -13490,7 +13533,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13512,7 +13555,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -13538,7 +13581,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13560,7 +13603,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -13586,7 +13629,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13608,7 +13651,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -13634,7 +13677,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13656,7 +13699,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -13682,7 +13725,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13704,7 +13747,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -13730,7 +13773,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13752,7 +13795,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -13778,7 +13821,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13800,7 +13843,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -13826,7 +13869,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13848,7 +13891,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -13874,7 +13917,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13896,7 +13939,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -13922,7 +13965,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13944,7 +13987,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -13970,7 +14013,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13992,7 +14035,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -14018,7 +14061,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14040,7 +14083,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -14066,7 +14109,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14088,7 +14131,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -14114,7 +14157,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14140,7 +14183,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "cronet_test",
@@ -14166,7 +14209,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14192,7 +14235,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "cronet_test",
@@ -14218,7 +14261,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14244,7 +14287,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -14270,7 +14313,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14292,7 +14335,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -14318,7 +14361,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14340,7 +14383,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -14366,7 +14409,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14388,7 +14431,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -14414,7 +14457,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14436,7 +14479,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -14462,7 +14505,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14484,7 +14527,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -14510,7 +14553,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14532,7 +14575,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -14558,7 +14601,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14580,7 +14623,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -14606,7 +14649,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14628,7 +14671,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -14654,7 +14697,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14676,7 +14719,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -14702,7 +14745,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14724,7 +14767,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -14750,7 +14793,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14772,7 +14815,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -14798,7 +14841,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14820,7 +14863,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -14846,7 +14889,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14868,7 +14911,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -14894,7 +14937,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14916,7 +14959,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -14942,7 +14985,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14964,7 +15007,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -14990,7 +15033,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15012,7 +15055,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -15038,7 +15081,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15060,7 +15103,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -15086,7 +15129,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15108,7 +15151,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15135,7 +15178,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15157,7 +15200,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15184,7 +15227,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15206,7 +15249,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15233,7 +15276,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15256,7 +15299,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15283,7 +15326,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15306,7 +15349,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15333,7 +15376,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15356,7 +15399,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15383,7 +15426,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15406,7 +15449,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15433,7 +15476,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15456,7 +15499,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15483,7 +15526,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15506,7 +15549,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15533,7 +15576,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15555,7 +15598,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15582,7 +15625,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15604,7 +15647,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15631,7 +15674,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15654,7 +15697,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15681,7 +15724,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15704,7 +15747,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -15730,7 +15773,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15752,7 +15795,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -15778,7 +15821,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15800,7 +15843,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15827,7 +15870,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15850,7 +15893,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15877,7 +15920,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15900,7 +15943,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -15926,7 +15969,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15948,7 +15991,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -15974,7 +16017,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15996,7 +16039,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -16022,7 +16065,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16045,7 +16088,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -16071,7 +16114,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16094,7 +16137,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -16120,7 +16163,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16142,7 +16185,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -16168,7 +16211,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16190,7 +16233,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16217,7 +16260,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16239,7 +16282,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16266,7 +16309,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16288,7 +16331,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -16314,7 +16357,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16336,7 +16379,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -16362,7 +16405,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16384,7 +16427,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -16410,7 +16453,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16432,7 +16475,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -16458,7 +16501,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16480,7 +16523,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16507,7 +16550,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16529,7 +16572,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -16556,7 +16599,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16578,7 +16621,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -16604,7 +16647,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16626,7 +16669,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -16652,7 +16695,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16674,7 +16717,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -16700,7 +16743,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16722,7 +16765,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -16748,7 +16791,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16770,7 +16813,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -16796,7 +16839,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16818,7 +16861,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -16844,7 +16887,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16866,7 +16909,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -16892,7 +16935,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16914,7 +16957,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -16940,7 +16983,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16962,7 +17005,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -16988,7 +17031,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17010,7 +17053,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -17036,7 +17079,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17058,7 +17101,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -17084,7 +17127,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17106,7 +17149,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -17132,7 +17175,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17154,7 +17197,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -17180,7 +17223,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17202,7 +17245,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -17228,7 +17271,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17250,7 +17293,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -17276,7 +17319,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17298,7 +17341,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -17324,7 +17367,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17346,7 +17389,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -17372,7 +17415,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17394,7 +17437,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -17420,7 +17463,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17448,7 +17491,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -17474,7 +17517,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17498,7 +17541,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -17524,7 +17567,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17548,7 +17591,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -17574,7 +17617,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17598,7 +17641,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -17624,7 +17667,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17648,7 +17691,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -17674,7 +17717,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17698,7 +17741,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -17724,7 +17767,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17748,7 +17791,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -17774,7 +17817,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17798,7 +17841,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -17824,7 +17867,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17848,7 +17891,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -17874,7 +17917,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17898,7 +17941,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -17924,7 +17967,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17948,7 +17991,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -17974,7 +18017,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17998,7 +18041,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -18024,7 +18067,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18048,7 +18091,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -18074,7 +18117,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18098,7 +18141,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -18124,7 +18167,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18148,7 +18191,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -18174,7 +18217,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18198,7 +18241,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -18224,7 +18267,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18248,7 +18291,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -18274,7 +18317,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18298,7 +18341,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -18324,7 +18367,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18348,7 +18391,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -18374,7 +18417,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18398,7 +18441,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -18424,7 +18467,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18448,7 +18491,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -18474,7 +18517,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18498,7 +18541,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -18524,7 +18567,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18548,7 +18591,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -18574,7 +18617,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18598,7 +18641,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -18624,7 +18667,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18648,7 +18691,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -18674,7 +18717,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18698,7 +18741,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -18724,7 +18767,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18748,7 +18791,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -18774,7 +18817,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18798,7 +18841,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -18824,7 +18867,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18848,7 +18891,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -18874,7 +18917,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18898,7 +18941,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -18924,7 +18967,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18948,7 +18991,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -18974,7 +19017,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18998,7 +19041,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -19024,7 +19067,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19048,7 +19091,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -19074,7 +19117,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19098,7 +19141,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -19124,7 +19167,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19148,7 +19191,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -19174,7 +19217,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19198,7 +19241,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -19224,7 +19267,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19248,7 +19291,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19275,7 +19318,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19299,7 +19342,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19326,7 +19369,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19350,7 +19393,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19377,7 +19420,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19401,7 +19444,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19428,7 +19471,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19452,7 +19495,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -19481,7 +19524,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19506,7 +19549,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -19535,7 +19578,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19560,7 +19603,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -19589,7 +19632,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19614,7 +19657,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -19643,7 +19686,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19668,7 +19711,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19695,7 +19738,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19720,7 +19763,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19747,7 +19790,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19772,7 +19815,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19799,7 +19842,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19824,7 +19867,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19851,7 +19894,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19876,7 +19919,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19903,7 +19946,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19928,7 +19971,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19955,7 +19998,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19980,7 +20023,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20007,7 +20050,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20032,7 +20075,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20059,7 +20102,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20084,7 +20127,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20111,7 +20154,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20135,7 +20178,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20162,7 +20205,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20186,7 +20229,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20213,7 +20256,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20237,7 +20280,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20264,7 +20307,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20288,7 +20331,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20315,7 +20358,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20340,7 +20383,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20367,7 +20410,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20392,7 +20435,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20419,7 +20462,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20444,7 +20487,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20471,7 +20514,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20496,7 +20539,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -20522,7 +20565,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20546,7 +20589,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -20572,7 +20615,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20596,7 +20639,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -20622,7 +20665,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20646,7 +20689,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -20672,7 +20715,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20696,7 +20739,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20723,7 +20766,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20748,7 +20791,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20775,7 +20818,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20800,7 +20843,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20827,7 +20870,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20852,7 +20895,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -20879,7 +20922,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20904,7 +20947,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -20930,7 +20973,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20954,7 +20997,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -20980,7 +21023,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21004,7 +21047,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -21030,7 +21073,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21054,7 +21097,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -21080,7 +21123,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21104,7 +21147,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -21130,7 +21173,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21155,7 +21198,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -21181,7 +21224,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21206,7 +21249,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -21232,7 +21275,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21257,7 +21300,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -21283,7 +21326,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21308,7 +21351,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -21334,7 +21377,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21358,7 +21401,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -21384,7 +21427,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21408,7 +21451,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -21434,7 +21477,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21458,7 +21501,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -21484,7 +21527,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21508,7 +21551,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -21535,7 +21578,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21559,7 +21602,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -21586,7 +21629,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21610,7 +21653,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -21637,7 +21680,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21661,7 +21704,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -21688,7 +21731,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21712,7 +21755,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -21738,7 +21781,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21762,7 +21805,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -21788,7 +21831,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21812,7 +21855,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -21838,7 +21881,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21862,7 +21905,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -21888,7 +21931,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21912,7 +21955,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -21938,7 +21981,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21962,7 +22005,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -21988,7 +22031,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22012,7 +22055,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -22038,7 +22081,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22062,7 +22105,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -22088,7 +22131,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22112,7 +22155,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -22139,7 +22182,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22163,7 +22206,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -22190,7 +22233,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22214,7 +22257,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -22241,7 +22284,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22265,7 +22308,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -22292,7 +22335,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22316,7 +22359,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -22342,7 +22385,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22366,7 +22409,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -22392,7 +22435,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22416,7 +22459,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -22442,7 +22485,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22466,7 +22509,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -22492,7 +22535,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22516,7 +22559,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -22542,7 +22585,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22566,7 +22609,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -22592,7 +22635,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22616,7 +22659,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -22642,7 +22685,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22666,7 +22709,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -22692,7 +22735,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22716,7 +22759,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -22742,7 +22785,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22766,7 +22809,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -22792,7 +22835,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22816,7 +22859,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -22842,7 +22885,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22866,7 +22909,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -22892,7 +22935,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22916,7 +22959,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -22942,7 +22985,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22966,7 +23009,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -22992,7 +23035,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23016,7 +23059,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -23042,7 +23085,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23066,7 +23109,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -23092,7 +23135,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23116,7 +23159,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -23142,7 +23185,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23166,7 +23209,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -23192,7 +23235,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23216,7 +23259,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -23242,7 +23285,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23266,7 +23309,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -23292,7 +23335,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23316,7 +23359,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -23342,7 +23385,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23366,7 +23409,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -23392,7 +23435,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23416,7 +23459,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -23442,7 +23485,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23466,7 +23509,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -23492,7 +23535,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23516,7 +23559,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -23542,7 +23585,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23566,7 +23609,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -23592,7 +23635,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23616,7 +23659,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -23642,7 +23685,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23666,7 +23709,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -23692,7 +23735,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23716,7 +23759,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -23742,7 +23785,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23766,7 +23809,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -23792,7 +23835,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23816,7 +23859,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -23842,7 +23885,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23866,7 +23909,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -23892,7 +23935,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23916,7 +23959,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -23942,7 +23985,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23966,7 +24009,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -23992,7 +24035,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -24016,7 +24059,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -24042,7 +24085,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -24066,7 +24109,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -24092,7 +24135,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -24113,7 +24156,7 @@
         "args": [
           "--no-wpt-internal",
           "--xcode-build-version",
-          "15a5219j"
+          "15a5229h"
         ],
         "experiment_percentage": 100,
         "isolate_name": "chrome_ios_wpt",
@@ -24145,7 +24188,7 @@
           "hard_timeout": 14400,
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             }
           ],
@@ -42779,9 +42822,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -42790,8 +42833,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -42926,9 +42969,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -42937,8 +42980,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -43058,9 +43101,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -43069,8 +43112,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -44304,9 +44347,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -44315,8 +44358,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -44451,9 +44494,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -44462,8 +44505,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -44583,9 +44626,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -44594,8 +44637,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -45226,9 +45269,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
         },
@@ -45237,8 +45280,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.mac.json b/testing/buildbot/chromium.mac.json
index 75e77d1..fd7851a 100644
--- a/testing/buildbot/chromium.mac.json
+++ b/testing/buildbot/chromium.mac.json
@@ -7827,7 +7827,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -7854,7 +7854,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7876,7 +7876,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -7903,7 +7903,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7925,7 +7925,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -7952,7 +7952,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -7974,7 +7974,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -8001,7 +8001,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8023,7 +8023,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -8050,7 +8050,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8072,7 +8072,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -8099,7 +8099,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8121,7 +8121,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -8148,7 +8148,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8170,7 +8170,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -8197,7 +8197,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8219,7 +8219,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -8246,7 +8246,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8268,7 +8268,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -8295,7 +8295,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8317,7 +8317,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8344,7 +8344,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8366,7 +8366,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8393,7 +8393,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8415,7 +8415,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8442,7 +8442,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8464,7 +8464,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -8491,7 +8491,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8513,7 +8513,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -8540,7 +8540,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8562,7 +8562,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -8589,7 +8589,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8611,7 +8611,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -8638,7 +8638,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8660,7 +8660,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -8687,7 +8687,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8709,7 +8709,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8736,7 +8736,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8758,7 +8758,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8785,7 +8785,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8807,7 +8807,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8834,7 +8834,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8856,7 +8856,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -8883,7 +8883,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8905,7 +8905,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -8932,7 +8932,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -8954,7 +8954,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -8981,7 +8981,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9003,7 +9003,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -9033,7 +9033,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9056,7 +9056,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -9086,7 +9086,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9109,7 +9109,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -9136,7 +9136,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9158,7 +9158,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -9185,7 +9185,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9207,7 +9207,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -9234,7 +9234,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9256,7 +9256,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -9283,7 +9283,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9305,7 +9305,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -9332,7 +9332,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9354,7 +9354,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -9381,7 +9381,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9403,7 +9403,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -9430,7 +9430,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9453,7 +9453,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -9480,7 +9480,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9503,7 +9503,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -9530,7 +9530,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9552,7 +9552,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -9579,7 +9579,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9601,7 +9601,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -9628,7 +9628,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9650,7 +9650,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -9677,7 +9677,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9699,7 +9699,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -9726,7 +9726,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9748,7 +9748,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -9775,7 +9775,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9797,7 +9797,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -9824,7 +9824,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9846,7 +9846,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -9873,7 +9873,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9895,7 +9895,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -9923,7 +9923,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9945,7 +9945,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -9973,7 +9973,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -9995,7 +9995,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -10022,7 +10022,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10044,7 +10044,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -10071,7 +10071,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10093,7 +10093,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -10120,7 +10120,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10142,7 +10142,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -10169,7 +10169,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10191,7 +10191,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -10218,7 +10218,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10240,7 +10240,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -10267,7 +10267,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10289,7 +10289,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -10316,7 +10316,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10338,7 +10338,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -10365,7 +10365,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10387,7 +10387,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -10414,7 +10414,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10436,7 +10436,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -10463,7 +10463,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10485,7 +10485,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -10512,7 +10512,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10534,7 +10534,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -10561,7 +10561,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10583,7 +10583,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -10610,7 +10610,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10632,7 +10632,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -10659,7 +10659,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10681,7 +10681,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -10708,7 +10708,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10730,7 +10730,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -10757,7 +10757,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10779,7 +10779,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -10806,7 +10806,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10828,7 +10828,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -10855,7 +10855,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10877,7 +10877,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -10904,7 +10904,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10926,7 +10926,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -10953,7 +10953,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -10975,7 +10975,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -11002,7 +11002,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11024,7 +11024,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -11051,7 +11051,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11073,7 +11073,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -11100,7 +11100,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11122,7 +11122,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -11149,7 +11149,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11171,7 +11171,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -11198,7 +11198,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11220,7 +11220,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -11247,7 +11247,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11269,7 +11269,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -11296,7 +11296,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11318,7 +11318,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -11345,7 +11345,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11374,7 +11374,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -11401,7 +11401,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11423,7 +11423,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -11450,7 +11450,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11472,7 +11472,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -11499,7 +11499,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11521,7 +11521,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -11548,7 +11548,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11570,7 +11570,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -11597,7 +11597,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11619,7 +11619,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -11646,7 +11646,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11668,7 +11668,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -11695,7 +11695,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11717,7 +11717,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -11744,7 +11744,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11766,7 +11766,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -11793,7 +11793,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11815,7 +11815,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -11842,7 +11842,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11864,7 +11864,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -11891,7 +11891,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11913,7 +11913,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -11940,7 +11940,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -11962,7 +11962,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -11989,7 +11989,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12011,7 +12011,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -12038,7 +12038,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12060,7 +12060,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -12087,7 +12087,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12109,7 +12109,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -12136,7 +12136,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12158,7 +12158,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -12185,7 +12185,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12207,7 +12207,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -12234,7 +12234,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12256,7 +12256,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -12283,7 +12283,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12305,7 +12305,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -12332,7 +12332,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12354,7 +12354,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -12381,7 +12381,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12403,7 +12403,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -12430,7 +12430,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12452,7 +12452,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -12479,7 +12479,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12501,7 +12501,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -12528,7 +12528,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12550,7 +12550,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12578,7 +12578,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12600,7 +12600,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12628,7 +12628,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12650,7 +12650,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12678,7 +12678,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12700,7 +12700,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -12728,7 +12728,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12750,7 +12750,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12780,7 +12780,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12803,7 +12803,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12833,7 +12833,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12856,7 +12856,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12886,7 +12886,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12909,7 +12909,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12939,7 +12939,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -12962,7 +12962,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -12992,7 +12992,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13015,7 +13015,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13045,7 +13045,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13068,7 +13068,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13098,7 +13098,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13121,7 +13121,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13151,7 +13151,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13174,7 +13174,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13204,7 +13204,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13227,7 +13227,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13257,7 +13257,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13280,7 +13280,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13308,7 +13308,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13331,7 +13331,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13359,7 +13359,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13382,7 +13382,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13410,7 +13410,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13433,7 +13433,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13461,7 +13461,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13484,7 +13484,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13512,7 +13512,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13534,7 +13534,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13562,7 +13562,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13584,7 +13584,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13612,7 +13612,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13634,7 +13634,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -13662,7 +13662,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13684,7 +13684,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13714,7 +13714,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13737,7 +13737,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13767,7 +13767,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13790,7 +13790,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13820,7 +13820,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13843,7 +13843,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--shards",
           "2",
@@ -13873,7 +13873,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13896,7 +13896,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -13923,7 +13923,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13945,7 +13945,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -13972,7 +13972,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13994,7 +13994,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14021,7 +14021,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14043,7 +14043,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -14070,7 +14070,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14092,7 +14092,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -14120,7 +14120,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14143,7 +14143,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -14171,7 +14171,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14194,7 +14194,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -14222,7 +14222,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14245,7 +14245,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -14273,7 +14273,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14296,7 +14296,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -14323,7 +14323,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14345,7 +14345,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -14372,7 +14372,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14394,7 +14394,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -14421,7 +14421,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14444,7 +14444,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -14471,7 +14471,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14494,7 +14494,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -14521,7 +14521,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14543,7 +14543,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -14570,7 +14570,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14592,7 +14592,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -14620,7 +14620,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14642,7 +14642,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -14670,7 +14670,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14692,7 +14692,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -14720,7 +14720,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14742,7 +14742,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -14770,7 +14770,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14792,7 +14792,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -14819,7 +14819,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14841,7 +14841,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -14868,7 +14868,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14890,7 +14890,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -14917,7 +14917,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14939,7 +14939,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -14966,7 +14966,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14988,7 +14988,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -15015,7 +15015,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15037,7 +15037,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -15064,7 +15064,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15086,7 +15086,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15114,7 +15114,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15136,7 +15136,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15164,7 +15164,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15186,7 +15186,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15214,7 +15214,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15236,7 +15236,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15264,7 +15264,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15286,7 +15286,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15314,7 +15314,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15336,7 +15336,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -15364,7 +15364,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15386,7 +15386,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -15413,7 +15413,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15435,7 +15435,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -15462,7 +15462,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15484,7 +15484,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -15511,7 +15511,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15533,7 +15533,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -15560,7 +15560,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15582,7 +15582,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -15609,7 +15609,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15631,7 +15631,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -15658,7 +15658,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15680,7 +15680,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -15707,7 +15707,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15729,7 +15729,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -15756,7 +15756,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15778,7 +15778,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -15805,7 +15805,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15827,7 +15827,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -15854,7 +15854,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15876,7 +15876,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -15903,7 +15903,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15925,7 +15925,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -15952,7 +15952,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15974,7 +15974,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -16001,7 +16001,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16023,7 +16023,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -16050,7 +16050,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16072,7 +16072,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -16099,7 +16099,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16121,7 +16121,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -16148,7 +16148,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16170,7 +16170,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -16197,7 +16197,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16219,7 +16219,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -16246,7 +16246,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16268,7 +16268,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -16295,7 +16295,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16317,7 +16317,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -16344,7 +16344,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16366,7 +16366,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -16393,7 +16393,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16415,7 +16415,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -16442,7 +16442,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16464,7 +16464,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -16491,7 +16491,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16513,7 +16513,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -16540,7 +16540,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16562,7 +16562,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -16589,7 +16589,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16611,7 +16611,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -16638,7 +16638,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16660,7 +16660,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -16687,7 +16687,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16709,7 +16709,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -16736,7 +16736,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16765,7 +16765,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -16791,7 +16791,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16813,7 +16813,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -16839,7 +16839,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16861,7 +16861,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -16887,7 +16887,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16909,7 +16909,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -16935,7 +16935,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16957,7 +16957,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -16983,7 +16983,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17005,7 +17005,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -17031,7 +17031,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17053,7 +17053,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -17079,7 +17079,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17101,7 +17101,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -17127,7 +17127,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17149,7 +17149,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -17175,7 +17175,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17197,7 +17197,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -17223,7 +17223,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17245,7 +17245,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17271,7 +17271,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17293,7 +17293,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17319,7 +17319,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17341,7 +17341,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17367,7 +17367,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17389,7 +17389,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17415,7 +17415,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17437,7 +17437,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17463,7 +17463,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17485,7 +17485,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17511,7 +17511,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17533,7 +17533,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17559,7 +17559,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17581,7 +17581,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17607,7 +17607,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17629,7 +17629,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17655,7 +17655,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17677,7 +17677,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -17703,7 +17703,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17725,7 +17725,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -17751,7 +17751,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17773,7 +17773,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -17799,7 +17799,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17821,7 +17821,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -17847,7 +17847,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17869,7 +17869,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -17895,7 +17895,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17917,7 +17917,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -17943,7 +17943,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -17965,7 +17965,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -17991,7 +17991,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18013,7 +18013,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -18039,7 +18039,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18061,7 +18061,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -18087,7 +18087,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18109,7 +18109,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -18135,7 +18135,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18157,7 +18157,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -18183,7 +18183,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18205,7 +18205,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18234,7 +18234,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18256,7 +18256,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18285,7 +18285,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18307,7 +18307,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18336,7 +18336,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18358,7 +18358,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18387,7 +18387,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18410,7 +18410,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18439,7 +18439,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18462,7 +18462,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18491,7 +18491,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18514,7 +18514,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18543,7 +18543,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18566,7 +18566,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18595,7 +18595,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18618,7 +18618,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18647,7 +18647,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18670,7 +18670,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18699,7 +18699,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18722,7 +18722,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18751,7 +18751,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18774,7 +18774,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18803,7 +18803,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18826,7 +18826,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18855,7 +18855,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18877,7 +18877,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18906,7 +18906,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18928,7 +18928,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -18957,7 +18957,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -18979,7 +18979,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -19008,7 +19008,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19031,7 +19031,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -19060,7 +19060,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19083,7 +19083,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -19112,7 +19112,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19135,7 +19135,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19161,7 +19161,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19183,7 +19183,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19209,7 +19209,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19231,7 +19231,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19257,7 +19257,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19279,7 +19279,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19305,7 +19305,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19327,7 +19327,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19353,7 +19353,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19375,7 +19375,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19401,7 +19401,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19423,7 +19423,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19449,7 +19449,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19471,7 +19471,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19497,7 +19497,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19519,7 +19519,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19545,7 +19545,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19567,7 +19567,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -19593,7 +19593,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19615,7 +19615,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -19644,7 +19644,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19667,7 +19667,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -19696,7 +19696,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19719,7 +19719,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -19748,7 +19748,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19771,7 +19771,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19798,7 +19798,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19820,7 +19820,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19847,7 +19847,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19869,7 +19869,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization"
         ],
@@ -19896,7 +19896,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19918,7 +19918,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -19947,7 +19947,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -19969,7 +19969,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -19998,7 +19998,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20020,7 +20020,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -20049,7 +20049,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20071,7 +20071,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20097,7 +20097,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20119,7 +20119,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20145,7 +20145,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20167,7 +20167,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20193,7 +20193,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20215,7 +20215,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20241,7 +20241,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20263,7 +20263,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20289,7 +20289,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20311,7 +20311,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20337,7 +20337,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20359,7 +20359,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20385,7 +20385,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20407,7 +20407,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20433,7 +20433,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20455,7 +20455,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20481,7 +20481,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20503,7 +20503,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -20529,7 +20529,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20551,7 +20551,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -20580,7 +20580,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20602,7 +20602,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -20631,7 +20631,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20653,7 +20653,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest",
           "--xcode-parallelization",
           "--record-video",
@@ -20682,7 +20682,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20704,7 +20704,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -20730,7 +20730,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20752,7 +20752,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -20778,7 +20778,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20800,7 +20800,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -20826,7 +20826,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20848,7 +20848,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -20874,7 +20874,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20896,7 +20896,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -20922,7 +20922,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20944,7 +20944,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -20970,7 +20970,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -20992,7 +20992,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -21018,7 +21018,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21040,7 +21040,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -21066,7 +21066,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21088,7 +21088,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -21114,7 +21114,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21136,7 +21136,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -21162,7 +21162,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21184,7 +21184,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21210,7 +21210,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21232,7 +21232,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21258,7 +21258,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21280,7 +21280,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21306,7 +21306,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21328,7 +21328,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21354,7 +21354,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21376,7 +21376,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21402,7 +21402,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21424,7 +21424,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21450,7 +21450,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21472,7 +21472,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21498,7 +21498,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21520,7 +21520,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21546,7 +21546,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21568,7 +21568,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21594,7 +21594,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21616,7 +21616,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -21642,7 +21642,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21664,7 +21664,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -21690,7 +21690,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21712,7 +21712,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -21738,7 +21738,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21760,7 +21760,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -21786,7 +21786,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21808,7 +21808,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -21834,7 +21834,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21856,7 +21856,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -21882,7 +21882,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21904,7 +21904,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -21930,7 +21930,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -21952,7 +21952,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -21978,7 +21978,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22000,7 +22000,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -22026,7 +22026,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22048,7 +22048,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -22074,7 +22074,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22096,7 +22096,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -22122,7 +22122,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22144,7 +22144,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22170,7 +22170,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22192,7 +22192,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22218,7 +22218,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22240,7 +22240,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22266,7 +22266,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22288,7 +22288,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22314,7 +22314,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22336,7 +22336,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22362,7 +22362,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22384,7 +22384,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22410,7 +22410,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22432,7 +22432,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22458,7 +22458,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22480,7 +22480,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22506,7 +22506,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22528,7 +22528,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22554,7 +22554,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22576,7 +22576,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -22602,7 +22602,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22624,7 +22624,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -22650,7 +22650,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22672,7 +22672,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -22698,7 +22698,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22720,7 +22720,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -22746,7 +22746,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22768,7 +22768,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -22794,7 +22794,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22816,7 +22816,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -22842,7 +22842,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22864,7 +22864,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -22890,7 +22890,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22912,7 +22912,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -22938,7 +22938,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -22960,7 +22960,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -22986,7 +22986,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23008,7 +23008,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -23034,7 +23034,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -23056,7 +23056,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -23082,7 +23082,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 0696b4ce..65f2afa 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -12971,7 +12971,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -12997,7 +12997,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13019,7 +13019,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "absl_hardening_tests",
@@ -13045,7 +13045,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13067,7 +13067,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -13093,7 +13093,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13115,7 +13115,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "base_unittests",
@@ -13141,7 +13141,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13163,7 +13163,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -13189,7 +13189,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13211,7 +13211,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_crypto_tests",
@@ -13237,7 +13237,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13259,7 +13259,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -13285,7 +13285,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13307,7 +13307,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "boringssl_ssl_tests",
@@ -13333,7 +13333,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13355,7 +13355,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -13381,7 +13381,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13403,7 +13403,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "components_unittests",
@@ -13429,7 +13429,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13451,7 +13451,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -13477,7 +13477,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13499,7 +13499,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crashpad_tests",
@@ -13525,7 +13525,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13547,7 +13547,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -13573,7 +13573,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13595,7 +13595,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "crypto_unittests",
@@ -13621,7 +13621,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13643,7 +13643,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -13669,7 +13669,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13691,7 +13691,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "gfx_unittests",
@@ -13717,7 +13717,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13739,7 +13739,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -13765,7 +13765,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13787,7 +13787,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "google_apis_unittests",
@@ -13813,7 +13813,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13835,7 +13835,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -13861,7 +13861,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13883,7 +13883,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_chrome_unittests",
@@ -13909,7 +13909,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13931,7 +13931,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -13957,7 +13957,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -13979,7 +13979,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_components_unittests",
@@ -14005,7 +14005,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14027,7 +14027,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -14053,7 +14053,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14076,7 +14076,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_net_unittests",
@@ -14102,7 +14102,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14125,7 +14125,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -14151,7 +14151,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14173,7 +14173,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -14199,7 +14199,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14221,7 +14221,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -14247,7 +14247,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14269,7 +14269,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_testing_unittests",
@@ -14295,7 +14295,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14317,7 +14317,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -14343,7 +14343,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14365,7 +14365,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_inttests",
@@ -14391,7 +14391,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14413,7 +14413,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -14439,7 +14439,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14461,7 +14461,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_unittests",
@@ -14487,7 +14487,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14509,7 +14509,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -14535,7 +14535,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14557,7 +14557,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_inttests",
@@ -14583,7 +14583,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14605,7 +14605,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -14631,7 +14631,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14653,7 +14653,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_web_view_unittests",
@@ -14679,7 +14679,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14701,7 +14701,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -14727,7 +14727,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14749,7 +14749,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "net_unittests",
@@ -14775,7 +14775,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14797,7 +14797,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -14823,7 +14823,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14845,7 +14845,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "services_unittests",
@@ -14871,7 +14871,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14893,7 +14893,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -14919,7 +14919,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14941,7 +14941,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "skia_unittests",
@@ -14967,7 +14967,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -14989,7 +14989,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -15015,7 +15015,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15037,7 +15037,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "sql_unittests",
@@ -15063,7 +15063,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15085,7 +15085,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -15111,7 +15111,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15133,7 +15133,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ui_base_unittests",
@@ -15159,7 +15159,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15181,7 +15181,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -15207,7 +15207,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -15229,7 +15229,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "url_unittests",
@@ -15255,7 +15255,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -16118,12 +16118,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16133,8 +16133,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -16285,12 +16285,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16300,8 +16300,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
@@ -16432,12 +16432,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 118.0.5969.0",
+        "description": "Run with ash-chrome version 118.0.5970.0",
         "isolate_profile_data": true,
         "merge": {
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -16447,8 +16447,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v118.0.5969.0",
-              "revision": "version:118.0.5969.0"
+              "location": "lacros_version_skew_tests_v118.0.5970.0",
+              "revision": "version:118.0.5970.0"
             }
           ],
           "dimensions": {
diff --git a/testing/buildbot/chromium.webrtc.fyi.json b/testing/buildbot/chromium.webrtc.fyi.json
index 00136f9..93597c3 100644
--- a/testing/buildbot/chromium.webrtc.fyi.json
+++ b/testing/buildbot/chromium.webrtc.fyi.json
@@ -627,7 +627,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -653,7 +653,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -675,7 +675,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -701,7 +701,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -723,7 +723,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -749,7 +749,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
@@ -771,7 +771,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "15a5219j",
+          "15a5229h",
           "--xctest"
         ],
         "isolate_name": "ios_remoting_unittests",
@@ -797,7 +797,7 @@
           },
           "named_caches": [
             {
-              "name": "xcode_ios_15a5219j",
+              "name": "xcode_ios_15a5229h",
               "path": "Xcode.app"
             },
             {
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl
index 8ec6e0d..97f6dba0 100644
--- a/testing/buildbot/mixins.pyl
+++ b/testing/buildbot/mixins.pyl
@@ -1234,12 +1234,12 @@
   'xcode_15_main': {
     'args': [
       '--xcode-build-version',
-      '15a5219j',
+      '15a5229h',
     ],
     'swarming': {
       'named_caches': [
         {
-          'name': 'xcode_ios_15a5219j',
+          'name': 'xcode_ios_15a5229h',
           'path': 'Xcode.app',
         },
       ],
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index c4bf37af..161b6cd 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -4104,6 +4104,7 @@
           'shards': 8,
         },
       },
+      'content_nocompile_tests': {},
       'content_unittests': {},
       'crashpad_tests': {},
       'crypto_unittests': {},
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 5922ed2..4ca98f8 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -16,16 +16,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'identifier': 'Lacros version skew testing ash canary',
-    'description': 'Run with ash-chrome version 118.0.5969.0',
+    'description': 'Run with ash-chrome version 118.0.5970.0',
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5969.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v118.0.5970.0/test_ash_chrome',
     ],
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v118.0.5969.0',
-          'revision': 'version:118.0.5969.0',
+          'location': 'lacros_version_skew_tests_v118.0.5970.0',
+          'revision': 'version:118.0.5970.0',
         },
       ],
     },
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index 0ac4a80..14deb7f 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -3228,16 +3228,6 @@
           'xctest',
         ],
       },
-      'Linux Builder (j-500) (reclient)': {
-        # Copied from
-        # https://source.chromium.org/chromium/chromium/src/+/main:testing/buildbot/waterfalls.pyl;l=4844-4854;drc=75f767e92e86611728189739fb26f4e2cdf212d9
-        'mixins': [
-          'isolate_profile_data',
-        ],
-        'additional_compile_targets': [
-          'all'
-        ],
-      },
       'Linux Viz': {
         'mixins': [
           'linux-jammy',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index f440bdc16..40680a7c8 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -44,6 +44,21 @@
             ]
         }
     ],
+    "AccessibilityPerformanceTesting": [
+        {
+            "platforms": [
+                "android"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled_20230825",
+                    "enable_features": [
+                        "AccessibilityPerformanceTesting"
+                    ]
+                }
+            ]
+        }
+    ],
     "AdaptiveCharging": [
         {
             "platforms": [
@@ -2697,6 +2712,21 @@
             ]
         }
     ],
+    "CVDisplayLinkBeginFrameSource": [
+        {
+            "platforms": [
+                "mac"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "CVDisplayLinkBeginFrameSource"
+                    ]
+                }
+            ]
+        }
+    ],
     "CacheCodeOnIdle": [
         {
             "platforms": [
@@ -3375,6 +3405,33 @@
             ]
         }
     ],
+    "ChromeOSWelcomeTour": [
+        {
+            "platforms": [
+                "chromeos"
+            ],
+            "experiments": [
+                {
+                    "name": "Counterfactual_CANARY_DEV_10",
+                    "params": {
+                        "is-counterfactual": "true"
+                    },
+                    "enable_features": [
+                        "WelcomeTour"
+                    ]
+                },
+                {
+                    "name": "Enabled_CANARY_DEV_10",
+                    "params": {
+                        "is-counterfactual": "false"
+                    },
+                    "enable_features": [
+                        "WelcomeTour"
+                    ]
+                }
+            ]
+        }
+    ],
     "ChromeOSZramWriteback": [
         {
             "platforms": [
@@ -6096,6 +6153,25 @@
             ]
         }
     ],
+    "ExtensionTelemetryDisableOffstoreExtensionStudy": [
+        {
+            "platforms": [
+                "chromeos",
+                "chromeos_lacros",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "SafeBrowsingExtensionTelemetryDisableOffstoreExtension"
+                    ]
+                }
+            ]
+        }
+    ],
     "FastCheckout": [
         {
             "platforms": [
@@ -6155,16 +6231,175 @@
             ]
         }
     ],
-    "FeedPerformanceStudy": [
+    "FeedPerformanceStudyV2": [
         {
             "platforms": [
                 "android"
             ],
             "experiments": [
                 {
-                    "name": "Enabled",
+                    "name": "Prestable_rs4_rr1_im0_rvip0_20230719",
                     "params": {
-                        "useIncrementalMount": "false"
+                        "rangeRatio": "1",
+                        "rangeSize": "4",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "false"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "Prestable_rs4_rr2_im0_rvip0_20230719",
+                    "params": {
+                        "rangeRatio": "2",
+                        "rangeSize": "4",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "false"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "Prestable_rs4_rr1_im0_rvip1_20230719",
+                    "params": {
+                        "rangeRatio": "1",
+                        "rangeSize": "4",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "true"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "Prestable_rs2_rr2_im0_rvip0_20230726",
+                    "params": {
+                        "rangeRatio": "2",
+                        "rangeSize": "2",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "false"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "rs1_rr1_im0_rvip0_20230824",
+                    "params": {
+                        "rangeRatio": "1",
+                        "rangeSize": "1",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "false"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "rs2_rr1_im0_rvip0_20230824",
+                    "params": {
+                        "rangeRatio": "1",
+                        "rangeSize": "2",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "false"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "rs4_rr1_im0_rvip0_20230824",
+                    "params": {
+                        "rangeRatio": "1",
+                        "rangeSize": "4",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "false"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "rs1_rr2_im0_rvip0_20230824",
+                    "params": {
+                        "rangeRatio": "2",
+                        "rangeSize": "1",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "false"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "rs2_rr2_im0_rvip0_20230824",
+                    "params": {
+                        "rangeRatio": "2",
+                        "rangeSize": "2",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "false"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "rs2_rr0.5_im0_rvip0_20230824",
+                    "params": {
+                        "rangeRatio": "0.5",
+                        "rangeSize": "2",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "false"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "rs2_rr0.5_im0_rvip1_20230824",
+                    "params": {
+                        "rangeRatio": "0.5",
+                        "rangeSize": "2",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "true"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "rs4_rr1_im0_rvip1_20230824",
+                    "params": {
+                        "rangeRatio": "1",
+                        "rangeSize": "4",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "true"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "Prestable_enabled_20230824",
+                    "params": {
+                        "rangeRatio": "1",
+                        "rangeSize": "4",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "true"
+                    },
+                    "enable_features": [
+                        "FeedPerformanceStudy"
+                    ]
+                },
+                {
+                    "name": "Stable_enabled_20230824",
+                    "params": {
+                        "rangeRatio": "1",
+                        "rangeSize": "4",
+                        "useIncrementalMount": "false",
+                        "useRecyclerViewItemPrefetch": "true"
                     },
                     "enable_features": [
                         "FeedPerformanceStudy"
@@ -13165,6 +13400,22 @@
             ]
         }
     ],
+    "ReportVisibleLineBounds": [
+        {
+            "platforms": [
+                "android",
+                "android_webview"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "ReportVisibleLineBounds"
+                    ]
+                }
+            ]
+        }
+    ],
     "ReportingStorageControlledDegradation": [
         {
             "platforms": [
diff --git a/third_party/blink/PRESUBMIT.py b/third_party/blink/PRESUBMIT.py
index 3042f885..8339b34d 100644
--- a/third_party/blink/PRESUBMIT.py
+++ b/third_party/blink/PRESUBMIT.py
@@ -78,12 +78,11 @@
         'third_party/blink/public/mojom/loader/resource_load_info',
         'third_party/blink/public/mojom/loader/resource_load_info_notifier',
         'third_party/blink/public/mojom/worker/subresource_loader_updater',
+        'third_party/blink/public/mojom/worker/worklet_global_scope_creation_params',
         'third_party/blink/public/mojom/loader/transferrable_url_loader',
         'third_party/blink/public/mojom/loader/code_cache',
-        'media/mojo/mojom/interface_factory',
-        'media/mojo/mojom/audio_decoder',
-        'media/mojo/mojom/audio_encoder',
-        'media/mojo/mojom/video_decoder',
+        'media/mojo/mojom/interface_factory', 'media/mojo/mojom/audio_decoder',
+        'media/mojo/mojom/audio_encoder', 'media/mojo/mojom/video_decoder',
         'media/mojo/mojom/media_metrics_provider')
 
     for f in input_api.AffectedFiles(file_filter=source_file_filter):
diff --git a/third_party/blink/public/mojom/BUILD.gn b/third_party/blink/public/mojom/BUILD.gn
index 9641fba4e..0d4c02f5 100644
--- a/third_party/blink/public/mojom/BUILD.gn
+++ b/third_party/blink/public/mojom/BUILD.gn
@@ -244,6 +244,7 @@
     "worker/worker_content_settings_proxy.mojom",
     "worker/worker_main_script_load_params.mojom",
     "worker/worker_options.mojom",
+    "worker/worklet_global_scope_creation_params.mojom",
   ]
 
   if (is_android) {
diff --git a/third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom b/third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom
new file mode 100644
index 0000000..5892b8d6
--- /dev/null
+++ b/third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom
@@ -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.
+
+module blink.mojom;
+
+import "third_party/blink/public/mojom/devtools/devtools_agent.mojom";
+import "mojo/public/mojom/base/unguessable_token.mojom";
+import "url/mojom/url.mojom";
+
+// Interface implemented in the browser for the worklets to forward
+// ready-for-inspection notification.
+interface WorkletDevToolsHost {
+  // Indicates that the worklet is ready for inspection, passes a DevToolsAgent
+  // interface for this worklet and requests a corresponding host.
+  OnReadyForInspection(
+    pending_remote<blink.mojom.DevToolsAgent> agent,
+    pending_receiver<blink.mojom.DevToolsAgentHost> agent_host);
+};
+
+// Parameters for initializing WorkerOrWorkletGlobalScope. This is suitable for
+// worklets starting from a different process.
+struct WorkletGlobalScopeCreationParams {
+  url.mojom.Url script_url;
+  mojo_base.mojom.UnguessableToken devtools_token;
+  pending_remote<WorkletDevToolsHost> devtools_host;
+};
diff --git a/third_party/blink/public/web/web_form_control_element.h b/third_party/blink/public/web/web_form_control_element.h
index 88404811..461e400 100644
--- a/third_party/blink/public/web/web_form_control_element.h
+++ b/third_party/blink/public/web/web_form_control_element.h
@@ -111,6 +111,7 @@
   // with value matches the given parameter and make the option as the suggested
   // selection. The goal of introducing suggested value is to not leak any
   // information to JavaScript.
+  // A null value indicates that the suggested value should be hidden.
   void SetSuggestedValue(const WebString&);
   // Returns suggested value of element. If element doesn't fall into input
   // element, textarea element and select element categories, a null string is
diff --git a/third_party/blink/public/web/web_shared_storage_worklet_thread.h b/third_party/blink/public/web/web_shared_storage_worklet_thread.h
index d3b7bdc..a445c52e 100644
--- a/third_party/blink/public/web/web_shared_storage_worklet_thread.h
+++ b/third_party/blink/public/web/web_shared_storage_worklet_thread.h
@@ -8,6 +8,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "base/task/single_thread_task_runner.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-forward.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-forward.h"
 #include "third_party/blink/public/platform/cross_variant_mojo_util.h"
 #include "third_party/blink/public/platform/web_common.h"
 
@@ -19,7 +20,8 @@
   static void Start(
       scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
       CrossVariantMojoReceiver<mojom::SharedStorageWorkletServiceInterfaceBase>
-          receiver);
+          receiver,
+      mojom::WorkletGlobalScopeCreationParamsPtr global_scope_creation_params);
 
   virtual ~WebSharedStorageWorkletThread() = default;
 };
diff --git a/third_party/blink/renderer/core/accessibility/ax_object_cache.h b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
index 32f4a77..d0bf754 100644
--- a/third_party/blink/renderer/core/accessibility/ax_object_cache.h
+++ b/third_party/blink/renderer/core/accessibility/ax_object_cache.h
@@ -120,9 +120,10 @@
   // Called when the NGOffsetMapping is invalidated for the given object.
   virtual void TextOffsetsChanged(const LayoutBlockFlow*) = 0;
   virtual void DocumentTitleChanged() = 0;
-  // Called when a layout tree for a node has just been attached, so we can make
-  // sure we have the right subclass of AXObject.
-  virtual void UpdateCacheAfterNodeIsAttached(Node*) = 0;
+  // Called when a node is connected to the document.
+  virtual void NodeIsConnected(Node*) = 0;
+  // Called when a node is attached to the layout tree.
+  virtual void NodeIsAttached(Node*) = 0;
   // A DOM node was inserted , but does not necessarily have a layout tree.
   virtual void DidInsertChildrenOfNode(Node*) = 0;
 
diff --git a/third_party/blink/renderer/core/dom/container_node.cc b/third_party/blink/renderer/core/dom/container_node.cc
index dd8ee11..50a8952 100644
--- a/third_party/blink/renderer/core/dom/container_node.cc
+++ b/third_party/blink/renderer/core/dom/container_node.cc
@@ -364,8 +364,9 @@
   }
   DispatchSubtreeModifiedEvent();
 
-  if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
+  if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) {
     cache->DidInsertChildrenOfNode(this);
+  }
 }
 
 class ContainerNode::AdoptAndInsertBefore {
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 72dfc24..b717ed8e 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3493,6 +3493,19 @@
   return false;
 }
 
+void Element::NotifyAXOfAttachedSubtree() {
+  if (auto* ax_cache = GetDocument().ExistingAXObjectCache()) {
+    // NodeIsAttached is normally called when a node becomes connected, but if
+    // this subtree is display:none or content-visibility:hidden/auto, there's
+    // no guarantee that AttachLayoutTree will be called.
+    Node* node = this;
+    do {
+      ax_cache->NodeIsAttached(node);
+      node = FlatTreeTraversal::Next(*node, this);
+    } while (node);
+  }
+}
+
 // This function performs two important tasks:
 //
 //  1. It computes the correct style for the element itself.
@@ -3567,13 +3580,13 @@
   bool base_is_display_none =
       !new_style ||
       new_style->GetBaseComputedStyleOrThis()->Display() == EDisplay::kNone;
-  if (new_style && !ShouldStoreComputedStyle(*new_style)) {
-    new_style = nullptr;
-    if (auto* ax_cache = GetDocument().ExistingAXObjectCache()) {
-      // UpdateCacheAfterNodeIsAttached is normally called from
-      // Node::AttachLayoutTree, but if this Element is display:none, there's no
-      // guarantee that AttachLayoutTree will be called.
-      ax_cache->UpdateCacheAfterNodeIsAttached(this);
+
+  if (new_style) {
+    if (!ShouldStoreComputedStyle(*new_style)) {
+      new_style = nullptr;
+      NotifyAXOfAttachedSubtree();
+    } else if (!new_style->IsContentVisibilityVisible()) {
+      NotifyAXOfAttachedSubtree();
     }
   }
 
diff --git a/third_party/blink/renderer/core/dom/element.h b/third_party/blink/renderer/core/dom/element.h
index 86512ba..7e3b4c9a 100644
--- a/third_party/blink/renderer/core/dom/element.h
+++ b/third_party/blink/renderer/core/dom/element.h
@@ -1336,6 +1336,8 @@
   void InlineStyleChanged();
   void SetInlineStyleFromString(const AtomicString&);
 
+  void NotifyAXOfAttachedSubtree();
+
   // If the only inherited changes in the parent element are independent,
   // these changes can be directly propagated to this element (the child).
   // If these conditions are met, propagates the changes to the current style
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc
index 1b732fe..9599c05 100644
--- a/third_party/blink/renderer/core/dom/node.cc
+++ b/third_party/blink/renderer/core/dom/node.cc
@@ -1590,8 +1590,9 @@
 
   ClearNeedsReattachLayoutTree();
 
-  if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache())
-    cache->UpdateCacheAfterNodeIsAttached(this);
+  if (AXObjectCache* cache = GetDocument().ExistingAXObjectCache()) {
+    cache->NodeIsAttached(this);
+  }
 
   if (context.performing_reattach)
     ReattachHookScope::NotifyAttach(*this);
@@ -2271,6 +2272,9 @@
   if (ParentOrShadowHostNode()->IsInShadowTree())
     SetFlag(kIsInShadowTreeFlag);
   if (auto* cache = GetDocument().ExistingAXObjectCache()) {
+    cache->NodeIsConnected(this);
+    // TODO(accessibility) NodeIsAttached() calls ChildrenChanged(), so we may
+    // not need this.
     cache->ChildrenChanged(&insertion_point);
   }
   return kInsertionDone;
diff --git a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
index 530a490..766f7ff 100644
--- a/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_form_control_element.cc
@@ -545,6 +545,8 @@
   Document& document = GetDocument();
   if (!document.IsActive() || !document.View())
     return 0;
+  // TODO(accessibility) Simplify this once AXIDs use DOMNodeIds. At that
+  // point it will be safe to get the AXID at any time.
   if (AXObjectCache* cache = document.ExistingAXObjectCache()) {
     LocalFrameView* local_frame_view = document.View();
     if (local_frame_view->IsUpdatingLifecycle()) {
@@ -555,11 +557,6 @@
       return cache->GetExistingAXID(const_cast<HTMLFormControlElement*>(this));
     }
 
-    if (document.NeedsLayoutTreeUpdate() || document.View()->NeedsLayout() ||
-        document.Lifecycle().GetState() < DocumentLifecycle::kPrePaintClean) {
-      document.View()->UpdateAllLifecyclePhasesExceptPaint(
-          DocumentUpdateReason::kAccessibility);
-    }
     return cache->GetAXID(const_cast<HTMLFormControlElement*>(this));
   }
 
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.h b/third_party/blink/renderer/core/html/forms/html_input_element.h
index 6f094d6..971a090 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.h
@@ -171,6 +171,7 @@
   // Sets the suggested value and puts the element into
   // WebAutofillState::kPreviewed state if |value| is non-empty, or
   // WebAutofillState::kNotFilled otherwise.
+  // A null value indicates that the suggested value should be hidden.
   void SetSuggestedValue(const String& value) override;
 
   ScriptValue valueAsDate(ScriptState* script_state) const;
diff --git a/third_party/blink/renderer/core/html/forms/html_text_area_element.h b/third_party/blink/renderer/core/html/forms/html_text_area_element.h
index aba91ba..e79b2d2c 100644
--- a/third_party/blink/renderer/core/html/forms/html_text_area_element.h
+++ b/third_party/blink/renderer/core/html/forms/html_text_area_element.h
@@ -60,6 +60,7 @@
   // Sets the suggested value and puts the element into
   // WebAutofillState::kPreviewed state if |value| is non-empty, or
   // WebAutofillState::kNotFilled otherwise.
+  // A null value indicates that the suggested value should be hidden.
   void SetSuggestedValue(const String& value) override;
 
   // For ValidityState
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.cc b/third_party/blink/renderer/core/html/forms/text_control_element.cc
index 44051b3..00ac30d 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element.cc
+++ b/third_party/blink/renderer/core/html/forms/text_control_element.cc
@@ -1011,22 +1011,21 @@
            value.empty() ? WebAutofillState::kNotFilled : autofill_state);
 }
 
-// TODO(crbug.com/772433): Create and use a new suggested-value element instead.
 void TextControlElement::SetSuggestedValue(const String& value) {
   // Avoid calling maxLength() if possible as it's non-trivial.
   const String new_suggested_value =
       value.empty() ? value : value.Substring(0, maxLength());
-  if (new_suggested_value == suggested_value_)
+  if (new_suggested_value == suggested_value_) {
     return;
+  }
   suggested_value_ = new_suggested_value;
 
-  if (!suggested_value_.empty() && !InnerEditorValue().empty()) {
-    // If there is an inner editor value, hide it so the suggested value can be
-    // shown to the user.
+  // A null value indicates that the inner editor value should be shown, and a
+  // non-null one indicates it should be hidden so that the suggested value can
+  // be shown.
+  if (!value.IsNull() && !InnerEditorValue().empty()) {
     InnerEditorElement()->SetVisibility(false);
-  } else if (suggested_value_.empty() && InnerEditorElement()) {
-    // If there is no suggested value and there is an InnerEditorElement, reset
-    // its visibility.
+  } else if (value.IsNull() && InnerEditorElement()) {
     InnerEditorElement()->SetVisibility(true);
   }
 
diff --git a/third_party/blink/renderer/core/html/forms/text_control_element.h b/third_party/blink/renderer/core/html/forms/text_control_element.h
index 2f76dfc..ae9e72a 100644
--- a/third_party/blink/renderer/core/html/forms/text_control_element.h
+++ b/third_party/blink/renderer/core/html/forms/text_control_element.h
@@ -155,6 +155,7 @@
   void SetAutofillValue(const String& value,
                         WebAutofillState = WebAutofillState::kAutofilled);
 
+  // A null value indicates that the suggested value should be hidden.
   virtual void SetSuggestedValue(const String& value);
   const String& SuggestedValue() const;
 
diff --git a/third_party/blink/renderer/core/layout/layout_block.cc b/third_party/blink/renderer/core/layout/layout_block.cc
index 24b539b4..848bbca 100644
--- a/third_party/blink/renderer/core/layout/layout_block.cc
+++ b/third_party/blink/renderer/core/layout/layout_block.cc
@@ -347,9 +347,9 @@
   NOT_DESTROYED();
   for (LayoutBox* child = FirstChildBox(); child;
        child = child->NextSiblingBox()) {
-    if ((!IsLayoutNGContainingBlock(this) && child->IsFloating()) ||
-        child->IsOutOfFlowPositioned() || child->IsColumnSpanAll())
+    if (child->IsOutOfFlowPositioned() || child->IsColumnSpanAll()) {
       continue;
+    }
 
     AddVisualOverflowFromChild(*child);
   }
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 953647d..46b1795 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1403,11 +1403,6 @@
     return bitfields_.Floating();
   }
 
-  bool IsFloatingWithNonContainingBlockParent() const {
-    NOT_DESTROYED();
-    return IsFloating() && Parent() && !Parent()->IsLayoutBlockFlow();
-  }
-
   virtual bool IsInitialLetterBox() const {
     NOT_DESTROYED();
     return false;
diff --git a/third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h b/third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h
index 20d9fd8..8ce8a00 100644
--- a/third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h
+++ b/third_party/blink/renderer/core/layout/ng/legacy_layout_tree_walking.h
@@ -62,15 +62,6 @@
   return false;
 }
 
-// Return true if the block is of NG type, or if it's a block invisible to
-// LayoutNG and it has an NG containg block. False if it's hosted by the legacy
-// layout engine.
-inline bool IsLayoutNGContainingBlock(const LayoutBlock* containing_block) {
-  if (UNLIKELY(containing_block->IsLayoutFlowThread()))
-    containing_block = containing_block->ContainingBlock();
-  return containing_block && containing_block->IsLayoutNGObject();
-}
-
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_LAYOUT_NG_LEGACY_LAYOUT_TREE_WALKING_H_
diff --git a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc
index ab6fd9f..81fc880 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc
+++ b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.cc
@@ -9,7 +9,6 @@
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/editing/markers/custom_highlight_marker.h"
 #include "third_party/blink/renderer/core/editing/markers/document_marker_controller.h"
-#include "third_party/blink/renderer/core/editing/markers/highlight_pseudo_marker.h"
 #include "third_party/blink/renderer/core/editing/markers/styleable_marker.h"
 #include "third_party/blink/renderer/core/editing/markers/text_match_marker.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
@@ -609,6 +608,12 @@
               LayoutUnit(font_data->GetFontMetrics().Height()),
               fragment_item_.GetNode()->GetDocument().InDarkMode());
         }
+        if (marker->GetType() == DocumentMarker::kComposition &&
+            !styleable_marker.TextColor().IsFullyTransparent() &&
+            RuntimeEnabledFeatures::CompositionForegroundMarkersEnabled()) {
+          PaintDecoratedText(text, styleable_marker.TextColor(),
+                             paint_start_offset, paint_end_offset);
+        }
       } break;
 
       case DocumentMarker::kTextFragment:
@@ -635,44 +640,10 @@
         DCHECK_EQ(phase, kForeground);
         Color text_color =
             originating_style_.VisitedDependentColor(GetCSSPropertyColor());
-
-        TextPaintStyle text_style;
-        text_style.current_color = text_style.fill_color =
-            text_style.stroke_color = text_style.emphasis_mark_color =
-                text_color;
-        text_style.stroke_width = originating_style_.TextStrokeWidth();
-        text_style.color_scheme = originating_style_.UsedColorScheme();
-        text_style.shadow = nullptr;
-
-        const TextPaintStyle final_text_style =
-            HighlightStyleUtils::HighlightPaintingStyle(
-                document, originating_style_, node_,
-                highlight_pseudo_marker.GetPseudoId(), text_style, paint_info_,
-                highlight_pseudo_marker.GetPseudoArgument());
-
-        const ComputedStyle* pseudo_style =
-            HighlightStyleUtils::HighlightPseudoStyle(
-                node_, originating_style_,
-                highlight_pseudo_marker.GetPseudoId(),
-                highlight_pseudo_marker.GetPseudoArgument());
-        PhysicalRect decoration_rect = fragment_item_.LocalRect(
-            text, paint_start_offset, paint_end_offset);
-        decoration_rect.Move(PhysicalOffset(box_origin_));
-        NGTextDecorationPainter decoration_painter(
-            text_painter_, fragment_item_, paint_info_,
-            pseudo_style ? *pseudo_style : originating_style_, final_text_style,
-            decoration_rect, selection_);
-
-        decoration_painter.Begin(NGTextDecorationPainter::kOriginating);
-        decoration_painter.PaintExceptLineThrough(
-            fragment_paint_info_.Slice(paint_start_offset, paint_end_offset));
-
-        text_painter_.Paint(
-            fragment_paint_info_.Slice(paint_start_offset, paint_end_offset),
-            paint_end_offset - paint_start_offset, final_text_style,
-            kInvalidDOMNodeId, foreground_auto_dark_mode_);
-
-        decoration_painter.PaintOnlyLineThrough();
+        PaintDecoratedText(text, text_color, paint_start_offset,
+                           paint_end_offset,
+                           highlight_pseudo_marker.GetPseudoId(),
+                           highlight_pseudo_marker.GetPseudoArgument());
       } break;
 
       default:
@@ -1265,6 +1236,52 @@
   }
 }
 
+void NGHighlightPainter::PaintDecoratedText(
+    const StringView& text,
+    const Color& text_color,
+    unsigned paint_start_offset,
+    unsigned paint_end_offset,
+    const PseudoId pseudo,
+    const AtomicString& pseudo_argument) {
+  const Document& document = node_->GetDocument();
+  TextPaintStyle text_style;
+  text_style.current_color = text_style.fill_color = text_style.stroke_color =
+      text_style.emphasis_mark_color = text_color;
+  text_style.stroke_width = originating_style_.TextStrokeWidth();
+  text_style.color_scheme = originating_style_.UsedColorScheme();
+  text_style.shadow = nullptr;
+
+  const ComputedStyle* pseudo_style =
+      pseudo == PseudoId::kPseudoIdNone
+          ? nullptr
+          : HighlightStyleUtils::HighlightPseudoStyle(node_, originating_style_,
+                                                      pseudo, pseudo_argument);
+
+  if (pseudo_style) {
+    text_style = HighlightStyleUtils::HighlightPaintingStyle(
+        document, originating_style_, node_, pseudo, text_style, paint_info_,
+        pseudo_argument);
+  }
+  PhysicalRect decoration_rect =
+      fragment_item_.LocalRect(text, paint_start_offset, paint_end_offset);
+  decoration_rect.Move(PhysicalOffset(box_origin_));
+  NGTextDecorationPainter decoration_painter(
+      text_painter_, fragment_item_, paint_info_,
+      pseudo_style ? *pseudo_style : originating_style_, text_style,
+      decoration_rect, selection_);
+
+  decoration_painter.Begin(NGTextDecorationPainter::kOriginating);
+  decoration_painter.PaintExceptLineThrough(
+      fragment_paint_info_.Slice(paint_start_offset, paint_end_offset));
+
+  text_painter_.Paint(
+      fragment_paint_info_.Slice(paint_start_offset, paint_end_offset),
+      paint_end_offset - paint_start_offset, text_style, kInvalidDOMNodeId,
+      foreground_auto_dark_mode_);
+
+  decoration_painter.PaintOnlyLineThrough();
+}
+
 NGHighlightPainter::LayerPaintState::LayerPaintState(
     NGHighlightOverlay::HighlightLayer id,
     const ComputedStyle* style,
diff --git a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h
index 3fc4ef8..68f66c3 100644
--- a/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h
+++ b/third_party/blink/renderer/core/paint/ng/ng_highlight_painter.h
@@ -9,6 +9,7 @@
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/editing/frame_selection.h"
 #include "third_party/blink/renderer/core/editing/markers/document_marker.h"
+#include "third_party/blink/renderer/core/editing/markers/highlight_pseudo_marker.h"
 #include "third_party/blink/renderer/core/layout/geometry/physical_rect.h"
 #include "third_party/blink/renderer/core/layout/selection_state.h"
 #include "third_party/blink/renderer/core/paint/ng/ng_highlight_overlay.h"
@@ -258,6 +259,16 @@
   void PaintSpellingGrammarDecorations(
       const NGHighlightOverlay::HighlightPart&);
 
+  // Paints text with a highlight color. For composition markers, omit the last
+  // two arguments. For PseudoHighlightMarkers, include both the PseudoId and
+  // PseudoArgument.
+  void PaintDecoratedText(const StringView& text,
+                          const Color& text_color,
+                          unsigned paint_start_offset,
+                          unsigned paint_end_offset,
+                          const PseudoId pseudo = PseudoId::kPseudoIdNone,
+                          const AtomicString& pseudo_argument = g_empty_atom);
+
   const NGTextFragmentPaintInfo& fragment_paint_info_;
   NGTextPainter& text_painter_;
   NGTextDecorationPainter& decoration_painter_;
diff --git a/third_party/blink/renderer/core/paint/paint_invalidator.cc b/third_party/blink/renderer/core/paint/paint_invalidator.cc
index 092b008..5b3aa25 100644
--- a/third_party/blink/renderer/core/paint/paint_invalidator.cc
+++ b/third_party/blink/renderer/core/paint/paint_invalidator.cc
@@ -35,19 +35,11 @@
   if (object.HasLayer() &&
       To<LayoutBoxModelObject>(object).HasSelfPaintingLayer()) {
     context.painting_layer = To<LayoutBoxModelObject>(object).Layer();
-  } else if (object.IsColumnSpanAll() ||
-             object.IsFloatingWithNonContainingBlockParent()) {
-    // See |LayoutObject::PaintingLayer| for the special-cases of floating under
-    // inline and multicolumn.
-    // Post LayoutNG the |LayoutObject::IsFloatingWithNonContainingBlockParent|
-    // check can be removed as floats will be painted by the correct layer.
-    context.painting_layer = object.PaintingLayer();
   }
 
-  if (object.IsFloating() &&
-      (object.IsInLayoutNGInlineFormattingContext() ||
-       IsLayoutNGContainingBlock(object.ContainingBlock())))
+  if (object.IsFloating()) {
     context.painting_layer->SetNeedsPaintPhaseFloat();
+  }
 
   if (!context.painting_layer->NeedsPaintPhaseDescendantOutlines() &&
       ((object != context.painting_layer->GetLayoutObject() &&
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
index a5daebd..b3ab5f7 100644
--- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
+++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -3333,12 +3333,6 @@
   if (object_.HasLayer() &&
       To<LayoutBoxModelObject>(object_).HasSelfPaintingLayer()) {
     context_.painting_layer = To<LayoutBoxModelObject>(object_).Layer();
-  } else if (!IsInNGFragmentTraversal() &&
-             (object_.IsColumnSpanAll() ||
-              object_.IsFloatingWithNonContainingBlockParent())) {
-    // See LayoutObject::paintingLayer() for the special-cases of floating under
-    // inline and multicolumn.
-    context_.painting_layer = object_.PaintingLayer();
   }
   DCHECK(context_.painting_layer == object_.PaintingLayer());
 }
diff --git a/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc b/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
index 22906d68..6d4df91 100644
--- a/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
+++ b/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.cc
@@ -12,7 +12,6 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/inspector/console_message.h"
 #include "third_party/blink/renderer/core/inspector/devtools_agent.h"
-#include "third_party/blink/renderer/core/inspector/worker_devtools_params.h"
 #include "third_party/blink/renderer/core/loader/document_loader.h"
 #include "third_party/blink/renderer/core/workers/global_scope_creation_params.h"
 #include "third_party/blink/renderer/core/workers/worker_global_scope.h"
@@ -70,7 +69,8 @@
 void ThreadedMessagingProxyBase::InitializeWorkerThread(
     std::unique_ptr<GlobalScopeCreationParams> global_scope_creation_params,
     const absl::optional<WorkerBackingThreadStartupData>& thread_startup_data,
-    const absl::optional<const blink::DedicatedWorkerToken>& token) {
+    const absl::optional<const blink::DedicatedWorkerToken>& token,
+    std::unique_ptr<WorkerDevToolsParams> client_provided_devtools_params) {
   DCHECK(IsParentContextThread());
 
   KURL script_url = global_scope_creation_params->script_url;
@@ -82,9 +82,12 @@
 
   worker_thread_ = CreateWorkerThread();
 
-  auto devtools_params = DevToolsAgent::WorkerThreadCreated(
-      execution_context_.Get(), worker_thread_.get(), script_url,
-      global_scope_creation_params->global_scope_name, token);
+  auto devtools_params =
+      client_provided_devtools_params
+          ? std::move(client_provided_devtools_params)
+          : DevToolsAgent::WorkerThreadCreated(
+                execution_context_.Get(), worker_thread_.get(), script_url,
+                global_scope_creation_params->global_scope_name, token);
 
   worker_thread_->Start(std::move(global_scope_creation_params),
                         thread_startup_data, std::move(devtools_params));
diff --git a/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h b/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h
index 0744840..7fc66135 100644
--- a/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h
+++ b/third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h
@@ -10,6 +10,7 @@
 #include "third_party/blink/public/mojom/devtools/console_message.mojom-blink-forward.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/frame/web_feature_forward.h"
+#include "third_party/blink/renderer/core/inspector/worker_devtools_params.h"
 #include "third_party/blink/renderer/core/workers/parent_execution_context_task_runners.h"
 #include "third_party/blink/renderer/core/workers/worker_backing_thread_startup_data.h"
 #include "third_party/blink/renderer/core/workers/worker_thread.h"
@@ -74,10 +75,19 @@
       scoped_refptr<base::SingleThreadTaskRunner>
           parent_agent_group_task_runner = nullptr);
 
+  // Normally, for dedicated worker and for worklets created in-process, the
+  // devtools params will be derived within this function, based on the parent
+  // (Window) context and/or based on the dedicated worker token. When worklet
+  // creation is proxied via the browser process (e.g. shared storage worklet),
+  // where the original Window context isn't directly accessible,
+  // `client_provided_devtools_params` will be pre-calculated and passed to this
+  // function, and this param will be used directly to start the worklet thread.
   void InitializeWorkerThread(
       std::unique_ptr<GlobalScopeCreationParams>,
       const absl::optional<WorkerBackingThreadStartupData>&,
-      const absl::optional<const blink::DedicatedWorkerToken>&);
+      const absl::optional<const blink::DedicatedWorkerToken>&,
+      std::unique_ptr<WorkerDevToolsParams> client_provided_devtools_params =
+          nullptr);
 
   ExecutionContext* GetExecutionContext() const;
   ParentExecutionContextTaskRunners* GetParentExecutionContextTaskRunners()
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
index 84c0b9e..26f7a1ea 100644
--- a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
+++ b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.cc
@@ -45,7 +45,9 @@
 void ThreadedWorkletMessagingProxy::Initialize(
     WorkerClients* worker_clients,
     WorkletModuleResponsesMap* module_responses_map,
-    const absl::optional<WorkerBackingThreadStartupData>& thread_startup_data) {
+    const absl::optional<WorkerBackingThreadStartupData>& thread_startup_data,
+    mojom::blink::WorkletGlobalScopeCreationParamsPtr
+        client_provided_global_scope_creation_params) {
   DCHECK(IsMainThread());
   if (AskedToTerminate())
     return;
@@ -66,8 +68,9 @@
   // to support an out-of-process worklet architecture where the
   // GlobalScopeCreationParams is reasonably filled in.
   if (!GetExecutionContext()) {
+    CHECK(client_provided_global_scope_creation_params);
     auto creation_params = std::make_unique<GlobalScopeCreationParams>(
-        /*script_url=*/KURL(),
+        client_provided_global_scope_creation_params->script_url,
         /*script_type=*/mojom::blink::ScriptType::kModule, global_scope_name,
         /*user_agent=*/String(),
         /*ua_metadata=*/absl::optional<UserAgentMetadata>(),
@@ -83,16 +86,35 @@
         /*worker_clients=*/nullptr,
         /*content_settings_client=*/nullptr,
         /*inherited_trial_features=*/nullptr,
-        /*parent_devtools_token=*/base::UnguessableToken::Create(),
+        /*parent_devtools_token=*/
+        client_provided_global_scope_creation_params->devtools_token,
         /*worker_settings=*/nullptr,
         /*v8_cache_options=*/mojom::blink::V8CacheOptions::kDefault,
         /*module_responses_map=*/nullptr);
 
+    auto devtools_params = std::make_unique<WorkerDevToolsParams>();
+    devtools_params->devtools_worker_token =
+        client_provided_global_scope_creation_params->devtools_token;
+    mojo::PendingRemote<mojom::blink::DevToolsAgent> devtools_agent_remote;
+    devtools_params->agent_receiver =
+        devtools_agent_remote.InitWithNewPipeAndPassReceiver();
+    mojo::PendingReceiver<mojom::blink::DevToolsAgentHost>
+        devtools_agent_host_receiver =
+            devtools_params->agent_host_remote.InitWithNewPipeAndPassReceiver();
+
     InitializeWorkerThread(std::move(creation_params), thread_startup_data,
-                           absl::nullopt);
+                           /*token=*/absl::nullopt, std::move(devtools_params));
+
+    mojo::Remote<mojom::blink::WorkletDevToolsHost> devtools_host(
+        std::move(client_provided_global_scope_creation_params->devtools_host));
+    devtools_host->OnReadyForInspection(
+        std::move(devtools_agent_remote),
+        std::move(devtools_agent_host_receiver));
     return;
   }
 
+  CHECK(!client_provided_global_scope_creation_params);
+
   LocalDOMWindow* window = To<LocalDOMWindow>(GetExecutionContext());
   ContentSecurityPolicy* csp = window->GetContentSecurityPolicy();
   DCHECK(csp);
diff --git a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h
index 82468e6c3..15ce625b 100644
--- a/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h
+++ b/third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_WORKERS_THREADED_WORKLET_MESSAGING_PROXY_H_
 
 #include "base/task/single_thread_task_runner.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-blink.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/workers/threaded_messaging_proxy_base.h"
 #include "third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h"
@@ -31,10 +32,18 @@
   void WorkletObjectDestroyed() final;
   void TerminateWorkletGlobalScope() final;
 
+  // Normally, for worklets created in-process, the worklet thread will be
+  // initialized with state taking from the original Window context. When
+  // worklet creation is proxied via the browser process (e.g. shared storage
+  // worklet), where the original Window context isn't directly accessible, the
+  // worklet thread will be initialized with state taking from
+  // `client_provided_global_scope_creation_params`.
   void Initialize(
       WorkerClients*,
       WorkletModuleResponsesMap*,
-      const absl::optional<WorkerBackingThreadStartupData>& = absl::nullopt);
+      const absl::optional<WorkerBackingThreadStartupData>& = absl::nullopt,
+      mojom::blink::WorkletGlobalScopeCreationParamsPtr
+          client_provided_global_scope_creation_params = {});
 
   void Trace(Visitor*) const override;
 
diff --git a/third_party/blink/renderer/core/workers/worker_thread.cc b/third_party/blink/renderer/core/workers/worker_thread.cc
index b52cbc1f..1073865 100644
--- a/third_party/blink/renderer/core/workers/worker_thread.cc
+++ b/third_party/blink/renderer/core/workers/worker_thread.cc
@@ -626,16 +626,9 @@
     worker_scheduler_->InitializeOnWorkerThread(global_scope_);
     worker_reporting_proxy_.DidCreateWorkerGlobalScope(GlobalScope());
 
-    // `url_for_debugger` can be null for out-of-process worklet (e.g. shared
-    // storage worklet). Tentatively skip creating the
-    // `WorkerInspectorController`.
-    // TODO(crbug.com/1419253): support inspector for out-of-process worklet and
-    // remove this if-check.
-    if (!url_for_debugger.IsNull()) {
-      worker_inspector_controller_ = WorkerInspectorController::Create(
-          this, url_for_debugger, inspector_task_runner_,
-          std::move(devtools_params));
-    }
+    worker_inspector_controller_ = WorkerInspectorController::Create(
+        this, url_for_debugger, inspector_task_runner_,
+        std::move(devtools_params));
 
     // Since context initialization below may fail, we should notify debugger
     // about the new worker thread separately, so that it can resolve it by id
@@ -670,21 +663,15 @@
     WorkerThreads().insert(this);
   }
 
-  // `worker_inspector_controller_` can be null for out-of-process worklet (e.g.
-  // shared storage worklet).
-  // TODO(crbug.com/1419253): support inspector for out-of-process worklet and
-  // remove this if-check.
-  if (worker_inspector_controller_) {
-    // It is important that no code is run on the Isolate between
-    // initializing InspectorTaskRunner and pausing on start.
-    // Otherwise, InspectorTaskRunner might interrupt isolate execution
-    // from another thread and try to resume "pause on start" before
-    // we even paused.
-    worker_inspector_controller_->WaitForDebuggerIfNeeded();
-    // Note the above call runs nested message loop which may result in
-    // worker thread being torn down by request from the parent thread,
-    // while waiting for debugger.
-  }
+  // It is important that no code is run on the Isolate between
+  // initializing InspectorTaskRunner and pausing on start.
+  // Otherwise, InspectorTaskRunner might interrupt isolate execution
+  // from another thread and try to resume "pause on start" before
+  // we even paused.
+  worker_inspector_controller_->WaitForDebuggerIfNeeded();
+  // Note the above call runs nested message loop which may result in
+  // worker thread being torn down by request from the parent thread,
+  // while waiting for debugger.
 }
 
 void WorkerThread::EvaluateClassicScriptOnWorkerThread(
diff --git a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
index 2c5fa077..56a10af 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_node_object.cc
@@ -5286,10 +5286,9 @@
     return AXObjectVector();
   }
 
-  Vector<String> ignored;
   HeapVector<Member<Element>> elements_from_attribute;
   if (!ElementsFromAttribute(el, elements_from_attribute,
-                             html_names::kAriaErrormessageAttr, ignored)) {
+                             html_names::kAriaErrormessageAttr)) {
     return AXObjectVector();
   }
 
@@ -5988,10 +5987,9 @@
   if (!element)
     return String();
 
-  Vector<String> ids;
   HeapVector<Member<Element>> elements_from_attribute;
   if (ElementsFromAttribute(element, elements_from_attribute,
-                            html_names::kAriaDescribedbyAttr, ids)) {
+                            html_names::kAriaDescribedbyAttr)) {
     // TODO(meredithl): Determine description sources when |aria_describedby| is
     // the empty string, in order to make devtools work with attr-associated
     // elements.
@@ -6003,12 +6001,6 @@
     description = TextFromElements(true, visited, elements_from_attribute,
                                    related_objects);
 
-    for (auto& member_element : elements_from_attribute)
-      ids.push_back(member_element->GetIdAttribute());
-
-    TokenVectorFromAttribute(element, ids, html_names::kAriaDescribedbyAttr);
-    AXObjectCache().UpdateReverseTextRelations(this, ids);
-
     if (!description.IsNull()) {
       if (description_sources) {
         DescriptionSource& source = description_sources->back();
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index df77998..497a016a 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -2501,10 +2501,9 @@
   // the textfield's invalid aria-owns to be remapped to aria-controls.
   DCHECK(GetElement());
   HeapVector<Member<Element>> owned_elements;
-  Vector<String> ids;
   AXObject* listbox_candidate = nullptr;
   if (ElementsFromAttribute(GetElement(), owned_elements,
-                            html_names::kAriaOwnsAttr, ids) &&
+                            html_names::kAriaOwnsAttr) &&
       owned_elements.size() > 0) {
     DCHECK(owned_elements[0]);
     listbox_candidate = AXObjectCache().GetOrCreate(owned_elements[0]);
@@ -4526,8 +4525,7 @@
     Element* element = GetElement();
     if (element) {
       HeapVector<Member<Element>> elements_from_attribute;
-      Vector<String> ids;
-      ElementsFromAttribute(element, elements_from_attribute, attr, ids);
+      ElementsFromAttribute(element, elements_from_attribute, attr);
 
       const AtomicString& aria_labelledby = GetAttribute(attr);
 
@@ -4541,8 +4539,6 @@
         AXObjectSet visited_copy = visited;
         text_alternative = TextFromElements(
             true, visited_copy, elements_from_attribute, related_objects);
-        if (!ids.empty())
-          AXObjectCache().UpdateReverseTextRelations(this, ids);
         if (!text_alternative.IsNull()) {
           if (name_sources) {
             NameSource& source = name_sources->back();
@@ -4641,39 +4637,33 @@
 // static
 bool AXObject::ElementsFromAttribute(Element* from,
                                      HeapVector<Member<Element>>& elements,
-                                     const QualifiedName& attribute,
-                                     Vector<String>& ids) {
+                                     const QualifiedName& attribute) {
   if (!from)
     return false;
 
-  // We compute the attr-associated elements, which are either explicitly set
-  // element references set via the IDL, or computed from the content attribute.
-  TokenVectorFromAttribute(from, ids, attribute);
   HeapVector<Member<Element>>* attr_associated_elements =
       from->GetElementArrayAttribute(attribute);
   if (!attr_associated_elements)
-    return ids.size();
+    return false;
 
   for (const auto& element : *attr_associated_elements)
     elements.push_back(element);
 
-  return ids.size();
+  return elements.size();
 }
 
 // static
 bool AXObject::AriaLabelledbyElementVector(
     Element* from,
-    HeapVector<Member<Element>>& elements,
-    Vector<String>& ids) {
+    HeapVector<Member<Element>>& elements) {
   // Try both spellings, but prefer aria-labelledby, which is the official spec.
-  if (ElementsFromAttribute(from, elements, html_names::kAriaLabelledbyAttr,
-                            ids) &&
+  if (ElementsFromAttribute(from, elements, html_names::kAriaLabelledbyAttr) &&
       elements.size() > 0) {
     return true;
   }
 
-  return ElementsFromAttribute(from, elements, html_names::kAriaLabeledbyAttr,
-                               ids) &&
+  return ElementsFromAttribute(from, elements,
+                               html_names::kAriaLabeledbyAttr) &&
          elements.size() > 0;
 }
 
@@ -4685,9 +4675,9 @@
     return false;
 
   HeapVector<Member<Element>> elements_from_attribute;
-  Vector<String> ids;
-  if (AriaLabelledbyElementVector(element, elements_from_attribute, ids))
+  if (AriaLabelledbyElementVector(element, elements_from_attribute)) {
     return true;
+  }
 
   const AtomicString& aria_label = AccessibleNode::GetPropertyOrARIAAttribute(
       element, AOMStringProperty::kLabel);
@@ -7548,14 +7538,18 @@
     // Add useful HTML element info, like <div.myClass#myId>.
     if (GetNode()) {
       string_builder = string_builder + " " + GetNodeString(GetNode());
-      if (IsA<Document>(GetNode())) {
-        if (IsRoot())
-          string_builder = string_builder + " isRoot";
+      if (IsRoot()) {
+        string_builder = string_builder + " isRoot";
+      }
+      if (GetDocument()) {
         if (GetDocument()->GetFrame() &&
             GetDocument()->GetFrame()->PagePopupOwner()) {
-          string_builder = string_builder + " isPopup";
+          string_builder = string_builder + " inPopup";
         }
+      } else {
+        string_builder = string_builder + " missingDocument";
       }
+
       if (!GetNode()->isConnected()) {
         // TODO(accessibility) Do we have a handy helper for determining whether
         // a node is still in the flat tree? That would be useful to log.
@@ -7563,9 +7557,6 @@
       }
     }
 
-    if (!GetDocument())
-      string_builder = string_builder + " missingDocument";
-
     if (cached_values_need_update_) {
       string_builder = string_builder + " needsToUpdateCachedValues";
     }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index 0f711bd2..54614c0e 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -1436,11 +1436,10 @@
   // Returns true if |attribute| was present on |from|.
   static bool ElementsFromAttribute(Element* from,
                                     HeapVector<Member<Element>>& elements,
-                                    const QualifiedName& attribute,
-                                    Vector<String>& ids);
-  static bool AriaLabelledbyElementVector(Element* from,
-                                          HeapVector<Member<Element>>& elements,
-                                          Vector<String>& ids);
+                                    const QualifiedName& attribute);
+  static bool AriaLabelledbyElementVector(
+      Element* from,
+      HeapVector<Member<Element>>& elements);
   // Return true if the ame is from @aria-label / @aria-labelledby.
   static bool IsNameFromAriaAttribute(Element* element);
   // Return true if the name is from @aria-label / @aria-labelledby / @title.
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
index 08d4b67..0d2d695 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -692,15 +692,16 @@
       ax_mode_(ax_mode),
       validation_message_axid_(0),
       active_aria_modal_dialog_(nullptr),
-      relation_cache_(std::make_unique<AXRelationCache>(this)),
       accessibility_event_permission_(mojom::blink::PermissionStatus::ASK),
       permission_service_(document.GetExecutionContext()),
       permission_observer_receiver_(this, document.GetExecutionContext()),
       render_accessibility_host_(document.GetExecutionContext()),
       ax_tree_source_(BlinkAXTreeSource::Create(*this)),
-      ax_tree_serializer_(std::make_unique<ui::AXTreeSerializer<AXObject*>>(
-          ax_tree_source_,
-          /*crash_on_error*/ true)) {
+      ax_tree_serializer_(
+          std::make_unique<
+              ui::AXTreeSerializer<AXObject*, HeapVector<AXObject*>>>(
+              ax_tree_source_,
+              /*crash_on_error*/ true)) {
   use_ax_menu_list_ = GetSettings()->GetUseAXMenuList();
 }
 
@@ -739,6 +740,13 @@
   agents_.erase(agent);
 }
 
+void AXObjectCacheImpl::EnsureRelationCache() {
+  if (!relation_cache_) {
+    relation_cache_ = std::make_unique<AXRelationCache>(this);
+    relation_cache_->Init();
+  }
+}
+
 AXObject* AXObjectCacheImpl::Root() {
   if (AXObject* root = SafeGet(document_))
     return root;
@@ -1018,6 +1026,7 @@
 }
 
 AXID AXObjectCacheImpl::GetAXID(Node* node) {
+  UpdateAXForAllDocuments();
   AXObject* ax_object = GetOrCreate(node);
   if (!ax_object)
     return ui::AXNodeData::kInvalidAXID;
@@ -1319,6 +1328,10 @@
   if (!node)
     return nullptr;
 
+  // The relation cache must exit before the creation of any object, as it
+  // can affect the parent chain of any object returned.
+  EnsureRelationCache();
+
   if (AXObject* obj = Get(node)) {
     return obj;
   }
@@ -1431,11 +1444,20 @@
   AssociateAXID(new_obj, axid);
   new_obj->Init(parent);
 
-  // Register incomplete relations with the relation cache, so that when the
-  // target id shows up at a later time, the source node can be reserialized
-  // with the completed relation.
-  relation_cache_->RegisterIncompleteRelations(new_obj);
-
+  // Process new relations.
+  // Only elements (non-pseudo ones) can have relations.
+  CHECK(relation_cache_);
+  if (IsA<Element>(node) && !node->IsPseudoElement()) {
+    // Register incomplete relations with the relation cache, so that when the
+    // target id shows up at a later time, the source node can be reserialized
+    // with the completed relation.
+    relation_cache_->RegisterIncompleteRelations(new_obj);
+#if DCHECK_IS_ON()
+    // Ensure that the relation cache is properly initialized with information
+    // from this element.
+    relation_cache_->CheckRelationsCached(*To<Element>(node));
+#endif
+  }
   return new_obj;
 }
 
@@ -1989,7 +2011,9 @@
   fixed_or_sticky_node_ids_.erase(obj_id);
   cached_bounding_boxes_.erase(obj_id);
   // Clear id from relation cache.
-  relation_cache_->RemoveAXID(obj_id);
+  if (relation_cache_) {
+    relation_cache_->RemoveAXID(obj_id);
+  }
 }
 
 AXObject* AXObjectCacheImpl::NearestExistingAncestor(Node* node) {
@@ -2141,13 +2165,6 @@
     MarkElementDirty(text_control);
 }
 
-void AXObjectCacheImpl::UpdateReverseTextRelations(
-    const AXObject* relation_source,
-    const Vector<String>& target_ids) {
-  relation_cache_->UpdateReverseTextRelations(relation_source->GetNode(),
-                                              target_ids);
-}
-
 void AXObjectCacheImpl::StyleChanged(const LayoutObject* layout_object,
                                      bool visibility_or_inertness_changed) {
   DCHECK(layout_object);
@@ -2252,8 +2269,10 @@
     MarkAXObjectDirtyWithCleanLayout(obj);
   }
 
-  if (optional_node_for_relation_update)
+  if (optional_node_for_relation_update) {
+    CHECK(relation_cache_);
     relation_cache_->UpdateRelatedTree(optional_node_for_relation_update, obj);
+  }
 }
 
 void AXObjectCacheImpl::TextChangedWithCleanLayout(Node* node) {
@@ -2294,7 +2313,16 @@
     PostNotification(root, ax::mojom::blink::Event::kDocumentTitleChanged);
 }
 
-void AXObjectCacheImpl::UpdateCacheAfterNodeIsAttached(Node* node) {
+void AXObjectCacheImpl::NodeIsConnected(Node* node) {
+  // Register relation ids so that reverse relations can be computed.
+  if (relation_cache_) {
+    if (Element* element = DynamicTo<Element>(node)) {
+      relation_cache_->CacheRelationIds(*element);
+    }
+  }
+}
+
+void AXObjectCacheImpl::NodeIsAttached(Node* node) {
   DCHECK(node);
   SCOPED_DISALLOW_LIFECYCLE_TRANSITION();
 
@@ -2329,11 +2357,10 @@
                                    /* notify_parent */ false);
   }
 
-  DeferTreeUpdate(TreeUpdateReason::kUpdateCacheAfterNodeIsAttached, node);
+  DeferTreeUpdate(TreeUpdateReason::kNodeIsAttached, node);
 }
 
-void AXObjectCacheImpl::UpdateCacheAfterNodeIsAttachedWithCleanLayout(
-    Node* node) {
+void AXObjectCacheImpl::NodeIsAttachedWithCleanLayout(Node* node) {
   if (!node || !node->isConnected()) {
     return;
   }
@@ -2348,11 +2375,11 @@
 #endif  // DCHECK_IS_ON()
 
   // Process any relation attributes that can affect ax objects already created.
-
   // Force computation of aria-owns, so that original parents that already
   // computed their children get the aria-owned children removed.
   if (AXObject::HasARIAOwns(element)) {
     if (AXObject* obj = GetOrCreate(element)) {
+      CHECK(relation_cache_);
       relation_cache_->UpdateAriaOwnsWithCleanLayout(obj);
     }
   }
@@ -2611,8 +2638,10 @@
       return;
   }
 
-  if (optional_node)
+  if (optional_node) {
+    CHECK(relation_cache_);
     relation_cache_->UpdateRelatedTree(optional_node, obj);
+  }
 
   TableCellRoleMaybeChanged(optional_node);
 }
@@ -2696,6 +2725,15 @@
     return;
   }
 
+  if (GetPopupDocumentIfShowing()) {
+    UpdateLifecycleIfNeeded(*GetPopupDocumentIfShowing());
+  }
+
+  // Changes to ids or aria-owns may have resulted in queued up relation
+  // cache work; do that now.
+  EnsureRelationCache();
+  relation_cache_->ProcessUpdatesWithCleanLayout();
+
   // If MarkDocumentDirty() was called, do it now, so that the entire tree is
   // invalidated before updating it.
   if (mark_all_dirty_) {
@@ -2704,7 +2742,6 @@
 
   if (IsDirty()) {
     if (GetPopupDocumentIfShowing()) {
-      UpdateLifecycleIfNeeded(*GetPopupDocumentIfShowing());
       ProcessDeferredAccessibilityEventsImpl(*GetPopupDocumentIfShowing());
     }
     ProcessDeferredAccessibilityEventsImpl(document);
@@ -2777,10 +2814,6 @@
     // FooBarredWithCleanLayout().
     ProcessCleanLayoutCallbacks(document);
 
-    // Changes to ids or aria-owns may have resulted in queued up relation
-    // cache work; do that now.
-    relation_cache_->ProcessUpdatesWithCleanLayout();
-
     // Keep going if there are more ids to invalidate or children changes to
     // process from previous steps. For example, a display locked
     // (content-visibility:auto) element could be invalidated as it is scrolled
@@ -2813,7 +2846,7 @@
 }
 
 bool AXObjectCacheImpl::IsDirty() {
-  if (IsMainDocumentDirty() || IsPopupDocumentDirty() ||
+  if (IsMainDocumentDirty() || IsPopupDocumentDirty() || !relation_cache_ ||
       relation_cache_->IsDirty()) {
     return true;
   }
@@ -2928,6 +2961,7 @@
       // new object.
       if (AXObject::HasARIAOwns(DynamicTo<Element>(node)) &&
           AXRelationCache::IsValidOwner(new_object)) {
+        CHECK(relation_cache_);
         relation_cache_->UpdateAriaOwnsWithCleanLayout(new_object, true);
       }
     } else {
@@ -3249,9 +3283,6 @@
     case TreeUpdateReason::kInvalidateCachedValuesOnSubtree:
       InvalidateCachedValuesOnSubtreeWithCleanLayout(node);
       break;
-    case TreeUpdateReason::kLabelChanged:
-      LabelChangedWithCleanLayout(node);
-      break;
     case TreeUpdateReason::kMarkDirtyFromHandleLayout:
     case TreeUpdateReason::kMarkDirtyFromHandleScroll:
     case TreeUpdateReason::kMarkDirtyFromRemove:
@@ -3268,6 +3299,7 @@
       break;
     case TreeUpdateReason::kPostNotificationFromHandleLoadComplete:
     case TreeUpdateReason::kPostNotificationFromHandleLoadStart:
+    case TreeUpdateReason::kPostNotificationFromHandleScrolledToAnchor:
       EnsurePostNotification(node, tree_update->event);
       break;
     case TreeUpdateReason::kRemoveValidationMessageObjectFromFocusedUIElement:
@@ -3284,6 +3316,7 @@
       HandleRoleMaybeChangedWithCleanLayout(node);
       break;
     case TreeUpdateReason::kSectionOrRegionRoleMaybeChangedFromLabel:
+    case TreeUpdateReason::kSectionOrRegionRoleMaybeChangedFromLabelledBy:
     case TreeUpdateReason::kSectionOrRegionRoleMaybeChangedFromTitle:
       SectionOrRegionRoleMaybeChangedWithCleanLayout(node);
       break;
@@ -3296,8 +3329,8 @@
     case TreeUpdateReason::kUpdateActiveMenuOption:
       HandleUpdateActiveMenuOptionWithCleanLayout(node);
       break;
-    case TreeUpdateReason::kUpdateCacheAfterNodeIsAttached:
-      UpdateCacheAfterNodeIsAttachedWithCleanLayout(node);
+    case TreeUpdateReason::kNodeIsAttached:
+      NodeIsAttachedWithCleanLayout(node);
       break;
     case TreeUpdateReason::kUpdateTableRole:
       UpdateTableRoleWithCleanLayout(node);
@@ -3334,10 +3367,14 @@
 }
 
 bool AXObjectCacheImpl::IsAriaOwned(const AXObject* object) const {
+  CHECK(relation_cache_);
   return relation_cache_->IsAriaOwned(object);
 }
 
 AXObject* AXObjectCacheImpl::ValidatedAriaOwner(const AXObject* object) const {
+  DCHECK(GetDocument().Lifecycle().GetState() >=
+         DocumentLifecycle::kLayoutClean);
+  CHECK(relation_cache_);
   return relation_cache_->ValidatedAriaOwner(object);
 }
 
@@ -3346,19 +3383,26 @@
     HeapVector<Member<AXObject>>& owned_children) {
   DCHECK(GetDocument().Lifecycle().GetState() >=
          DocumentLifecycle::kLayoutClean);
+  CHECK(relation_cache_);
   relation_cache_->ValidatedAriaOwnedChildren(owner, owned_children);
 }
 
 bool AXObjectCacheImpl::MayHaveHTMLLabel(const HTMLElement& elem) {
+  CHECK(elem.GetDocument().Lifecycle().GetState() >=
+        DocumentLifecycle::kLayoutClean)
+      << "Unclean document at lifecycle " << elem.GetDocument().ToString();
+  CHECK(relation_cache_);
+
   // Return false if this type of element will not accept a <label for> label.
   if (!elem.IsLabelable())
     return false;
 
   // Return true if a <label for> pointed to this element at some point.
-  if (relation_cache_->MayHaveHTMLLabelViaForAttribute(elem))
+  if (relation_cache_->MayHaveHTMLLabelViaForAttribute(elem)) {
     return true;
+  }
 
-  // Return true if any amcestor is a label, as in <label><input></label>.
+  // Return true if any ancestor is a label, as in <label><input></label>.
   return Traversal<HTMLLabelElement>::FirstAncestor(elem);
 }
 
@@ -3560,6 +3604,7 @@
 // This might be the new target of a relation. Handle all possible cases.
 void AXObjectCacheImpl::MaybeNewRelationTarget(Node& node, AXObject* obj) {
   // Track reverse relations
+  CHECK(relation_cache_);
   relation_cache_->UpdateRelatedTree(&node, obj);
 
   if (!obj)
@@ -3567,7 +3612,8 @@
 
   DCHECK_EQ(obj->GetNode(), &node);
 
-  // Process completed relations for new ids.
+  // Process completed relations for new ids. These are relations where
+  // the target AXObject didn't exist when the relation was initially cached.
   if (Element* element = DynamicTo<Element>(node)) {
     const AtomicString& id = element->GetIdAttribute();
     if (!id.IsNull()) {
@@ -3594,13 +3640,6 @@
   DCHECK(node);
   DCHECK(!node->GetDocument().NeedsLayoutTreeUpdateForNode(*node));
 
-  if (Element* element = DynamicTo<Element>(node)) {
-    if (auto& value = AccessibleNode::GetPropertyOrARIAAttributeValue(
-            element, AOMRelationProperty::kActiveDescendant)) {
-      relation_cache_->UpdateReverseActiveDescendantRelations(node, value);
-    }
-  }
-
   if (AXObject* obj = GetOrCreate(node))
     obj->HandleActiveDescendantChanged();
 }
@@ -3685,6 +3724,7 @@
     // In addition, any owned objects need to reset their parent_ to point
     // to the new object.
     if (AXObject* new_object = GetOrCreate(node)) {
+      CHECK(relation_cache_);
       relation_cache_->UpdateAriaOwnsWithCleanLayout(new_object, true);
       // Notify parent synchronously (Remove() does it async).
       DCHECK(new_object->CachedParentObject());
@@ -3699,17 +3739,36 @@
   if (attr_name.LocalName().StartsWith("aria-")) {
     // Perform updates specific to each attribute.
     if (attr_name == html_names::kAriaActivedescendantAttr) {
+      if (relation_cache_) {
+        if (auto& value = AccessibleNode::GetPropertyOrARIAAttributeValue(
+                element, AOMRelationProperty::kActiveDescendant)) {
+          relation_cache_->UpdateReverseActiveDescendantRelations(element,
+                                                                  value);
+        }
+      }
       DeferTreeUpdate(TreeUpdateReason::kActiveDescendantChanged, element);
     } else if (attr_name == html_names::kAriaValuenowAttr ||
                attr_name == html_names::kAriaValuetextAttr) {
       HandleValueChanged(element);
-    } else if (attr_name == html_names::kAriaLabelAttr ||
-               attr_name == html_names::kAriaLabeledbyAttr ||
-               attr_name == html_names::kAriaLabelledbyAttr) {
+    } else if (attr_name == html_names::kAriaLabelAttr) {
+      TextChanged(element);
       DeferTreeUpdate(
           TreeUpdateReason::kSectionOrRegionRoleMaybeChangedFromLabel, element);
-    } else if (attr_name == html_names::kAriaDescriptionAttr ||
-               attr_name == html_names::kAriaDescribedbyAttr) {
+    } else if (attr_name == html_names::kAriaLabeledbyAttr ||
+               attr_name == html_names::kAriaLabelledbyAttr) {
+      if (relation_cache_) {
+        relation_cache_->UpdateReverseTextRelations(*element, attr_name);
+      }
+      DeferTreeUpdate(
+          TreeUpdateReason::kSectionOrRegionRoleMaybeChangedFromLabelledBy,
+          element);
+      TextChanged(element);
+    } else if (attr_name == html_names::kAriaDescriptionAttr) {
+      TextChanged(element);
+    } else if (attr_name == html_names::kAriaDescribedbyAttr) {
+      if (relation_cache_) {
+        relation_cache_->UpdateReverseTextRelations(*element, attr_name);
+      }
       TextChanged(element);
     } else if (attr_name == html_names::kAriaCheckedAttr) {
       PostNotification(element, ax::mojom::blink::Event::kCheckedStateChanged);
@@ -3739,8 +3798,10 @@
                attr_name == html_names::kAriaErrormessageAttr ||
                attr_name == html_names::kAriaFlowtoAttr) {
       MarkElementDirty(element);
-      if (AXObject* obj = SafeGet(element)) {
-        relation_cache_->RegisterIncompleteRelation(obj, attr_name);
+      if (relation_cache_) {
+        if (AXObject* obj = SafeGet(element)) {
+          relation_cache_->RegisterIncompleteRelation(obj, attr_name);
+        }
       }
     } else {
       MarkElementDirty(element);
@@ -3766,9 +3827,12 @@
   } else if (attr_name == html_names::kTitleAttr) {
     DeferTreeUpdate(TreeUpdateReason::kSectionOrRegionRoleMaybeChangedFromTitle,
                     element);
-  } else if (attr_name == html_names::kForAttr &&
-             IsA<HTMLLabelElement>(*element)) {
-    DeferTreeUpdate(TreeUpdateReason::kLabelChanged, element);
+  } else if (attr_name == html_names::kForAttr) {
+    if (relation_cache_) {
+      if (HTMLLabelElement* label = DynamicTo<HTMLLabelElement>(element)) {
+        MarkElementDirty(relation_cache_->LabelChanged(*label));
+      }
+    }
   } else if (attr_name == html_names::kIdAttr) {
     DeferTreeUpdate(TreeUpdateReason::kIdChanged, element);
   } else if (attr_name == html_names::kTabindexAttr) {
@@ -4005,11 +4069,6 @@
   }
 }
 
-void AXObjectCacheImpl::LabelChangedWithCleanLayout(Node* node) {
-  // Will call back to TextChanged() when done updating relation cache.
-  relation_cache_->LabelChanged(To<Element>(node));
-}
-
 void AXObjectCacheImpl::IdChangedWithCleanLayout(Node* node) {
   if (AXObject* obj = Get(node)) {
     // The id attribute has changed, which can change an object's ignored
@@ -4029,6 +4088,7 @@
 }
 
 void AXObjectCacheImpl::AriaOwnsChangedWithCleanLayout(Node* node) {
+  CHECK(relation_cache_);
   if (AXObject* obj = GetOrCreate(node)) {
     relation_cache_->UpdateAriaOwnsWithCleanLayout(obj);
   }
@@ -4478,7 +4538,8 @@
   // or a partial accessibility tree. AXTreeSerializer is stateful, but the
   // first time you serialize from a brand-new tree you're guaranteed to get a
   // complete tree.
-  ui::AXTreeSerializer<AXObject*> serializer(tree_source);
+  ui::AXTreeSerializer<AXObject*, HeapVector<AXObject*>> serializer(
+      tree_source);
 
   if (max_node_count)
     serializer.set_max_node_count(max_node_count);
@@ -4738,6 +4799,15 @@
   Position start_pos = changed_selection.ComputeStartPosition();
   Position end_pos = changed_selection.ComputeEndPosition();
 
+#if DCHECK_IS_ON()
+  Document& selection_document =
+      start_pos.ComputeContainerNode()->GetDocument();
+  DCHECK(selection_document.Lifecycle().GetState() >=
+         DocumentLifecycle::kAfterPerformLayout)
+      << "Unclean document at lifecycle "
+      << selection_document.Lifecycle().ToString();
+#endif
+
   // Currently there are scenarios where the start/end are not offset in
   // anchor, if this is the case, we need to compute their offset in the
   // container node since we need this information on the browser side.
@@ -4958,14 +5028,9 @@
   if (!anchor_node)
     return;
 
-  SCOPED_DISALLOW_LIFECYCLE_TRANSITION();
-
-  AXObject* obj = GetOrCreate(anchor_node->GetLayoutObject());
-  if (!obj)
-    return;
-  if (!obj->AccessibilityIsIncludedInTree())
-    obj = obj->ParentObjectUnignored();
-  PostNotification(obj, ax::mojom::Event::kScrolledToAnchor);
+  DeferTreeUpdate(TreeUpdateReason::kPostNotificationFromHandleScrolledToAnchor,
+                  const_cast<Node*>(anchor_node),
+                  ax::mojom::blink::Event::kScrolledToAnchor);
 }
 
 void AXObjectCacheImpl::HandleFrameRectsChanged(Document& document) {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
index 4d976c5..9af59f25 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h
@@ -159,10 +159,7 @@
   //
 
   void SelectionChanged(Node*) override;
-  // Update reverse relation cache when aria-labelledby or aria-describedby
-  // point to the relation_source.
-  void UpdateReverseTextRelations(const AXObject* relation_source,
-                                  const Vector<String>& target_ids);
+
   // Effects a ChildrenChanged() on the passed-in object, if unignored,
   // otherwise, uses the first unignored ancestor. Returns the object that the
   // children changed occurs on.
@@ -243,9 +240,10 @@
 
   void FocusableChangedWithCleanLayout(Node* node);
   void DocumentTitleChanged() override;
-  // Called when a layout tree for a node has just been attached, so we can make
-  // sure we have the right subclass of AXObject.
-  void UpdateCacheAfterNodeIsAttached(Node*) override;
+  // Called when a node is connected to the document.
+  void NodeIsConnected(Node*) override;
+  // Called when a node is attached to the layout tree.
+  void NodeIsAttached(Node*) override;
   // A DOM node was inserted , but does not necessarily have a layout tree.
   void DidInsertChildrenOfNode(Node*) override;
 
@@ -402,7 +400,7 @@
   void HandleAriaPressedChangedWithCleanLayout(Node*);
   void HandleNodeLostFocusWithCleanLayout(Node*);
   void HandleNodeGainedFocusWithCleanLayout(Node*);
-  void UpdateCacheAfterNodeIsAttachedWithCleanLayout(Node*);
+  void NodeIsAttachedWithCleanLayout(Node*);
   void DidShowMenuListPopupWithCleanLayout(Node*);
   void DidHideMenuListPopupWithCleanLayout(Node*);
   void HandleScrollPositionChangedWithCleanLayout(Node*);
@@ -553,6 +551,7 @@
   void MarkDocumentDirty() override;
   void ResetSerializer() override;
   void MarkElementDirty(const Node*) override;
+  void MarkElementDirtyWithCleanLayout(const Node*);
 
   // TODO(accessibility) Create an a11y lifecyvcle that encompasses these.
   // Layout is clean and the cache is processing callbacks.
@@ -580,7 +579,6 @@
       ax::mojom::blink::Action event_from_action =
           ax::mojom::blink::Action::kNone,
       const BlinkAXEventIntentsSet& event_intents = BlinkAXEventIntentsSet());
-  void LabelChangedWithCleanLayout(Node*);
   void IdChangedWithCleanLayout(Node*);
   void AriaOwnsChangedWithCleanLayout(Node*);
 
@@ -632,6 +630,10 @@
   // details.
   void UpdateTreeIfNeeded();
 
+  // Make sure a relation cache exists and is initialized. Mst be called with
+  // clean layout.
+  void EnsureRelationCache();
+
   // Create an AXObject, and do not check if a previous one exists.
   // Also, initialize the object and add it to maps for later retrieval.
   AXObject* CreateAndInit(Node*,
@@ -716,15 +718,15 @@
     kFocusableChanged = 9,
     kIdChanged = 10,
     kInvalidateCachedValuesOnSubtree = 11,
-    kLabelChanged = 12,
-    kMarkDirtyFromHandleLayout = 13,
-    kMarkDirtyFromHandleScroll = 14,
-    kMarkDirtyFromRemove = 15,
-    kNameAttributeChanged = 16,
-    kNodeGainedFocus = 17,
-    kNodeLostFocus = 18,
-    kPostNotificationFromHandleLoadComplete = 19,
-    kPostNotificationFromHandleLoadStart = 20,
+    kMarkDirtyFromHandleLayout = 12,
+    kMarkDirtyFromHandleScroll = 13,
+    kMarkDirtyFromRemove = 14,
+    kNameAttributeChanged = 15,
+    kNodeGainedFocus = 16,
+    kNodeLostFocus = 17,
+    kPostNotificationFromHandleLoadComplete = 18,
+    kPostNotificationFromHandleLoadStart = 19,
+    kPostNotificationFromHandleScrolledToAnchor = 20,
     kRemoveValidationMessageObjectFromFocusedUIElement = 21,
     kRemoveValidationMessageObjectFromValidationMessageObject = 22,
     kRoleChangeFromAriaHasPopup = 23,
@@ -732,14 +734,15 @@
     kRoleMaybeChangedFromEventListener = 25,
     kRoleMaybeChangedFromHref = 26,
     kSectionOrRegionRoleMaybeChangedFromLabel = 27,
-    kSectionOrRegionRoleMaybeChangedFromTitle = 28,
-    kTextChangedFromTextChangedNode = 29,
-    kTextMarkerDataAdded = 30,
-    kUpdateActiveMenuOption = 31,
-    kUpdateCacheAfterNodeIsAttached = 32,
-    kUpdateTableRole = 33,
-    kUseMapAttributeChanged = 34,
-    kValidationMessageVisibilityChanged = 35,
+    kSectionOrRegionRoleMaybeChangedFromLabelledBy = 28,
+    kSectionOrRegionRoleMaybeChangedFromTitle = 29,
+    kTextChangedFromTextChangedNode = 30,
+    kTextMarkerDataAdded = 31,
+    kUpdateActiveMenuOption = 32,
+    kNodeIsAttached = 33,
+    kUpdateTableRole = 34,
+    kUseMapAttributeChanged = 35,
+    kValidationMessageVisibilityChanged = 36,
 
     // These updates are associated with an AXID:
     kChildrenChanged = 100,
@@ -795,7 +798,6 @@
       ax::mojom::blink::EventFrom event_from,
       ax::mojom::blink::Action event_from_action);
   void MarkAXSubtreeDirty(AXObject*);
-  void MarkElementDirtyWithCleanLayout(const Node*);
   void MarkDocumentDirtyWithCleanLayout();
 
   // Given an object to mark dirty or fire an event on, return an object
@@ -1066,7 +1068,8 @@
       render_accessibility_host_;
 
   Member<BlinkAXTreeSource> ax_tree_source_;
-  std::unique_ptr<ui::AXTreeSerializer<AXObject*>> ax_tree_serializer_;
+  std::unique_ptr<ui::AXTreeSerializer<AXObject*, HeapVector<AXObject*>>>
+      ax_tree_serializer_;
 
   HeapDeque<Member<AXDirtyObject>> dirty_objects_;
 
diff --git a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
index 525f5c63..d7dff68 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.cc
@@ -5,7 +5,9 @@
 #include "third_party/blink/renderer/modules/accessibility/ax_relation_cache.h"
 
 #include "base/memory/ptr_util.h"
-#include "third_party/blink/renderer/core/dom/element_traversal.h"
+#include "third_party/blink/renderer/core/aom/accessible_node.h"
+#include "third_party/blink/renderer/core/dom/dom_node_ids.h"
+#include "third_party/blink/renderer/core/dom/shadow_including_tree_order_traversal.h"
 #include "third_party/blink/renderer/core/html/forms/html_label_element.h"
 #include "ui/accessibility/ax_common.h"
 
@@ -16,37 +18,172 @@
 
 AXRelationCache::~AXRelationCache() = default;
 
-void AXRelationCache::DoInitialDocumentScan() {
-  // Init the relation cache with elements already in the document.
-  Document& document = object_cache_->GetDocument();
-  for (Element& element :
-       ElementTraversal::DescendantsOf(*document.documentElement())) {
-    const auto& id = element.FastGetAttribute(html_names::kForAttr);
-    if (!id.empty())
-      all_previously_seen_label_target_ids_.insert(id);
+void AXRelationCache::Init() {
+  // Init the relation cache with elements already present.
+  // Normally, these relations would be cached when the node is first attached,
+  // via AXObjectCacheImpl::NodeIsConnected().
+  // The initial scan must include both flat traversal and node traversal,
+  // othrwise some connected elements can be missed.
+  DoInitialDocumentScan(object_cache_->GetDocument());
+  if (Document* popup_doc = object_cache_->GetPopupDocumentIfShowing()) {
+    DoInitialDocumentScan(*popup_doc);
+  }
+}
 
-    // Ensure correct ancestor chains even when not all AXObject's in the
-    // document are created, e.g. in the devtools accessibility panel.
-    // Defers adding aria-owns targets as children of their new parents,
-    // and to the relation cache, until the appropriate document lifecycle.
+void AXRelationCache::DoInitialDocumentScan(Document& document) {
 #if DCHECK_IS_ON()
-    DCHECK(document.Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean)
-        << "Unclean document at lifecycle " << document.Lifecycle().ToString();
+  DCHECK(document.Lifecycle().GetState() >= DocumentLifecycle::kLayoutClean)
+      << "Unclean document at lifecycle " << document.Lifecycle().ToString();
 #endif
-    if (element.FastHasAttribute(html_names::kAriaOwnsAttr)) {
-      if (AXObject* owner = GetOrCreate(&element, nullptr)) {
-        owner_ids_to_update_.insert(owner->AXObjectID());
+
+  // TODO(crbug.com/1473733) Address flaw that all DOM ids are being cached
+  // together regardless of their TreeScope, which can lead to conflicts.
+  // Traverse all connected nodes in the document, via both DOM and shadow DOM.
+  Node* node = &document;
+  while (Node* next =
+             ShadowIncludingTreeOrderTraversal::Next(*node, &document)) {
+    Element* element = DynamicTo<Element>(next);
+    if (element) {
+      // Cache relations that do not require an AXObject.
+      CacheRelationIds(*element);
+
+      // Caching aria-owns requires creating target AXObjects.
+      if (element->FastHasAttribute(html_names::kAriaOwnsAttr)) {
+        if (AXObject* owner = GetOrCreate(element, nullptr)) {
+          owner_ids_to_update_.insert(owner->AXObjectID());
+        }
       }
     }
+    node = next;
+  }
+}
+
+void AXRelationCache::CacheRelationIds(Element& element) {
+#if DCHECK_IS_ON()
+  // Register that the relations for this element have been cached, to
+  // help enforce that relations are never missed.
+  DOMNodeId node_id = DOMNodeIds::IdForNode(&element);
+  DCHECK(node_id);
+  processed_elements_.insert(node_id);
+#endif
+
+  // Register aria-owns.
+  Vector<String> owned_ids;
+  AXObject::TokenVectorFromAttribute(&element, owned_ids,
+                                     html_names::kAriaOwnsAttr);
+  if (!owned_ids.empty()) {
+    UpdateReverseRelations(id_attr_to_owns_relation_mapping_, &element,
+                           owned_ids);
+  }
+
+  // Register <label for>.
+  const auto& id = element.FastGetAttribute(html_names::kForAttr);
+  if (!id.empty()) {
+    all_previously_seen_label_target_ids_.insert(id);
+  }
+
+  // Register aria-labelledby, aria-describedby relations.
+  UpdateReverseTextRelations(element);
+
+  // Register aria-activedescendant.
+  if (auto& activedescendant_id =
+          AccessibleNode::GetPropertyOrARIAAttributeValue(
+              &element, AOMRelationProperty::kActiveDescendant)) {
+    UpdateReverseActiveDescendantRelations(&element, activedescendant_id);
+  }
+}
+
+#if DCHECK_IS_ON()
+void AXRelationCache::CheckRelationsCached(Element& element) {
+  CheckElementWasProcessed(element);
+
+  // Check aria-owns.
+  Vector<String> owns_ids;
+  AXObject::TokenVectorFromAttribute(&element, owns_ids,
+                                     html_names::kAriaOwnsAttr);
+  for (const auto& owns_id : owns_ids) {
+    DCHECK(id_attr_to_owns_relation_mapping_.Contains(owns_id))
+        << element << " with aria-owns=" << owns_id
+        << " and DOMNodeId=" << DOMNodeIds::ExistingIdForNode(&element)
+        << " should already be in cache.";
+  }
+
+  // Check <label for>.
+  if (IsA<HTMLLabelElement>(element)) {
+    const auto& for_id = element.FastGetAttribute(html_names::kForAttr);
+    if (!for_id.empty()) {
+      DCHECK(all_previously_seen_label_target_ids_.Contains(for_id))
+          << element << " <label for=" << for_id
+          << " with DOMNodeId=" << DOMNodeIds::ExistingIdForNode(&element)
+          << " should already be in cache.";
+    }
   }
 
-  initialized_ = true;
+  // Check aria-labelledby, aria-describedby.
+  Vector<String> target_ids = GetTextRelationIds(element);
+  for (const auto& target_id : target_ids) {
+    DCHECK(id_attr_to_text_relation_mapping_.Contains(target_id))
+        << element << " with aria-labelledby/describedby=" << target_id
+        << " and DOMNodeId=" << DOMNodeIds::ExistingIdForNode(&element)
+        << " should already be in cache.";
+  }
+
+  // Check aria-activedescendant.
+  if (auto activedescendant_id =
+          AccessibleNode::GetPropertyOrARIAAttributeValue(
+              &element, AOMRelationProperty::kActiveDescendant)) {
+    DCHECK(id_attr_to_active_descendant_mapping_.Contains(activedescendant_id))
+        << element << " with aria-activedescendant=" << activedescendant_id
+        << " and DOMNodeId=" << DOMNodeIds::ExistingIdForNode(&element)
+        << " should already be in cache.";
+  }
 }
 
-void AXRelationCache::ProcessUpdatesWithCleanLayout() {
-  if (!initialized_)
-    DoInitialDocumentScan();
+void AXRelationCache::CheckElementWasProcessed(Element& element) {
+  DOMNodeId node_id = DOMNodeIds::ExistingIdForNode(&element);
+  if (node_id && processed_elements_.Contains(node_id)) {
+    return;
+  }
 
+  // Find first ancestor that was not processed.
+  Node* ancestor = &element;
+  if (element.GetDocument().IsFlatTreeTraversalForbidden()) {
+    LOG(ERROR) << "Note: flat tree traversal forbidden.";
+  } else {
+    while (true) {
+      Node* next_ancestor = FlatTreeTraversal::Parent(*ancestor);
+      if (!next_ancestor) {
+        break;
+      }
+      if (!IsA<Element>(next_ancestor)) {
+        break;
+      }
+
+      node_id = DOMNodeIds::ExistingIdForNode(next_ancestor);
+      if (node_id && processed_elements_.Contains(node_id)) {
+        // next_ancestor was not processed, therefore ancestor is the
+        // top unprocessed node.
+        break;
+      }
+      ancestor = next_ancestor;
+    }
+  }
+
+  AXObject* obj = Get(ancestor);
+  NOTREACHED_NORETURN()
+      << "The following element was attached to the document, but "
+         "UpdateCacheAfterNodeIsAttached() was never called with it, and it "
+         "did not exist when the cache was first initialized:"
+      << "\n* Element: " << ancestor
+      << "\n* LayoutObject: " << ancestor->GetLayoutObject()
+      << "\n* AXObject: " << (obj ? obj->ToString(true, true) : "") << "\n"
+      << (obj && obj->ParentObjectIncludedInTree()
+              ? obj->ParentObjectIncludedInTree()->GetAXTreeForThis()
+              : "");
+}
+#endif
+
+void AXRelationCache::ProcessUpdatesWithCleanLayout() {
   HashSet<AXID> old_owner_ids_to_update;
   old_owner_ids_to_update.swap(owner_ids_to_update_);
 
@@ -56,15 +193,11 @@
       UpdateAriaOwnsWithCleanLayout(obj);
   }
 
-  // TODO(1301117): this is a workaround to avoid an infinite loop.
-  // owner_ids_to_update_ is modified in calls to
-  // UpdateAriaOwnsWithCleanLayout and add again AXIDs that will end up
-  // looping forever in AXObjectCacheImpl::ProcessDeferredAccessibilityEvents
   owner_ids_to_update_.clear();
 }
 
 bool AXRelationCache::IsDirty() const {
-  return !initialized_ || !owner_ids_to_update_.empty();
+  return !owner_ids_to_update_.empty();
 }
 
 bool AXRelationCache::IsAriaOwned(const AXObject* child) const {
@@ -93,6 +226,19 @@
   return nullptr;
 }
 
+Vector<String> AXRelationCache::GetTextRelationIds(Element& relation_source) {
+  Vector<String> ids_1, ids_2, ids_3;
+  AXObject::TokenVectorFromAttribute(&relation_source, ids_1,
+                                     html_names::kAriaLabelledbyAttr);
+  AXObject::TokenVectorFromAttribute(&relation_source, ids_2,
+                                     html_names::kAriaLabeledbyAttr);
+  AXObject::TokenVectorFromAttribute(&relation_source, ids_3,
+                                     html_names::kAriaDescribedbyAttr);
+  ids_1.AppendVector(ids_2);
+  ids_1.AppendVector(ids_3);
+  return ids_1;
+}
+
 // Update reverse relation map, where relation_source is related to target_ids.
 // TODO Support when HasExplicitlySetAttrAssociatedElement() == true.
 void AXRelationCache::UpdateReverseRelations(
@@ -106,10 +252,33 @@
   }
 }
 
+void AXRelationCache::UpdateReverseTextRelations(Element& relation_source) {
+  // Update cache of reverse relations for labels and descriptions.
+  UpdateReverseTextRelations(relation_source,
+                             GetTextRelationIds(relation_source));
+}
+
 void AXRelationCache::UpdateReverseTextRelations(
-    Node* relation_source,
+    Element& relation_source,
+    const QualifiedName& attr_name) {
+  Vector<String> ids;
+  AXObject::TokenVectorFromAttribute(&relation_source, ids, attr_name);
+  UpdateReverseTextRelations(relation_source, ids);
+}
+
+void AXRelationCache::UpdateReverseTextRelations(
+    Element& relation_source,
     const Vector<String>& target_ids) {
-  UpdateReverseRelations(id_attr_to_text_relation_mapping_, relation_source,
+  // Get a list of ids that are new targets of text relations.
+  Vector<String> new_target_ids;
+  for (const auto& id : target_ids) {
+    if (!id_attr_to_text_relation_mapping_.Contains(id)) {
+      new_target_ids.push_back(id);
+    }
+  }
+
+  // Update the target ids so that the point back to the relation source node.
+  UpdateReverseRelations(id_attr_to_text_relation_mapping_, &relation_source,
                          target_ids);
 }
 
@@ -574,6 +743,10 @@
     }
   }
 
+  if (object_cache_->IsProcessingDeferredEvents()) {
+    ProcessUpdatesWithCleanLayout();
+  }
+
   UpdateRelatedText(node);
 
   UpdateRelatedActiveDescendant(node);
@@ -614,8 +787,8 @@
     }
 
     // Forward relation via <label for="[id]">.
-    if (IsA<HTMLLabelElement>(*current_node)) {
-      LabelChanged(current_node);
+    if (HTMLLabelElement* label = DynamicTo<HTMLLabelElement>(current_node)) {
+      object_cache_->MarkElementDirtyWithCleanLayout(LabelChanged(*label));
       break;  // Unlikely/unusual to need multiple name/description changes.
     }
   }
@@ -696,16 +869,14 @@
   object->ChildrenChangedWithCleanLayout();
 }
 
-void AXRelationCache::LabelChanged(Node* node) {
-  const auto& id =
-      To<HTMLElement>(node)->FastGetAttribute(html_names::kForAttr);
-  if (!id.empty()) {
-    all_previously_seen_label_target_ids_.insert(id);
-    if (AXObject* obj = Get(To<HTMLLabelElement>(node)->control())) {
-      if (obj->AccessibilityIsIncludedInTree())
-        object_cache_->MarkAXObjectDirtyWithCleanLayout(obj);
-    }
+Node* AXRelationCache::LabelChanged(HTMLLabelElement& label) {
+  const auto& id = label.FastGetAttribute(html_names::kForAttr);
+  if (id.empty()) {
+    return nullptr;
   }
+
+  all_previously_seen_label_target_ids_.insert(id);
+  return label.control();
 }
 
 void AXRelationCache::MaybeRestoreParentOfOwnedChild(AXObject* child) {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
index 75095cc..dc58ac1 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_relation_cache.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_ACCESSIBILITY_AX_RELATION_CACHE_H_
 
 #include "third_party/blink/renderer/core/dom/dom_node_ids.h"
+#include "third_party/blink/renderer/core/html/forms/html_label_element.h"
 #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
@@ -23,9 +24,10 @@
 
   AXRelationCache(const AXRelationCache&) = delete;
   AXRelationCache& operator=(const AXRelationCache&) = delete;
-
   virtual ~AXRelationCache();
 
+  void Init();
+
   //
   // Safe to call at any time. Doesn't make any changes to the tree.
   //
@@ -73,16 +75,35 @@
       HashMap<String, HashSet<DOMNodeId>>& id_attr_to_node_map,
       Node* relation_source,
       const Vector<String>& target_ids);
+
+  void UpdateReverseTextRelations(Element& relation_source,
+                                  const QualifiedName& attr_name);
+
   // Update map of ids to related objects for aria-labelledby/aria-describedby.
-  void UpdateReverseTextRelations(Node* relation_source,
+  void UpdateReverseTextRelations(Element& relation_source);
+  void UpdateReverseTextRelations(Element& relation_source,
                                   const Vector<String>& target_ids);
 
   void UpdateReverseActiveDescendantRelations(Node* relation_source,
                                               const String& id);
 
+  // Process a new element and cache relations from its relevant attributes
+  // using values of type IDREF/IDREFS.
+  void CacheRelationIds(Element& element);
+
+#if DCHECK_IS_ON()
+  void CheckElementWasProcessed(Element& element);
+
+  // Check that reverse relations were cached when the node was attached via
+  // AXObjectCacheImpl::UpdateCacheAfterNodeIsAttached() or in
+  // AXRelationCache::DoInitialDocumentScan().
+  void CheckRelationsCached(Element& element);
+#endif
+
   // Called when the "for" attribute of a label element changes and the
   // reverse mapping needs to be updated.
-  void LabelChanged(Node*);
+  // Returns the control, if any, pointed to by the label.
+  Node* LabelChanged(HTMLLabelElement&);
 
   //
   // Only called when layout is clean, in the kInAccessibility lifecycle
@@ -123,7 +144,14 @@
   static bool IsValidOwner(AXObject* owner);
   static bool IsValidOwnedChild(AXObject* child);
 
+#if EXPENSIVE_DCHECKS_ARE_ON()
+  void ElementHasBeenProcessed(Element&);
+#endif
+
  private:
+  // Check that the element has been previouslly processed.
+  void CheckElementWasProcessed(Element&) const;
+
   // Returns the parent of the given object due to aria-owns.
   AXObject* GetAriaOwnedParent(const AXObject*) const;
 
@@ -142,6 +170,9 @@
   // aria-describedby or aria-labeledby, update the text for the related object.
   void UpdateRelatedText(Node*);
 
+  // Get ids that the element points to via aria-labelledby/describedby.
+  Vector<String> GetTextRelationIds(Element& relation_source);
+
   bool IsValidOwnsRelation(AXObject* owner, AXObject* child) const;
   void UnmapOwnedChildrenWithCleanLayout(const AXObject* owner,
                                          const Vector<AXID>& removed_child_ids,
@@ -162,10 +193,6 @@
       HeapVector<Member<AXObject>>& validated_owned_children_result,
       bool force);
 
-  // Whether the document has been scanned for initial relationships
-  // first or not.
-  bool initialized_ = false;
-
   WeakPersistent<AXObjectCacheImpl> object_cache_;
 
   // Map from the AXID of the owner to the AXIDs of the children.
@@ -212,9 +239,17 @@
   AXObject* Get(Node*);
   void ChildrenChanged(AXObject*);
 
-  // Do an initial scan of the document to find any relationships.
-  // We'll catch any subsequent ones when attributes change.
-  void DoInitialDocumentScan();
+  // Do an initial scan of document to find any relations. We'll catch any
+  // subsequent relations when nodes fare attached or attributes change.
+  void DoInitialDocumentScan(Document&);
+
+#if DCHECK_IS_ON()
+  // A list of all elements that have had a chance to be processed for relations
+  // before an AXObject has been created (it's important for crrev.com/c/4778093
+  // to process relations first). An error here indicates that
+  // UpdateCacheAfterNodeIsAttached() was never called for the element.
+  HashSet<DOMNodeId> processed_elements_;
+#endif
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.cc b/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.cc
index 509edb9..b8c52b0 100644
--- a/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.cc
+++ b/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.cc
@@ -5,28 +5,48 @@
 #include "third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h"
 
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-blink.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom.h"
 #include "third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h"
 #include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 
 namespace blink {
 
+namespace {
+
+mojom::blink::WorkletGlobalScopeCreationParamsPtr ToBlinkMojomType(
+    mojom::WorkletGlobalScopeCreationParamsPtr global_scope_creation_params) {
+  return mojom::blink::WorkletGlobalScopeCreationParams::New(
+      KURL(global_scope_creation_params->script_url),
+      global_scope_creation_params->devtools_token,
+      CrossVariantMojoRemote<mojom::WorkletDevToolsHostInterfaceBase>(
+          std::move(global_scope_creation_params->devtools_host)));
+}
+
+}  // namespace
+
 // static
 void WebSharedStorageWorkletThread::Start(
     scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
     CrossVariantMojoReceiver<
-        mojom::blink::SharedStorageWorkletServiceInterfaceBase> receiver) {
-  MakeGarbageCollected<WebSharedStorageWorkletThreadImpl>(main_thread_runner,
-                                                          std::move(receiver));
+        mojom::blink::SharedStorageWorkletServiceInterfaceBase> receiver,
+    mojom::WorkletGlobalScopeCreationParamsPtr global_scope_creation_params) {
+  MakeGarbageCollected<WebSharedStorageWorkletThreadImpl>(
+      main_thread_runner, std::move(receiver),
+      ToBlinkMojomType(std::move(global_scope_creation_params)));
 }
 
 WebSharedStorageWorkletThreadImpl::WebSharedStorageWorkletThreadImpl(
     scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
-    mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver)
+    mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver,
+    mojom::blink::WorkletGlobalScopeCreationParamsPtr
+        global_scope_creation_params)
     : main_thread_runner_(std::move(main_thread_runner)) {
   DCHECK(main_thread_runner_->BelongsToCurrentThread());
 
   messaging_proxy_ = MakeGarbageCollected<SharedStorageWorkletMessagingProxy>(
       main_thread_runner_, std::move(receiver),
+      std::move(global_scope_creation_params),
       /*worklet_terminated_callback=*/
       WTF::BindOnce(&WebSharedStorageWorkletThreadImpl::DeleteSelf,
                     WrapPersistent(this)));
diff --git a/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h b/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h
index ce38979..942569c 100644
--- a/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h
+++ b/third_party/blink/renderer/modules/exported/web_shared_storage_worklet_thread_impl.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_EXPORTED_WEB_SHARED_STORAGE_WORKLET_THREAD_IMPL_H_
 
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-blink-forward.h"
 #include "third_party/blink/public/web/web_shared_storage_worklet_thread.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h"
@@ -23,8 +24,9 @@
  public:
   WebSharedStorageWorkletThreadImpl(
       scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
-      mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService>
-          receiver);
+      mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver,
+      mojom::blink::WorkletGlobalScopeCreationParamsPtr
+          global_scope_creation_params);
 
   ~WebSharedStorageWorkletThreadImpl() override;
 
diff --git a/third_party/blink/renderer/modules/file_system_access/file_system_observer.cc b/third_party/blink/renderer/modules/file_system_access/file_system_observer.cc
index fcaa0225..042664f 100644
--- a/third_party/blink/renderer/modules/file_system_access/file_system_observer.cc
+++ b/third_party/blink/renderer/modules/file_system_access/file_system_observer.cc
@@ -31,10 +31,6 @@
     ExceptionState& exception_state) {
   auto* context = ExecutionContext::From(script_state);
 
-  if (!base::FeatureList::IsEnabled(blink::features::kFileSystemObserver)) {
-    return nullptr;
-  }
-
   SECURITY_CHECK(context->IsWindow() ||
                  context->IsDedicatedWorkerGlobalScope() ||
                  context->IsSharedWorkerGlobalScope());
@@ -71,8 +67,6 @@
       callback_(callback),
       observer_receivers_(this, context),
       host_remote_(context) {
-  CHECK(base::FeatureList::IsEnabled(blink::features::kFileSystemObserver));
-
   host_remote_.Bind(std::move(host_remote),
                     execution_context_->GetTaskRunner(TaskType::kStorage));
 }
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.cc b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.cc
index 7888fce..200bafc 100644
--- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.cc
+++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.cc
@@ -9,6 +9,7 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/serialization/serialized_script_value.h"
 #include "third_party/blink/renderer/core/workers/threaded_worklet_object_proxy.h"
 #include "third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_thread.h"
@@ -23,6 +24,8 @@
 SharedStorageWorkletMessagingProxy::SharedStorageWorkletMessagingProxy(
     scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
     mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver,
+    mojom::blink::WorkletGlobalScopeCreationParamsPtr
+        global_scope_creation_params,
     base::OnceClosure worklet_terminated_callback)
     : ThreadedWorkletMessagingProxy(
           /*execution_context=*/nullptr,
@@ -30,7 +33,9 @@
       worklet_terminated_callback_(std::move(worklet_terminated_callback)) {
   DCHECK(IsMainThread());
 
-  Initialize(/*worker_clients=*/nullptr, /*module_responses_map=*/nullptr);
+  Initialize(/*worker_clients=*/nullptr, /*module_responses_map=*/nullptr,
+             /*thread_startup_data=*/absl::nullopt,
+             std::move(global_scope_creation_params));
 
   PostCrossThreadTask(
       *GetWorkerThread()->GetTaskRunner(TaskType::kMiscPlatformAPI), FROM_HERE,
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h
index c23cca0..278ddd65 100644
--- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h
+++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_messaging_proxy.h
@@ -9,6 +9,7 @@
 
 #include "third_party/blink/public/common/browser_interface_broker_proxy.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom-blink-forward.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-blink-forward.h"
 #include "third_party/blink/renderer/core/workers/threaded_worklet_messaging_proxy.h"
 #include "third_party/blink/renderer/modules/modules_export.h"
 #include "third_party/blink/renderer/platform/heap/cross_thread_handle.h"
@@ -32,6 +33,8 @@
   SharedStorageWorkletMessagingProxy(
       scoped_refptr<base::SingleThreadTaskRunner> main_thread_runner,
       mojo::PendingReceiver<mojom::blink::SharedStorageWorkletService> receiver,
+      mojom::blink::WorkletGlobalScopeCreationParamsPtr
+          global_scope_creation_params,
       base::OnceClosure worklet_terminated_callback);
 
   void WorkerThreadTerminated() override;
diff --git a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc
index 38d80a8..7cf21bd 100644
--- a/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc
+++ b/third_party/blink/renderer/modules/shared_storage/shared_storage_worklet_unittest.cc
@@ -35,6 +35,7 @@
 #include "third_party/blink/public/mojom/private_aggregation/private_aggregation_host.mojom-blink.h"
 #include "third_party/blink/public/mojom/shared_storage/shared_storage_worklet_service.mojom.h"
 #include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom-blink.h"
+#include "third_party/blink/public/mojom/worker/worklet_global_scope_creation_params.mojom-blink.h"
 #include "third_party/blink/public/platform/web_runtime_features.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
 #include "third_party/blink/renderer/core/messaging/blink_cloneable_message_mojom_traits.h"
@@ -108,6 +109,30 @@
   return result;
 }
 
+class TestWorkletDevToolsHost : public mojom::blink::WorkletDevToolsHost {
+ public:
+  explicit TestWorkletDevToolsHost(
+      mojo::PendingReceiver<mojom::blink::WorkletDevToolsHost> receiver)
+      : receiver_(this, std::move(receiver)) {}
+
+  void OnReadyForInspection(
+      mojo::PendingRemote<mojom::blink::DevToolsAgent> agent,
+      mojo::PendingReceiver<mojom::blink::DevToolsAgentHost> agent_host)
+      override {
+    EXPECT_FALSE(ready_for_inspection_);
+    ready_for_inspection_ = true;
+  }
+
+  void FlushForTesting() { receiver_.FlushForTesting(); }
+
+  bool ready_for_inspection() const { return ready_for_inspection_; }
+
+ private:
+  bool ready_for_inspection_ = false;
+
+  mojo::Receiver<mojom::blink::WorkletDevToolsHost> receiver_{this};
+};
+
 class TestClient : public blink::mojom::SharedStorageWorkletServiceClient {
  public:
   explicit TestClient(mojo::PendingAssociatedReceiver<
@@ -380,6 +405,7 @@
   base::test::TestFuture<void> worklet_terminated_future_;
 
   std::unique_ptr<TestClient> test_client_;
+  std::unique_ptr<TestWorkletDevToolsHost> test_worklet_devtools_host_;
   std::unique_ptr<MockMojomPrivateAggregationHost>
       mock_private_aggregation_host_;
 
@@ -435,11 +461,23 @@
     mojo::PendingReceiver<mojom::SharedStorageWorkletService> receiver =
         shared_storage_worklet_service_.BindNewPipeAndPassReceiver();
 
+    mojo::PendingRemote<mojom::blink::WorkletDevToolsHost>
+        pending_devtools_host_remote;
+    mojo::PendingReceiver<mojom::blink::WorkletDevToolsHost>
+        pending_devtools_host_receiver =
+            pending_devtools_host_remote.InitWithNewPipeAndPassReceiver();
+    test_worklet_devtools_host_ = std::make_unique<TestWorkletDevToolsHost>(
+        std::move(pending_devtools_host_receiver));
+
     messaging_proxy_ = MakeGarbageCollected<SharedStorageWorkletMessagingProxy>(
         base::SingleThreadTaskRunner::GetCurrentDefault(),
         CrossVariantMojoReceiver<
             mojom::blink::SharedStorageWorkletServiceInterfaceBase>(
             std::move(receiver)),
+        mojom::blink::WorkletGlobalScopeCreationParams::New(
+            KURL(kModuleScriptSource),
+            /*devtools_worker_token=*/base::UnguessableToken(),
+            std::move(pending_devtools_host_remote)),
         worklet_terminated_future_.GetCallback());
 
     mojo::PendingAssociatedRemote<mojom::SharedStorageWorkletServiceClient>
@@ -475,6 +513,9 @@
   AddModuleResult result = AddModule(/*script_content=*/"let a = 1;");
   EXPECT_TRUE(result.success);
   EXPECT_TRUE(result.error_message.empty());
+
+  test_worklet_devtools_host_->FlushForTesting();
+  EXPECT_TRUE(test_worklet_devtools_host_->ready_for_inspection());
 }
 
 TEST_F(SharedStorageWorkletTest, AddModule_SimpleScriptError) {
@@ -482,6 +523,9 @@
   EXPECT_FALSE(result.success);
   EXPECT_THAT(result.error_message,
               testing::HasSubstr("ReferenceError: a is not defined"));
+
+  test_worklet_devtools_host_->FlushForTesting();
+  EXPECT_TRUE(test_worklet_devtools_host_->ready_for_inspection());
 }
 
 TEST_F(SharedStorageWorkletTest, AddModule_ScriptDownloadError) {
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 898a6d2..cfe7b5b02 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -677,6 +677,13 @@
       status: "stable",
     },
     {
+      name: "CompositionForegroundMarkers",
+      status: {
+        "Android": "stable",
+        "default": "",
+      }
+    },
+    {
       name: "CompressionDictionaryTransport",
       base_feature: "none",
       origin_trial_feature_name: "CompressionDictionaryTransport",
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py
index be76d4f0..b395b22 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline.py
@@ -39,6 +39,7 @@
     Dict,
     List,
     NamedTuple,
+    Optional,
     Set,
     Tuple,
 )
@@ -245,7 +246,11 @@
     def runs_for_test(self, test: str):
         return list(self._test_map[test])
 
-    def add(self, test, build, step_name=None, port_name=None):
+    def add(self,
+            test: str,
+            build: Build,
+            step_name: str,
+            port_name: Optional[str] = None):
         """Adds an entry for baselines to download for some set of tests.
 
         Args:
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py
index 716098f..929ecdd5 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl.py
@@ -386,7 +386,8 @@
             _log.warning('Unexpected retry summary content:\n%s', content)
             return None
 
-    def fill_in_missing_results(self, test_baseline_set):
+    def fill_in_missing_results(
+            self, test_baseline_set: TestBaselineSet) -> TestBaselineSet:
         """Adds entries, filling in results for missing jobs.
 
         For each test prefix, if there is an entry missing for some port,
@@ -397,21 +398,38 @@
         is an entry for the "win-win11" port, then an entry might be added
         for "win-win10" using the results from "win-win11".
         """
-        all_ports = {
-            self._tool.builders.port_name_for_builder_name(b)
-            for b in self.selected_try_bots
-        }
-        for test in test_baseline_set.all_tests():
-            build_port_pairs = test_baseline_set.build_port_pairs(test)
-            missing_ports = all_ports - {p for _, p in build_port_pairs}
-            if not missing_ports:
-                continue
-            _log.info('For %s:', test)
-            for port in sorted(missing_ports):
-                build = self._choose_fill_in_build(port, build_port_pairs)
-                _log.info('Using "%s" build %d for %s.', build.builder_name,
-                          build.build_number, port)
-                test_baseline_set.add(test, build, port_name=port)
+        # Group tasks by step, since not all steps run the same tests (e.g., we
+        # should not fill in WPT tests in a `blink_web_tests` step).
+        tasks_by_step = collections.defaultdict(set)
+        for task in test_baseline_set:
+            tasks_by_step[task.step_name].add(task)
+        for step_name, tasks in tasks_by_step.items():
+            all_ports = {
+                self._tool.builders.port_name_for_builder_name(builder)
+                for builder in self.selected_try_bots if step_name in
+                self._tool.builders.step_names_for_builder(builder)
+            }
+            build_ports_by_test = collections.defaultdict(set)
+            for task in tasks:
+                build_ports_by_test[task.test].add(
+                    (task.build, task.port_name))
+            for test in sorted(build_ports_by_test):
+                build_port_pairs = build_ports_by_test[test]
+                missing_ports = all_ports - {
+                    port
+                    for _, port in build_port_pairs
+                }
+                if not missing_ports:
+                    continue
+                _log.info('For %s:', test)
+                for port in sorted(missing_ports):
+                    build = self._choose_fill_in_build(port, build_port_pairs)
+                    _log.info('Using "%s" build %d for %s.',
+                              build.builder_name, build.build_number, port)
+                    test_baseline_set.add(test,
+                                          build,
+                                          step_name,
+                                          port_name=port)
         return test_baseline_set
 
     def _choose_fill_in_build(self, target_port, build_port_pairs):
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py
index 2f5b992..04bcf74 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_cl_unittest.py
@@ -876,26 +876,40 @@
                 'port_name': 'foo-foo12',
                 'specifiers': ['Foo12', 'Release'],
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
             'MOCK Foo45': {
                 'port_name': 'foo-foo45',
                 'specifiers': ['Foo45', 'Release'],
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
             'MOCK Bar3': {
                 'port_name': 'bar-bar3',
                 'specifiers': ['Bar3', 'Release'],
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
             'MOCK Bar4': {
                 'port_name': 'bar-bar4',
                 'specifiers': ['Bar4', 'Release'],
                 'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                },
             },
         })
         test_baseline_set = TestBaselineSet(self.tool.builders)
-        test_baseline_set.add('one/flaky-fail.html', Build('MOCK Foo12', 100))
-        test_baseline_set.add('one/flaky-fail.html', Build('MOCK Bar4', 200))
+        test_baseline_set.add('one/flaky-fail.html', Build('MOCK Foo12', 100),
+                              'blink_web_tests (with patch)')
+        test_baseline_set.add('one/flaky-fail.html', Build('MOCK Bar4', 200),
+                              'blink_web_tests (with patch)')
         self.command.fill_in_missing_results(test_baseline_set)
         self.assertEqual(
             sorted(test_baseline_set.build_port_pairs('one/flaky-fail.html')),
@@ -911,6 +925,58 @@
             'INFO: Using "MOCK Foo12" build 100 for foo-foo45.\n',
         ])
 
+    def test_fill_in_missing_results_partition_by_steps(self):
+        self.tool.builders = BuilderList({
+            'MOCK Foo12': {
+                'port_name': 'foo-foo12',
+                'specifiers': ['Foo12', 'Release'],
+                'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                    'blink_wpt_tests (with patch)': {},
+                },
+            },
+            'MOCK Foo45': {
+                'port_name': 'foo-foo45',
+                'specifiers': ['Foo45', 'Release'],
+                'is_try_builder': True,
+                'steps': {
+                    'blink_web_tests (with patch)': {},
+                    'blink_wpt_tests (with patch)': {},
+                },
+            },
+        })
+        test_baseline_set = TestBaselineSet(self.tool.builders)
+        test_baseline_set.add('one/flaky-fail.html', Build('MOCK Foo12', 100),
+                              'blink_web_tests (with patch)')
+        test_baseline_set.add('two/image-fail.html', Build('MOCK Foo45', 200),
+                              'blink_wpt_tests (with patch)')
+        self.command.fill_in_missing_results(test_baseline_set)
+        self.assertEqual(
+            sorted(test_baseline_set.runs_for_test('one/flaky-fail.html')),
+            [
+                # Do not add this test to `blink_wpt_tests`.
+                (Build('MOCK Foo12',
+                       100), 'blink_web_tests (with patch)', 'foo-foo12'),
+                (Build('MOCK Foo12',
+                       100), 'blink_web_tests (with patch)', 'foo-foo45'),
+            ])
+        self.assertEqual(
+            sorted(test_baseline_set.runs_for_test('two/image-fail.html')),
+            [
+                # Do not add this test to `blink_web_tests`.
+                (Build('MOCK Foo45',
+                       200), 'blink_wpt_tests (with patch)', 'foo-foo12'),
+                (Build('MOCK Foo45',
+                       200), 'blink_wpt_tests (with patch)', 'foo-foo45'),
+            ])
+        self.assertLog([
+            'INFO: For one/flaky-fail.html:\n',
+            'INFO: Using "MOCK Foo12" build 100 for foo-foo45.\n',
+            'INFO: For two/image-fail.html:\n',
+            'INFO: Using "MOCK Foo45" build 200 for foo-foo12.\n',
+        ])
+
     def test_explicit_builder_list(self):
         builders = ['MOCK Try Linux', 'MOCK Try Mac']
         options = self.command_options(builders=builders)
diff --git a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py
index 95ee96b..50f33369 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/rebaseline_unittest.py
@@ -404,22 +404,26 @@
     def test_rebaseline_test_passes_on_all_builders(self):
         self.tool.results_fetcher.set_results(
             Build('MOCK Win7'),
-            WebTestResults.from_json({
-                'tests': {
-                    'userscripts': {
-                        'first-test.html': {
-                            'expected': 'REBASELINE',
-                            'actual': 'PASS'
-                        }
-                    }
-                }
-            }))
+            WebTestResults.from_json(
+                {
+                    'tests': {
+                        'userscripts': {
+                            'first-test.html': {
+                                'expected': 'PASS',
+                                'actual': 'PASS',
+                            },
+                        },
+                    },
+                },
+                step_name='blink_web_tests (with patch)'))
 
-        self._write(self.test_expectations_path,
-                    'Bug(x) userscripts/first-test.html [ Failure ]\n')
+        self._write(
+            self.test_expectations_path, '# results: [ Failure ]\n'
+            'userscripts/first-test.html [ Failure ]\n')
         test_baseline_set = TestBaselineSet(self.tool.builders)
         test_baseline_set.add('userscripts/first-test.html',
-                              Build('MOCK Win7'))
+                              Build('MOCK Win7'),
+                              'blink_web_tests (with patch)')
         self.command.rebaseline(self.options(), test_baseline_set)
         self.tool.main.assert_not_called()
 
@@ -867,9 +871,11 @@
             }))
         test_baseline_set = TestBaselineSet(self.tool.builders)
         test_baseline_set.add('userscripts/skipped-test.html',
-                              Build('MOCK Mac10.11'))
+                              Build('MOCK Mac10.11'),
+                              'blink_web_tests (with patch)')
         test_baseline_set.add('userscripts/skipped-test.html',
-                              Build('MOCK Win7'))
+                              Build('MOCK Win7'),
+                              'blink_web_tests (with patch)')
 
         self.command.rebaseline(self.options(), test_baseline_set)
 
@@ -903,7 +909,8 @@
             }))
         test_baseline_set = TestBaselineSet(self.tool.builders)
         test_baseline_set.add('userscripts/flaky-test.html',
-                              Build('MOCK Mac10.11'))
+                              Build('MOCK Mac10.11'),
+                              'blink_web_tests (with patch)')
 
         self.command.rebaseline(self.options(), test_baseline_set)
 
@@ -937,7 +944,8 @@
                 }
             }))
         test_baseline_set.add('userscripts/all-pass.html',
-                              Build('MOCK Mac10.11'))
+                              Build('MOCK Mac10.11'),
+                              'blink_web_tests (with patch)')
 
         self.command.rebaseline(self.options(), test_baseline_set)
 
@@ -976,7 +984,8 @@
                         }
                     }
                 }))
-            test_baseline_set.add('userscripts/all-pass.html', Build(builder))
+            test_baseline_set.add('userscripts/all-pass.html', Build(builder),
+                                  'blink_web_tests (with patch)')
 
         self.command.rebaseline(self.options(), test_baseline_set)
 
@@ -1120,18 +1129,21 @@
 
     def test_add_and_iter_tests(self):
         test_baseline_set = TestBaselineSet(self.host.builders)
-        test_baseline_set.add('a/x.html', Build('MOCK Trusty'))
-        test_baseline_set.add('a/y.html', Build('MOCK Trusty'))
-        test_baseline_set.add('a/z.html', Build('MOCK Trusty'))
+        test_baseline_set.add('a/x.html', Build('MOCK Trusty'),
+                              'blink_web_tests (with patch)')
+        test_baseline_set.add('a/y.html', Build('MOCK Trusty'),
+                              'blink_web_tests (with patch)')
+        test_baseline_set.add('a/z.html', Build('MOCK Trusty'),
+                              'blink_web_tests (with patch)')
         test_baseline_set.add('a/z.html', Build('MOCK Win10'),
                               'blink_web_tests (with patch)')
         self.assertEqual(list(test_baseline_set), [
-            ('a/x.html', Build(builder_name='MOCK Trusty'), None,
-             'test-linux-trusty'),
-            ('a/y.html', Build(builder_name='MOCK Trusty'), None,
-             'test-linux-trusty'),
-            ('a/z.html', Build(builder_name='MOCK Trusty'), None,
-             'test-linux-trusty'),
+            ('a/x.html', Build(builder_name='MOCK Trusty'),
+             'blink_web_tests (with patch)', 'test-linux-trusty'),
+            ('a/y.html', Build(builder_name='MOCK Trusty'),
+             'blink_web_tests (with patch)', 'test-linux-trusty'),
+            ('a/z.html', Build(builder_name='MOCK Trusty'),
+             'blink_web_tests (with patch)', 'test-linux-trusty'),
             ('a/z.html', Build(builder_name='MOCK Win10'),
              'blink_web_tests (with patch)', 'test-win-win10'),
         ])
@@ -1144,19 +1156,23 @@
 
     def test_str_basic(self):
         test_baseline_set = TestBaselineSet(self.host.builders)
-        test_baseline_set.add('a/x.html', Build('MOCK Mac10.12'))
+        test_baseline_set.add('a/x.html', Build('MOCK Mac10.12'),
+                              'blink_web_tests (with patch)')
         test_baseline_set.add('a/x.html', Build('MOCK Win10'),
                               'blink_web_tests (with patch)')
-        self.assertRegex(str(test_baseline_set),
-                         'a/x.html: .*, None, test-mac-mac10.12')
+        self.assertRegex(
+            str(test_baseline_set),
+            'a/x.html: .*, blink_web_tests \(with patch\), test-mac-mac10\.12')
         self.assertRegex(
             str(test_baseline_set),
             'a/x.html: .*, blink_web_tests \(with patch\), test-win-win10')
 
     def test_getters(self):
         test_baseline_set = TestBaselineSet(self.host.builders)
-        test_baseline_set.add('a/x.html', Build('MOCK Mac10.12'))
-        test_baseline_set.add('a/x.html', Build('MOCK Win10'))
+        test_baseline_set.add('a/x.html', Build('MOCK Mac10.12'),
+                              'blink_web_tests (with patch)')
+        test_baseline_set.add('a/x.html', Build('MOCK Win10'),
+                              'blink_web_tests (with patch)')
         self.assertEqual(test_baseline_set.all_tests(), ['a/x.html'])
         self.assertEqual(
             test_baseline_set.build_port_pairs('a/x.html'),
@@ -1166,12 +1182,13 @@
     def test_non_prefix_mode(self):
         test_baseline_set = TestBaselineSet(self.host.builders)
         # This test does not exist in setUp.
-        test_baseline_set.add('wpt/foo.html', Build('some-wpt-bot'))
+        test_baseline_set.add('wpt/foo.html', Build('some-wpt-bot'),
+                              'blink_web_tests (with patch)')
         # But it should still appear in various getters since no test lookup is
         # done when prefix_mode=False.
-        self.assertEqual(
-            list(test_baseline_set),
-            [('wpt/foo.html', Build('some-wpt-bot'), None, 'linux-trusty')])
+        self.assertEqual(list(test_baseline_set),
+                         [('wpt/foo.html', Build('some-wpt-bot'),
+                           'blink_web_tests (with patch)', 'linux-trusty')])
         self.assertEqual(test_baseline_set.all_tests(), ['wpt/foo.html'])
         self.assertEqual(test_baseline_set.build_port_pairs('wpt/foo.html'),
                          [(Build('some-wpt-bot'), 'linux-trusty')])
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 fa0114e..98e034a 100644
--- a/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py
+++ b/third_party/blink/tools/blinkpy/tool/commands/update_metadata.py
@@ -552,6 +552,16 @@
                                                    props)
 
 
+class BugUpdate(manifestupdate.AppendOnlyListUpdate):
+    property_name = 'bug'
+
+    def from_ini_value(self, value: Union[str, List[str]]) -> List[str]:
+        return [value] if isinstance(value, str) else value
+
+    def to_ini_value(self, value: List[str]) -> Union[str, List[str]]:
+        return value[0] if len(value) == 1 else value  # Unwrap single bugs.
+
+
 class TestInfo(NamedTuple):
     extra_bugs: Set[str]
     extra_comments: List[str]
@@ -952,10 +962,7 @@
             for section, test_info in self._sections_to_annotate(expected):
                 self._migrate_disables(section, test_info)
                 self._migrate_comments(section, test_info)
-            if self._bug:
-                for test in expected.iterchildren():
-                    if test.modified:
-                        self._add_bug_urls(test, {f'crbug.com/{self._bug}'})
+                self._update_bugs(section, test_info)
 
         modified = expected and expected.modified
         if modified:
@@ -1020,9 +1027,18 @@
         section.node.comments.clear()
         section.node.comments.extend(
             ('comment', comment) for comment in test_info.extra_comments)
-        self._add_bug_urls(section, test_info.extra_bugs, overwrite=False)
         section.modified = True
 
+    def _update_bugs(self, section: wptmanifest.ManifestItem,
+                     test_info: TestInfo):
+        update = BugUpdate(section)
+        for extra_bug in test_info.extra_bugs:
+            update.set(None, extra_bug)
+        if self._bug and section.modified:
+            section.set('bug', [])  # Overwrite existing bugs.
+            update.set(None, f'crbug.com/{self._bug}')
+        update.update()
+
     def _sections_to_annotate(
         self,
         expected: manifestupdate.ExpectedManifest,
@@ -1036,23 +1052,6 @@
             for test in expected.iterchildren():
                 yield test, self._test_info[test.id]
 
-    def _add_bug_urls(self,
-                      test: manifestupdate.TestNode,
-                      new_bugs: FrozenSet[str],
-                      overwrite: bool = True,
-                      key: str = 'bug'):
-        bugs = []
-        with contextlib.suppress(KeyError):
-            bugs = test.get(key)
-            if isinstance(bugs, str):
-                bugs = [bugs]
-        if overwrite:
-            bugs.clear()
-        bugs = sorted({*bugs, *new_bugs})
-        test.clear(key)
-        if bugs:
-            test.set(key, bugs[0] if len(bugs) == 1 else bugs)
-
 
 def _strip_comment(maybe_comment: str) -> str:
     maybe_comment = maybe_comment.lstrip()
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index e877708..4d8ea28b 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -5737,6 +5737,8 @@
 
 crbug.com/1459038 [ Linux ] external/wpt/webmidi/idlharness.https.window.html [ Failure ]
 
+crbug.com/1446799 external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html [ Failure Pass ]
+
 # These tests are optional and not reliably supported in Chrome.
 crbug.com/1370307 [ Release Win ] external/wpt/encoding-detection/ar-ISO-8859-6-late.tentative.html [ Failure Pass ]
 crbug.com/1370307 external/wpt/encoding-detection/ar-windows-1256-late.tentative.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index e6c069e5..8526bb12 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1758,13 +1758,15 @@
     "platforms": ["Linux", "Mac", "Win"],
     "bases": [
       "external/wpt/shared-storage",
+      "http/tests/inspector-protocol/shared-storage",
       "http/tests/inspector-protocol/storage/shared-storage.js",
       "http/tests/inspector-protocol/storage/shared-storage-delete.js",
       "http/tests/inspector-protocol/storage/shared-storage-set.js",
       "http/tests/inspector-protocol/storage/shared-storage-tracking-disabled.js"
     ],
     "exclusive_tests": [
-      "external/wpt/shared-storage"
+      "external/wpt/shared-storage",
+      "http/tests/inspector-protocol/shared-storage"
     ],
     "args": ["--enable-features=SharedStorageAPI,FencedFrames:implementation_type/mparch,PrivacySandboxAdsAPIsOverride,FencedFramesAPIChanges,FencedFramesDefaultMode,SharedStorageAPIM118,FencedFramesEnforceFocus",
              "--disable-threaded-compositing", "--disable-threaded-animation"],
diff --git a/third_party/blink/web_tests/accessibility/aria-activedescendant-events.html b/third_party/blink/web_tests/accessibility/aria-activedescendant-events.html
index 02c3af4..c42995fe 100644
--- a/third_party/blink/web_tests/accessibility/aria-activedescendant-events.html
+++ b/third_party/blink/web_tests/accessibility/aria-activedescendant-events.html
@@ -57,7 +57,7 @@
                   [ "input-textbox", "list2" ],
                   [ "input-combobox", "list3" ],
                   [ "textarea-searchbox", "list4" ],
-                  [  "pure-native-input-textbox", "list5" ] ];
+                  [ "pure-native-input-textbox", "list5" ] ];
 
 function testEventExpectations(t, widgetId, listboxId) {
     var focusChangedEventCount = 0;
@@ -71,17 +71,20 @@
     var axWidget = accessibilityController.accessibleElementById(widgetId);
     var focusChangedEventCount = 0;
     var markDirtyEventCount = 0;
+    var eventsComplete = false;
     axWidget.addNotificationListener(t.step_func(function(notification) {
         if (notification == "Focus") {
-            console.log("Got focus notification on " + widgetId);
             ++focusChangedEventCount;
+            console.log("Got focus notification #" + focusChangedEventCount + " on " + widgetId);
         }
         if (notification == "MarkDirty") {
-            console.log("Got MarkDirty notification on " + widgetId);
             ++markDirtyEventCount;
+            console.log("Got MarkDirty notification #" + markDirtyEventCount + " on " + widgetId);
         }
-        if (focusChangedEventCount == 1 && markDirtyEventCount == 3) {
+        if (focusChangedEventCount >= 1 && markDirtyEventCount >= 3 && !eventsComplete) {
+            eventsComplete = true;
             window.setTimeout(t.step_func(() => {
+                console.log('** Events complete for ' + widgetId);
                 testNext(t);
             }, 0));
         }
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/disallowed-navigations-dangling-markup-urn.https.html b/third_party/blink/web_tests/external/wpt/fenced-frame/disallowed-navigations-dangling-markup-urn.https.html
index eceb2a4a..a1c01d6 100644
--- a/third_party/blink/web_tests/external/wpt/fenced-frame/disallowed-navigations-dangling-markup-urn.https.html
+++ b/third_party/blink/web_tests/external/wpt/fenced-frame/disallowed-navigations-dangling-markup-urn.https.html
@@ -32,7 +32,7 @@
     const interestGroup = {
       name: 'testAd1',
       owner: location.origin,
-      biddingLogicUrl: new URL(FLEDGE_BIDDING_URL, location.origin),
+      biddingLogicURL: new URL(FLEDGE_BIDDING_URL, location.origin),
       ads: [{renderUrl: url_string, bid: 1}],
       userBiddingSignals: {biddingToken: bidding_token},
       trustedBiddingSignalsKeys: ['key1'],
diff --git a/third_party/blink/web_tests/external/wpt/fenced-frame/resources/utils.js b/third_party/blink/web_tests/external/wpt/fenced-frame/resources/utils.js
index a402dfd..10ca3a0 100644
--- a/third_party/blink/web_tests/external/wpt/fenced-frame/resources/utils.js
+++ b/third_party/blink/web_tests/external/wpt/fenced-frame/resources/utils.js
@@ -87,23 +87,23 @@
       {
         name: 'testAd1',
         owner: location.origin,
-        biddingLogicUrl: new URL(FLEDGE_BIDDING_URL, location.origin),
+    biddingLogicURL: new URL(FLEDGE_BIDDING_URL, location.origin),
         ads: [{renderUrl: href, bid: 1}],
         userBiddingSignals: {biddingToken: bidding_token},
         trustedBiddingSignalsKeys: ['key1'],
         adComponents: ad_components_list,
       };
 
-  let biddingUrlParams =
-      new URLSearchParams(interestGroup.biddingLogicUrl.search);
+  let biddingURLParams =
+    new URLSearchParams(interestGroup.biddingLogicURL.search);
   if (requested_size)
-    biddingUrlParams.set(
+    biddingURLParams.set(
         'requested-size', requested_size[0] + '-' + requested_size[1]);
   if (ad_with_size)
-    biddingUrlParams.set('ad-with-size', 1);
+    biddingURLParams.set('ad-with-size', 1);
   if (automatic_beacon)
-    biddingUrlParams.set('automatic-beacon', 1);
-  interestGroup.biddingLogicUrl.search = biddingUrlParams;
+    biddingURLParams.set('automatic-beacon', 1);
+  interestGroup.biddingLogicURL.search = biddingURLParams;
 
   if (ad_with_size) {
     interestGroup.ads[0].sizeGroup = 'group1';
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js
index 9b2b501f..31707aa 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js
@@ -167,31 +167,31 @@
                      enableBiddingSignalsPrioritization: false}
   },
 
-  // "biddingLogicUrl" tests
+  // "biddingLogicURL" tests
   { expectJoinSucces: true,
     expectLeaveSucces: true,
     interestGroup: { ...BASE_INTEREST_GROUP,
-                     biddingLogicUrl: null }
+                     biddingLogicURL: null }
   },
   { expectJoinSucces: false,
     expectLeaveSucces: true,
     interestGroup: { ...BASE_INTEREST_GROUP,
-                     biddingLogicUrl: 'https://{{hosts[][www]}}/foo.js' }
+                     biddingLogicURL: 'https://{{hosts[][www]}}/foo.js' }
   },
   { expectJoinSucces: false,
     expectLeaveSucces: true,
     interestGroup: { ...BASE_INTEREST_GROUP,
-                     biddingLogicUrl: 'data:text/javascript,Foo' }
+                     biddingLogicURL: 'data:text/javascript,Foo' }
   },
   { expectJoinSucces: true,
     expectLeaveSucces: true,
     interestGroup: { ...BASE_INTEREST_GROUP,
-                     biddingLogicUrl: `${window.location.origin}/foo.js`}
+                     biddingLogicURL: `${window.location.origin}/foo.js`}
   },
   { expectJoinSucces: true,
     expectLeaveSucces: true,
     interestGroup: { ...BASE_INTEREST_GROUP,
-                     biddingLogicUrl: 'relative/path' }
+                     biddingLogicURL: 'relative/path' }
   },
 
   // "biddingWasmHelperUrl" tests
@@ -531,7 +531,7 @@
 
   // Joining an interest group without a bidding script and run an auction.
   // There should be no winner.
-  await joinInterestGroup(test, uuid, { biddingLogicUrl: null });
+  await joinInterestGroup(test, uuid, { biddingLogicURL: null });
   assert_equals(null, await runBasicFledgeAuction(test, uuid),
                 'Auction unexpectedly had a winner');
 
@@ -546,7 +546,7 @@
 
   // Re-join the first interest group, and re-run the auction. The interest
   // group should be overwritten again, and there should be no winner.
-  await joinInterestGroup(test, uuid, { biddingLogicUrl: null });
+  await joinInterestGroup(test, uuid, { biddingLogicURL: null });
   assert_equals(null, await runBasicFledgeAuction(test, uuid),
                 'Auction unexpectedly had a winner');
 }, 'Join same interest group overwrites old matching group.');
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js.ini b/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js.ini
index ed4e8ae4..779475d 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js.ini
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/join-leave-ad-interest-group.https.sub.window.js.ini
@@ -95,11 +95,11 @@
     expected:
       if product == "chrome": FAIL
 
-  [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":"data:text/javascript,Foo"}}]
+  [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicURL":"data:text/javascript,Foo"}}]
     expected:
       if product == "chrome": FAIL
 
-  [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":"https://www.web-platform.test/foo.js"}}]
+  [Join and leave interest group: {"expectJoinSucces":false,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicURL":"https://www.web-platform.test/foo.js"}}]
     expected:
       if product == "chrome": FAIL
 
@@ -203,15 +203,15 @@
     expected:
       if product == "chrome": FAIL
 
-  [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":"https://web-platform.test:8444/foo.js"}}]
+  [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicURL":"https://web-platform.test:8444/foo.js"}}]
     expected:
       if product == "chrome": FAIL
 
-  [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":"relative/path"}}]
+  [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicURL":"relative/path"}}]
     expected:
       if product == "chrome": FAIL
 
-  [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicUrl":null}}]
+  [Join and leave interest group: {"expectJoinSucces":true,"expectLeaveSucces":true,"interestGroup":{"owner":"https://web-platform.test:8444","name":"default name","biddingLogicURL":null}}]
     expected:
       if product == "chrome": FAIL
 
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js
index 8fd7df50..103e5f90 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/no-winner.https.sub.window.js
@@ -61,10 +61,10 @@
 
 for (error of BIDDING_LOGIC_SCRIPT_ERRORS) {
   promise_test((async (error, test) => {
-    let biddingLogicUrl = `${BASE_URL}resources/bidding-logic.sub.py?${error}`;
+    let biddingLogicURL = `${BASE_URL}resources/bidding-logic.sub.py?${error}`;
     await runBasicFledgeTestExpectingNoWinner(
       test,
-      {interestGroupOverrides: {biddingLogicUrl: biddingLogicUrl}}
+      {interestGroupOverrides: {biddingLogicURL: biddingLogicURL}}
     );
   }).bind(undefined, error), `Bidding logic script: ${error}`);
 }
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/reporting-arguments.https.sub.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/reporting-arguments.https.sub.window.js
index 3b03d29..0b4d3cf 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/reporting-arguments.https.sub.window.js
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/reporting-arguments.https.sub.window.js
@@ -207,10 +207,12 @@
 promise_test(async test => {
   const uuid = generateUuid(test);
   await joinInterestGroup(test, uuid,
-                          { biddingLogicUrl: createBiddingScriptUrl({bid: -2}),
+    {
+      biddingLogicURL: createBiddingScriptURL({ bid: -2 }),
                             name: 'other interest group 1' });
   await joinInterestGroup(test, uuid,
-                          { biddingLogicUrl: createBiddingScriptUrl({bid: -1}),
+    {
+      biddingLogicURL: createBiddingScriptURL({ bid: -1 }),
                             name: 'other interest group 2' });
   await runReportArgumentValidationTest(
     test,
@@ -225,13 +227,16 @@
 promise_test(async test => {
   const uuid = generateUuid(test);
   await joinInterestGroup(test, uuid,
-                          { biddingLogicUrl: createBiddingScriptUrl({bid: 2}),
+    {
+      biddingLogicURL: createBiddingScriptURL({ bid: 2 }),
                             name: 'other interest group 1' });
   await joinInterestGroup(test, uuid,
-                          { biddingLogicUrl: createBiddingScriptUrl({bid: 5}),
+    {
+      biddingLogicURL: createBiddingScriptURL({ bid: 5 }),
                             name: 'other interest group 2' });
   await joinInterestGroup(test, uuid,
-                          { biddingLogicUrl: createBiddingScriptUrl({bid: 2}),
+    {
+      biddingLogicURL: createBiddingScriptURL({ bid: 2 }),
                             name: 'other interest group 3' });
   await runReportArgumentValidationTest(
     test,
@@ -266,7 +271,8 @@
 promise_test(async test => {
   const uuid = generateUuid(test);
   await joinInterestGroup(test, uuid,
-                          { biddingLogicUrl: createBiddingScriptUrl({bid: -1}),
+    {
+      biddingLogicURL: createBiddingScriptURL({ bid: -1 }),
                             name: 'other interest group 2' });
   await runReportArgumentValidationTest(
     test,
@@ -280,7 +286,8 @@
 promise_test(async test => {
   const uuid = generateUuid(test);
   await joinInterestGroup(test, uuid,
-    { biddingLogicUrl: createBiddingScriptUrl({bid: 1}),
+    {
+      biddingLogicURL: createBiddingScriptURL({ bid: 1 }),
       name: 'other interest group 2' });
 await runReportArgumentValidationTest(
     test,
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js
index f941d228..99461d2 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/resources/fledge-util.js
@@ -127,7 +127,7 @@
 // run, unless it returns something or throws.
 //
 // The default reportWin() method is empty.
-function createBiddingScriptUrl(params = {}) {
+function createBiddingScriptURL(params = {}) {
   let url = new URL(`${BASE_URL}resources/bidding-logic.sub.py`);
   if (params.generateBid)
     url.searchParams.append('generateBid', params.generateBid);
@@ -188,8 +188,8 @@
   let interestGroup = {
     owner: window.location.origin,
     name: DEFAULT_INTEREST_GROUP_NAME,
-    biddingLogicUrl: createBiddingScriptUrl(
-        { reportWin: `sendReportTo('${createBidderReportUrl(uuid)}');` }),
+    biddingLogicURL: createBiddingScriptURL(
+      { reportWin: `sendReportTo('${createBiddingScriptURL(uuid)}');` }),
     ads: [{renderUrl: createRenderUrl(uuid)}],
     ...interestGroupOverrides
   };
@@ -335,19 +335,19 @@
                  }
                  ${reportWin}`;
   }
-  let biddingScriptUrlParams = {};
+  let biddingScriptURLParams = {};
 
   if (generateBid !== undefined) {
-    biddingScriptUrlParams.generateBid = generateBid;
+    biddingScriptURLParams.generateBid = generateBid;
   }
 
   if (reportWin !== null)
-    biddingScriptUrlParams.reportWin = reportWin;
+    biddingScriptURLParams.reportWin = reportWin;
   else
-    biddingScriptUrlParams.error = 'no-reportWin';
+    biddingScriptURLParams.error = 'no-reportWin';
 
   let interestGroupOverrides =
-      { biddingLogicUrl: createBiddingScriptUrl(biddingScriptUrlParams) };
+    { biddingLogicURL: createBiddingScriptURL(biddingScriptURLParams) };
   if (renderUrlOverride)
     interestGroupOverrides.ads = [{renderUrl: renderUrlOverride}]
 
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/round-a-value.https.sub.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/round-a-value.https.sub.window.js
index 252e4db..47eff38 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/round-a-value.https.sub.window.js
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/round-a-value.https.sub.window.js
@@ -60,7 +60,8 @@
 promise_test(async test => {
   const uuid = generateUuid(test);
   await joinInterestGroup(test, uuid,
-    { biddingLogicUrl: createBiddingScriptUrl({ bid: 1.99 }),
+    {
+      biddingLogicURL: createBiddingScriptURL({ bid: 1.99 }),
       name: 'other interest group 1' });
   await runReportTest(
     test, uuid,
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/trusted-bidding-signals.https.sub.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/trusted-bidding-signals.https.sub.window.js
index 90c1c39..7f34e4c 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/trusted-bidding-signals.https.sub.window.js
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/trusted-bidding-signals.https.sub.window.js
@@ -22,8 +22,8 @@
 // fields.
 async function runTrustedBiddingSignalsTest(
     test, generateBidCheck, interestGroupOverrides = {}) {
-  interestGroupOverrides.biddingLogicUrl =
-      createBiddingScriptUrl({
+  interestGroupOverrides.biddingLogicURL =
+    createBiddingScriptURL({
           generateBid: `if (!(${generateBidCheck})) return false;` });
   await runBasicFledgeTestExpectingWinner(
       test, {interestGroupOverrides: interestGroupOverrides});
@@ -36,8 +36,8 @@
 async function runTrustedBiddingSignalsDataVersionTest(
     test, check, interestGroupOverrides = {}) {
   const uuid = generateUuid(test);
-  interestGroupOverrides.biddingLogicUrl =
-      createBiddingScriptUrl({
+  interestGroupOverrides.biddingLogicURL =
+    createBiddingScriptURL({
           generateBid:
               `if (!(${check})) return false;`,
           reportWin:
diff --git a/third_party/blink/web_tests/external/wpt/fledge/tentative/trusted-scoring-signals.https.sub.window.js b/third_party/blink/web_tests/external/wpt/fledge/tentative/trusted-scoring-signals.https.sub.window.js
index 94385fd..60e6ec2 100644
--- a/third_party/blink/web_tests/external/wpt/fledge/tentative/trusted-scoring-signals.https.sub.window.js
+++ b/third_party/blink/web_tests/external/wpt/fledge/tentative/trusted-scoring-signals.https.sub.window.js
@@ -35,8 +35,8 @@
 async function runTrustedScoringSignalsDataVersionTest(
     test, uuid, renderURL, check) {
   const interestGroupOverrides = {
-      biddingLogicUrl :
-          createBiddingScriptUrl({
+      biddingLogicURL :
+      createBiddingScriptURL({
               generateBid:
                   `if (browserSignals.dataVersion !== undefined)
                       throw "Bad browserSignals.dataVersion"`,
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html
index 902e23b4..d501ae0 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_attributes_nohover_pointers.html
@@ -1,110 +1,134 @@
 <!doctype html>
-<title>Pointer Events no-hover pointer attributes test</title>
-<meta name="variant" content="?touch">
-<meta name="viewport" content="width=device-width">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-actions.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<script type="text/javascript" src="pointerevent_support.js"></script>
-<style>
-  div {
-    height: 80px;
-    width: 80px;
-  }
-</style>
-<body onload="run()">
-  <div id="square1"></div>
-  <div id="done"></div>
-</body>
-<script>
-  'use strict';
-  const pointer_type = location.search.substring(1);
-  const test_pointer = pointer_type + "TestPointer";
+<html>
+    <head>
+        <title>Pointer Events properties tests</title>
+        <meta name="viewport" content="width=device-width">
+        <link rel="stylesheet" type="text/css" href="pointerevent_styles.css">
+        <script src="/resources/testharness.js"></script>
+        <script src="/resources/testharnessreport.js"></script>
+        <script src="/resources/testdriver.js"></script>
+        <script src="/resources/testdriver-actions.js"></script>
+        <script src="/resources/testdriver-vendor.js"></script>
+        <!-- Additional helper script for common checks across event types -->
+        <script type="text/javascript" src="pointerevent_support.js"></script>
+        <script>
+            var detected_pointertypes = {};
+            var detected_eventTypes = {};
+            var eventList = ['pointerover', 'pointerenter', 'pointerdown', 'pointerup', 'pointerout', 'pointerleave'];
+            // TODO(mustaq@chromium.org): missing touch pointermove coverage!
+            var expectedPointerId = NaN;
 
-  const logged_events = [
-    "pointerover", "pointerenter", "pointerdown",
-    "pointerup", "pointerout", "pointerleave"
-  ];
+            function resetTestState() {
+                detected_eventTypes = {};
+                document.getElementById("square1").style.visibility = 'visible';
+                document.getElementById('innerFrame').contentDocument.getElementById("square2").style.visibility = 'hidden';
+            }
+            function checkPointerEventAttributes(event, targetBoundingClientRect, testNamePrefix) {
+                if (detected_eventTypes[event.type])
+                    return;
+                var expectedEventType =  eventList[Object.keys(detected_eventTypes).length];
+                detected_eventTypes[event.type] = true;
+                var pointerTestName = (testNamePrefix ? testNamePrefix + ' ' : '')
+                    + expectedPointerType + ' ' + expectedEventType;
 
-  // TODO(mustaq@chromium.org): add pointermove coverage with touch-action:none.
+                detected_pointertypes[event.pointerType] = true;
 
-  function checkPointerEventAttributes(event,
-      expected_pointer_id, expected_event_type,
-      expected_bounding_rect) {
-    assert_equals(event.pointerType, pointer_type,
-        expected_event_type + ".pointerType should match test input");
+                test(function() {
+                    assert_equals(event.type, expectedEventType);
+                }, pointerTestName + ".type should be " + expectedEventType);
 
-    assert_equals(event.pointerId, expected_pointer_id,
-        expected_event_type + ".pointerId should match all other events");
-    assert_equals(event.type, expected_event_type,
-        expected_event_type + ".type should be " + expected_event_type);
+                // Test button and buttons
+                test(function() {
+                    assert_equals(event.button, 0);
+                }, pointerTestName + ".button attribute is 0 on touch-down.");
 
-    assert_equals(event.button, 0,
-        expected_event_type + ".button should be 0");
+                if (event.type == 'pointerdown' || event.type == 'pointerover' || event.type == 'pointerenter') {
+                    test(function() {
+                        assert_equals(event.buttons, 1);
+                    }, pointerTestName + ".buttons attribute is 1 on touch-down.");
+                } else {
+                    test(function() {
+                        assert_equals(event.buttons, 0);
+                    }, pointerTestName + ".buttons is 0 on touch-release.");
+                }
 
-    if (['pointerover', 'pointerenter', 'pointerdown'].includes(event.type)) {
-      assert_equals(event.buttons, 1,
-          expected_event_type + ".buttons should be 1");
-    } else {
-      assert_equals(event.buttons, 0,
-          expected_event_type + ".buttons should be 0");
-    }
+                // Test clientX and clientY
+                test(function () {
+                    assert_true(event.clientX >= targetBoundingClientRect.left && event.clientX < targetBoundingClientRect.right && event.clientY >= targetBoundingClientRect.top && event.clientY < targetBoundingClientRect.bottom);
+                }, pointerTestName + ".clientX and .clientY attributes are correct.");
 
-    assert_true(event.clientX >= expected_bounding_rect.left &&
-        event.clientX < expected_bounding_rect.right,
-        expected_event_type + ".clientX should be within bounding client rect.");
+                check_PointerEvent(event, testNamePrefix);
 
-    assert_true(event.clientY >= expected_bounding_rect.top &&
-        event.clientY < expected_bounding_rect.bottom,
-        expected_event_type + ".clientY should be within bounding client rect.");
+                // Test isPrimary
+                test(function () {
+                    assert_equals(event.isPrimary, true);
+                }, pointerTestName + ".isPrimary attribute is true.");
 
-    check_PointerEvent(event, expected_event_type);
+                // Test pointerId value
+                if (isNaN(expectedPointerId)) {
+                    expectedPointerId = event.pointerId;
+                } else {
+                    test(function () {
+                        assert_equals(event.pointerId, expectedPointerId);
+                    }, pointerTestName + ".pointerId should be the same as previous pointer events for this active pointer.");
+                }
+            }
 
-    assert_equals(event.isPrimary, true,
-        expected_event_type + ".isPrimary is true.");
-  }
+            async function run() {
+                var test_pointerEvent = setup_pointerevent_test("pointerevent attributes", ['touch']);
+                var square1 = document.getElementById("square1");
+                var rectSquare1 = square1.getBoundingClientRect();
+                var innerFrame = document.getElementById('innerFrame');
+                var square2 = innerFrame.contentDocument.getElementById('square2');
+                var rectSquare2 = square2.getBoundingClientRect();
 
-  async function checkEventsOnTarget(test, elem) {
-    const done = document.getElementById("done");
+                eventList.forEach(function(eventName) {
+                    on_event(square1, eventName, function (event) {
+                        if (square1.style.visibility == 'hidden')
+                            return;
+                        checkPointerEventAttributes(event, rectSquare1, "");
+                        if (Object.keys(detected_eventTypes).length == eventList.length) {
+                            square1.style.visibility = 'hidden';
+                            detected_eventTypes = {};
+                            square2.style.visibility = 'visible';
+                            expectedPointerId = NaN;
+                        }
+                    });
+                    on_event(square2, eventName, function (event) {
+                        checkPointerEventAttributes(event, rectSquare2, "Inner frame ");
+                        if (Object.keys(detected_eventTypes).length == eventList.length) {
+                            square2.style.visibility = 'hidden';
+                            test_pointerEvent.done();
+                        }
+                    });
+                });
 
-    let logged_event_promises = [];
-    for (let i = 0; i < logged_events.length; i++) {
-      logged_event_promises.push(getEvent(logged_events[i], elem, test));
-    }
-    let done_promise = getEvent("pointerup", done, test);
+                // Inject touch inputs.
+                await clickInTarget("touch", square1);
+                await clickInTarget("touch", square2);
+            }
+        </script>
+    </head>
+    <body onload="run()">
+        <h1>Pointer Events no-hover pointer attributes test</h1>
+        <h2 id="pointerTypeDescription"></h2>
+        <h4>
+            Test Description: This test checks the properties of pointer events that do not support hover.
+            <ol>
+                 <li>Tap the black square.</li>
+                 <li>Then move it off the black square so that it disappears.</li>
+                 <li>When the red square appears tap on that as well.</li>
+            </ol>
 
-    let actions = new test_driver.Actions();
-    actions = actions
-      .addPointer(test_pointer, pointer_type)
-      .pointerMove(0, 0, {origin:elem, sourceName:test_pointer})
-      .pointerDown({sourceName:test_pointer})
-      .pointerUp({sourceName:test_pointer})
-      .pointerMove(0, 0, {origin:done, sourceName:test_pointer})
-      .pointerDown({sourceName:test_pointer})
-      .pointerUp({sourceName:test_pointer});
-    await actions.send();
-
-    let done_event = await done_promise;
-
-    let expected_pointer_id;
-
-    // All Promises in logged_event_promises are already resolved bynow.
-    for (let i = 0; i < logged_event_promises.length; i++) {
-      let event = await logged_event_promises[i];
-      if (expected_pointer_id === undefined) {
-        expected_pointer_id = event.pointerId;
-      }
-      checkPointerEventAttributes(event, expected_pointer_id,
-          logged_events[i], elem.getBoundingClientRect());
-    }
-  }
-
-  function run() {
-    promise_test(async test => {
-      const target = document.getElementById("square1");
-      checkEventsOnTarget(test, target);
-    }, "PointerEvent attributes");
-  }
-</script>
+            Test passes if the proper behavior of the events is observed.
+        </h4>
+        <div id="square1" class="square"></div>
+        <iframe id="innerFrame" src="resources/pointerevent_attributes_hoverable_pointers-iframe.html"></iframe>
+        <div class="spacer"></div>
+        <div id="complete-notice">
+            <p>The following pointer types were detected: <span id="pointertype-log"></span>.</p>
+            <p>Refresh the page to run the tests again with a different pointer type.</p>
+        </div>
+        <div id="log"></div>
+    </body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/private-aggregation/resources/protected-audience-helper-module.js b/third_party/blink/web_tests/external/wpt/private-aggregation/resources/protected-audience-helper-module.js
index abec6408..e5f5a472 100644
--- a/third_party/blink/web_tests/external/wpt/private-aggregation/resources/protected-audience-helper-module.js
+++ b/third_party/blink/web_tests/external/wpt/private-aggregation/resources/protected-audience-helper-module.js
@@ -72,7 +72,7 @@
 // run, unless it returns something or throws.
 //
 // The default reportWin() method is empty.
-function createBiddingScriptUrl(params = {}) {
+function createBiddingScriptURL(params = {}) {
   let url = new URL(`${FLEDGE_BASE_URL}resources/bidding-logic.sub.py`);
   if (params.generateBid)
     url.searchParams.append('generateBid', params.generateBid);
@@ -186,7 +186,7 @@
   let reportResult = codeToInsert.reportResult;
 
   let interestGroupOverrides =
-    { biddingLogicUrl: createBiddingScriptUrl({ generateBid, reportWin }) };
+    { biddingLogicURL: createBiddingScriptURL({ generateBid, reportWin }) };
 
   await joinInterestGroup(test, uuid, interestGroupOverrides);
   await runBasicFledgeAuctionAndNavigate(
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/content-security-policy-issue-creation-inline-script.js b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/content-security-policy-issue-creation-inline-script.js
index 67021ce..5b74d4d 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/content-security-policy-issue-creation-inline-script.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/content-security-policy-issue-creation-inline-script.js
@@ -8,6 +8,12 @@
       'https://devtools.test:8443/inspector-protocol/resources/content-security-policy-issue-inline-script.php');
   const issue = await dp.Audits.onceIssueAdded();
 
+  // Technically it only matters that the violatingNodeId is present and >=1.
+  // The actual nodeId can be affected by which nodes are assigned ids first.
+  if (issue.violatingNodeId > 1) {
+    issue.violatingNodeId = 1;
+  }
+
   testRunner.log(issue.params, 'Inspector issue: ');
   testRunner.completeTest();
 })
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/fledge_join.html b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/fledge_join.html
index 360937c..e4e40b68 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/fledge_join.html
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/fledge_join.html
@@ -6,7 +6,7 @@
   navigator.joinAdInterestGroup({
     name: i,
     owner: "https://a.test:8443/",
-    biddingLogicUrl: "https://a.test:8443/inspector-protocol/resources/fledge_bidding_logic.js.php",
+    biddingLogicURL: "https://a.test:8443/inspector-protocol/resources/fledge_bidding_logic.js.php",
     ads: [{
       renderUrl: 'https://example.com/render' + i,
       metadata: {ad: 'metadata', here: [1, 2, 3]}
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/debugger-pause-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/debugger-pause-expected.txt
new file mode 100644
index 0000000..855a8afe
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/debugger-pause-expected.txt
@@ -0,0 +1,4 @@
+Tests debugger pause in shared storage worklet.
+Paused in the worklet
+Worklet state: globalVar=5
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/debugger-pause.js b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/debugger-pause.js
new file mode 100644
index 0000000..d65dae5
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/debugger-pause.js
@@ -0,0 +1,33 @@
+(async function(testRunner) {
+  const {session, dp} = await testRunner.startURL(
+    'http://127.0.0.1:8000/inspector-protocol/shared-storage/resources/empty.html', 'Tests debugger pause in shared storage worklet.');
+
+  await session.evaluateAsync(`
+      sharedStorage.worklet.addModule('http://127.0.0.1:8000/inspector-protocol/shared-storage/resources/module.js');
+  `);
+
+  const bp = testRunner.browserP();
+  bp.Target.setAutoAttach({autoAttach: true, flatten: true, waitForDebuggerOnStart: false});
+
+  const worklet = await bp.Target.onceAttachedToTarget(event => event.params.targetInfo.type === 'shared_storage_worklet');
+
+  const workletSession = session.createChild(worklet.params.sessionId);
+  await workletSession.protocol.Debugger.enable();
+
+  session.evaluate(`
+    sharedStorage.run(
+      'set-global-var-and-pause-on-debugger-operation',
+      {
+        data: {'setGlobalVarTo': 5},
+        keepAlive: true
+      }
+    );
+  `);
+
+  await workletSession.protocol.Debugger.oncePaused();
+
+  testRunner.log('Paused in the worklet');
+  testRunner.log('Worklet state: globalVar=' + await workletSession.evaluate(`globalVar`));
+
+  testRunner.completeTest();
+});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/resources/empty.html b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/resources/empty.html
new file mode 100644
index 0000000..0e76edd6
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/resources/empty.html
@@ -0,0 +1 @@
+<!DOCTYPE html>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/resources/module.js b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/resources/module.js
new file mode 100644
index 0000000..3d50cd0
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/resources/module.js
@@ -0,0 +1,20 @@
+var globalVar = 0;
+
+class EmptyOperation {
+  async run(data) {}
+}
+
+class SetGlobalVarAndPauseOnDebuggerOperation {
+  async run(data) {
+    if (data && data.hasOwnProperty('setGlobalVarTo')) {
+      globalVar = data['setGlobalVarTo'];
+    }
+
+    debugger;
+    globalVar = 100;
+  }
+}
+
+register("empty-operation", EmptyOperation);
+register("set-global-var-and-pause-on-debugger-operation",
+         SetGlobalVarAndPauseOnDebuggerOperation);
\ No newline at end of file
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/target-events-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/target-events-expected.txt
new file mode 100644
index 0000000..1505613
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/target-events-expected.txt
@@ -0,0 +1,13 @@
+Tests target attach and crash for shared storage worklet.
+{
+    attached : true
+    browserContextId : <string>
+    canAccessOpener : false
+    targetId : <string>
+    title : Shared storage worklet for http://127.0.0.1:8000/inspector-protocol/shared-storage/resources/module.js
+    type : shared_storage_worklet
+    url : http://127.0.0.1:8000/inspector-protocol/shared-storage/resources/module.js
+}
+Stopped shared storage worklet and received Inspector.targetCrashed event
+
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/target-events.js b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/target-events.js
new file mode 100644
index 0000000..cc19286
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/shared-storage/target-events.js
@@ -0,0 +1,26 @@
+(async function(testRunner) {
+  const {page, session, dp} = await testRunner.startURL(
+    'http://127.0.0.1:8000/inspector-protocol/shared-storage/resources/empty.html', 'Tests target attach and crash for shared storage worklet.');
+
+  await session.evaluateAsync(`
+      sharedStorage.worklet.addModule('http://127.0.0.1:8000/inspector-protocol/shared-storage/resources/module.js');
+  `);
+
+  const bp = testRunner.browserP();
+  bp.Target.setAutoAttach({autoAttach: true, flatten: true, waitForDebuggerOnStart: false});
+
+  const worklet = await bp.Target.onceAttachedToTarget(event => event.params.targetInfo.type === 'shared_storage_worklet');
+  testRunner.log(worklet.params.targetInfo);
+
+  const workletSession = session.createChild(worklet.params.sessionId);
+
+  await Promise.all([
+    workletSession.protocol.Inspector.onceTargetCrashed(),
+    session.evaluate(`
+      sharedStorage.run('empty-operation', {keepAlive: false});
+    `),
+  ]);
+  testRunner.log('Stopped shared storage worklet and received Inspector.targetCrashed event\n');
+
+  testRunner.completeTest();
+});
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/storage/interest-groups.js b/third_party/blink/web_tests/http/tests/inspector-protocol/storage/interest-groups.js
index b32c5030..aedf8ca 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/storage/interest-groups.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/storage/interest-groups.js
@@ -9,7 +9,7 @@
     navigator.joinAdInterestGroup({
         name: ${id},
         owner: "${baseOrigin}",
-        biddingLogicUrl: "${base}fledge_bidding_logic.js.php",
+        biddingLogicURL: "${base}fledge_bidding_logic.js.php",
         ads: [{
           renderUrl: 'https://example.com/render' + ${id},
           metadata: {ad: 'metadata', here: [1, 2, 3]}
diff --git a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
index 6449333..2651b94f 100644
--- a/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
+++ b/third_party/blink/web_tests/wpt_internal/fenced_frame/resources/utils.js
@@ -87,7 +87,7 @@
   let interestGroup = {
     name: 'testAd1',
     owner: location.origin,
-    biddingLogicUrl: new URL(FLEDGE_BIDDING_URL, location.origin),
+    biddingLogicURL: new URL(FLEDGE_BIDDING_URL, location.origin),
     ads: [{renderUrl: href, bid: 1}],
     userBiddingSignals: {biddingToken: bidding_token},
     trustedBiddingSignalsKeys: ['key1'],
@@ -95,7 +95,7 @@
   };
 
   let biddingUrlParams =
-      new URLSearchParams(interestGroup.biddingLogicUrl.search);
+    new URLSearchParams(interestGroup.biddingLogicURL.search);
   if (requested_size)
     biddingUrlParams.set(
         'requested-size', requested_size[0] + '-' + requested_size[1]);
@@ -103,7 +103,7 @@
     biddingUrlParams.set('ad-with-size', 1);
   if (automatic_beacon)
     biddingUrlParams.set('automatic-beacon', 1);
-  interestGroup.biddingLogicUrl.search = biddingUrlParams;
+  interestGroup.biddingLogicURL.search = biddingUrlParams;
 
   if (ad_with_size) {
     interestGroup.ads[0].sizeGroup = 'group1';
diff --git a/third_party/catapult b/third_party/catapult
index 95899ca9..92eef23 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit 95899ca94864dd5d811a9935e30d0174095eb7aa
+Subproject commit 92eef236f6cfab3f1c24a65ac265fdd6de917553
diff --git a/third_party/dawn b/third_party/dawn
index bf0426a..0e1f8d4 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit bf0426a4388288ef406a5e1c7f9f4109db7d2de9
+Subproject commit 0e1f8d431a4dac84d2681b3e01f10036b900b0ae
diff --git a/third_party/depot_tools b/third_party/depot_tools
index c7aca34..bb14391 160000
--- a/third_party/depot_tools
+++ b/third_party/depot_tools
@@ -1 +1 @@
-Subproject commit c7aca34c8e5fff27dd8424b55ef520de960d0bff
+Subproject commit bb14391a5092f01557cf1fedfa3f7fe3afdbd1fb
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index 2c64239..95908e6 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit 2c6423900dc9b550cba8f3954b60104f3fc433c8
+Subproject commit 95908e63edbfd2f41e38749c175a30a61a5941f3
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index e459007..c8b83c57 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit e4590077122a04c3ab18c08a87bb6eff665fe2a8
+Subproject commit c8b83c57ef4546aba4d1010b6af459b6813691d9
diff --git a/third_party/libavif/src b/third_party/libavif/src
index 676aded..5e7a177 160000
--- a/third_party/libavif/src
+++ b/third_party/libavif/src
@@ -1 +1 @@
-Subproject commit 676aded3501ff453c88a6d9ed1e5b4f33b458f3e
+Subproject commit 5e7a1778f1199b4cb96f25f64a1dc050d7e15ee9
diff --git a/third_party/perfetto b/third_party/perfetto
index 1d0ca00..49e44b0 160000
--- a/third_party/perfetto
+++ b/third_party/perfetto
@@ -1 +1 @@
-Subproject commit 1d0ca0005e4681498030fc4c1015abbec4a2077c
+Subproject commit 49e44b0a869219ed1acc1a55bb0a1a60bc9bf037
diff --git a/third_party/webrtc b/third_party/webrtc
index 92fe5c4..4d25a77 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit 92fe5c4db3bf97b559640b196d8c40a7b3e10a78
+Subproject commit 4d25a77fd32fade871cba7d93a7d5716180e2307
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index 80425e00..fcebe9c2 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -128,6 +128,10 @@
     "META": {"sizes": {"includes": [5],}},
     "includes": [2400],
   },
+  "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/chromeos/add_supervision/resources.grd": {
+    "META": {"sizes": {"includes": [10],}},
+    "includes": [2410],
+  },
   "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/chromeos/arc_account_picker/resources.grd": {
     "META": {"sizes": {"includes": [10],}},
     "includes": [2420],
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index bee707a..bc2a1500 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -401,7 +401,6 @@
         'build1': 'ios_simulator_debug_static_bot_xctest_reclient',
         '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_reclient',
       'Linux Viz': 'release_trybot_minimal_symbols_reclient',
       # TODO(crbug.com/1260232): remove this after the migration.
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index ccb9dc4..cf98172 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -231,16 +231,6 @@
       }
     }
   },
-  "Linux Builder (j-500) (reclient)": {
-    "gn_args": {
-      "dcheck_always_on": false,
-      "ffmpeg_branding": "Chrome",
-      "is_component_build": false,
-      "is_debug": false,
-      "proprietary_codecs": true,
-      "use_remoteexec": true
-    }
-  },
   "Linux Builder (reclient compare)": {
     "gn_args": {
       "dcheck_always_on": false,
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml
index 7a89bc4..087e0a1 100644
--- a/tools/metrics/actions/actions.xml
+++ b/tools/metrics/actions/actions.xml
@@ -12830,6 +12830,12 @@
   </description>
 </action>
 
+<action name="IOSMagicStackSafetyCheckFreshSignal" not_user_triggered="true">
+  <owner>thegreenfrog@google.com</owner>
+  <owner>bling-team@google.com</owner>
+  <description>Recorded when the Safety Check result has changed.</description>
+</action>
+
 <action name="IOSMagicStackShortcutsFreshSignal" not_user_triggered="true">
   <owner>thegreenfrog@google.com</owner>
   <owner>bling-team@google.com</owner>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 72b0070..bb0b8f5 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -25387,6 +25387,13 @@
   <int value="2" label="Has enough SCTs"/>
 </enum>
 
+<enum name="CustomTabsBrandingAppIdType">
+  <summary>Used by CustomTabs.Branding.AppIdType</summary>
+  <int value="0" label="INVALID"/>
+  <int value="1" label="PACKAGE_NAME"/>
+  <int value="2" label="REFERRER"/>
+</enum>
+
 <enum name="CustomTabsBrandingDecision">
   <summary>Used by CustomTabs.Branding.BrandingDecision</summary>
   <int value="0" label="None">
@@ -104080,6 +104087,12 @@
   <int value="2" label="Leave Chrome"/>
 </enum>
 
+<enum name="TabRevisitTracker.TabState">
+  <int value="0" label="Active"/>
+  <int value="1" label="Background"/>
+  <int value="2" label="Closed"/>
+</enum>
+
 <enum name="TabScreenshotAction">
   <int value="0" label="User took no actions">
     User made a screenshot, but did not take any actions with it before
@@ -107949,6 +107962,16 @@
   <int value="3" label="Occluding and Non-Occluding Damages"/>
 </enum>
 
+<enum name="UnexportableKeyServiceResult">
+  <int value="0" label="Success"/>
+  <int value="1" label="Crypto API failed"/>
+  <int value="2" label="Key not found"/>
+  <int value="3" label="Key collision"/>
+  <int value="4" label="No key provider"/>
+  <int value="5" label="Algorithm not supported"/>
+  <int value="6" label="Key not ready"/>
+</enum>
+
 <enum name="UnifiedConsentBumpAction">
   <int value="0" label="Opt into Unified Consent was clicked"/>
   <int value="1" label="More options: Opt into Unified Consent was selected"/>
@@ -111226,6 +111249,7 @@
   <int value="41679711" label="Floral"/>
   <int value="711032077" label="Cityscapes"/>
   <int value="1129315377" label="Composition"/>
+  <int value="1541868299" label="Dawn to Dark"/>
   <int value="1659755048" label="Illustrations"/>
   <int value="1668389814" label="Art"/>
   <int value="1804492839" label="Colors"/>
@@ -111469,6 +111493,8 @@
   <int value="14" label="Radiance - 14"/>
   <int value="15" label="Radiance - 15"/>
   <int value="16" label="Radiance - 16"/>
+  <int value="17" label="Dawn to Dark New Mexico - 17"/>
+  <int value="18" label="Dawn to Dark Clouds - 18"/>
   <int value="11921136" label="Art - 18441231667880650480"/>
   <int value="21374230" label="Element - 3650936971339030"/>
   <int value="50416017" label="Togetherness - 18439398008941529489"/>
diff --git a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
index 60a4240..0ea99b7 100644
--- a/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
+++ b/tools/metrics/histograms/metadata/custom_tabs/histograms.xml
@@ -52,6 +52,23 @@
   </summary>
 </histogram>
 
+<histogram name="CustomTabs.Branding.AppIdType"
+    enum="CustomTabsBrandingAppIdType" expires_after="2024-08-24">
+  <owner>jinsukkim@chromium.org</owner>
+  <owner>chrome-connective-tissue@google.com</owner>
+  <summary>
+    For every CCT launch, Chrome will start an async task in the background
+    checking the last time branding is shown for the client app. Each client app
+    is identified with a unique string. It was initially (and preferably) its
+    package name but is extended to be of any text string from the intent's
+    referrer if the package name is unavailable. An empty string is regarded as
+    invalid id.
+
+    Record the type of the id for a given CCT when the async task is finished.
+    Record for Android CCT only.
+  </summary>
+</histogram>
+
 <histogram name="CustomTabs.Branding.BrandingCheckCanceled"
     enum="BooleanCanceled" expires_after="2023-12-31">
   <owner>wenyufu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml
index 7e1f3e9..6f9f276 100644
--- a/tools/metrics/histograms/metadata/net/histograms.xml
+++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -237,6 +237,27 @@
   </token>
 </histogram>
 
+<histogram name="Crypto.UnexportableKeys.BackgroundTaskResult{TaskType}"
+    enum="UnexportableKeyServiceResult" expires_after="2024-01-14">
+  <owner>alexilin@chromium.org</owner>
+  <owner>kristianm@chromium.org</owner>
+  <summary>
+    Records the result of the subset of TPM operations that are scheduled
+    asynchronously through unexportable_keys::UnexportableKeyService. In some
+    error cases, the result might be returned synchronously.
+
+    Recorded right after a TPM operation completes. Recorded only for
+    {TaskType}.
+  </summary>
+  <token key="TaskType">
+    <variant name=".FromWrappedKey"
+        summary="operations to create a signing key from a wrapped key"/>
+    <variant name=".GenerateKey"
+        summary="operations to generate a new signing key"/>
+    <variant name=".Sign" summary="signing operations"/>
+  </token>
+</histogram>
+
 <histogram name="Crypto.VirtualKeySupport" enum="TPMSupport"
     expires_after="2024-03-01">
   <owner>kristianm@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index 573b5f5..271b05f 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -2057,14 +2057,39 @@
   </summary>
 </histogram>
 
-<histogram name="PasswordManager.MigrationToOSCrypt"
+<histogram name="PasswordManager.MigrationToOSCrypt.{Store}ErrorLatency"
+    units="ms" expires_after="M119">
+  <owner>vsemeniuk@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    Records the latency of a failed migration of PasswordStore to OSCrypt on iOS
+    {Store}. Recorded when the migration finishes with an error.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.MigrationToOSCrypt.{Store}SuccessLatency"
+    units="ms" expires_after="M119">
+  <owner>vsemeniuk@google.com</owner>
+  <owner>vasilii@chromium.org</owner>
+  <summary>
+    Records the latency of a successful migration of PasswordStore to OSCrypt on
+    iOS {Store}. Recorded when the migration finishes successfully.
+  </summary>
+</histogram>
+
+<histogram name="PasswordManager.MigrationToOSCrypt{StoreType}"
     enum="MigrationToOSCryptEnum" expires_after="M119">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>
-    Records a migration status of PasswordStore to OSCrypt on iOS. Recorded when
-    migration starts and finishes.
+    Records the migration status of PasswordStore to OSCrypt on iOS for
+    {StoreType}. Recorded when migration starts and finishes.
   </summary>
+  <token key="StoreType">
+    <variant name="" summary="both profile and account store"/>
+    <variant name=".AccountStore" summary="the AccountStore"/>
+    <variant name=".ProfileStore" summary="the ProfileStore"/>
+  </token>
 </histogram>
 
 <histogram name="PasswordManager.MoveUIDismissalReason{UserSyncingType}"
diff --git a/tools/metrics/histograms/metadata/stability/histograms.xml b/tools/metrics/histograms/metadata/stability/histograms.xml
index ab990cd0..01128cf 100644
--- a/tools/metrics/histograms/metadata/stability/histograms.xml
+++ b/tools/metrics/histograms/metadata/stability/histograms.xml
@@ -429,7 +429,7 @@
 </histogram>
 
 <histogram name="Stability.iOS.UTE.BatteryCharge" units="%"
-    expires_after="2023-10-04">
+    expires_after="2024-05-01">
   <owner>michaeldo@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -442,7 +442,7 @@
 </histogram>
 
 <histogram name="Stability.iOS.UTE.DeviceThermalState"
-    enum="IOSDeviceThermalState" expires_after="2023-10-04">
+    enum="IOSDeviceThermalState" expires_after="2024-05-01">
   <owner>michaeldo@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -452,7 +452,7 @@
 </histogram>
 
 <histogram name="Stability.iOS.UTE.HasPossibleExplanation"
-    enum="BooleanHasPossibleExplanation" expires_after="2024-01-28">
+    enum="BooleanHasPossibleExplanation" expires_after="2024-05-01">
   <owner>michaeldo@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -499,7 +499,7 @@
 </histogram>
 
 <histogram name="Stability.iOS.UTE.OSRestartedAfterPreviousSession"
-    enum="BooleanRebooted" expires_after="2024-01-28">
+    enum="BooleanRebooted" expires_after="2024-05-01">
   <owner>olivierrobin@chromium.org</owner>
   <owner>michaeldo@chromium.org</owner>
   <summary>
@@ -510,7 +510,7 @@
 </histogram>
 
 <histogram name="Stability.iOS.UTE.OSVersion" enum="VersionComparison"
-    expires_after="2023-10-04">
+    expires_after="2024-05-01">
   <owner>michaeldo@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
@@ -533,7 +533,7 @@
 </histogram>
 
 <histogram name="Stability.MobileSessionShutdownType"
-    enum="MobileSessionShutdownType" expires_after="2024-01-28">
+    enum="MobileSessionShutdownType" expires_after="2024-05-01">
   <owner>michaeldo@chromium.org</owner>
   <owner>olivierrobin@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml
index 549fda7..fd9ab21b 100644
--- a/tools/metrics/ukm/ukm.xml
+++ b/tools/metrics/ukm/ukm.xml
@@ -24529,6 +24529,67 @@
   </metric>
 </event>
 
+<event name="TabRevisitTracker.TabStateChange">
+  <owner>anthonyvd@chromium.org</owner>
+  <owner>chrome-catan@google.com</owner>
+  <summary>
+    Recorded when a tab changes state to/from &quot;active&quot;,
+    &quot;background&quot;, and &quot;closed&quot;.
+  </summary>
+  <metric name="ConnectednessToActiveTab">
+    <summary>
+      How connected the tab is to the active tab, if `NewState` isn't `Active`.
+      Computed from tab switches in the current session, and represents a
+      probability in the range [0.0, 1.0].
+    </summary>
+  </metric>
+  <metric name="NewState" enum="TabRevisitTracker.TabState">
+    <summary>
+      The state the tab is in after the transition.
+    </summary>
+  </metric>
+  <metric name="NumTabsOnSameUrl">
+    <summary>
+      The count of tabs with the same main frame URL as this one in the current
+      browser session. Used to identify instances of duplicate tabs. Bucketed in
+      20 buckets (0 to 20) + an overflow bucket.
+    </summary>
+  </metric>
+  <metric name="NumTotalRevisits">
+    <summary>
+      The count of times this tab was revisited since it was created. Bucketed
+      in 20 buckets (0 to 20) + an overflow bucket.
+    </summary>
+  </metric>
+  <metric name="PreviousState" enum="TabRevisitTracker.TabState">
+    <summary>
+      The state the tab was in before the transition.
+    </summary>
+  </metric>
+  <metric name="SameTabGroupAsActiveTab" enum="Boolean">
+    <summary>
+      Whether the tab is in the same tab group as the current active tab.
+    </summary>
+  </metric>
+  <metric name="SameWindowAsActiveTab" enum="Boolean">
+    <summary>
+      Whether the tab is in the same browser window as the current active tab.
+    </summary>
+  </metric>
+  <metric name="TimeInPreviousState">
+    <summary>
+      The time spent by the tab in `PreviousState`, before transitioning to
+      `NewState`, in seconds.
+    </summary>
+  </metric>
+  <metric name="TotalTimeActive">
+    <summary>
+      The total time the tab has spent as the active tab since it was created,
+      in seconds.
+    </summary>
+  </metric>
+</event>
+
 <event name="TabStripOrganization">
   <owner>dpenning@chromium.org</owner>
   <owner>chrome-desktop-ui-sea@google.com</owner>
diff --git a/ui/accessibility/ax_event_generator.cc b/ui/accessibility/ax_event_generator.cc
index 547354b8..edf6ca9 100644
--- a/ui/accessibility/ax_event_generator.cc
+++ b/ui/accessibility/ax_event_generator.cc
@@ -836,6 +836,13 @@
       continue;
     }
 
+    if (change.node->GetBoolAttribute(ax::mojom::BoolAttribute::kSelected) &&
+        (change.type == SUBTREE_CREATED || change.type == NODE_CREATED)) {
+      OnBoolAttributeChanged(tree, change.node,
+                             ax::mojom::BoolAttribute::kSelected,
+                             /*new_value*/ true);
+    }
+
     if (IsAlert(change.node->GetRole()))
       AddEvent(change.node, Event::ALERT);
     else if (change.node->data().IsActiveLiveRegionRoot())
diff --git a/ui/accessibility/ax_event_generator_unittest.cc b/ui/accessibility/ax_event_generator_unittest.cc
index 8a747e5..d6e4725 100644
--- a/ui/accessibility/ax_event_generator_unittest.cc
+++ b/ui/accessibility/ax_event_generator_unittest.cc
@@ -667,6 +667,104 @@
           HasEventAtNode(AXEventGenerator::Event::RELATED_NODE_CHANGED, 1)));
 }
 
+TEST(AXEventGeneratorTest, ActiveDescendantChangedAndNewNodeSelection) {
+  AXTreeUpdate initial_state;
+  initial_state.root_id = 1;
+  initial_state.nodes.resize(3);
+  initial_state.nodes[0].id = 1;
+  initial_state.nodes[0].role = ax::mojom::Role::kGrid;
+  initial_state.nodes[0].child_ids.push_back(2);
+  initial_state.nodes[0].child_ids.push_back(3);
+  initial_state.nodes[0].AddIntAttribute(
+      ax::mojom::IntAttribute::kActivedescendantId, 2);
+  initial_state.nodes[1].id = 2;
+  initial_state.nodes[1].role = ax::mojom::Role::kCell;
+  initial_state.nodes[1].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected,
+                                          true);
+  initial_state.nodes[2].id = 3;
+  initial_state.nodes[2].role = ax::mojom::Role::kCell;
+  AXTree tree(initial_state);
+
+  AXEventGenerator event_generator(&tree);
+  ASSERT_THAT(event_generator, IsEmpty());
+  AXTreeUpdate update = initial_state;
+  update.nodes.resize(4);
+  update.nodes[0].int_attributes.clear();
+  update.nodes[0].child_ids.push_back(4);
+  update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
+                                  4);
+  update.nodes[1].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
+  update.nodes[3].id = 4;
+  update.nodes[3].role = ax::mojom::Role::kCell;
+  update.nodes[3].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
+  ASSERT_TRUE(tree.Unserialize(update));
+  EXPECT_THAT(
+      event_generator,
+      UnorderedElementsAre(
+          HasEventAtNode(AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED, 1),
+          HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 1),
+          HasEventAtNode(AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED, 1),
+          HasEventAtNode(AXEventGenerator::Event::SELECTED_CHANGED, 2),
+          HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+                         2),
+          HasEventAtNode(AXEventGenerator::Event::SELECTED_CHANGED, 4),
+          HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 4),
+          HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+                         4)));
+}
+
+TEST(AXEventGeneratorTest, ActiveDescendantChangedAndNewNodeSelectionIndirect) {
+  AXTreeUpdate initial_state;
+  initial_state.root_id = 1;
+  initial_state.nodes.resize(5);
+  initial_state.nodes[0].id = 1;
+  initial_state.nodes[0].role = ax::mojom::Role::kGrid;
+  initial_state.nodes[0].child_ids.push_back(2);
+  initial_state.nodes[0].child_ids.push_back(4);
+  initial_state.nodes[0].AddIntAttribute(
+      ax::mojom::IntAttribute::kActivedescendantId, 3);
+  initial_state.nodes[1].id = 2;
+  initial_state.nodes[1].child_ids.push_back(3);
+  initial_state.nodes[2].id = 3;
+  initial_state.nodes[2].role = ax::mojom::Role::kCell;
+  initial_state.nodes[2].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected,
+                                          true);
+  initial_state.nodes[3].id = 4;
+  initial_state.nodes[3].child_ids.push_back(5);
+  initial_state.nodes[4].id = 5;
+  initial_state.nodes[4].role = ax::mojom::Role::kCell;
+  AXTree tree(initial_state);
+
+  AXEventGenerator event_generator(&tree);
+  ASSERT_THAT(event_generator, IsEmpty());
+  AXTreeUpdate update = initial_state;
+  update.nodes.resize(7);
+  update.nodes[0].int_attributes.clear();
+  update.nodes[0].child_ids.push_back(6);
+  update.nodes[0].AddIntAttribute(ax::mojom::IntAttribute::kActivedescendantId,
+                                  7);
+  update.nodes[2].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, false);
+  update.nodes[5].id = 6;
+  update.nodes[5].child_ids.push_back(7);
+  update.nodes[6].id = 7;
+  update.nodes[6].role = ax::mojom::Role::kCell;
+  update.nodes[6].AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, true);
+  ASSERT_TRUE(tree.Unserialize(update));
+  EXPECT_THAT(
+      event_generator,
+      UnorderedElementsAre(
+          HasEventAtNode(AXEventGenerator::Event::ACTIVE_DESCENDANT_CHANGED, 1),
+          HasEventAtNode(AXEventGenerator::Event::CHILDREN_CHANGED, 1),
+          HasEventAtNode(AXEventGenerator::Event::SELECTED_CHILDREN_CHANGED, 1),
+          HasEventAtNode(AXEventGenerator::Event::SELECTED_CHANGED, 3),
+          HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+                         3),
+          HasEventAtNode(AXEventGenerator::Event::SUBTREE_CREATED, 6),
+          HasEventAtNode(AXEventGenerator::Event::SELECTED_CHANGED, 7),
+          HasEventAtNode(AXEventGenerator::Event::WIN_IACCESSIBLE_STATE_CHANGED,
+                         7)));
+}
+
 TEST(AXEventGeneratorTest, CreateAlertAndLiveRegion) {
   AXTreeUpdate initial_state;
   initial_state.root_id = 1;
diff --git a/ui/accessibility/ax_generated_tree_unittest.cc b/ui/accessibility/ax_generated_tree_unittest.cc
index 2e24152..cea591f 100644
--- a/ui/accessibility/ax_generated_tree_unittest.cc
+++ b/ui/accessibility/ax_generated_tree_unittest.cc
@@ -75,7 +75,8 @@
 AXTreeUpdate SerializeEntireTree(AXSerializableTree& tree) {
   std::unique_ptr<AXTreeSource<const AXNode*>> tree_source(
       tree.CreateTreeSource());
-  AXTreeSerializer<const AXNode*> serializer(tree_source.get());
+  AXTreeSerializer<const AXNode*, std::vector<const AXNode*>> serializer(
+      tree_source.get());
   AXTreeUpdate update;
   CHECK(serializer.SerializeChanges(tree.root(), &update));
   return update;
@@ -270,7 +271,8 @@
           // empty tree |dst_tree|.
           std::unique_ptr<AXTreeSource<const AXNode*>> tree0_source(
               tree0.CreateTreeSource());
-          AXTreeSerializer<const AXNode*> serializer(tree0_source.get());
+          AXTreeSerializer<const AXNode*, std::vector<const AXNode*>>
+              serializer(tree0_source.get());
           AXTreeUpdate update0;
           ASSERT_TRUE(serializer.SerializeChanges(tree0.root(), &update0));
 
diff --git a/ui/accessibility/ax_tree_serializer.h b/ui/accessibility/ax_tree_serializer.h
index 0fb9303..7874a55 100644
--- a/ui/accessibility/ax_tree_serializer.h
+++ b/ui/accessibility/ax_tree_serializer.h
@@ -64,7 +64,7 @@
 // because AXTreeSerializer always keeps track of what updates it's sent,
 // it will never send an invalid update and the client tree will not break,
 // it just may not contain all of the changes.
-template <typename AXSourceNode>
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
 class AXTreeSerializer {
  public:
   explicit AXTreeSerializer(AXTreeSource<AXSourceNode>* tree,
@@ -260,14 +260,14 @@
   bool in_dirty_subtree;
 };
 
-template <typename AXSourceNode>
-AXTreeSerializer<AXSourceNode>::AXTreeSerializer(
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::AXTreeSerializer(
     AXTreeSource<AXSourceNode>* tree,
     bool crash_on_error)
     : tree_(tree), crash_on_error_(crash_on_error) {}
 
-template <typename AXSourceNode>
-AXTreeSerializer<AXSourceNode>::~AXTreeSerializer() {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::~AXTreeSerializer() {
   // Clear |tree_| to prevent any additional calls to the tree source
   // during teardown.
   // TODO(accessibility) How would that happen?
@@ -276,14 +276,14 @@
   Reset();
 }
 
-template <typename AXSourceNode>
-void AXTreeSerializer<AXSourceNode>::Reset() {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+void AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::Reset() {
   InternalReset();
   did_reset_ = true;
 }
 
-template <typename AXSourceNode>
-void AXTreeSerializer<AXSourceNode>::InternalReset() {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+void AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::InternalReset() {
   client_tree_data_ = AXTreeData();
 
   // Normally we use DeleteClientSubtree to remove nodes from the tree,
@@ -296,26 +296,28 @@
   client_root_ = nullptr;
 }
 
-template <typename AXSourceNode>
-void AXTreeSerializer<AXSourceNode>::ChangeTreeSourceForTesting(
-    AXTreeSource<AXSourceNode>* new_tree) {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+void AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::
+    ChangeTreeSourceForTesting(AXTreeSource<AXSourceNode>* new_tree) {
   tree_ = new_tree;
 }
 
-template <typename AXSourceNode>
-size_t AXTreeSerializer<AXSourceNode>::ClientTreeNodeCount() const {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+size_t AXTreeSerializer<AXSourceNode,
+                        AXSourceNodeVectorType>::ClientTreeNodeCount() const {
   return client_id_map_.size();
 }
 
-template <typename AXSourceNode>
-AXSourceNode AXTreeSerializer<AXSourceNode>::LeastCommonAncestor(
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+AXSourceNode
+AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::LeastCommonAncestor(
     AXSourceNode node,
     ClientTreeNode* client_node) {
   if (!node || client_node == nullptr) {
     return tree_->GetNull();
   }
 
-  std::vector<AXSourceNode> ancestors;
+  AXSourceNodeVectorType ancestors;
   while (node) {
     ancestors.push_back(node);
     node = tree_->GetParent(node);
@@ -334,17 +336,18 @@
   for (size_t source_index = ancestors.size(),
               client_index = client_ancestors.size();
        source_index > 0 && client_index > 0; --source_index, --client_index) {
-    if (tree_->GetId(ancestors[source_index - 1]) !=
+    if (tree_->GetId(ancestors[(unsigned int)(source_index - 1)]) !=
         client_ancestors[client_index - 1]->id) {
       return lca;
     }
-    lca = ancestors[source_index - 1];
+    lca = ancestors[(unsigned int)(source_index - 1)];
   }
   return lca;
 }
 
-template <typename AXSourceNode>
-AXSourceNode AXTreeSerializer<AXSourceNode>::LeastCommonAncestor(
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+AXSourceNode
+AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::LeastCommonAncestor(
     AXSourceNode node) {
   // Walk up the tree until the source node's id also exists in the
   // client tree, whose parent is not invalid, then call LeastCommonAncestor
@@ -371,10 +374,9 @@
   return LeastCommonAncestor(node, client_node);
 }
 
-template <typename AXSourceNode>
-bool AXTreeSerializer<AXSourceNode>::AnyDescendantWasReparented(
-    AXSourceNode node,
-    AXSourceNode* out_lca) {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+bool AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::
+    AnyDescendantWasReparented(AXSourceNode node, AXSourceNode* out_lca) {
   bool result = false;
   int id = tree_->GetId(node);
   tree_->CacheChildrenIfNeeded(node);
@@ -422,8 +424,9 @@
   return result;
 }
 
-template <typename AXSourceNode>
-ClientTreeNode* AXTreeSerializer<AXSourceNode>::ClientTreeNodeById(
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+ClientTreeNode*
+AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::ClientTreeNodeById(
     AXNodeID id) {
   std::map<AXNodeID, ClientTreeNode*>::iterator iter = client_id_map_.find(id);
   if (iter != client_id_map_.end())
@@ -431,8 +434,9 @@
   return nullptr;
 }
 
-template <typename AXSourceNode>
-ClientTreeNode* AXTreeSerializer<AXSourceNode>::GetClientTreeNodeParent(
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+ClientTreeNode*
+AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::GetClientTreeNodeParent(
     ClientTreeNode* obj) {
   ClientTreeNode* parent = obj->parent;
   if (!parent)
@@ -457,8 +461,8 @@
   return parent;
 }
 
-template <typename AXSourceNode>
-bool AXTreeSerializer<AXSourceNode>::SerializeChanges(
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+bool AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::SerializeChanges(
     AXSourceNode node,
     AXTreeUpdate* out_update) {
   if (!timeout_.is_zero())
@@ -540,33 +544,37 @@
   return true;
 }
 
-template <typename AXSourceNode>
-std::vector<AXNodeID> AXTreeSerializer<AXSourceNode>::GetIncompleteNodeIds() {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+std::vector<AXNodeID>
+AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::GetIncompleteNodeIds() {
   DCHECK(max_node_count_ > 0 || !timeout_.is_zero());
   return incomplete_node_ids_;
 }
 
-template <typename AXSourceNode>
-void AXTreeSerializer<AXSourceNode>::MarkSubtreeDirty(AXSourceNode node) {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+void AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::MarkSubtreeDirty(
+    AXSourceNode node) {
   ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
   if (client_node)
     MarkClientSubtreeDirty(client_node);
 }
 
-template <typename AXSourceNode>
-bool AXTreeSerializer<AXSourceNode>::IsInClientTree(AXSourceNode node) {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+bool AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::IsInClientTree(
+    AXSourceNode node) {
   return ClientTreeNodeById(tree_->GetId(node));
 }
 
-template <typename AXSourceNode>
-bool AXTreeSerializer<AXSourceNode>::IsDirty(AXSourceNode node) {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+bool AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::IsDirty(
+    AXSourceNode node) {
   ClientTreeNode* client_node = ClientTreeNodeById(tree_->GetId(node));
   return client_node ? client_node->in_dirty_subtree : false;
 }
 
-template <typename AXSourceNode>
-void AXTreeSerializer<AXSourceNode>::MarkClientSubtreeDirty(
-    ClientTreeNode* client_node) {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+void AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::
+    MarkClientSubtreeDirty(ClientTreeNode* client_node) {
   // Return early if already marked dirty, in order to avoid duplicate work in
   // subtree, as the only method that marks nodes dirty is this one.
   if (client_node->in_dirty_subtree) {
@@ -578,9 +586,9 @@
   }
 }
 
-template <typename AXSourceNode>
-void AXTreeSerializer<AXSourceNode>::DeleteClientSubtree(
-    ClientTreeNode* client_node) {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+void AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::
+    DeleteClientSubtree(ClientTreeNode* client_node) {
   if (client_node == client_root_) {
     Reset();  // Do not try to reuse a bad root later.
     // A heuristic for this condition rather than an explicit Reset() from a
@@ -601,18 +609,17 @@
   }
 }
 
-template <typename AXSourceNode>
-void AXTreeSerializer<AXSourceNode>::DeleteDescendants(
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+void AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::DeleteDescendants(
     ClientTreeNode* client_node) {
   for (size_t i = 0; i < client_node->children.size(); ++i)
     DeleteClientSubtree(client_node->children[i]);
   client_node->children.clear();
 }
 
-template <typename AXSourceNode>
-bool AXTreeSerializer<AXSourceNode>::SerializeChangedNodes(
-    AXSourceNode node,
-    AXTreeUpdate* out_update) {
+template <typename AXSourceNode, typename AXSourceNodeVectorType>
+bool AXTreeSerializer<AXSourceNode, AXSourceNodeVectorType>::
+    SerializeChangedNodes(AXSourceNode node, AXTreeUpdate* out_update) {
   // This method has three responsibilities:
   // 1. Serialize |node| into an AXNodeData, and append it to
   //    the AXTreeUpdate to be sent to the client.
diff --git a/ui/accessibility/ax_tree_serializer_unittest.cc b/ui/accessibility/ax_tree_serializer_unittest.cc
index 3955a06..126e43a 100644
--- a/ui/accessibility/ax_tree_serializer_unittest.cc
+++ b/ui/accessibility/ax_tree_serializer_unittest.cc
@@ -21,7 +21,8 @@
 
 namespace ui {
 
-using BasicAXTreeSerializer = AXTreeSerializer<const AXNode*>;
+using BasicAXTreeSerializer =
+    AXTreeSerializer<const AXNode*, std::vector<const AXNode*>>;
 
 // The framework for these tests is that each test sets up |treedata0_|
 // and |treedata1_| and then calls GetTreeSerializer, which creates a
@@ -535,7 +536,7 @@
     // The result should be indistinguishable from the source tree.
     std::unique_ptr<AXTreeSource<const AXNode*>> dst_tree_source(
         dst_tree.CreateTreeSource());
-    AXTreeSerializer<const AXNode*> serializer(dst_tree_source.get());
+    BasicAXTreeSerializer serializer(dst_tree_source.get());
     AXTreeUpdate dst_update;
     CHECK(serializer.SerializeChanges(dst_tree.root(), &dst_update));
     ASSERT_EQ(treedata1_.ToString(), dst_update.ToString());
diff --git a/ui/accessibility/ax_tree_unittest.cc b/ui/accessibility/ax_tree_unittest.cc
index 52338dc..0255cb7 100644
--- a/ui/accessibility/ax_tree_unittest.cc
+++ b/ui/accessibility/ax_tree_unittest.cc
@@ -378,7 +378,8 @@
 
   std::unique_ptr<AXTreeSource<const AXNode*>> tree_source(
       src_tree.CreateTreeSource());
-  AXTreeSerializer<const AXNode*> serializer(tree_source.get());
+  AXTreeSerializer<const AXNode*, std::vector<const AXNode*>> serializer(
+      tree_source.get());
   AXTreeUpdate update;
   serializer.SerializeChanges(src_tree.root(), &update);
 
diff --git a/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc b/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc
index 43445ea..c62dd62b 100644
--- a/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc
+++ b/ui/ozone/platform/wayland/host/gtk_primary_selection_device.cc
@@ -17,10 +17,11 @@
     WaylandConnection* connection,
     gtk_primary_selection_device* data_device)
     : WaylandDataDeviceBase(connection), data_device_(data_device) {
-  static constexpr gtk_primary_selection_device_listener kListener = {
-      &OnDataOffer, &OnSelection};
-  gtk_primary_selection_device_add_listener(data_device_.get(), &kListener,
-                                            this);
+  static constexpr gtk_primary_selection_device_listener
+      kPrimarySelectionListener = {.data_offer = &OnDataOffer,
+                                   .selection = &OnSelection};
+  gtk_primary_selection_device_add_listener(data_device_.get(),
+                                            &kPrimarySelectionListener, this);
 }
 
 GtkPrimarySelectionDevice::~GtkPrimarySelectionDevice() = default;
@@ -37,7 +38,7 @@
 // static
 void GtkPrimarySelectionDevice::OnDataOffer(
     void* data,
-    gtk_primary_selection_device* data_device,
+    gtk_primary_selection_device* selection_device,
     gtk_primary_selection_offer* offer) {
   auto* self = static_cast<GtkPrimarySelectionDevice*>(data);
   DCHECK(self);
@@ -47,7 +48,7 @@
 // static
 void GtkPrimarySelectionDevice::OnSelection(
     void* data,
-    gtk_primary_selection_device* data_device,
+    gtk_primary_selection_device* selection_device,
     gtk_primary_selection_offer* offer) {
   auto* self = static_cast<GtkPrimarySelectionDevice*>(data);
   DCHECK(self);
diff --git a/ui/ozone/platform/wayland/host/gtk_primary_selection_device.h b/ui/ozone/platform/wayland/host/gtk_primary_selection_device.h
index ab03bae..19e4da13 100644
--- a/ui/ozone/platform/wayland/host/gtk_primary_selection_device.h
+++ b/ui/ozone/platform/wayland/host/gtk_primary_selection_device.h
@@ -36,12 +36,12 @@
   void SetSelectionSource(GtkPrimarySelectionSource* source, uint32_t serial);
 
  private:
-  // gtk_primary_selection_device_listener callbacks
+  // gtk_primary_selection_device_listener callbacks:
   static void OnDataOffer(void* data,
-                          gtk_primary_selection_device* data_device,
+                          gtk_primary_selection_device* selection_device,
                           gtk_primary_selection_offer* offer);
   static void OnSelection(void* data,
-                          gtk_primary_selection_device* data_device,
+                          gtk_primary_selection_device* selection_device,
                           gtk_primary_selection_offer* offer);
 
   // The Wayland object wrapped by this instance.
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.cc b/ui/ozone/platform/wayland/host/wayland_data_device.cc
index 398585b..a7adfd3 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_device.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_device.cc
@@ -27,7 +27,12 @@
                                      wl_data_device* data_device)
     : WaylandDataDeviceBase(connection), data_device_(data_device) {
   static constexpr wl_data_device_listener kDataDeviceListener = {
-      &OnOffer, &OnEnter, &OnLeave, &OnMotion, &OnDrop, &OnSelection};
+      .data_offer = &OnDataOffer,
+      .enter = &OnEnter,
+      .leave = &OnLeave,
+      .motion = &OnMotion,
+      .drop = &OnDrop,
+      .selection = &OnSelection};
   wl_data_device_add_listener(data_device_.get(), &kDataDeviceListener, this);
 }
 
@@ -99,9 +104,9 @@
 }
 
 // static
-void WaylandDataDevice::OnOffer(void* data,
-                                wl_data_device* data_device,
-                                wl_data_offer* offer) {
+void WaylandDataDevice::OnDataOffer(void* data,
+                                    wl_data_device* data_device,
+                                    wl_data_offer* offer) {
   auto* self = static_cast<WaylandDataDevice*>(data);
   DCHECK(self);
   DCHECK(!self->new_offer_);
diff --git a/ui/ozone/platform/wayland/host/wayland_data_device.h b/ui/ozone/platform/wayland/host/wayland_data_device.h
index 04d8c351..078066b 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_device.h
+++ b/ui/ozone/platform/wayland/host/wayland_data_device.h
@@ -94,11 +94,10 @@
 
   void ReadDragDataFromFD(base::ScopedFD fd, RequestDataCallback callback);
 
-  // wl_data_device_listener callbacks
-  static void OnOffer(void* data,
-                      wl_data_device* data_device,
-                      wl_data_offer* id);
-
+  // wl_data_device_listener callbacks:
+  static void OnDataOffer(void* data,
+                          wl_data_device* data_device,
+                          wl_data_offer* offer);
   static void OnEnter(void* data,
                       wl_data_device* data_device,
                       uint32_t serial,
@@ -106,24 +105,17 @@
                       wl_fixed_t x,
                       wl_fixed_t y,
                       wl_data_offer* offer);
-
   static void OnMotion(void* data,
                        struct wl_data_device* data_device,
                        uint32_t time,
                        wl_fixed_t x,
                        wl_fixed_t y);
-
   static void OnDrop(void* data, struct wl_data_device* data_device);
-
   static void OnLeave(void* data, struct wl_data_device* data_device);
-
-  // Called by the compositor when the window gets pointer or keyboard focus,
-  // or clipboard content changes behind the scenes.
-  //
-  // https://wayland.freedesktop.org/docs/html/apa.html#protocol-spec-wl_data_device
+  // Called when either keyboard/pointer focus or clipboard content changes.
   static void OnSelection(void* data,
                           wl_data_device* data_device,
-                          wl_data_offer* id);
+                          wl_data_offer* offer);
 
   // The wl_data_device wrapped by this WaylandDataDevice.
   wl::Object<wl_data_device> data_device_;
diff --git a/ui/ozone/platform/wayland/host/wayland_data_offer.cc b/ui/ozone/platform/wayland/host/wayland_data_offer.cc
index 4aa6203..737ad09c 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_offer.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_offer.cc
@@ -16,7 +16,9 @@
       source_actions_(WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE),
       dnd_action_(WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE) {
   static constexpr wl_data_offer_listener kDataOfferListener = {
-      &OnOffer, &OnSourceAction, &OnAction};
+      .offer = &OnOffer,
+      .source_actions = &OnSourceActions,
+      .action = &OnAction};
   wl_data_offer_add_listener(data_offer, &kDataOfferListener, this);
 }
 
@@ -85,9 +87,9 @@
   self->AddMimeType(mime_type);
 }
 
-void WaylandDataOffer::OnSourceAction(void* data,
-                                      wl_data_offer* offer,
-                                      uint32_t source_actions) {
+void WaylandDataOffer::OnSourceActions(void* data,
+                                       wl_data_offer* offer,
+                                       uint32_t source_actions) {
   auto* self = static_cast<WaylandDataOffer*>(data);
   self->source_actions_ = source_actions;
 }
diff --git a/ui/ozone/platform/wayland/host/wayland_data_offer.h b/ui/ozone/platform/wayland/host/wayland_data_offer.h
index 0736ce0..5036b7e 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_offer.h
+++ b/ui/ozone/platform/wayland/host/wayland_data_offer.h
@@ -43,14 +43,14 @@
   uint32_t id() const { return data_offer_.id(); }
 
  private:
-  // wl_data_offer_listener callbacks.
+  // wl_data_offer_listener callbacks:
   static void OnOffer(void* data,
                       wl_data_offer* data_offer,
                       const char* mime_type);
   // Notifies the source-side available actions
-  static void OnSourceAction(void* data,
-                             wl_data_offer* offer,
-                             uint32_t source_actions);
+  static void OnSourceActions(void* data,
+                              wl_data_offer* offer,
+                              uint32_t source_actions);
   // Notifies the selected action
   static void OnAction(void* data, wl_data_offer* offer, uint32_t dnd_action);
 
diff --git a/ui/ozone/platform/wayland/host/wayland_data_source.cc b/ui/ozone/platform/wayland/host/wayland_data_source.cc
index 134114f..c0e95c8a2 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_source.cc
+++ b/ui/ozone/platform/wayland/host/wayland_data_source.cc
@@ -82,13 +82,13 @@
 }
 
 template <typename T>
-void DataSource<T>::OnCancel(void* data, T* source) {
+void DataSource<T>::OnCancelled(void* data, T* source) {
   auto* self = static_cast<DataSource<T>*>(data);
   self->HandleFinishEvent(/*completed=*/false);
 }
 
 template <typename T>
-void DataSource<T>::OnDnDFinished(void* data, T* source) {
+void DataSource<T>::OnDndFinished(void* data, T* source) {
   auto* self = static_cast<DataSource<T>*>(data);
   self->HandleFinishEvent(/*completed=*/true);
 }
@@ -105,7 +105,7 @@
 }
 
 template <typename T>
-void DataSource<T>::OnDnDDropPerformed(void* data, T* source) {
+void DataSource<T>::OnDndDropPerformed(void* data, T* source) {
   NOTIMPLEMENTED_LOG_ONCE();
 }
 
@@ -116,8 +116,12 @@
 template <>
 void DataSource<wl_data_source>::Initialize() {
   static constexpr wl_data_source_listener kDataSourceListener = {
-      &OnTarget,           &OnSend,        &OnCancel,
-      &OnDnDDropPerformed, &OnDnDFinished, &OnAction};
+      .target = &OnTarget,
+      .send = &OnSend,
+      .cancelled = &OnCancelled,
+      .dnd_drop_performed = &OnDndDropPerformed,
+      .dnd_finished = &OnDndFinished,
+      .action = &OnAction};
   wl_data_source_add_listener(data_source_.get(), &kDataSourceListener, this);
 }
 
@@ -151,7 +155,7 @@
 template <>
 void DataSource<gtk_primary_selection_source>::Initialize() {
   static constexpr gtk_primary_selection_source_listener kDataSourceListener = {
-      &OnSend, &OnCancel};
+      .send = &OnSend, .cancelled = &OnCancelled};
   gtk_primary_selection_source_add_listener(data_source_.get(),
                                             &kDataSourceListener, this);
 }
@@ -168,8 +172,9 @@
 void DataSource<zwp_primary_selection_source_v1>::Initialize() {
   static constexpr zwp_primary_selection_source_v1_listener
       kDataSourceListener = {
-          DataSource<zwp_primary_selection_source_v1>::OnSend,
-          DataSource<zwp_primary_selection_source_v1>::OnCancel};
+          .send = DataSource<zwp_primary_selection_source_v1>::OnSend,
+          .cancelled =
+              DataSource<zwp_primary_selection_source_v1>::OnCancelled};
   zwp_primary_selection_source_v1_add_listener(data_source_.get(),
                                                &kDataSourceListener, this);
 }
diff --git a/ui/ozone/platform/wayland/host/wayland_data_source.h b/ui/ozone/platform/wayland/host/wayland_data_source.h
index a158a43..41e5c8b 100644
--- a/ui/ozone/platform/wayland/host/wayland_data_source.h
+++ b/ui/ozone/platform/wayland/host/wayland_data_source.h
@@ -81,12 +81,13 @@
   void HandleFinishEvent(bool completed);
   void HandleSendEvent(const std::string& mime_type, int32_t fd);
 
+  // {T}_listener callbacks:
   static void OnSend(void* data, T* source, const char* mime_type, int32_t fd);
-  static void OnCancel(void* data, T* source);
-  static void OnDnDFinished(void* data, T* source);
+  static void OnCancelled(void* data, T* source);
+  static void OnDndFinished(void* data, T* source);
   static void OnAction(void* data, T* source, uint32_t dnd_action);
   static void OnTarget(void* data, T* source, const char* mime_type);
-  static void OnDnDDropPerformed(void* data, T* source);
+  static void OnDndDropPerformed(void* data, T* source);
 
   wl::Object<T> data_source_;
 
diff --git a/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc b/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc
index d02c76d..9057d1be 100644
--- a/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc
+++ b/ui/ozone/platform/wayland/host/zwp_primary_selection_device.cc
@@ -17,10 +17,11 @@
     WaylandConnection* connection,
     zwp_primary_selection_device_v1* data_device)
     : WaylandDataDeviceBase(connection), data_device_(data_device) {
-  static constexpr zwp_primary_selection_device_v1_listener kListener = {
-      &OnDataOffer, &OnSelection};
-  zwp_primary_selection_device_v1_add_listener(data_device_.get(), &kListener,
-                                               this);
+  static constexpr zwp_primary_selection_device_v1_listener
+      kPrimarySelectionListener = {.data_offer = &OnDataOffer,
+                                   .selection = &OnSelection};
+  zwp_primary_selection_device_v1_add_listener(
+      data_device_.get(), &kPrimarySelectionListener, this);
 }
 
 ZwpPrimarySelectionDevice::~ZwpPrimarySelectionDevice() = default;
@@ -37,7 +38,7 @@
 // static
 void ZwpPrimarySelectionDevice::OnDataOffer(
     void* data,
-    zwp_primary_selection_device_v1* data_device,
+    zwp_primary_selection_device_v1* selection_device,
     zwp_primary_selection_offer_v1* offer) {
   auto* self = static_cast<ZwpPrimarySelectionDevice*>(data);
   DCHECK(self);
@@ -47,7 +48,7 @@
 // static
 void ZwpPrimarySelectionDevice::OnSelection(
     void* data,
-    zwp_primary_selection_device_v1* data_device,
+    zwp_primary_selection_device_v1* selection_device,
     zwp_primary_selection_offer_v1* offer) {
   auto* self = static_cast<ZwpPrimarySelectionDevice*>(data);
   DCHECK(self);
diff --git a/ui/ozone/platform/wayland/host/zwp_primary_selection_device.h b/ui/ozone/platform/wayland/host/zwp_primary_selection_device.h
index a1ea6da..6d4e54d 100644
--- a/ui/ozone/platform/wayland/host/zwp_primary_selection_device.h
+++ b/ui/ozone/platform/wayland/host/zwp_primary_selection_device.h
@@ -36,12 +36,12 @@
   void SetSelectionSource(ZwpPrimarySelectionSource* source, uint32_t serial);
 
  private:
-  // primary_selection_device_listener callbacks
+  // zwp_primary_selection_device_listener callbacks:
   static void OnDataOffer(void* data,
-                          zwp_primary_selection_device_v1* data_device,
+                          zwp_primary_selection_device_v1* selection_device,
                           zwp_primary_selection_offer_v1* offer);
   static void OnSelection(void* data,
-                          zwp_primary_selection_device_v1* data_device,
+                          zwp_primary_selection_device_v1* selection_device,
                           zwp_primary_selection_offer_v1* offer);
 
   // The Wayland object wrapped by this instance.
diff --git a/ui/views/accessibility/ax_aura_obj_cache_unittest.cc b/ui/views/accessibility/ax_aura_obj_cache_unittest.cc
index 42e505a..68f6b64 100644
--- a/ui/views/accessibility/ax_aura_obj_cache_unittest.cc
+++ b/ui/views/accessibility/ax_aura_obj_cache_unittest.cc
@@ -216,7 +216,8 @@
   ui::AXTreeID tree_id = ui::AXTreeID::CreateNewAXTreeID();
   AXTreeSourceViews tree_source(
       cache.GetOrCreate(parent_widget->GetNativeWindow()), tree_id, &cache);
-  ui::AXTreeSerializer<AXAuraObjWrapper*> serializer(&tree_source);
+  ui::AXTreeSerializer<AXAuraObjWrapper*, std::vector<AXAuraObjWrapper*>>
+      serializer(&tree_source);
   ui::AXTreeUpdate serialized_tree;
   serializer.SerializeChanges(tree_source.GetRoot(), &serialized_tree);
 
diff --git a/ui/views/accessibility/views_ax_tree_manager.h b/ui/views/accessibility/views_ax_tree_manager.h
index 0caff17..00fe01d 100644
--- a/ui/views/accessibility/views_ax_tree_manager.h
+++ b/ui/views/accessibility/views_ax_tree_manager.h
@@ -93,7 +93,8 @@
   void OnWidgetDestroyed(Widget* widget) override;
 
  private:
-  using ViewsAXTreeSerializer = ui::AXTreeSerializer<AXAuraObjWrapper*>;
+  using ViewsAXTreeSerializer =
+      ui::AXTreeSerializer<AXAuraObjWrapper*, std::vector<AXAuraObjWrapper*>>;
 
   void SerializeTreeUpdates();
   void UnserializeTreeUpdates(const std::vector<ui::AXTreeUpdate>& updates);
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc
index ce7b498..219acf74 100644
--- a/ui/views/widget/widget.cc
+++ b/ui/views/widget/widget.cc
@@ -425,6 +425,10 @@
         std::make_unique<SublevelManager>(this, params.sublevel);
   }
 
+  if (params.native_theme) {
+    native_theme_ = params.native_theme;
+  }
+
   internal::NativeWidgetPrivate* native_widget_raw_ptr =
       CreateNativeWidget(params, this)->AsNativeWidgetPrivate();
   native_widget_ = native_widget_raw_ptr->GetWeakPtr();
diff --git a/ui/views/widget/widget.h b/ui/views/widget/widget.h
index 745d643..10da731 100644
--- a/ui/views/widget/widget.h
+++ b/ui/views/widget/widget.h
@@ -442,6 +442,12 @@
     // even if it matches with the compositor's keyboard shortcuts.
     bool inhibit_keyboard_shortcuts = false;
 #endif
+
+    // Directly sets the NativeTheme used by the Widget. Providing the
+    // NativeTheme here vs setting afterwards potentially avoids lots of
+    // notifications of theme changes.
+    // A value of null results in the default theme being used.
+    raw_ptr<ui::NativeTheme> native_theme = nullptr;
   };
 
   // Represents a lock held on the widget's ShouldPaintAsActive() state. As
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc
index 9aced70..b4ade6d 100644
--- a/ui/views/widget/widget_unittest.cc
+++ b/ui/views/widget/widget_unittest.cc
@@ -308,6 +308,48 @@
   EXPECT_EQ(contents->GetClassName(), widget->GetName());
 }
 
+TEST_F(WidgetWithCustomParamsTest, InitWithNativeTheme) {
+  // Verify that `InitParams::native_theme` is applied during widget
+  // initialization.
+
+  class TestView : public View {
+   public:
+    ~TestView() override = default;
+
+    void OnThemeChanged() override {
+      View::OnThemeChanged();
+      auto* native_theme = GetNativeTheme();
+      if (native_theme && native_theme->user_color()) {
+        user_color_ = *native_theme->user_color();
+      }
+    }
+
+    SkColor user_color() const { return user_color_; }
+
+   private:
+    SkColor user_color_ = SK_ColorWHITE;
+  };
+
+  const SkColor test_color = SkColorSetARGB(1, 2, 3, 4);
+
+  WidgetDelegate delegate;
+  auto view = std::make_unique<TestView>();
+  auto* view_raw_ptr = view.get();
+  delegate.SetContentsView(std::move(view));
+
+  ui::TestNativeTheme test_native_theme;
+  test_native_theme.set_user_color(test_color);
+
+  SetInitFunction(base::BindLambdaForTesting([&](Widget::InitParams* params) {
+    params->delegate = &delegate;
+    params->native_theme = &test_native_theme;
+  }));
+
+  std::unique_ptr<Widget> widget = CreateTestWidget();
+
+  EXPECT_EQ(view_raw_ptr->user_color(), test_color);
+}
+
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 TEST_F(WidgetWithCustomParamsTest, SkottieColorsTest) {
   struct SkottieColors {
diff --git a/v8 b/v8
index cb7e3eb..efc281b 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit cb7e3eb9cb05d2f42d99a8e6fef4df6f81263d53
+Subproject commit efc281b337f79ca57ff0097300905a2c39a5a321