diff --git a/DEPS b/DEPS
index 2fb65e90..4d5fbdd 100644
--- a/DEPS
+++ b/DEPS
@@ -300,19 +300,19 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'src_internal_revision': '619a026e7cb0711040338bb724d00e8420611336',
+  'src_internal_revision': 'a8d0d660e4e573f811962bfaeb3437067efd8d24',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Skia
   # and whatever else without interference from each other.
-  'skia_revision': '7c2ab74e6d1b9c3017114a8d13a200a888fc5b10',
+  'skia_revision': '9bea95918e6982e9d9a3a2ee5a009f8ce8b5d4d2',
   # 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': '9927247d821b1fefa9d225acee0d67f2cbdbfd0f',
+  'v8_revision': '00eda7279f265f2a645ef0256059b583209075af',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '53476d6ff2740267db0c0573644378621c4e7d78',
+  'angle_revision': '941b3df3df32a06a4b8a01c41c5522e2ea859d04',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -372,7 +372,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': '753e45cfb999f676e785e60d6fb01aba62a2d5cf',
+  'catapult_revision': '51cd0db6db2f574b40b8261daa7d55e9ffb57df8',
   # 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.
@@ -396,7 +396,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': 'a058cb54ecbbb8630ccc3b959b209b20d7ad2fa8',
+  'devtools_frontend_revision': 'b15f4a8c0754de1220114b21b33be7ca47374d63',
   # 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.
@@ -420,7 +420,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': '73d7f7ee1b320591b78dfbc35ceec83e6baea621',
+  'dawn_revision': 'c440212fcfff6a0e11ef41db0f884a9676a04e37',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -1287,12 +1287,12 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    'e5ba0da2a173ac40347c806053698ca2624857ea',
+    'f7ba534d8096b3224d4e77b886988aa1128e1f28',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + 'f377d194c7d27d9f7627080a1f3a31b112febe8e',
+    'url': Var('chromium_git') + '/website.git' + '@' + '59974df09115902c44c20a65b3e47c038384d643',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -1430,7 +1430,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': '5-5Af0VmJjFumJl7ERH797iZnbfuxyFyJryKqc4gFH4C',
+          'version': 'ecwebseKHbl8Z3FO4hkzxZaiztlmDnZdqKEMtjvqCwkC',
       },
     ],
     'condition': 'checkout_android and non_git_source',
@@ -1523,7 +1523,7 @@
       'packages': [
           {
                'package': 'chromium/third_party/android_build_tools/lint',
-               'version': 'IH7AKIwWSYXSo48ZTygnHFqznygQpejo_a94GUIyqAAC',
+               'version': '0j6PgTJxbBi5tTD1TAeLuyhU5iSUjgiXdpEhVCDtxC4C',
           },
       ],
       'condition': 'checkout_android and non_git_source',
@@ -1534,7 +1534,7 @@
       'packages': [
           {
                'package': 'chromium/third_party/android_build_tools/manifest_merger',
-               'version': 'BAf3JISR2TbfPyRYeLa62W7tsmuAQ6x7THsx6qvpSb4C',
+               'version': '2bcaX6fJS6WildBm3bMUKnbKuGk-TIiSBKQ9P9Q4O18C',
           },
       ],
       'condition': 'checkout_android and non_git_source',
@@ -1760,13 +1760,13 @@
   },
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '653e86a6f020e89e7f9249d40a22b25a8d6ba02a',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8258c1340ad8681925118da131a2fdfec19ddfbd',
 
   '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' + '@' + '7ae8cb30b21435841a28f345b03624cc31029418',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '644a99897c4e4ccfc00f77b5dd2f5a5c2cff5b39',
     'condition': 'checkout_src_internal',
   },
 
@@ -2487,7 +2487,7 @@
   'src/third_party/swift-format': {
       'packages': [
           {
-              'package': 'infra/3pp/tools/swift-format/${{platform}}',
+              'package': 'infra/3pp/tools/swift-format/mac-${{arch}}',
               'version': 'version:2@505.chromium.1',
           },
       ],
@@ -2707,7 +2707,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/eche_app/app',
-        'version': 'auycllKPcEYFNFZTYx--HG6DATpH9VcBfAwqVuN0AooC',
+        'version': '4-RMUU9V71eQLYM6a-nZ6rD8z0I7hQSXZUNikQjZ6bAC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4382,7 +4382,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        'ec602e23d833ae149c27f173248ef9c6255442bc',
+        '0b6564166940fa48dc3a219f6d4eda6e3188f8e3',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/ash/auth/active_session_auth_controller_impl.cc b/ash/auth/active_session_auth_controller_impl.cc
index 1b4ca2a..f1644b4 100644
--- a/ash/auth/active_session_auth_controller_impl.cc
+++ b/ash/auth/active_session_auth_controller_impl.cc
@@ -138,28 +138,6 @@
   NOTREACHED();
 }
 
-std::u16string BuildPinStatusMessage(const cryptohome::PinStatus& pin_status) {
-  if (!pin_status.IsLockedFactor()) {
-    return u"";
-  }
-  if (pin_status.AvailableAt() == base::Time::Max()) {
-    return l10n_util::GetStringUTF16(
-        IDS_ASH_IN_SESSION_AUTH_PIN_TOO_MANY_ATTEMPTS);
-  } else {
-    base::TimeDelta delta = pin_status.AvailableAt() - base::Time::Now();
-    std::u16string time_left_message;
-    if (base::TimeDurationCompactFormatWithSeconds(
-            delta, base::DurationFormatWidth::DURATION_WIDTH_WIDE,
-            &time_left_message)) {
-      return l10n_util::GetStringFUTF16(
-          IDS_ASH_IN_SESSION_AUTH_PIN_DELAY_REQUIRED, time_left_message);
-    } else {
-      return l10n_util::GetStringUTF16(
-          IDS_ASH_IN_SESSION_AUTH_PIN_TOO_MANY_ATTEMPTS);
-    }
-  }
-}
-
 }  // namespace
 
 ActiveSessionAuthControllerImpl::TestApi::TestApi(
@@ -183,18 +161,18 @@
   controller_->OnPinSubmit(base::UTF8ToUTF16(pin));
 }
 
-void ActiveSessionAuthControllerImpl::TestApi::DisplayPinStatusMessage(
-    const cryptohome::PinStatus pin_status) {
-  controller_->DisplayPinStatusMessage(pin_status);
+void ActiveSessionAuthControllerImpl::TestApi::Close() {
+  controller_->StartClose();
+}
+
+void ActiveSessionAuthControllerImpl::TestApi::SetPinStatus(
+    std::unique_ptr<cryptohome::PinStatus> pin_status) {
+  controller_->contents_view_->SetPinStatus(std::move(pin_status));
 }
 
 const std::u16string&
 ActiveSessionAuthControllerImpl::TestApi::GetPinStatusMessage() const {
-  return controller_->pin_status_message_;
-}
-
-void ActiveSessionAuthControllerImpl::TestApi::Close() {
-  controller_->StartClose();
+  return controller_->contents_view_->GetPinStatusMessage();
 }
 
 ActiveSessionAuthControllerImpl::ActiveSessionAuthControllerImpl() = default;
@@ -267,6 +245,8 @@
     return;
   }
 
+  auth_session_broadcast_id_ = user_context_->GetBroadcastId();
+
   uma_recorder_.RecordShow(auth_request_->GetAuthReason());
   UserDataAuthClient::Get()->AddAuthFactorStatusUpdateObserver(this);
 
@@ -282,7 +262,6 @@
     if (!pin_factor->GetPinStatus().IsLockedFactor()) {
       available_factors_.Put(AuthInputType::kPin);
     }
-    pin_status_message_ = BuildPinStatusMessage(pin_factor->GetPinStatus());
   }
 
   MaybePrepareFingerprint(
@@ -396,8 +375,13 @@
   contents_view_observer_.Observe(contents_view_);
   contents_view_->AddObserver(this);
   SetState(ActiveSessionAuthState::kInitialized);
-  if (!pin_status_message_.empty()) {
-    contents_view_->SetPinStatus(pin_status_message_);
+
+  const auto& auth_factors = user_context_->GetAuthFactorsData();
+
+  auto* pin_factor = auth_factors.FindPinFactor();
+  if (pin_factor) {
+    contents_view_->SetPinStatus(
+        std::make_unique<cryptohome::PinStatus>(pin_factor->GetPinStatus()));
   }
 
   MoveToTheCenter();
@@ -419,8 +403,8 @@
   CHECK(contents_view_);
   contents_view_->RemoveObserver(this);
   contents_view_ = nullptr;
+  auth_session_broadcast_id_.clear();
 
-  pending_pin_factor_status_update_.reset();
   UserDataAuthClient::Get()->RemoveAuthFactorStatusUpdateObserver(this);
 
   auth_performer_->InvalidateCurrentAttempts();
@@ -523,10 +507,6 @@
   }
   if (authentication_error.has_value()) {
     uma_recorder_.RecordAuthFailed(input_type);
-    if (pending_pin_factor_status_update_.has_value()) {
-      ProcessAuthFactorStatusUpdate(pending_pin_factor_status_update_.value());
-      pending_pin_factor_status_update_.reset();
-    }
     contents_view_->SetErrorTitle(l10n_util::GetStringUTF16(
         input_type == AuthInputType::kPassword
             ? IDS_ASH_IN_SESSION_AUTH_PASSWORD_INCORRECT
@@ -615,24 +595,21 @@
     const user_data_auth::AuthFactorStatusUpdate& update) {
   switch (state_) {
     case ActiveSessionAuthState::kInitialized:
-      // Handle the updates in the initialized state.
-      CHECK(user_context_);
-      if (update.auth_factor_with_status().auth_factor().type() ==
-          user_data_auth::AUTH_FACTOR_TYPE_PIN) {
-        ProcessAuthFactorStatusUpdate(update);
-      }
-      return;
     case ActiveSessionAuthState::kPinAuthStarted:
     case ActiveSessionAuthState::kPasswordAuthStarted:
-      // Handle the updates in the *Started states.
-      if (update.auth_factor_with_status().auth_factor().type() ==
-          user_data_auth::AUTH_FACTOR_TYPE_PIN) {
-        if (pending_pin_factor_status_update_.has_value()) {
-          LOG(WARNING) << "Overwrite pending pin status update.";
+      CHECK_NE(auth_session_broadcast_id_, "");
+      if (auth_session_broadcast_id_ == update.broadcast_id()) {
+        auto auth_factor = cryptohome::DeserializeAuthFactor(
+            update.auth_factor_with_status(),
+            /*fallback_type=*/cryptohome::AuthFactorType::kPassword);
+        if (auth_factor.ref().type() == cryptohome::AuthFactorType::kPin) {
+          auto pin_status = auth_factor.GetPinStatus();
+          contents_view_->SetPinStatus(
+              std::make_unique<cryptohome::PinStatus>(pin_status));
         }
-        pending_pin_factor_status_update_ = update;
       }
       return;
+
     case ActiveSessionAuthState::kWaitForInit:
       return;
 
@@ -647,33 +624,4 @@
   NOTREACHED();
 }
 
-void ActiveSessionAuthControllerImpl::ProcessAuthFactorStatusUpdate(
-    const user_data_auth::AuthFactorStatusUpdate& update) {
-  CHECK(user_context_);
-  // Broadcast id is a public id of an ongoing auth session.
-  // Generally it is unlikely to have two active auth session running
-  // in parallel, but we need to make sure we only react to signals
-  // mapped to this session.
-  if (user_context_->GetBroadcastId() == update.broadcast_id()) {
-    auto auth_factor = cryptohome::DeserializeAuthFactor(
-        update.auth_factor_with_status(),
-        /*fallback_type=*/cryptohome::AuthFactorType::kPassword);
-    if (auth_factor.ref().type() == cryptohome::AuthFactorType::kPin) {
-      CHECK(contents_view_);
-      auto pin_status = auth_factor.GetPinStatus();
-      bool pin_enabled = !pin_status.IsLockedFactor();
-      // Only need to update the auth view because |available_factors_| is only
-      // used to initialize the view.
-      contents_view_->SetHasPin(pin_enabled);
-      DisplayPinStatusMessage(pin_status);
-    }
-  }
-}
-
-void ActiveSessionAuthControllerImpl::DisplayPinStatusMessage(
-    const cryptohome::PinStatus pin_status) {
-  pin_status_message_ = BuildPinStatusMessage(pin_status);
-  contents_view_->SetPinStatus(pin_status_message_);
-}
-
 }  // namespace ash
diff --git a/ash/auth/active_session_auth_controller_impl.h b/ash/auth/active_session_auth_controller_impl.h
index 297ef04..fcc26595 100644
--- a/ash/auth/active_session_auth_controller_impl.h
+++ b/ash/auth/active_session_auth_controller_impl.h
@@ -6,7 +6,6 @@
 #define ASH_AUTH_ACTIVE_SESSION_AUTH_CONTROLLER_IMPL_H_
 
 #include <memory>
-#include <optional>
 #include <string>
 
 #include "ash/ash_export.h"
@@ -62,8 +61,7 @@
     // manually entered it.
     void SubmitPin(const std::string& pin);
 
-    // Simulate building and displaying a pin status message.
-    void DisplayPinStatusMessage(const cryptohome::PinStatus pin_status);
+    void SetPinStatus(std::unique_ptr<cryptohome::PinStatus> pin_status);
 
     const std::u16string& GetPinStatusMessage() const;
 
@@ -175,10 +173,6 @@
   // cryptohome.
   void InitUi();
 
-  // Show a PinStatus based error message, only if |pin_status| represents
-  // a locked factor.
-  void DisplayPinStatusMessage(const cryptohome::PinStatus pin_status);
-
   std::unique_ptr<views::Widget> widget_;
 
   base::ScopedObservation<views::View, ViewObserver> contents_view_observer_{
@@ -189,6 +183,8 @@
   AccountId account_id_;
   std::u16string title_;
   std::u16string description_;
+
+  std::string auth_session_broadcast_id_;
   std::u16string pin_status_message_;
 
   std::unique_ptr<AuthFactorEditor> auth_factor_editor_;
@@ -199,8 +195,6 @@
   AuthFactorSet available_factors_;
   ActiveSessionAuthState state_ = ActiveSessionAuthState::kWaitForInit;
 
-  std::optional<user_data_auth::AuthFactorStatusUpdate>
-      pending_pin_factor_status_update_ = std::nullopt;
   std::unique_ptr<AuthRequest> auth_request_;
 
   raw_ptr<ActiveSessionFingerprintClient> fp_client_;
diff --git a/ash/auth/test/active_session_auth_controller_unittest.cc b/ash/auth/test/active_session_auth_controller_unittest.cc
index ad78a6b..54f6178 100644
--- a/ash/auth/test/active_session_auth_controller_unittest.cc
+++ b/ash/auth/test/active_session_auth_controller_unittest.cc
@@ -438,16 +438,15 @@
   ASSERT_TRUE(base::test::RunUntil([&]() { return controller->IsShown(); }));
 
   const base::TimeDelta in_a_while = base::Seconds(60);
-  cryptohome::PinStatus soft_lockout{in_a_while};
-  test_api.DisplayPinStatusMessage(soft_lockout);
+  test_api.SetPinStatus(std::make_unique<cryptohome::PinStatus>(in_a_while));
 
   EXPECT_EQ(
       test_api.GetPinStatusMessage(),
       l10n_util::GetStringFUTF16(IDS_ASH_IN_SESSION_AUTH_PIN_DELAY_REQUIRED,
                                  u"1 minute, 0 seconds"));
 
-  cryptohome::PinStatus hard_lockout{base::TimeDelta::Max()};
-  test_api.DisplayPinStatusMessage(hard_lockout);
+  test_api.SetPinStatus(
+      std::make_unique<cryptohome::PinStatus>(base::TimeDelta::Max()));
   EXPECT_EQ(
       test_api.GetPinStatusMessage(),
       l10n_util::GetStringUTF16(IDS_ASH_IN_SESSION_AUTH_PIN_TOO_MANY_ATTEMPTS));
diff --git a/ash/auth/views/active_session_auth_view.cc b/ash/auth/views/active_session_auth_view.cc
index 005c24b..e1e2b04 100644
--- a/ash/auth/views/active_session_auth_view.cc
+++ b/ash/auth/views/active_session_auth_view.cc
@@ -244,8 +244,13 @@
   return auth_container_->HasPin();
 }
 
-void ActiveSessionAuthView::SetPinStatus(const std::u16string& status_str) {
-  auth_container_->SetPinStatus(status_str);
+void ActiveSessionAuthView::SetPinStatus(
+    std::unique_ptr<cryptohome::PinStatus> pin_status) {
+  auth_container_->SetPinStatus(std::move(pin_status));
+}
+
+const std::u16string& ActiveSessionAuthView::GetPinStatusMessage() const {
+  return auth_container_->GetPinStatusMessage();
 }
 
 void ActiveSessionAuthView::SetInputEnabled(bool enabled) {
diff --git a/ash/auth/views/active_session_auth_view.h b/ash/auth/views/active_session_auth_view.h
index 08eaf6a..a6dc9f60 100644
--- a/ash/auth/views/active_session_auth_view.h
+++ b/ash/auth/views/active_session_auth_view.h
@@ -27,6 +27,10 @@
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/view.h"
 
+namespace cryptohome {
+class PinStatus;
+}  // namespace cryptohome
+
 namespace ash {
 
 // ActiveSessionAuthView is a view that contains a header view: close button,
@@ -97,7 +101,8 @@
 
   void SetHasPin(bool has_pin);
   bool HasPin() const;
-  void SetPinStatus(const std::u16string& status_str);
+  void SetPinStatus(std::unique_ptr<cryptohome::PinStatus> pin_status);
+  const std::u16string& GetPinStatusMessage() const;
 
   // Enables or disables the input area of the view. The header area (e.g.,
   // close button) remains accessible even in the disabled state.
diff --git a/ash/auth/views/active_session_auth_view_unittest.cc b/ash/auth/views/active_session_auth_view_unittest.cc
index b79da6a..a83a2ea 100644
--- a/ash/auth/views/active_session_auth_view_unittest.cc
+++ b/ash/auth/views/active_session_auth_view_unittest.cc
@@ -15,6 +15,8 @@
 #include "ash/test/ash_test_base.h"
 #include "ash/test/ash_test_util.h"
 #include "base/containers/enum_set.h"
+#include "base/time/time.h"
+#include "chromeos/ash/components/cryptohome/auth_factor.h"
 #include "components/account_id/account_id.h"
 #include "components/user_manager/fake_user_manager.h"
 #include "components/user_manager/scoped_user_manager.h"
@@ -243,8 +245,12 @@
 }
 
 TEST_F(ActiveSessionAuthViewUnitTest, SetPinStatusTest) {
-  const std::u16string status_message = u"Too many failed attempts.";
-  test_api_->GetView()->SetPinStatus(status_message);
+  const std::u16string status_message = u"Too many PIN attempts";
+
+  cryptohome::PinStatus pin_status(base::TimeDelta::Max());
+
+  test_api_->GetView()->SetPinStatus(
+      std::make_unique<cryptohome::PinStatus>(base::TimeDelta::Max()));
 
   EXPECT_EQ(test_pin_status_->GetCurrentText(), status_message);
 }
diff --git a/ash/auth/views/auth_container_view.cc b/ash/auth/views/auth_container_view.cc
index da0e99a..2f23fdb 100644
--- a/ash/auth/views/auth_container_view.cc
+++ b/ash/auth/views/auth_container_view.cc
@@ -24,6 +24,7 @@
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
+#include "chromeos/ash/components/cryptohome/auth_factor.h"
 #include "ui/accessibility/ax_node_data.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
@@ -218,7 +219,7 @@
 
 void AuthContainerView::AddPinStatusView() {
   CHECK_EQ(pin_status_, nullptr);
-  pin_status_ = AddChildView(std::make_unique<PinStatusView>(std::u16string()));
+  pin_status_ = AddChildView(std::make_unique<PinStatusView>());
   pin_status_->SetVisible(false);
 }
 
@@ -311,12 +312,19 @@
   return available_auth_factors_.Has(AuthInputType::kPin);
 }
 
-void AuthContainerView::SetPinStatus(const std::u16string& status_str) {
-  pin_status_->SetText(status_str);
-  pin_status_->SetVisible(!status_str.empty());
+void AuthContainerView::SetPinStatus(
+    std::unique_ptr<cryptohome::PinStatus> pin_status) {
+  if (pin_status != nullptr) {
+    SetHasPin(!pin_status->IsLockedFactor());
+  }
+  pin_status_->SetPinStatus(std::move(pin_status));
   PreferredSizeChanged();
 }
 
+const std::u16string& AuthContainerView::GetPinStatusMessage() const {
+  return pin_status_->GetCurrentText();
+}
+
 void AuthContainerView::SetFingerprintState(FingerprintState state) {
   CHECK(fingerprint_view_);
   fingerprint_view_->SetState(state);
diff --git a/ash/auth/views/auth_container_view.h b/ash/auth/views/auth_container_view.h
index 1e7c435..967876e 100644
--- a/ash/auth/views/auth_container_view.h
+++ b/ash/auth/views/auth_container_view.h
@@ -28,6 +28,10 @@
 #include "ui/views/layout/box_layout.h"
 #include "ui/views/view.h"
 
+namespace cryptohome {
+class PinStatus;
+}  // namespace cryptohome
+
 namespace ash {
 
 // AuthContainer is a view that contains the authentication views currently only
@@ -100,7 +104,8 @@
 
   void SetHasPin(bool has_pin);
   bool HasPin() const;
-  void SetPinStatus(const std::u16string& status_str);
+  void SetPinStatus(std::unique_ptr<cryptohome::PinStatus> pin_status);
+  const std::u16string& GetPinStatusMessage() const;
 
   // Enables or disables the following UI elements:
   // - View
diff --git a/ash/auth/views/auth_container_view_pixeltest.cc b/ash/auth/views/auth_container_view_pixeltest.cc
index e86990ce..2aa155d 100644
--- a/ash/auth/views/auth_container_view_pixeltest.cc
+++ b/ash/auth/views/auth_container_view_pixeltest.cc
@@ -135,12 +135,17 @@
   // Turn off the PIN factor availability.
   test_api_->GetView()->SetHasPin(false);
 
-  const std::u16string status_message = u"Too many failed attempts.";
-  test_api_->GetView()->SetPinStatus(status_message);
-  EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
-      "SetPinStatus", /*revision_number=*/0, container_view_));
+  const std::u16string status_message = u"Too many PIN attempts";
 
-  test_api_->GetView()->SetPinStatus(u"");
+  cryptohome::PinStatus pin_status(base::TimeDelta::Max());
+
+  test_api_->GetView()->SetPinStatus(
+      std::make_unique<cryptohome::PinStatus>(pin_status));
+
+  EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
+      "SetPinStatus", /*revision_number=*/1, container_view_));
+
+  test_api_->GetView()->SetPinStatus(nullptr);
   EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
       "PasswordOnly", /*revision_number=*/0, container_view_));
 }
diff --git a/ash/auth/views/auth_container_view_unittest.cc b/ash/auth/views/auth_container_view_unittest.cc
index 9bf200d..4a5788e 100644
--- a/ash/auth/views/auth_container_view_unittest.cc
+++ b/ash/auth/views/auth_container_view_unittest.cc
@@ -15,6 +15,7 @@
 #include "ash/test/ash_test_base.h"
 #include "ash/test/ash_test_util.h"
 #include "base/containers/enum_set.h"
+#include "chromeos/ash/components/cryptohome/auth_factor.h"
 #include "ui/events/keycodes/keyboard_code_conversion.h"
 #include "ui/views/test/views_test_utils.h"
 #include "ui/views/view.h"
@@ -285,14 +286,18 @@
 }
 
 TEST_F(AuthContainerUnitTest, SetPinStatusTest) {
-  const std::u16string status_message = u"Too many failed attempts.";
-  test_api_->GetView()->SetPinStatus(status_message);
+  const std::u16string status_message = u"Too many PIN attempts";
+
+  cryptohome::PinStatus pin_status(base::TimeDelta::Max());
+
+  test_api_->GetView()->SetPinStatus(
+      std::make_unique<cryptohome::PinStatus>(pin_status));
 
   EXPECT_EQ(test_pin_status_->GetCurrentText(), status_message);
   EXPECT_TRUE(test_pin_status_->GetView()->GetVisible());
 
   // Now set the status back to an empty string.
-  test_api_->GetView()->SetPinStatus(u"");
+  test_api_->GetView()->SetPinStatus(nullptr);
   EXPECT_FALSE(test_pin_status_->GetView()->GetVisible());
 }
 
diff --git a/ash/auth/views/pin_status_view.cc b/ash/auth/views/pin_status_view.cc
index 43222c3..4266349 100644
--- a/ash/auth/views/pin_status_view.cc
+++ b/ash/auth/views/pin_status_view.cc
@@ -4,16 +4,24 @@
 
 #include "ash/auth/views/pin_status_view.h"
 
+#include <memory>
+#include <string>
+
 #include "ash/ash_export.h"
 #include "ash/auth/views/auth_common.h"
 #include "ash/auth/views/auth_view_utils.h"
 #include "ash/login/ui/non_accessible_view.h"
 #include "ash/public/cpp/login/login_utils.h"
 #include "ash/public/cpp/session/user_info.h"
+#include "ash/strings/grit/ash_strings.h"
 #include "ash/style/typography.h"
+#include "base/i18n/time_formatting.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list_types.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/time/time.h"
+#include "chromeos/ash/components/cryptohome/auth_factor.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
@@ -27,6 +35,29 @@
 // Distance between the top of the view and the label.
 constexpr int kTopLabelDistanceDp = 28;
 
+std::u16string BuildPinStatusMessage(cryptohome::PinStatus* pin_status) {
+  if (pin_status == nullptr || !pin_status->IsLockedFactor()) {
+    return u"";
+  }
+
+  if (pin_status->AvailableAt() == base::Time::Max()) {
+    return l10n_util::GetStringUTF16(
+        IDS_ASH_IN_SESSION_AUTH_PIN_TOO_MANY_ATTEMPTS);
+  }
+
+  base::TimeDelta delta = pin_status->AvailableAt() - base::Time::Now();
+  std::u16string time_left_message;
+  if (base::TimeDurationCompactFormatWithSeconds(
+          delta, base::DurationFormatWidth::DURATION_WIDTH_WIDE,
+          &time_left_message)) {
+    return l10n_util::GetStringFUTF16(
+        IDS_ASH_IN_SESSION_AUTH_PIN_DELAY_REQUIRED, time_left_message);
+  }
+
+  return l10n_util::GetStringUTF16(
+      IDS_ASH_IN_SESSION_AUTH_PIN_TOO_MANY_ATTEMPTS);
+}
+
 }  // namespace
 
 namespace ash {
@@ -35,14 +66,14 @@
 PinStatusView::TestApi::~TestApi() = default;
 
 const std::u16string& PinStatusView::TestApi::GetCurrentText() const {
-  return view_->text_label_->GetText();
+  return view_->GetCurrentText();
 }
 
 raw_ptr<PinStatusView> PinStatusView::TestApi::GetView() {
   return view_;
 }
 
-PinStatusView::PinStatusView(const std::u16string& text) {
+PinStatusView::PinStatusView() {
   auto decorate_label = [](views::Label* label) {
     label->SetSubpixelRenderingEnabled(false);
     label->SetAutoColorReadabilityEnabled(false);
@@ -60,7 +91,7 @@
   AddVerticalSpace(this, kTopLabelDistanceDp);
 
   // Add text.
-  text_label_ = new views::Label(text, views::style::CONTEXT_LABEL,
+  text_label_ = new views::Label(u"", views::style::CONTEXT_LABEL,
                                  views::style::STYLE_PRIMARY);
   text_label_->SetMultiLine(true);
   text_label_->SizeToFit(kTextLineWidthDp);
@@ -83,9 +114,20 @@
 }
 
 void PinStatusView::SetText(const std::u16string& text_str) {
+  SetVisible(!text_str.empty());
   text_label_->SetText(text_str);
 }
 
+const std::u16string& PinStatusView::GetCurrentText() const {
+  return text_label_->GetText();
+}
+
+void PinStatusView::SetPinStatus(
+    std::unique_ptr<cryptohome::PinStatus> pin_status) {
+  pin_status_ = std::move(pin_status);
+  SetText(BuildPinStatusMessage(pin_status_.get()));
+}
+
 BEGIN_METADATA(PinStatusView)
 END_METADATA
 
diff --git a/ash/auth/views/pin_status_view.h b/ash/auth/views/pin_status_view.h
index ffffda4..3c04595f 100644
--- a/ash/auth/views/pin_status_view.h
+++ b/ash/auth/views/pin_status_view.h
@@ -5,6 +5,7 @@
 #ifndef ASH_AUTH_VIEWS_PIN_STATUS_VIEW_H_
 #define ASH_AUTH_VIEWS_PIN_STATUS_VIEW_H_
 
+#include <memory>
 #include <string>
 
 #include "ash/ash_export.h"
@@ -16,6 +17,10 @@
 #include "ui/views/controls/label.h"
 #include "ui/views/view.h"
 
+namespace cryptohome {
+class PinStatus;
+}  // namespace cryptohome
+
 namespace ash {
 
 // Contains the pin status text.
@@ -38,7 +43,7 @@
     const raw_ptr<PinStatusView> view_;
   };
 
-  PinStatusView(const std::u16string& text);
+  PinStatusView();
 
   PinStatusView(const PinStatusView&) = delete;
   PinStatusView& operator=(const PinStatusView&) = delete;
@@ -54,10 +59,15 @@
   }
 
   void SetText(const std::u16string& text_str);
+  const std::u16string& GetCurrentText() const;
+
+  void SetPinStatus(std::unique_ptr<cryptohome::PinStatus> pin_status);
 
  private:
   raw_ptr<views::Label> text_label_ = nullptr;
 
+  std::unique_ptr<cryptohome::PinStatus> pin_status_;
+
   base::WeakPtrFactory<PinStatusView> weak_ptr_factory_{this};
 };
 
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index 51f15d2..54179e7e 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -886,8 +886,15 @@
 
 // Enables WiFi QoS to detect and prioritize selected egress network traffic
 // using WiFi QoS/WMM in congested WiFi environments.
-BASE_FEATURE(kEnableWifiQos,
-             "EnableWifiQos",
+BASE_FEATURE(kEnableWifiQos, "EnableWifiQos", base::FEATURE_ENABLED_BY_DEFAULT);
+
+// Enables WiFi QoS to detect and prioritize selected egress network traffic
+// using WiFi QoS/WMM in congested WiFi environments. For an Enterprise enrolled
+// device:
+// - If this flag is enabled, the feature will be controlled by EnableWifiQos;
+// - If this flag is disabled, the feature will be disabled.
+BASE_FEATURE(kEnableWifiQosEnterprise,
+             "EnableWifiQosEnterprise",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 // Enforces Ash extension keep-list. Only the extensions/Chrome apps in the
@@ -1949,7 +1956,7 @@
 // Enables Mahi on PDF contents in the Media App.
 BASE_FEATURE(kMediaAppPdfMahi,
              "MediaAppPdfMahi",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Enables lens support in the Media App.
 BASE_FEATURE(kMediaAppLens, "MediaAppLens", base::FEATURE_ENABLED_BY_DEFAULT);
@@ -3189,7 +3196,7 @@
 
 // Controls whether the DLC downloading UI for video conferencing tiles is
 // enabled.
-BASE_FEATURE(kVcDlcUi, "VcDlcUi", base::FEATURE_DISABLED_BY_DEFAULT);
+BASE_FEATURE(kVcDlcUi, "VcDlcUi", base::FEATURE_ENABLED_BY_DEFAULT);
 
 // This is only used as a way to disable portrait relighting.
 BASE_FEATURE(kVcPortraitRelight,
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index aedda02..71c6ad6 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -288,6 +288,7 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kEnableTouchscreensInDiagnosticsApp);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kEnableWifiQos);
+COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kEnableWifiQosEnterprise);
 COMPONENT_EXPORT(ASH_CONSTANTS)
 BASE_DECLARE_FEATURE(kEnforceAshExtensionKeeplist);
 COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/picker/views/picker_image_item_grid_view.cc b/ash/picker/views/picker_image_item_grid_view.cc
index 85b1918..b5604e0 100644
--- a/ash/picker/views/picker_image_item_grid_view.cc
+++ b/ash/picker/views/picker_image_item_grid_view.cc
@@ -63,7 +63,11 @@
 }  // namespace
 
 PickerImageItemGridView::PickerImageItemGridView(int grid_width)
-    : grid_width_(grid_width) {
+    : grid_width_(grid_width),
+      focus_search_(std::make_unique<FocusSearch>(
+          this,
+          base::BindRepeating(&PickerImageItemGridView::GetFocusableItems,
+                              base::Unretained(this)))) {
   SetLayoutManager(std::make_unique<views::TableLayout>())
       ->AddColumn(/*h_align=*/views::LayoutAlignment::kCenter,
                   /*v_align=*/views::LayoutAlignment::kStretch,
@@ -90,6 +94,10 @@
 
 PickerImageItemGridView::~PickerImageItemGridView() = default;
 
+views::FocusTraversable* PickerImageItemGridView::GetPaneFocusTraversable() {
+  return focus_search_.get();
+}
+
 views::View* PickerImageItemGridView::GetTopItem() {
   views::View* column = children().front();
   return column->children().empty()
@@ -173,8 +181,73 @@
                         /*proj=*/[](const views::View* v) {
                           return v->GetPreferredSize().height();
                         });
-  return shortest_column->AddChildView(CreateListItemView())
-      ->AddChildView(std::move(image_item));
+  PickerImageItemView* new_item =
+      shortest_column->AddChildView(CreateListItemView())
+          ->AddChildView(std::move(image_item));
+  focusable_items_.push_back(new_item);
+  return new_item;
+}
+
+PickerImageItemGridView::FocusSearch::FocusSearch(
+    views::View* view,
+    const GetFocusableViewsCallback& callback)
+    : views::FocusSearch(/*root=*/view,
+                         /*cycle=*/true,
+                         /*accessibility_mode=*/true),
+      view_(view),
+      get_focusable_views_callback_(callback) {}
+
+PickerImageItemGridView::FocusSearch::~FocusSearch() = default;
+
+views::View* PickerImageItemGridView::FocusSearch::FindNextFocusableView(
+    views::View* starting_view,
+    SearchDirection search_direction,
+    TraversalDirection traversal_direction,
+    StartingViewPolicy check_starting_view,
+    AnchoredDialogPolicy can_go_into_anchored_dialog,
+    views::FocusTraversable** focus_traversable,
+    views::View** focus_traversable_view) {
+  // The callback polls the currently focusable views.
+  const views::View::Views& focusable_views =
+      get_focusable_views_callback_.Run();
+  if (focusable_views.empty()) {
+    return nullptr;
+  }
+
+  int delta =
+      search_direction == FocusSearch::SearchDirection::kForwards ? 1 : -1;
+  int focusable_views_size = static_cast<int>(focusable_views.size());
+  for (int i = 0; i < focusable_views_size; ++i) {
+    // If current view from the set is found to be focused, return the view
+    // next (or previous) to it as next focusable view.
+    if (focusable_views[i] == starting_view) {
+      const int next_index = i + delta;
+      if (next_index >= 0 && next_index < focusable_views_size) {
+        return focusable_views[next_index];
+      } else {
+        return nullptr;
+      }
+    }
+  }
+
+  // Case when none of the views are already focused.
+  return (search_direction == FocusSearch::SearchDirection::kForwards)
+             ? focusable_views.front()
+             : focusable_views.back();
+}
+
+views::FocusSearch* PickerImageItemGridView::FocusSearch::GetFocusSearch() {
+  return this;
+}
+
+views::FocusTraversable*
+PickerImageItemGridView::FocusSearch::GetFocusTraversableParent() {
+  return nullptr;
+}
+
+views::View*
+PickerImageItemGridView::FocusSearch::GetFocusTraversableParentView() {
+  return nullptr;
 }
 
 views::View* PickerImageItemGridView::GetColumnContaining(views::View* item) {
@@ -183,6 +256,10 @@
   return column && column->parent() == this ? column : nullptr;
 }
 
+const views::View::Views& PickerImageItemGridView::GetFocusableItems() const {
+  return focusable_items_;
+}
+
 BEGIN_METADATA(PickerImageItemGridView)
 END_METADATA
 
diff --git a/ash/picker/views/picker_image_item_grid_view.h b/ash/picker/views/picker_image_item_grid_view.h
index 5903f35..ea1b365 100644
--- a/ash/picker/views/picker_image_item_grid_view.h
+++ b/ash/picker/views/picker_image_item_grid_view.h
@@ -10,6 +10,8 @@
 #include "ash/ash_export.h"
 #include "ash/picker/views/picker_traversable_item_container.h"
 #include "ui/base/metadata/metadata_header_macros.h"
+#include "ui/views/focus/focus_manager.h"
+#include "ui/views/focus/focus_search.h"
 #include "ui/views/view.h"
 
 namespace ash {
@@ -29,6 +31,9 @@
   PickerImageItemGridView& operator=(const PickerImageItemGridView&) = delete;
   ~PickerImageItemGridView() override;
 
+  // views::View:
+  views::FocusTraversable* GetPaneFocusTraversable() override;
+
   // PickerTraversableItemContainer:
   views::View* GetTopItem() override;
   views::View* GetBottomItem() override;
@@ -42,11 +47,47 @@
       std::unique_ptr<PickerImageItemView> image_item);
 
  private:
+  class FocusSearch : public views::FocusSearch,
+                      public views::FocusTraversable {
+   public:
+    using GetFocusableViewsCallback =
+        base::RepeatingCallback<const views::View::Views&(void)>;
+
+    FocusSearch(views::View* view, const GetFocusableViewsCallback& callback);
+    FocusSearch(const FocusSearch&) = delete;
+    FocusSearch& operator=(const FocusSearch) = delete;
+    ~FocusSearch() override;
+
+    // views::FocusSearch:
+    views::View* FindNextFocusableView(
+        views::View* starting_view,
+        SearchDirection search_direction,
+        TraversalDirection traversal_direction,
+        StartingViewPolicy check_starting_view,
+        AnchoredDialogPolicy can_go_into_anchored_dialog,
+        views::FocusTraversable** focus_traversable,
+        views::View** focus_traversable_view) override;
+
+    // views::FocusTraversable:
+    views::FocusSearch* GetFocusSearch() override;
+    views::FocusTraversable* GetFocusTraversableParent() override;
+    views::View* GetFocusTraversableParentView() override;
+
+   private:
+    const raw_ptr<views::View> view_ = nullptr;
+    const GetFocusableViewsCallback get_focusable_views_callback_;
+  };
+
   // Returns the column containing `item`, or nullptr if `item` is not part of
   // this grid.
   views::View* GetColumnContaining(views::View* item);
 
+  // Returns items in this grid in focus traversal order.
+  const views::View::Views& GetFocusableItems() const;
+
   int grid_width_ = 0;
+  views::View::Views focusable_items_;
+  std::unique_ptr<FocusSearch> focus_search_;
 };
 
 }  // namespace ash
diff --git a/ash/picker/views/picker_image_item_grid_view_unittest.cc b/ash/picker/views/picker_image_item_grid_view_unittest.cc
index 0afd69f..ddacee4 100644
--- a/ash/picker/views/picker_image_item_grid_view_unittest.cc
+++ b/ash/picker/views/picker_image_item_grid_view_unittest.cc
@@ -14,6 +14,8 @@
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/gfx/geometry/size.h"
+#include "ui/views/focus/focus_manager.h"
+#include "ui/views/test/views_test_base.h"
 #include "ui/views/view.h"
 
 namespace ash {
@@ -39,7 +41,9 @@
       u"gif", base::DoNothing());
 }
 
-TEST(PickerImageItemGridViewTest, OneGifItem) {
+using PickerImageItemGridViewTest = views::ViewsTestBase;
+
+TEST_F(PickerImageItemGridViewTest, OneGifItem) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   const PickerItemView* item =
@@ -53,7 +57,7 @@
                   Pointee(Property(&views::View::children, IsEmpty()))));
 }
 
-TEST(PickerImageItemGridViewTest, TwoGifItems) {
+TEST_F(PickerImageItemGridViewTest, TwoGifItems) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   const PickerItemView* item1 =
@@ -69,7 +73,7 @@
                                            ElementsAre(item2->parent())))));
 }
 
-TEST(PickerImageItemGridViewTest, GifItemsWithVaryingHeight) {
+TEST_F(PickerImageItemGridViewTest, GifItemsWithVaryingHeight) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   const PickerItemView* item1 =
@@ -92,7 +96,7 @@
 }
 
 // TODO: b/357146181 - Re-enable once Gifs are used again.
-TEST(PickerImageItemGridViewTest, DISABLED_GifItemsAreResizedToSameWidth) {
+TEST_F(PickerImageItemGridViewTest, DISABLED_GifItemsAreResizedToSameWidth) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   const PickerItemView* item1 =
@@ -104,7 +108,7 @@
             item2->GetPreferredSize().width());
 }
 
-TEST(PickerImageItemGridViewTest, PreservesAspectRatioOfGifItems) {
+TEST_F(PickerImageItemGridViewTest, PreservesAspectRatioOfGifItems) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   constexpr gfx::Size kGifDimensions(100, 200);
@@ -115,7 +119,7 @@
             GetAspectRatio(kGifDimensions));
 }
 
-TEST(PickerImageItemGridViewTest, GetsTopItem) {
+TEST_F(PickerImageItemGridViewTest, GetsTopItem) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   PickerItemView* item1 =
@@ -134,13 +138,13 @@
   EXPECT_EQ(item_grid.GetTopItem(), item1);
 }
 
-TEST(PickerImageItemGridViewTest, EmptyGridHasNoTopItem) {
+TEST_F(PickerImageItemGridViewTest, EmptyGridHasNoTopItem) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   EXPECT_EQ(item_grid.GetTopItem(), nullptr);
 }
 
-TEST(PickerImageItemGridViewTest, GetsBottomItem) {
+TEST_F(PickerImageItemGridViewTest, GetsBottomItem) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   PickerItemView* item1 =
@@ -159,13 +163,13 @@
   EXPECT_EQ(item_grid.GetBottomItem(), item3);
 }
 
-TEST(PickerImageItemGridViewTest, EmptyGridHasNoBottomItem) {
+TEST_F(PickerImageItemGridViewTest, EmptyGridHasNoBottomItem) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   EXPECT_EQ(item_grid.GetBottomItem(), nullptr);
 }
 
-TEST(PickerImageItemGridViewTest, GetsItemAbove) {
+TEST_F(PickerImageItemGridViewTest, GetsItemAbove) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   PickerItemView* item1 =
@@ -190,7 +194,7 @@
   EXPECT_EQ(item_grid.GetItemAbove(item4), item2);
 }
 
-TEST(PickerImageItemGridViewTest, ItemNotInGridHasNoItemAbove) {
+TEST_F(PickerImageItemGridViewTest, ItemNotInGridHasNoItemAbove) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
   std::unique_ptr<PickerImageItemView> item_not_in_grid =
       CreateGifItem(gfx::Size(100, 100));
@@ -198,7 +202,7 @@
   EXPECT_EQ(item_grid.GetItemAbove(item_not_in_grid.get()), nullptr);
 }
 
-TEST(PickerImageItemGridViewTest, GetsItemBelow) {
+TEST_F(PickerImageItemGridViewTest, GetsItemBelow) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   PickerItemView* item1 =
@@ -223,7 +227,7 @@
   EXPECT_EQ(item_grid.GetItemBelow(item4), nullptr);
 }
 
-TEST(PickerImageItemGridViewTest, ItemNotInGridHasNoItemBelow) {
+TEST_F(PickerImageItemGridViewTest, ItemNotInGridHasNoItemBelow) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
   std::unique_ptr<PickerImageItemView> item_not_in_grid =
       CreateGifItem(gfx::Size(100, 100));
@@ -231,7 +235,7 @@
   EXPECT_EQ(item_grid.GetItemBelow(item_not_in_grid.get()), nullptr);
 }
 
-TEST(PickerImageItemGridViewTest, GetsItemLeftOf) {
+TEST_F(PickerImageItemGridViewTest, GetsItemLeftOf) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   PickerItemView* item1 =
@@ -256,7 +260,7 @@
   EXPECT_EQ(item_grid.GetItemLeftOf(item4), item3);
 }
 
-TEST(PickerImageItemGridViewTest, GetsItemLeftOfWithUnbalancedColumns) {
+TEST_F(PickerImageItemGridViewTest, GetsItemLeftOfWithUnbalancedColumns) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   PickerItemView* item1 =
@@ -277,7 +281,7 @@
   EXPECT_EQ(item_grid.GetItemLeftOf(item3), item1);
 }
 
-TEST(PickerImageItemGridViewTest, ItemNotInGridHasNoItemLeftOf) {
+TEST_F(PickerImageItemGridViewTest, ItemNotInGridHasNoItemLeftOf) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
   std::unique_ptr<PickerImageItemView> item_not_in_grid =
       CreateGifItem(gfx::Size(100, 100));
@@ -285,7 +289,7 @@
   EXPECT_EQ(item_grid.GetItemLeftOf(item_not_in_grid.get()), nullptr);
 }
 
-TEST(PickerImageItemGridViewTest, GetsItemRightOf) {
+TEST_F(PickerImageItemGridViewTest, GetsItemRightOf) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
 
   PickerItemView* item1 =
@@ -310,7 +314,7 @@
   EXPECT_EQ(item_grid.GetItemRightOf(item4), nullptr);
 }
 
-TEST(PickerImageItemGridViewTest, ItemNotInGridHasNoItemRightOf) {
+TEST_F(PickerImageItemGridViewTest, ItemNotInGridHasNoItemRightOf) {
   PickerImageItemGridView item_grid(kDefaultGridWidth);
   std::unique_ptr<PickerImageItemView> item_not_in_grid =
       CreateGifItem(gfx::Size(100, 100));
@@ -318,5 +322,68 @@
   EXPECT_EQ(item_grid.GetItemRightOf(item_not_in_grid.get()), nullptr);
 }
 
+TEST_F(PickerImageItemGridViewTest, TabFocusTraversesInOrderAdded) {
+  std::unique_ptr<views::Widget> widget =
+      CreateTestWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET);
+  PickerImageItemGridView* item_grid = widget->SetContentsView(
+      std::make_unique<PickerImageItemGridView>(kDefaultGridWidth));
+
+  PickerItemView* item1 =
+      item_grid->AddImageItem(CreateGifItem(gfx::Size(100, 100)));
+  PickerItemView* item2 =
+      item_grid->AddImageItem(CreateGifItem(gfx::Size(100, 110)));
+  PickerItemView* item3 =
+      item_grid->AddImageItem(CreateGifItem(gfx::Size(100, 120)));
+  PickerItemView* item4 =
+      item_grid->AddImageItem(CreateGifItem(gfx::Size(100, 130)));
+
+  views::FocusManager* focus_manager = item_grid->GetFocusManager();
+  ASSERT_TRUE(focus_manager);
+  EXPECT_EQ(focus_manager->GetNextFocusableView(
+                item1, widget.get(), /*reverse=*/false, /*dont_loop*/ true),
+            item2);
+  EXPECT_EQ(focus_manager->GetNextFocusableView(
+                item2, widget.get(), /*reverse=*/false, /*dont_loop*/ true),
+            item3);
+  EXPECT_EQ(focus_manager->GetNextFocusableView(
+                item3, widget.get(), /*reverse=*/false, /*dont_loop*/ true),
+            item4);
+  EXPECT_EQ(focus_manager->GetNextFocusableView(
+                item4, widget.get(), /*reverse=*/false, /*dont_loop*/ true),
+            nullptr);
+}
+
+TEST_F(PickerImageItemGridViewTest,
+       ReverseTabFocusTraversesInReverseOrderAdded) {
+  std::unique_ptr<views::Widget> widget =
+      CreateTestWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET);
+  PickerImageItemGridView* item_grid = widget->SetContentsView(
+      std::make_unique<PickerImageItemGridView>(kDefaultGridWidth));
+
+  PickerItemView* item1 =
+      item_grid->AddImageItem(CreateGifItem(gfx::Size(100, 100)));
+  PickerItemView* item2 =
+      item_grid->AddImageItem(CreateGifItem(gfx::Size(100, 110)));
+  PickerItemView* item3 =
+      item_grid->AddImageItem(CreateGifItem(gfx::Size(100, 120)));
+  PickerItemView* item4 =
+      item_grid->AddImageItem(CreateGifItem(gfx::Size(100, 130)));
+
+  views::FocusManager* focus_manager = item_grid->GetFocusManager();
+  ASSERT_TRUE(focus_manager);
+  EXPECT_EQ(focus_manager->GetNextFocusableView(
+                item1, widget.get(), /*reverse=*/true, /*dont_loop*/ true),
+            nullptr);
+  EXPECT_EQ(focus_manager->GetNextFocusableView(
+                item2, widget.get(), /*reverse=*/true, /*dont_loop*/ true),
+            item1);
+  EXPECT_EQ(focus_manager->GetNextFocusableView(
+                item3, widget.get(), /*reverse=*/true, /*dont_loop*/ true),
+            item2);
+  EXPECT_EQ(focus_manager->GetNextFocusableView(
+                item4, widget.get(), /*reverse=*/true, /*dont_loop*/ true),
+            item3);
+}
+
 }  // namespace
 }  // namespace ash
diff --git a/ash/picker/views/picker_image_item_view.cc b/ash/picker/views/picker_image_item_view.cc
index 5e4ff3ba..992d26b 100644
--- a/ash/picker/views/picker_image_item_view.cc
+++ b/ash/picker/views/picker_image_item_view.cc
@@ -8,7 +8,9 @@
 #include <utility>
 
 #include "ash/picker/views/picker_item_view.h"
+#include "ash/strings/grit/ash_strings.h"
 #include "base/memory/raw_ptr.h"
+#include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
 #include "ui/gfx/geometry/size.h"
 #include "ui/views/accessibility/view_accessibility.h"
@@ -26,10 +28,11 @@
     std::u16string accessible_name,
     SelectItemCallback select_item_callback)
     : PickerItemView(std::move(select_item_callback),
-                     FocusIndicatorStyle::kFocusRingWithInsetGap) {
+                     FocusIndicatorStyle::kFocusRingWithInsetGap),
+      accessible_name_(std::move(accessible_name)) {
   SetUseDefaultFillLayout(true);
   SetCornerRadius(kPickerImageItemCornerRadius);
-  GetViewAccessibility().SetName(std::move(accessible_name));
+  GetViewAccessibility().SetName(accessible_name_);
 
   image_view_ = AddChildView(std::move(image));
   image_view_->SetCanProcessEventsWithinSubtree(false);
@@ -37,6 +40,27 @@
 
 PickerImageItemView::~PickerImageItemView() = default;
 
+void PickerImageItemView::SetAction(PickerActionType action) {
+  switch (action) {
+    case PickerActionType::kDo:
+      GetViewAccessibility().SetName(accessible_name_);
+      break;
+    case PickerActionType::kInsert:
+      GetViewAccessibility().SetName(l10n_util::GetStringFUTF16(
+          IDS_PICKER_LIST_ITEM_INSERT_ACTION_ACCESSIBLE_NAME,
+          accessible_name_));
+      break;
+    case PickerActionType::kOpen:
+      GetViewAccessibility().SetName(l10n_util::GetStringFUTF16(
+          IDS_PICKER_LIST_ITEM_OPEN_ACTION_ACCESSIBLE_NAME, accessible_name_));
+      break;
+    case PickerActionType::kCreate:
+      // TODO: b/345303965 - Add internal strings for Create.
+      GetViewAccessibility().SetName(accessible_name_);
+      break;
+  }
+}
+
 BEGIN_METADATA(PickerImageItemView)
 END_METADATA
 
diff --git a/ash/picker/views/picker_image_item_view.h b/ash/picker/views/picker_image_item_view.h
index 9913015f..3f00ae4 100644
--- a/ash/picker/views/picker_image_item_view.h
+++ b/ash/picker/views/picker_image_item_view.h
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "ash/ash_export.h"
+#include "ash/picker/model/picker_action_type.h"
 #include "ash/picker/views/picker_item_view.h"
 #include "base/memory/raw_ptr.h"
 #include "ui/base/metadata/metadata_header_macros.h"
@@ -30,8 +31,11 @@
   PickerImageItemView& operator=(const PickerImageItemView&) = delete;
   ~PickerImageItemView() override;
 
+  void SetAction(PickerActionType action);
+
  private:
   raw_ptr<views::ImageView> image_view_ = nullptr;
+  std::u16string accessible_name_;
 };
 
 }  // namespace ash
diff --git a/ash/picker/views/picker_search_results_view.cc b/ash/picker/views/picker_search_results_view.cc
index bfd665a..8498414 100644
--- a/ash/picker/views/picker_search_results_view.cc
+++ b/ash/picker/views/picker_search_results_view.cc
@@ -287,6 +287,9 @@
 
   if (auto* list_item_view = views::AsViewClass<PickerListItemView>(view)) {
     list_item_view->SetBadgeAction(delegate_->GetActionForResult(result));
+  } else if (auto* image_item_view =
+                 views::AsViewClass<PickerImageItemView>(view)) {
+    image_item_view->SetAction(delegate_->GetActionForResult(result));
   }
 }
 
diff --git a/ash/picker/views/picker_zero_state_view.cc b/ash/picker/views/picker_zero_state_view.cc
index 821a76e..c61d623b 100644
--- a/ash/picker/views/picker_zero_state_view.cc
+++ b/ash/picker/views/picker_zero_state_view.cc
@@ -18,6 +18,7 @@
 #include "ash/picker/picker_clipboard_history_provider.h"
 #include "ash/picker/views/picker_category_type.h"
 #include "ash/picker/views/picker_icons.h"
+#include "ash/picker/views/picker_image_item_view.h"
 #include "ash/picker/views/picker_item_view.h"
 #include "ash/picker/views/picker_item_with_submenu_view.h"
 #include "ash/picker/views/picker_list_item_view.h"
@@ -222,6 +223,9 @@
 
   if (auto* list_item_view = views::AsViewClass<PickerListItemView>(view)) {
     list_item_view->SetBadgeAction(delegate_->GetActionForResult(result));
+  } else if (auto* image_item_view =
+                 views::AsViewClass<PickerImageItemView>(view)) {
+    image_item_view->SetAction(delegate_->GetActionForResult(result));
   }
 }
 
diff --git a/ash/public/cpp/BUILD.gn b/ash/public/cpp/BUILD.gn
index d3a2a2a9..0c68504c 100644
--- a/ash/public/cpp/BUILD.gn
+++ b/ash/public/cpp/BUILD.gn
@@ -125,6 +125,7 @@
     "clipboard_image_model_factory.h",
     "connectivity_services.cc",
     "connectivity_services.h",
+    "coral_delegate.h",
     "coral_util.cc",
     "coral_util.h",
     "debug_delegate.h",
diff --git a/ash/public/cpp/coral_delegate.h b/ash/public/cpp/coral_delegate.h
new file mode 100644
index 0000000..2b873a2
--- /dev/null
+++ b/ash/public/cpp/coral_delegate.h
@@ -0,0 +1,40 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef ASH_PUBLIC_CPP_CORAL_DELEGATE_H_
+#define ASH_PUBLIC_CPP_CORAL_DELEGATE_H_
+
+#include "ash/public/cpp/ash_public_export.h"
+#include "ash/public/cpp/coral_util.h"
+
+namespace ash {
+
+// This delegate is owned by Shell and used by ash/ to communicate with
+// `CoralClient` in chrome/ for browser operations.
+class ASH_PUBLIC_EXPORT CoralDelegate {
+ public:
+  virtual ~CoralDelegate() = default;
+
+  // Creates up to one browser with tabs from `cluster`. Launches the apps given
+  // the app ids in `cluster`. This should be called from the post-login
+  // overview screen and there should be no open applications. See
+  // ash/wm/window_restore/README.md for more details about post-login.
+  virtual void LaunchPostLoginCluster(
+      const coral_util::CoralCluster& cluster) = 0;
+
+  // Opens a new desk and adds up to one browser with tabs from `cluster`. Moves
+  // apps to the new desk from existing desks based on the apps from `cluster`.
+  virtual void OpenNewDeskWithCluster(
+      const coral_util::CoralCluster& cluster) = 0;
+
+  // Creates a saved desk with up to one browser with tabs from `cluster`.
+  // Closes apps based on the apps from `cluster`, and places them in the saved
+  // desk to be launched at a later time.
+  virtual void CreateSavedDeskFromCluster(
+      const coral_util::CoralCluster& cluster) = 0;
+};
+
+}  // namespace ash
+
+#endif  // ASH_PUBLIC_CPP_CORAL_DELEGATE_H_
diff --git a/ash/shell.cc b/ash/shell.cc
index 1f31a24f..d1fe724d 100644
--- a/ash/shell.cc
+++ b/ash/shell.cc
@@ -118,6 +118,7 @@
 #include "ash/projector/projector_controller_impl.h"
 #include "ash/public/cpp/accelerator_keycode_lookup_cache.h"
 #include "ash/public/cpp/ash_prefs.h"
+#include "ash/public/cpp/coral_delegate.h"
 #include "ash/public/cpp/holding_space/holding_space_controller.h"
 #include "ash/public/cpp/login/local_authentication_request_controller.h"
 #include "ash/public/cpp/nearby_share_delegate.h"
@@ -750,6 +751,8 @@
 
   ash_dbus_services_.reset();
 
+  coral_delegate_.reset();
+
   saved_desk_controller_.reset();
   saved_desk_delegate_.reset();
   desks_controller_->Shutdown();
@@ -1817,6 +1820,9 @@
       CoralController::IsSecretKeyMatched()) {
     coral_controller_ = std::make_unique<CoralController>();
   }
+  if (features::IsBirchCoralEnabled()) {
+    coral_delegate_ = shell_delegate_->CreateCoralDelegate();
+  }
 
   if (features::IsPickerUpdateEnabled()) {
     picker_controller_ = std::make_unique<PickerController>();
diff --git a/ash/shell.h b/ash/shell.h
index 29b6b9ee..8a428b0 100644
--- a/ash/shell.h
+++ b/ash/shell.h
@@ -136,6 +136,7 @@
 class ColorPaletteController;
 class ControlVHistogramRecorder;
 class CoralController;
+class CoralDelegate;
 class CrosDisplayConfig;
 class DarkLightModeControllerImpl;
 class DeskProfilesDelegate;
@@ -877,6 +878,7 @@
   }
 
   CoralController* coral_controller() { return coral_controller_.get(); }
+  CoralDelegate* coral_delegate() { return coral_delegate_.get(); }
 
   DragDropController* drag_drop_controller() {
     return drag_drop_controller_.get();
@@ -1307,6 +1309,7 @@
   std::unique_ptr<display::NativeDisplayDelegate> native_display_delegate_;
 
   std::unique_ptr<CoralController> coral_controller_;
+  std::unique_ptr<CoralDelegate> coral_delegate_;
 
   base::WeakPtrFactory<Shell> weak_factory_{this};
 };
diff --git a/ash/shell_delegate.h b/ash/shell_delegate.h
index 245c507..f52bb45 100644
--- a/ash/shell_delegate.h
+++ b/ash/shell_delegate.h
@@ -43,6 +43,7 @@
 class BackGestureContextualNudgeDelegate;
 class CaptureModeDelegate;
 class ClipboardHistoryControllerDelegate;
+class CoralDelegate;
 class DeskProfilesDelegate;
 class FocusModeDelegate;
 class GameDashboardDelegate;
@@ -78,6 +79,9 @@
   virtual std::unique_ptr<ClipboardHistoryControllerDelegate>
   CreateClipboardHistoryControllerDelegate() const = 0;
 
+  // Creates and returns the delegate of the Coral feature.
+  virtual std::unique_ptr<CoralDelegate> CreateCoralDelegate() const = 0;
+
   // Creates and returns the delegate of the Game Dashboard feature.
   virtual std::unique_ptr<GameDashboardDelegate> CreateGameDashboardDelegate()
       const = 0;
diff --git a/ash/system/focus_mode/sounds/focus_mode_sounds_controller.cc b/ash/system/focus_mode/sounds/focus_mode_sounds_controller.cc
index e31475cd..d9cae8b5 100644
--- a/ash/system/focus_mode/sounds/focus_mode_sounds_controller.cc
+++ b/ash/system/focus_mode/sounds/focus_mode_sounds_controller.cc
@@ -24,6 +24,7 @@
 #include "ash/system/focus_mode/focus_mode_util.h"
 #include "ash/system/focus_mode/sounds/focus_mode_soundscape_delegate.h"
 #include "ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.h"
+#include "ash/system/focus_mode/sounds/sound_section_view.h"
 #include "ash/system/focus_mode/sounds/youtube_music/youtube_music_types.h"
 #include "base/barrier_callback.h"
 #include "base/check.h"
@@ -42,8 +43,6 @@
 
 namespace {
 
-constexpr int kPlaylistNum = 4;
-
 // Arrays for histogram records.
 constexpr focus_mode_histogram_names::FocusModePlaylistChosen
     soundscapes_chosen[] = {
@@ -148,14 +147,14 @@
     return;
   }
 
-  CHECK_EQ(static_cast<int>(data.size()), kPlaylistNum);
+  CHECK_EQ(data.size(), kFocusModePlaylistViewsNum);
 
   // TODO(b/340304748): Currently, when opening the focus panel, we will clean
   // up all saved data and then download all playlists. In the future, we can
   // keep this cached and update if there are new playlists.
   using BarrierReturn = std::unique_ptr<FocusModeSoundsController::Playlist>;
   auto barrier_callback = base::BarrierCallback<BarrierReturn>(
-      /*num_callbacks=*/kPlaylistNum,
+      /*num_callbacks=*/kFocusModePlaylistViewsNum,
       /*done_callback=*/base::BindOnce(&ReorderPlaylists, data,
                                        std::move(sorted_playlists_callback)));
 
@@ -288,8 +287,8 @@
           std::make_unique<FocusModeYouTubeMusicDelegate>()) {
   // TODO(b/341176182): Plumb the locale here and replace the default
   // locale.
-  soundscape_playlists_.reserve(kPlaylistNum);
-  youtube_music_playlists_.reserve(kPlaylistNum);
+  soundscape_playlists_.reserve(kFocusModePlaylistViewsNum);
+  youtube_music_playlists_.reserve(kFocusModePlaylistViewsNum);
 
   // Default sound sections to enabled.
   enabled_sound_sections_ = {focus_mode_util::SoundType::kSoundscape,
@@ -652,11 +651,14 @@
     bool is_soundscape_type,
     UpdateSoundsViewCallback update_sounds_view_callback,
     std::vector<std::unique_ptr<Playlist>> sorted_playlists) {
-  // For the case that the `selected_playlist_` is missing from the list of
-  // playlists fetched from backend, we will show the cached playlist info if
-  // the selected playlist is currently playing; otherwise, we will clear the
-  // selected playlist in the controller.
-  if (!MayContainsSelectedPlaylist(selected_playlist_, is_soundscape_type,
+  // Please note, `sorted_playlists` can be empty, so it's important to check if
+  // the number of playlists is expected before manipulating the list. For the
+  // case that the `selected_playlist_` is missing from the list of playlists
+  // fetched from backend, we will show the cached playlist info if the selected
+  // playlist is currently playing; otherwise, we will clear the selected
+  // playlist in the controller.
+  if (sorted_playlists.size() == kFocusModePlaylistViewsNum &&
+      !MayContainsSelectedPlaylist(selected_playlist_, is_soundscape_type,
                                    sorted_playlists)) {
     if (selected_playlist_.state == focus_mode_util::SoundState::kPlaying) {
       sorted_playlists.pop_back();
diff --git a/ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.cc b/ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.cc
index ec6a10e..c633acb 100644
--- a/ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.cc
+++ b/ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.cc
@@ -5,6 +5,7 @@
 #include "ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.h"
 
 #include <cstddef>
+#include <memory>
 #include <optional>
 #include <string>
 #include <utility>
@@ -79,24 +80,27 @@
   GetMusicSectionInternal();
 }
 
-bool FocusModeYouTubeMusicDelegate::ReportPlayback(
+void FocusModeYouTubeMusicDelegate::ReportPlayback(
     const youtube_music::PlaybackData& playback_data) {
   // Check for token and see if it has sufficient data for the reporting
   // request.
-  if (report_playback_state_.url_to_token.find(playback_data.url) ==
-      report_playback_state_.url_to_token.end()) {
-    return false;
+  const auto state_iterator = report_playback_states_.find(playback_data.url);
+  if (state_iterator == report_playback_states_.end() ||
+      !state_iterator->second.get()) {
+    return;
   }
 
-  report_playback_state_.url_to_playback_state.insert(
-      {playback_data.url, playback_data.state});
-  const std::string& playback_reporting_token =
-      report_playback_state_.url_to_token[playback_data.url];
+  ReportPlaybackRequestState& state = *state_iterator->second;
+  state.retry_state.Reset();
+  state.playback_state = playback_data.state;
+  if (state.staged_playback_data.has_value() &&
+      state.staged_playback_data->CanAggregateWithNewData(playback_data)) {
+    state.staged_playback_data.value().AggregateWithNewData(playback_data);
+  } else {
+    state.staged_playback_data = playback_data;
+  }
 
-  return youtube_music_controller_->ReportPlayback(
-      playback_reporting_token, playback_data,
-      base::BindOnce(&FocusModeYouTubeMusicDelegate::OnReportPlaybackDone,
-                     weak_factory_.GetWeakPtr(), playback_data.url));
+  ReportPlaybackInternal(playback_data.url);
 }
 
 void FocusModeYouTubeMusicDelegate::SetNoPremiumCallback(
@@ -179,12 +183,6 @@
 FocusModeYouTubeMusicDelegate::ReportPlaybackRequestState::
     ~ReportPlaybackRequestState() = default;
 
-bool FocusModeYouTubeMusicDelegate::ReportPlaybackRequestState::
-    CanReportPlaybackForUrl(const GURL& url) {
-  return url_to_playback_state.find(url) != url_to_playback_state.end() &&
-         url_to_token.find(url) != url_to_token.end();
-}
-
 void FocusModeYouTubeMusicDelegate::GetPlaylistInternal(
     const GetPlaylistsRequestState::PlaylistType type) {
   std::string playlist_id;
@@ -459,7 +457,10 @@
         /*source_url=*/playback_context->stream_url,
         // YouTube Music requires playback reporting.
         /*enable_playback_reporting=*/true);
-    report_playback_state_.url_to_token[playback_context->stream_url] =
+    report_playback_states_.emplace(
+        playback_context->stream_url,
+        std::make_unique<ReportPlaybackRequestState>());
+    report_playback_states_.at(playback_context->stream_url)->token =
         playback_context->playback_reporting_token;
   }
 
@@ -471,20 +472,83 @@
   next_track_state_.retry_state.Reset();
 }
 
+void FocusModeYouTubeMusicDelegate::ReportPlaybackInternal(const GURL& url) {
+  const auto state_iterator = report_playback_states_.find(url);
+  if (state_iterator == report_playback_states_.end() ||
+      !state_iterator->second.get()) {
+    return;
+  }
+
+  ReportPlaybackRequestState& state = *state_iterator->second;
+  youtube_music_controller_->ReportPlayback(
+      state.token, state.staged_playback_data.value(),
+      base::BindOnce(&FocusModeYouTubeMusicDelegate::OnReportPlaybackDone,
+                     weak_factory_.GetWeakPtr(), url));
+}
+
 void FocusModeYouTubeMusicDelegate::OnReportPlaybackDone(
     const GURL& url,
     google_apis::ApiErrorCode http_error_code,
     std::optional<const std::string> new_playback_reporting_token) {
-  if (http_error_code != google_apis::ApiErrorCode::HTTP_SUCCESS) {
-    if (http_error_code == google_apis::ApiErrorCode::HTTP_FORBIDDEN &&
-        no_premium_callback_) {
-      no_premium_callback_.Run();
-    }
-    // TODO(b/354240276): Add more error handling and retries.
+  const auto state_iterator = report_playback_states_.find(url);
+  if (state_iterator == report_playback_states_.end() ||
+      !state_iterator->second.get()) {
     return;
   }
 
-  if (!report_playback_state_.CanReportPlaybackForUrl(url)) {
+  ReportPlaybackRequestState& state = *state_iterator->second;
+  const bool last_report =
+      state.playback_state == youtube_music::PlaybackState::kEnded ||
+      state.playback_state == youtube_music::PlaybackState::kSwitchedToNext;
+  if (http_error_code != google_apis::ApiErrorCode::HTTP_SUCCESS) {
+    // Handle forbidden error. No need for further attempts.
+    if (http_error_code == google_apis::ApiErrorCode::HTTP_FORBIDDEN) {
+      if (no_premium_callback_) {
+        no_premium_callback_.Run();
+      }
+
+      // Bail gracefully.
+      report_playback_states_.erase(url);
+      return;
+    }
+
+    // Handle too many request error. Retry if needed.
+    if (http_error_code == 429 &&
+        state.retry_state.retry_index < kMaxRetryTooManyRequests) {
+      state.retry_state.retry_index++;
+      state.retry_state.timer.Start(
+          FROM_HERE, kWaitTimeTooManyRequests,
+          base::BindOnce(&FocusModeYouTubeMusicDelegate::ReportPlaybackInternal,
+                         weak_factory_.GetWeakPtr(), url));
+      return;
+    }
+
+    // Handle general HTTP errors. Retry if needed.
+    if (ShouldRetryHttpError(http_error_code) &&
+        state.retry_state.retry_index < kMaxRetryOverall) {
+      state.retry_state.retry_index++;
+      state.retry_state.timer.Start(
+          FROM_HERE, kWaitTimeTooManyRequests,
+          base::BindOnce(&FocusModeYouTubeMusicDelegate::ReportPlaybackInternal,
+                         weak_factory_.GetWeakPtr(), url));
+      return;
+    }
+
+    // Bail gracefully. If it's the last report of the track, remove its local
+    // state; otherwise, reset the retry state for the next report so that the
+    // staged data could be aggregated into the new incoming data and still be
+    // reported.
+    if (last_report) {
+      report_playback_states_.erase(url);
+    } else {
+      state.retry_state.Reset();
+    }
+    return;
+  }
+
+  // When a track is completed, clear the local data.
+  if (last_report) {
+    report_playback_states_.erase(url);
     return;
   }
 
@@ -492,18 +556,15 @@
   // the API server may return empty tokens when a track is completed.
   if (new_playback_reporting_token.has_value() &&
       !new_playback_reporting_token.value().empty()) {
-    report_playback_state_.url_to_token[url] =
-        new_playback_reporting_token.value();
+    state.token = new_playback_reporting_token.value();
   }
 
-  // When a track is completed, clear the local data.
-  if (report_playback_state_.url_to_playback_state.at(url) ==
-          youtube_music::PlaybackState::kEnded ||
-      report_playback_state_.url_to_playback_state.at(url) ==
-          youtube_music::PlaybackState::kSwitchedToNext) {
-    report_playback_state_.url_to_playback_state.erase(url);
-    report_playback_state_.url_to_token.erase(url);
-  }
+  // Commit finished playback data from staging area.
+  state.staged_playback_data.reset();
+
+  // For a successful request, reset the retry state so that it could handle
+  // failure correctly going forward.
+  state.retry_state.Reset();
 }
 
 }  // namespace ash
diff --git a/ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.h b/ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.h
index 68a96133..fba561a 100644
--- a/ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.h
+++ b/ash/system/focus_mode/sounds/focus_mode_youtube_music_delegate.h
@@ -6,6 +6,7 @@
 #define ASH_SYSTEM_FOCUS_MODE_SOUNDS_FOCUS_MODE_YOUTUBE_MUSIC_DELEGATE_H_
 
 #include <array>
+#include <memory>
 #include <optional>
 #include <string>
 #include <vector>
@@ -50,7 +51,7 @@
   void SetNoPremiumCallback(base::RepeatingClosure callback);
 
   // Reports music playback.
-  bool ReportPlayback(const youtube_music::PlaybackData& playback_data);
+  void ReportPlayback(const youtube_music::PlaybackData& playback_data);
 
   // Reserves a playlist for the returned playlists.
   void ReservePlaylistForGetPlaylists(const std::string& playlist_id);
@@ -117,16 +118,10 @@
     ReportPlaybackRequestState();
     ~ReportPlaybackRequestState();
 
-    // Checks if it can report the playback for `url`.
-    bool CanReportPlaybackForUrl(const GURL& url);
-
-    // URL to `PlaybackState` map. It contains all playback data for the
-    // requests.
-    base::flat_map<GURL, youtube_music::PlaybackState> url_to_playback_state;
-
-    // URL to playback reporting token map. It contains all tokens for the
-    // requests.
-    base::flat_map<GURL, std::string> url_to_token;
+    youtube_music::PlaybackState playback_state;
+    std::optional<youtube_music::PlaybackData> staged_playback_data;
+    std::string token;
+    FocusModeRetryState retry_state;
   };
 
   // Triggers request to query for specific playlist for the given bucket.
@@ -159,6 +154,8 @@
       google_apis::ApiErrorCode http_error_code,
       std::optional<const youtube_music::PlaybackContext> playback_context);
 
+  void ReportPlaybackInternal(const GURL& url);
+
   // Called when report playback request is done.
   void OnReportPlaybackDone(
       const GURL& url,
@@ -171,8 +168,9 @@
   // Next track request state for `GetPlaylists`.
   GetNextTrackRequestState next_track_state_;
 
-  // Report playback request state for `ReportPlayback`.
-  ReportPlaybackRequestState report_playback_state_;
+  // Report playback request state per track for `ReportPlayback`.
+  base::flat_map<GURL, std::unique_ptr<ReportPlaybackRequestState>>
+      report_playback_states_;
 
   // Callback to run when the request fails with HTTP 403.
   base::RepeatingClosure no_premium_callback_;
diff --git a/ash/system/mahi/mahi_nudge_controller_unittest.cc b/ash/system/mahi/mahi_nudge_controller_unittest.cc
index a7fa84e6..e150bb72 100644
--- a/ash/system/mahi/mahi_nudge_controller_unittest.cc
+++ b/ash/system/mahi/mahi_nudge_controller_unittest.cc
@@ -45,6 +45,7 @@
     UpdateHMREnabled(enabled);
   }
 
+  bool IsMagicBoostAvailable() override { return true; }
   int32_t AsyncIncrementHMRConsentWindowDismissCount() override { return 0; }
   void DisableOrcaFeature() override {}
 };
diff --git a/ash/system/video_conference/bubble/bubble_view_pixeltest.cc b/ash/system/video_conference/bubble/bubble_view_pixeltest.cc
index d58b283..bda1d31 100644
--- a/ash/system/video_conference/bubble/bubble_view_pixeltest.cc
+++ b/ash/system/video_conference/bubble/bubble_view_pixeltest.cc
@@ -73,6 +73,8 @@
         features::kVcBackgroundReplace};
     if (IsVcDlcUiEnabled()) {
       enabled_features.push_back(features::kVcDlcUi);
+    } else {
+      disabled_features.push_back(features::kVcDlcUi);
     }
     scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
 
diff --git a/ash/system/video_conference/bubble/vc_tile_ui_controller.cc b/ash/system/video_conference/bubble/vc_tile_ui_controller.cc
index 99192a1..3d28e892 100644
--- a/ash/system/video_conference/bubble/vc_tile_ui_controller.cc
+++ b/ash/system/video_conference/bubble/vc_tile_ui_controller.cc
@@ -59,8 +59,13 @@
       /*is_togglable=*/true, FeatureTile::TileType::kCompact);
   tile_ = tile->GetWeakPtr();
 
-  // Set up view ids for the tile and its children.
-  tile->SetID(BubbleViewID::kToggleEffectsButton);
+  // Assign the ID, if present, to the outermost container view. Only used in
+  // tests.
+  std::optional<int> container_id =
+      effect_ ? effect_->container_id() : std::nullopt;
+  tile->SetID(container_id.has_value() ? container_id.value()
+                                       : BubbleViewID::kToggleEffectsButton);
+
   tile->label()->SetID(BubbleViewID::kToggleEffectLabel);
   tile->icon_button()->SetID(BubbleViewID::kToggleEffectIcon);
 
diff --git a/ash/test_shell_delegate.cc b/ash/test_shell_delegate.cc
index 6178701..cc2b17a786 100644
--- a/ash/test_shell_delegate.cc
+++ b/ash/test_shell_delegate.cc
@@ -53,6 +53,10 @@
   return std::make_unique<TestClipboardHistoryControllerDelegateImpl>();
 }
 
+std::unique_ptr<CoralDelegate> TestShellDelegate::CreateCoralDelegate() const {
+  return nullptr;
+}
+
 std::unique_ptr<GameDashboardDelegate>
 TestShellDelegate::CreateGameDashboardDelegate() const {
   return std::make_unique<TestGameDashboardDelegate>();
diff --git a/ash/test_shell_delegate.h b/ash/test_shell_delegate.h
index 5713d75..923f509 100644
--- a/ash/test_shell_delegate.h
+++ b/ash/test_shell_delegate.h
@@ -57,6 +57,7 @@
       const override;
   std::unique_ptr<ClipboardHistoryControllerDelegate>
   CreateClipboardHistoryControllerDelegate() const override;
+  std::unique_ptr<CoralDelegate> CreateCoralDelegate() const override;
   std::unique_ptr<GameDashboardDelegate> CreateGameDashboardDelegate()
       const override;
   std::unique_ptr<AcceleratorPrefsDelegate> CreateAcceleratorPrefsDelegate()
diff --git a/ash/webui/sanitize_ui/resources/sanitize_done.html b/ash/webui/sanitize_ui/resources/sanitize_done.html
index 6ddee68..99fd56c0 100644
--- a/ash/webui/sanitize_ui/resources/sanitize_done.html
+++ b/ash/webui/sanitize_ui/resources/sanitize_done.html
@@ -6,9 +6,9 @@
 
   cr-expand-button {
     background-color: var(--cros-sys-app_base);
-    border-radius: var(--cr-card-border-radius);
-    margin-bottom: 8px;
-    padding: 14px 16px 16px 14px;
+    border-top-left-radius: var(--cr-card-border-radius);
+    border-top-right-radius: var(--cr-card-border-radius);
+    padding: 14px 16px 0px 14px;
   }
 
   .expand-buttons {
@@ -20,6 +20,14 @@
     overflow-y: scroll;
   }
 
+  .expand-button-ending {
+    background-color: var(--cros-sys-app_base);
+    border-bottom-left-radius: var(--cr-card-border-radius);
+    border-bottom-right-radius: var(--cr-card-border-radius);
+    margin-bottom: 8px;
+    padding-bottom: 16px;
+  }
+
   .expand-container-icon {
     height: 24px;
     margin-right: 12px;
@@ -61,6 +69,7 @@
 
   .list-container {
     align-items: center;
+    background-color: var(--cros-sys-app_base);
     border-top: var(--cr-separator-line);
     color: var(--cros-sys-on_surface);
     display: flex;
@@ -70,6 +79,8 @@
     font-weight: var(--cros-button-1-font-weight);
     line-height: var(--cros-button-1-line-height);
     min-height: var(--settings-row-min-height);
+    padding-left: 14px;
+    padding-right: 16px;
     padding-top: 4px;
   }
 
@@ -78,14 +89,14 @@
   }
 </style>
 
-<div slot="body">
+<div slot="body" role="dialog">
   <div class="completed-icon-div">
     <svg class="completed-icon"
         preserveAspectRatio="xMidYMid meet" role="img" viewBox="0 0 32 32">
       <use href="svg/finished_32.svg#finished_32"></use>
     </svg>
   </div>
-  <div id="title" class="title">$i18n{sanitizeDoneTitle}</div>
+  <h2><div id="title" class="title">$i18n{sanitizeDoneTitle}</div></h2>
   <div class="sanitize-description">
     $i18n{sanitizeDoneExplanation}
   </div>
@@ -103,25 +114,29 @@
                role="img" viewBox="0 0 32 32">
             <use href="svg/extension_off_32.svg#extension_off_32"></use>
           </svg>
-          <span class="expand-title">
+          <span class="expand-title" id="accordionExtensionsTitle">
             $i18n{sanitizeDoneAccordionExtensionsTitle}
           </span>
         </div>
-        <template is="dom-if" if="[[extensionsExpanded_]]">
-          <div>
-            <div class="list-container">
-              $i18n{sanitizeDoneAccordionExtensionsReenable}
-              <span class="secondary-button-container">
-                <cros-button role="button" button-style="secondary"
-                    id="extensionsButton" on-click="onExtensionsButtonClick_"
-                    aria-label="$i18n{sanitizeDoneButtonExtensions}"
-                    label="$i18n{sanitizeDoneButtonExtensions}">
-                </cros-button>
-              </span>
-            </div>
-          </div>
-        </template>
       </cr-expand-button>
+      <template is="dom-if" if="[[extensionsExpanded_]]">
+        <div role="region" aria-labelledby="accordionExtensionsTitle">
+          <div class="list-container">
+            <div id="accordionExtensionsTitle">
+              $i18n{sanitizeDoneAccordionExtensionsReenable}
+            </div>
+            <span class="secondary-button-container">
+              <cros-button role="button" button-style="secondary"
+                  id="extensionsButton" on-click="onExtensionsButtonClick_"
+                  aria-label="$i18n{sanitizeDoneButtonExtensions}"
+                  aria-describedby="accordionExtensionsTitle"
+                  label="$i18n{sanitizeDoneButtonExtensions}">
+              </cros-button>
+            </span>
+          </div>
+        </div>
+      </template>
+      <div class="expand-button-ending"></div>
       <cr-expand-button
           class="expand-container"
           expanded="{{chromeOSSettingsInfoExpanded_}}"
@@ -132,36 +147,43 @@
               role="img" viewBox="0 0 24 24">
             <use href="svg/card_settings.svg#card_settings"></use>
           </svg>
-          <span class="expand-title">
+          <span class="expand-title" id="accordionChromeOsTitle">
             $i18n{sanitizeDoneAccordionChromeOsTitle}
           </span>
         </div>
-        <template is="dom-if" if="[[chromeOSSettingsInfoExpanded_]]">
-          <div>
-            <div class="list-container">
-              $i18n{sanitizeDoneAccordionChromeOsInput}
-              <span class="secondary-button-container">
-                <cros-button role="button" button-style="secondary"
-                    id="chromeOsInputButton" on-click="onChromeOsInputClick_"
-                    aria-label="$i18n{sanitizeDoneButtonChromeOSInput}"
-                    label="$i18n{sanitizeDoneButtonChromeOSInput}">
-                </cros-button>
-              </span>
-            </div>
-            <div class="list-container">
-              $i18n{sanitizeDoneAccordionChromeOsNetwork}
-              <span class="secondary-button-container">
-                <cros-button role="button" button-style="secondary"
-                    id="chromeOsNetworkButton"
-                    on-click="onChromeOsNetworkClick_"
-                    aria-label="$i18n{sanitizeDoneButtonChromeOSNetwork}"
-                    label="$i18n{sanitizeDoneButtonChromeOSNetwork}">
-                </cros-button>
-              </span>
-            </div>
-          </div>
-        </template>
       </cr-expand-button>
+      <template is="dom-if" if="[[chromeOSSettingsInfoExpanded_]]">
+        <div role="region" aria-labelledby="accordionChromeOsTitle">
+          <div class="list-container">
+            <div id="accordionChromeOsInputTitle">
+              $i18n{sanitizeDoneAccordionChromeOsInput}
+            </div>
+            <span class="secondary-button-container">
+              <cros-button role="button" button-style="secondary"
+                  id="chromeOsInputButton" on-click="onChromeOsInputClick_"
+                  aria-label="$i18n{sanitizeDoneButtonChromeOSInput}"
+                  aria-describedby="accordionChromeOsInputTitle"
+                  label="$i18n{sanitizeDoneButtonChromeOSInput}">
+              </cros-button>
+            </span>
+          </div>
+          <div class="list-container">
+            <div id="accordionChromeOsNetworkTitle">
+              $i18n{sanitizeDoneAccordionChromeOsNetwork}
+            </div>
+            <span class="secondary-button-container">
+              <cros-button role="button" button-style="secondary"
+                  id="chromeOsNetworkButton"
+                  on-click="onChromeOsNetworkClick_"
+                  aria-label="$i18n{sanitizeDoneButtonChromeOSNetwork}"
+                  aria-describedby="accordionChromeOsNetworkTitle"
+                  label="$i18n{sanitizeDoneButtonChromeOSNetwork}">
+              </cros-button>
+            </span>
+          </div>
+        </div>
+      </template>
+      <div class="expand-button-ending"></div>
       <cr-expand-button
           class="expand-container"
           expanded="{{chromeSettingsInfoExpanded_}}"
@@ -172,56 +194,68 @@
               role="img" viewBox="0 0 24 24">
             <use href="svg/card_chrome_product.svg#card_chrome_product"></use>
           </svg>
-          <span class="expand-title">
+          <span class="expand-title" id="accordionChromeTitle">
             $i18n{sanitizeDoneAccordionChromeTitle}
           </span>
         </div>
-        <template is="dom-if" if="[[chromeSettingsInfoExpanded_]]">
-          <div>
-            <div class="list-container">
-              $i18n{sanitizeDoneAccordionChromeSiteContent}
-              <span class="secondary-button-container">
-                <cros-button role="button" button-style="secondary"
-                    id="chromeSiteContentButton"
-                    on-click="onChromeSiteContentClick_"
-                    aria-label="$i18n{sanitizeDoneButtonChromeSiteContent}"
-                    label="$i18n{sanitizeDoneButtonChromeSiteContent}">
-                </cros-button>
-              </span>
-            </div>
-            <div class="list-container">
-              $i18n{sanitizeDoneAccordionChromeStartup}
-              <span class="secondary-button-container">
-                <cros-button role="button" button-style="secondary"
-                    id="chromeStartupButton" on-click="onChromeStartupClick_"
-                    aria-label="$i18n{sanitizeDoneButtonChromeStartup}"
-                    label="$i18n{sanitizeDoneButtonChromeStartup}">
-                </cros-button>
-              </span>
-            </div>
-            <div class="list-container">
-              $i18n{sanitizeDoneAccordionChromeHomepage}
-              <span class="secondary-button-container">
-                <cros-button role="button" button-style="secondary"
-                    id="chromeHomepageButton" on-click="onChromeHomepageClick_"
-                    aria-label="$i18n{sanitizeDoneButtonChromeHomepage}"
-                    label="$i18n{sanitizeDoneButtonChromeHomepage}">
-                </cros-button>
-              </span>
-            </div>
-            <div class="list-container">
-              $i18n{sanitizeDoneAccordionChromeLanguages}
-              <span class="secondary-button-container">
-                <cros-button role="button" button-style="secondary"
-                    id="chromeLanguagesButton" on-click="onChromeLanguagesClick_"
-                    aria-label="$i18n{sanitizeDoneButtonChromeLanguages}"
-                    label="$i18n{sanitizeDoneButtonChromeLanguages}">
-                </cros-button>
-              </span>
-            </div>
-          </div>
-        </template>
       </cr-expand-button>
+      <template is="dom-if" if="[[chromeSettingsInfoExpanded_]]">
+        <div role="region" aria-labelledby="accordionChromeTitle">
+          <div class="list-container">
+            <div id="accordionChromeSiteContentTitle">
+              $i18n{sanitizeDoneAccordionChromeSiteContent}
+            </div>
+            <span class="secondary-button-container">
+              <cros-button role="button" button-style="secondary"
+                  id="chromeSiteContentButton"
+                  on-click="onChromeSiteContentClick_"
+                  aria-describedby="accordionChromeSiteContentTitle"
+                  label="Chrome Site Content">
+              </cros-button>
+            </span>
+          </div>
+          <div class="list-container">
+            <div id="accordionChromeStartupTitle">
+              $i18n{sanitizeDoneAccordionChromeStartup}
+            </div>
+            <span class="secondary-button-container">
+              <cros-button role="button" button-style="secondary"
+                  id="chromeStartupButton" on-click="onChromeStartupClick_"
+                  aria-label="$i18n{sanitizeDoneButtonChromeStartup}"
+                  aria-describedby="accordionChromeStartupTitle"
+                  label="$i18n{sanitizeDoneButtonChromeStartup}">
+              </cros-button>
+            </span>
+          </div>
+          <div class="list-container">
+            <div id="accordionChromeHomepageTitle">
+              $i18n{sanitizeDoneAccordionChromeHomepage}
+            </div>
+            <span class="secondary-button-container">
+              <cros-button role="button" button-style="secondary"
+                  id="chromeHomepageButton" on-click="onChromeHomepageClick_"
+                  aria-label="$i18n{sanitizeDoneButtonChromeHomepage}"
+                  aria-describedby="accordionChromeHomepageTitle"
+                  label="$i18n{sanitizeDoneButtonChromeHomepage}">
+              </cros-button>
+            </span>
+          </div>
+          <div class="list-container">
+            <div id="accordionChromeLanguagesTitle">
+              $i18n{sanitizeDoneAccordionChromeLanguages}
+            </div>
+            <span class="secondary-button-container">
+              <cros-button role="button" button-style="secondary"
+                  id="chromeLanguagesButton" on-click="onChromeLanguagesClick_"
+                  aria-label="$i18n{sanitizeDoneButtonChromeLanguages}"
+                  aria-describedby="accordionChromeLanguagesTitle"
+                  label="$i18n{sanitizeDoneButtonChromeLanguages}">
+              </cros-button>
+            </span>
+          </div>
+        </div>
+      </template>
+      <div class="expand-button-ending"></div>
     </div>
   </div>
   <div class="button-container done-button-container">
diff --git a/ash/webui/sanitize_ui/resources/sanitize_initial.html b/ash/webui/sanitize_ui/resources/sanitize_initial.html
index ad754733..c977ad2 100644
--- a/ash/webui/sanitize_ui/resources/sanitize_initial.html
+++ b/ash/webui/sanitize_ui/resources/sanitize_initial.html
@@ -28,13 +28,13 @@
 }
 </style>
 
-<div slot="body">
+<div slot="body" role="dialog">
   <svg class="extensions-icon"
        preserveAspectRatio="xMidYMid meet"
        role="img" viewBox="0 0 32 32">
     <use href="svg/extension_off_32.svg#extension_off_32"></use>
   </svg>
-  <div class="title">$i18n{sanitizeDialogTitle}</div>
+  <h2><div class="title">$i18n{sanitizeDialogTitle}</div></h2>
   <div class="sanitize-description">
     $i18n{sanitizeDescription}
     $i18n{sanitizeDialogExplanation}
diff --git a/ash/webui/status_area_internals/status_area_internals_handler_unittest.cc b/ash/webui/status_area_internals/status_area_internals_handler_unittest.cc
index 46d938d..8d16af65 100644
--- a/ash/webui/status_area_internals/status_area_internals_handler_unittest.cc
+++ b/ash/webui/status_area_internals/status_area_internals_handler_unittest.cc
@@ -66,6 +66,7 @@
     UpdateHMRConsentStatus(consent_status);
   }
 
+  bool IsMagicBoostAvailable() override { return true; }
   int32_t AsyncIncrementHMRConsentWindowDismissCount() override { return 0; }
   void AsyncWriteHMREnabled(bool enabled) override {}
   void DisableOrcaFeature() override {}
diff --git a/base/containers/unique_ptr_adapters.h b/base/containers/unique_ptr_adapters.h
index 26f8093..6c6d1fa 100644
--- a/base/containers/unique_ptr_adapters.h
+++ b/base/containers/unique_ptr_adapters.h
@@ -29,21 +29,33 @@
 struct UniquePtrComparator {
   using is_transparent = int;
 
-  template <typename T, class Deleter = std::default_delete<T>>
+  template <typename T, class Deleter>
   bool operator()(const std::unique_ptr<T, Deleter>& lhs,
                   const std::unique_ptr<T, Deleter>& rhs) const {
     return lhs < rhs;
   }
 
-  template <typename T, class Deleter = std::default_delete<T>>
+  template <typename T, class Deleter>
   bool operator()(const T* lhs, const std::unique_ptr<T, Deleter>& rhs) const {
     return lhs < rhs.get();
   }
 
-  template <typename T, class Deleter = std::default_delete<T>>
+  template <typename T, class Deleter, base::RawPtrTraits Traits>
+  bool operator()(const raw_ptr<T, Traits>& lhs,
+                  const std::unique_ptr<T, Deleter>& rhs) const {
+    return lhs < rhs.get();
+  }
+
+  template <typename T, class Deleter>
   bool operator()(const std::unique_ptr<T, Deleter>& lhs, const T* rhs) const {
     return lhs.get() < rhs;
   }
+
+  template <typename T, class Deleter, base::RawPtrTraits Traits>
+  bool operator()(const std::unique_ptr<T, Deleter>& lhs,
+                  const raw_ptr<T, Traits>& rhs) const {
+    return lhs.get() < rhs;
+  }
 };
 
 // UniquePtrMatcher is useful for finding an element in a container of
@@ -74,6 +86,13 @@
   return UniquePtrMatcher<T, Deleter>(t);
 }
 
+template <class T,
+          class Deleter = std::default_delete<T>,
+          base::RawPtrTraits Traits = base::RawPtrTraits::kEmpty>
+UniquePtrMatcher<T, Deleter> MatchesUniquePtr(const raw_ptr<T, Traits>& t) {
+  return UniquePtrMatcher<T, Deleter>(t.get());
+}
+
 }  // namespace base
 
 #endif  // BASE_CONTAINERS_UNIQUE_PTR_ADAPTERS_H_
diff --git a/base/containers/unique_ptr_adapters_unittest.cc b/base/containers/unique_ptr_adapters_unittest.cc
index dd90370..f8dfc05 100644
--- a/base/containers/unique_ptr_adapters_unittest.cc
+++ b/base/containers/unique_ptr_adapters_unittest.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <vector>
 
+#include "base/memory/raw_ptr.h"
 #include "base/ranges/algorithm.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -29,69 +30,123 @@
   Foo* foo3 = new Foo();
   EXPECT_EQ(3, Foo::instance_count);
 
+  raw_ptr<Foo> raw_foo1 = foo1;
+  raw_ptr<Foo> raw_foo2 = foo2;
+  raw_ptr<Foo> raw_foo3 = foo3;
+  raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo1 = foo1;
+  raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo2 = foo2;
+  raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo3 = foo3;
+
   set.emplace(foo1);
   set.emplace(foo2);
 
   auto it1 = set.find(foo1);
   EXPECT_TRUE(it1 != set.end());
   EXPECT_EQ(foo1, it1->get());
+  EXPECT_TRUE(set.find(raw_foo1) == it1);
+  EXPECT_TRUE(set.find(dangling_foo1) == it1);
 
   {
     auto it2 = set.find(foo2);
     EXPECT_TRUE(it2 != set.end());
     EXPECT_EQ(foo2, it2->get());
+    EXPECT_TRUE(set.find(raw_foo2) == it2);
+    EXPECT_TRUE(set.find(dangling_foo2) == it2);
   }
 
   EXPECT_TRUE(set.find(foo3) == set.end());
+  EXPECT_TRUE(set.find(raw_foo3) == set.end());
+  EXPECT_TRUE(set.find(dangling_foo3) == set.end());
 
+  raw_foo1 = nullptr;  // Avoid dangling raw_ptr.
   set.erase(it1);
   EXPECT_EQ(2, Foo::instance_count);
 
   EXPECT_TRUE(set.find(foo1) == set.end());
+  EXPECT_TRUE(set.find(dangling_foo1) == set.end());
 
   {
     auto it2 = set.find(foo2);
     EXPECT_TRUE(it2 != set.end());
     EXPECT_EQ(foo2, it2->get());
+    EXPECT_TRUE(set.find(raw_foo2) == it2);
+    EXPECT_TRUE(set.find(dangling_foo2) == it2);
   }
 
+  raw_foo2 = nullptr;  // Avoid dangling raw_ptr.
   set.clear();
   EXPECT_EQ(1, Foo::instance_count);
 
   EXPECT_TRUE(set.find(foo1) == set.end());
   EXPECT_TRUE(set.find(foo2) == set.end());
   EXPECT_TRUE(set.find(foo3) == set.end());
+  EXPECT_TRUE(set.find(dangling_foo1) == set.end());
+  EXPECT_TRUE(set.find(dangling_foo2) == set.end());
+  EXPECT_TRUE(set.find(dangling_foo3) == set.end());
 
+  raw_foo3 = nullptr;  // Avoid dangling raw_ptr.
   delete foo3;
   EXPECT_EQ(0, Foo::instance_count);
 }
 
 TEST(UniquePtrMatcherTest, Basic) {
   std::vector<std::unique_ptr<Foo>> v;
+
   auto foo_ptr1 = std::make_unique<Foo>();
   Foo* foo1 = foo_ptr1.get();
+  raw_ptr<Foo> raw_foo1 = foo1;
+  raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo1 = foo1;
   v.push_back(std::move(foo_ptr1));
+
   auto foo_ptr2 = std::make_unique<Foo>();
   Foo* foo2 = foo_ptr2.get();
+  raw_ptr<Foo> raw_foo2 = foo2;
+  raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo2 = foo2;
   v.push_back(std::move(foo_ptr2));
 
+  auto foo_ptr3 = std::make_unique<Foo>();
+  Foo* foo3 = foo_ptr3.get();
+  raw_ptr<Foo> raw_foo3 = foo3;
+  raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo3 = foo3;
+
   {
     auto iter = ranges::find_if(v, UniquePtrMatcher<Foo>(foo1));
     ASSERT_TRUE(iter != v.end());
     EXPECT_EQ(foo1, iter->get());
+    EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(raw_foo1)) == iter);
+    EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(dangling_foo1)) ==
+                iter);
   }
 
   {
     auto iter = ranges::find_if(v, UniquePtrMatcher<Foo>(foo2));
     ASSERT_TRUE(iter != v.end());
     EXPECT_EQ(foo2, iter->get());
+    EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(raw_foo2)) == iter);
+    EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(dangling_foo2)) ==
+                iter);
   }
 
   {
     auto iter = ranges::find_if(v, MatchesUniquePtr(foo2));
     ASSERT_TRUE(iter != v.end());
     EXPECT_EQ(foo2, iter->get());
+    EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(raw_foo2)) == iter);
+    EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(dangling_foo2)) == iter);
   }
+
+  EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(foo3)) == v.end());
+  EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(raw_foo3)) == v.end());
+  EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo>(dangling_foo3)) ==
+              v.end());
+
+  EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(foo3)) == v.end());
+  EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(raw_foo3)) == v.end());
+  EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr(dangling_foo3)) == v.end());
+
+  raw_foo1 = nullptr;
+  raw_foo2 = nullptr;
+  raw_foo3 = nullptr;
 }
 
 class TestDeleter {
@@ -102,30 +157,71 @@
 TEST(UniquePtrMatcherTest, Deleter) {
   using UniqueFoo = std::unique_ptr<Foo, TestDeleter>;
   std::vector<UniqueFoo> v;
+
   UniqueFoo foo_ptr1(new Foo);
   Foo* foo1 = foo_ptr1.get();
+  raw_ptr<Foo> raw_foo1 = foo1;
+  raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo1 = foo1;
   v.push_back(std::move(foo_ptr1));
+
   UniqueFoo foo_ptr2(new Foo);
   Foo* foo2 = foo_ptr2.get();
+  raw_ptr<Foo> raw_foo2 = foo2;
+  raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo2 = foo2;
   v.push_back(std::move(foo_ptr2));
 
+  UniqueFoo foo_ptr3(new Foo);
+  Foo* foo3 = foo_ptr3.get();
+  raw_ptr<Foo> raw_foo3 = foo3;
+  raw_ptr<Foo, DisableDanglingPtrDetection> dangling_foo3 = foo3;
+
   {
     auto iter = ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo1));
     ASSERT_TRUE(iter != v.end());
     EXPECT_EQ(foo1, iter->get());
+    EXPECT_TRUE(ranges::find_if(
+                    v, UniquePtrMatcher<Foo, TestDeleter>(raw_foo1)) == iter);
+    EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(
+                                       dangling_foo1)) == iter);
   }
 
   {
     auto iter = ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo2));
     ASSERT_TRUE(iter != v.end());
     EXPECT_EQ(foo2, iter->get());
+    EXPECT_TRUE(ranges::find_if(
+                    v, UniquePtrMatcher<Foo, TestDeleter>(raw_foo2)) == iter);
+    EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(
+                                       dangling_foo2)) == iter);
   }
 
   {
     auto iter = ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(foo2));
     ASSERT_TRUE(iter != v.end());
     EXPECT_EQ(foo2, iter->get());
+    EXPECT_TRUE(ranges::find_if(
+                    v, MatchesUniquePtr<Foo, TestDeleter>(raw_foo2)) == iter);
+    EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(
+                                       dangling_foo2)) == iter);
   }
+
+  EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(foo3)) ==
+              v.end());
+  EXPECT_TRUE(ranges::find_if(
+                  v, UniquePtrMatcher<Foo, TestDeleter>(raw_foo3)) == v.end());
+  EXPECT_TRUE(ranges::find_if(v, UniquePtrMatcher<Foo, TestDeleter>(
+                                     dangling_foo3)) == v.end());
+
+  EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(foo3)) ==
+              v.end());
+  EXPECT_TRUE(ranges::find_if(
+                  v, MatchesUniquePtr<Foo, TestDeleter>(raw_foo3)) == v.end());
+  EXPECT_TRUE(ranges::find_if(v, MatchesUniquePtr<Foo, TestDeleter>(
+                                     dangling_foo3)) == v.end());
+
+  raw_foo1 = nullptr;
+  raw_foo2 = nullptr;
+  raw_foo3 = nullptr;
 }
 
 }  // namespace
diff --git a/base/i18n/time_formatting.cc b/base/i18n/time_formatting.cc
index edd4470..a593517f 100644
--- a/base/i18n/time_formatting.cc
+++ b/base/i18n/time_formatting.cc
@@ -195,7 +195,7 @@
 
 std::u16string LocalizedTimeFormatWithPattern(const Time& time,
                                               std::string_view pattern) {
-  return TimeFormat(CreateSimpleDateFormatter(std::move(pattern)), time);
+  return TimeFormat(CreateSimpleDateFormatter(pattern), time);
 }
 
 std::string UnlocalizedTimeFormatWithPattern(const Time& time,
@@ -259,7 +259,7 @@
 
   // Format any remaining pattern.
   if (!pattern.empty()) {
-    output += format_time(time, std::move(pattern));
+    output += format_time(time, pattern);
   }
   return output;
 }
diff --git a/base/metrics/field_trial_params.cc b/base/metrics/field_trial_params.cc
index 168942c8..05e2c50 100644
--- a/base/metrics/field_trial_params.cc
+++ b/base/metrics/field_trial_params.cc
@@ -27,20 +27,10 @@
 
 namespace base {
 
-namespace {
-
-bool IsCacheEnabled() {
-  static const bool enabled =
-      FeatureList::IsEnabled(features::kFeatureParamWithCache);
-  return enabled;
-}
-
-}  // namespace
-
 namespace internal {
 
 bool IsFeatureParamWithCacheEnabled() {
-  return IsCacheEnabled();
+  return FeatureList::IsEnabled(features::kFeatureParamWithCache);
 }
 
 }  // namespace internal
diff --git a/base/test/scoped_feature_list.cc b/base/test/scoped_feature_list.cc
index a0ba2ca6b..e89d11e 100644
--- a/base/test/scoped_feature_list.cc
+++ b/base/test/scoped_feature_list.cc
@@ -12,6 +12,7 @@
 #include "base/check_op.h"
 #include "base/containers/contains.h"
 #include "base/containers/flat_map.h"
+#include "base/features.h"
 #include "base/memory/ptr_util.h"
 #include "base/metrics/field_trial_param_associator.h"
 #include "base/strings/string_number_conversions.h"
@@ -21,8 +22,7 @@
 #include "base/test/mock_entropy_provider.h"
 #include "base/test/task_environment.h"
 
-namespace base {
-namespace test {
+namespace base::test {
 
 // A struct describes ParsedEnableFeatures()' result.
 struct ScopedFeatureList::FeatureWithStudyGroup {
@@ -73,8 +73,9 @@
   bool has_params() const { return !params.empty(); }
 
   std::string ParamsForFeatureList() const {
-    if (params.empty())
+    if (params.empty()) {
       return "";
+    }
     return ":" + params;
   }
 
@@ -167,13 +168,15 @@
   std::string_view feature_name = feature;
 
   // Remove default info.
-  if (StartsWith(feature_name, "*"))
+  if (StartsWith(feature_name, "*")) {
     feature_name = feature_name.substr(1);
+  }
 
   // Remove field_trial info.
   std::size_t index = feature_name.find("<");
-  if (index != std::string::npos)
+  if (index != std::string::npos) {
     feature_name = feature_name.substr(0, index);
+  }
 
   return feature_name;
 }
@@ -242,8 +245,9 @@
 
 // Inverse of HexEncodeString().
 std::string HexDecodeString(const std::string& input) {
-  if (input.empty())
+  if (input.empty()) {
     return std::string();
+  }
   std::string bytes;
   bool result = HexStringToString(input, &bytes);
   DCHECK(result);
@@ -300,8 +304,9 @@
 
 void ScopedFeatureList::Reset() {
   // If one of the Init() functions was never called, don't reset anything.
-  if (!init_called_)
+  if (!init_called_) {
     return;
+  }
 
   init_called_ = false;
 
@@ -339,8 +344,9 @@
     original_field_trial_list_ = nullptr;
   }
 
-  if (original_feature_list_)
+  if (original_feature_list_) {
     FeatureList::RestoreInstanceForTesting(std::move(original_feature_list_));
+  }
 }
 
 void ScopedFeatureList::Init() {
@@ -459,8 +465,9 @@
       std::string params;
       for (const auto& param : feature.params) {
         // Add separator from previous param information if it exists.
-        if (!params.empty())
+        if (!params.empty()) {
           params.append(1, '/');
+        }
         params.append(EscapeValue(param.first));
         params.append(1, '/');
         params.append(EscapeValue(param.second));
@@ -471,11 +478,24 @@
     }
     create_associated_field_trials = true;
   } else {
-    for (const auto& feature : enabled_features)
+    for (const auto& feature : enabled_features) {
       merged_features.enabled_feature_list.emplace_back(feature->name);
+    }
   }
-  for (const auto& feature : disabled_features)
+  // If there is any parameter override, we need to disable parameter cache so
+  // that the FeatureParam doesn't pick up a cached value.
+  bool need_to_disable_parameter_cache = create_associated_field_trials;
+  for (const auto& feature : disabled_features) {
     merged_features.disabled_feature_list.emplace_back(feature->name);
+    if (feature->name == features::kFeatureParamWithCache.name) {
+      // Reset the flag as the cache is already ordered to be disabled.
+      need_to_disable_parameter_cache = false;
+    }
+  }
+  if (need_to_disable_parameter_cache) {
+    merged_features.disabled_feature_list.emplace_back(
+        features::kFeatureParamWithCache.name);
+  }
 
   InitWithMergedFeatures(std::move(merged_features),
                          create_associated_field_trials, keep_existing_states);
@@ -531,8 +551,9 @@
     // If we don't need to create any field trials for the |feature| (i.e.
     // unless |create_associated_field_trials|=true or |feature| has any
     // params), we can skip the code: EraseIf()...ClearParamsForTesting().
-    if (!(create_associated_field_trials || feature.has_params()))
+    if (!(create_associated_field_trials || feature.has_params())) {
       continue;
+    }
 
     // |all_states| contains the existing field trials, and is used to
     // restore the field trials into a newly created field trial list with
@@ -592,5 +613,4 @@
   InitWithFeatureList(std::move(new_feature_list));
 }
 
-}  // namespace test
-}  // namespace base
+}  // namespace base::test
diff --git a/base/test/scoped_feature_list_unittest.cc b/base/test/scoped_feature_list_unittest.cc
index 7f9d4a55..b98223b6 100644
--- a/base/test/scoped_feature_list_unittest.cc
+++ b/base/test/scoped_feature_list_unittest.cc
@@ -8,18 +8,24 @@
 #include <string>
 #include <utility>
 
+#include "base/features.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/field_trial_params.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-namespace base {
-namespace test {
+namespace base::test {
 
 namespace {
 
 BASE_FEATURE(kTestFeature1, "TestFeature1", FEATURE_DISABLED_BY_DEFAULT);
 BASE_FEATURE(kTestFeature2, "TestFeature2", FEATURE_DISABLED_BY_DEFAULT);
 
+BASE_FEATURE_PARAM(bool,
+                   kTestFeatureParam1,
+                   &kTestFeature1,
+                   "TestFeatureParam1",
+                   false);
+
 void ExpectFeatures(const std::string& enabled_features,
                     const std::string& disabled_features) {
   FeatureList* list = FeatureList::GetInstance();
@@ -37,8 +43,9 @@
   FieldTrial::ActiveGroups groups;
   FieldTrialList::GetActiveFieldTrialGroups(&groups);
   for (const auto& group : groups) {
-    if (group.trial_name == trial_name)
+    if (group.trial_name == trial_name) {
       return group.group_name;
+    }
   }
   return std::string();
 }
@@ -699,5 +706,17 @@
   }
 }
 
-}  // namespace test
-}  // namespace base
+TEST_F(ScopedFeatureListTest, FeatureParameterCache) {
+  // Check the default parameter, and bring it on its local cache if the cache
+  // is enabled.
+  ASSERT_FALSE(kTestFeatureParam1.Get());
+
+  // Ensure if the parameter override works if the cache feature is enabled
+  // outside the ScopedFeatureList.
+  test::ScopedFeatureList feature_list_to_override_cached_parameter;
+  feature_list_to_override_cached_parameter.InitAndEnableFeatureWithParameters(
+      kTestFeature1, {{kTestFeatureParam1.name, "true"}});
+  ASSERT_TRUE(kTestFeatureParam1.Get());
+}
+
+}  // namespace base::test
diff --git a/base/threading/thread_restrictions.cc b/base/threading/thread_restrictions.cc
index 9ec4c77e..55633f7 100644
--- a/base/threading/thread_restrictions.cc
+++ b/base/threading/thread_restrictions.cc
@@ -4,54 +4,58 @@
 
 #include "base/threading/thread_restrictions.h"
 
-#include "base/check.h"
 #include "base/threading/hang_watcher.h"
 #include "base/trace_event/base_tracing.h"
 #include "build/build_config.h"
+
+#if DCHECK_IS_ON()
+#include "base/check_op.h"
 #include "third_party/abseil-cpp/absl/base/attributes.h"
 
+// NaCL doesn't support stack sampling and Android is slow at stack sampling and
+// this causes timeouts (crbug.com/959139).
+#if BUILDFLAG(IS_NACL) || BUILDFLAG(IS_ANDROID)
+constexpr bool kCaptureStackTraces = false;
+#else
+// Always disabled when !EXPENSIVE_DCHECKS_ARE_ON() because user-facing builds
+// typically drop log strings anyways.
+constexpr bool kCaptureStackTraces = EXPENSIVE_DCHECKS_ARE_ON();
+#endif
+
 namespace base {
 
-BooleanWithOptionalStack::BooleanWithOptionalStack(bool value) : value_(value) {
-#if CAPTURE_THREAD_RESTRICTIONS_STACK_TRACES()
-  stack_.emplace();
-#endif  // CAPTURE_THREAD_RESTRICTIONS_STACK_TRACES()
+BooleanWithStack::BooleanWithStack(bool value) : value_(value) {
+  if (kCaptureStackTraces) {
+    stack_.emplace();
+  }
 }
 
-std::ostream& operator<<(std::ostream& out,
-                         const BooleanWithOptionalStack& bws) {
+std::ostream& operator<<(std::ostream& out, const BooleanWithStack& bws) {
   out << bws.value_;
-#if CAPTURE_THREAD_RESTRICTIONS_STACK_TRACES()
-  if (bws.stack_.has_value()) {
-    out << " set by\n" << bws.stack_.value();
-  } else {
-    out << " (value by default)";
+  if (kCaptureStackTraces) {
+    if (bws.stack_.has_value()) {
+      out << " set by\n" << bws.stack_.value();
+    } else {
+      out << " (value by default)";
+    }
   }
-#endif  // CAPTURE_THREAD_RESTRICTIONS_STACK_TRACES()
   return out;
 }
 
-// A macro that dumps in official builds (non-fatal) if the condition is false,
-// or behaves as DCHECK in DCHECK-enabled builds. Unlike DUMP_WILL_BE_CHECK,
-// there is no intent to transform those into CHECKs. Used to report potential
-// performance issues.
-#define DUMP_OR_DCHECK DUMP_WILL_BE_CHECK
-
 namespace {
 
-ABSL_CONST_INIT thread_local BooleanWithOptionalStack tls_blocking_disallowed;
-ABSL_CONST_INIT thread_local BooleanWithOptionalStack tls_singleton_disallowed;
-ABSL_CONST_INIT thread_local BooleanWithOptionalStack
+ABSL_CONST_INIT thread_local BooleanWithStack tls_blocking_disallowed;
+ABSL_CONST_INIT thread_local BooleanWithStack tls_singleton_disallowed;
+ABSL_CONST_INIT thread_local BooleanWithStack
     tls_base_sync_primitives_disallowed;
-ABSL_CONST_INIT thread_local BooleanWithOptionalStack
-    tls_cpu_intensive_work_disallowed;
+ABSL_CONST_INIT thread_local BooleanWithStack tls_cpu_intensive_work_disallowed;
 
 }  // namespace
 
 namespace internal {
 
 void AssertBlockingAllowed() {
-  DUMP_OR_DCHECK(!tls_blocking_disallowed)
+  DCHECK(!tls_blocking_disallowed)
       << "Function marked as blocking was called from a scope that disallows "
          "blocking! If this task is running inside the ThreadPool, it needs "
          "to have MayBlock() in its TaskTraits. Otherwise, consider making "
@@ -68,11 +72,11 @@
 }  // namespace internal
 
 void DisallowBlocking() {
-  tls_blocking_disallowed = BooleanWithOptionalStack(true);
+  tls_blocking_disallowed = BooleanWithStack(true);
 }
 
 ScopedDisallowBlocking::ScopedDisallowBlocking()
-    : resetter_(&tls_blocking_disallowed, BooleanWithOptionalStack(true)) {}
+    : resetter_(&tls_blocking_disallowed, BooleanWithStack(true)) {}
 
 ScopedDisallowBlocking::~ScopedDisallowBlocking() {
   DCHECK(tls_blocking_disallowed)
@@ -82,12 +86,11 @@
 }
 
 void DisallowBaseSyncPrimitives() {
-  tls_base_sync_primitives_disallowed = BooleanWithOptionalStack(true);
+  tls_base_sync_primitives_disallowed = BooleanWithStack(true);
 }
 
 ScopedDisallowBaseSyncPrimitives::ScopedDisallowBaseSyncPrimitives()
-    : resetter_(&tls_base_sync_primitives_disallowed,
-                BooleanWithOptionalStack(true)) {}
+    : resetter_(&tls_base_sync_primitives_disallowed, BooleanWithStack(true)) {}
 
 ScopedDisallowBaseSyncPrimitives::~ScopedDisallowBaseSyncPrimitives() {
   DCHECK(tls_base_sync_primitives_disallowed)
@@ -98,8 +101,7 @@
 }
 
 ScopedAllowBaseSyncPrimitives::ScopedAllowBaseSyncPrimitives()
-    : resetter_(&tls_base_sync_primitives_disallowed,
-                BooleanWithOptionalStack(false)) {
+    : resetter_(&tls_base_sync_primitives_disallowed, BooleanWithStack(false)) {
   DCHECK(!tls_blocking_disallowed)
       << "To allow //base sync primitives in a scope where blocking is "
          "disallowed use ScopedAllowBaseSyncPrimitivesOutsideBlockingScope.\n"
@@ -116,8 +118,8 @@
 
 ScopedAllowBaseSyncPrimitivesForTesting::
     ScopedAllowBaseSyncPrimitivesForTesting()
-    : resetter_(&tls_base_sync_primitives_disallowed,
-                BooleanWithOptionalStack(false)) {}
+    : resetter_(&tls_base_sync_primitives_disallowed, BooleanWithStack(false)) {
+}
 
 ScopedAllowBaseSyncPrimitivesForTesting::
     ~ScopedAllowBaseSyncPrimitivesForTesting() {
@@ -130,11 +132,10 @@
 
 ScopedAllowUnresponsiveTasksForTesting::ScopedAllowUnresponsiveTasksForTesting()
     : base_sync_resetter_(&tls_base_sync_primitives_disallowed,
-                          BooleanWithOptionalStack(false)),
-      blocking_resetter_(&tls_blocking_disallowed,
-                         BooleanWithOptionalStack(false)),
+                          BooleanWithStack(false)),
+      blocking_resetter_(&tls_blocking_disallowed, BooleanWithStack(false)),
       cpu_resetter_(&tls_cpu_intensive_work_disallowed,
-                    BooleanWithOptionalStack(false)) {}
+                    BooleanWithStack(false)) {}
 
 ScopedAllowUnresponsiveTasksForTesting::
     ~ScopedAllowUnresponsiveTasksForTesting() {
@@ -157,7 +158,7 @@
 namespace internal {
 
 void AssertBaseSyncPrimitivesAllowed() {
-  DUMP_OR_DCHECK(!tls_base_sync_primitives_disallowed)
+  DCHECK(!tls_base_sync_primitives_disallowed)
       << "Waiting on a //base sync primitive is not allowed on this thread to "
          "prevent jank and deadlock. If waiting on a //base sync primitive is "
          "unavoidable, do it within the scope of a "
@@ -170,14 +171,14 @@
 }
 
 void ResetThreadRestrictionsForTesting() {
-  tls_blocking_disallowed = BooleanWithOptionalStack(false);
-  tls_singleton_disallowed = BooleanWithOptionalStack(false);
-  tls_base_sync_primitives_disallowed = BooleanWithOptionalStack(false);
-  tls_cpu_intensive_work_disallowed = BooleanWithOptionalStack(false);
+  tls_blocking_disallowed = BooleanWithStack(false);
+  tls_singleton_disallowed = BooleanWithStack(false);
+  tls_base_sync_primitives_disallowed = BooleanWithStack(false);
+  tls_cpu_intensive_work_disallowed = BooleanWithStack(false);
 }
 
 void AssertSingletonAllowed() {
-  DUMP_OR_DCHECK(!tls_singleton_disallowed)
+  DCHECK(!tls_singleton_disallowed)
       << "LazyInstance/Singleton is not allowed to be used on this thread. "
          "Most likely it's because this thread is not joinable (or the current "
          "task is running with TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN "
@@ -191,11 +192,11 @@
 }  // namespace internal
 
 void DisallowSingleton() {
-  tls_singleton_disallowed = BooleanWithOptionalStack(true);
+  tls_singleton_disallowed = BooleanWithStack(true);
 }
 
 ScopedDisallowSingleton::ScopedDisallowSingleton()
-    : resetter_(&tls_singleton_disallowed, BooleanWithOptionalStack(true)) {}
+    : resetter_(&tls_singleton_disallowed, BooleanWithStack(true)) {}
 
 ScopedDisallowSingleton::~ScopedDisallowSingleton() {
   DCHECK(tls_singleton_disallowed)
@@ -205,7 +206,7 @@
 }
 
 void AssertLongCPUWorkAllowed() {
-  DUMP_OR_DCHECK(!tls_cpu_intensive_work_disallowed)
+  DCHECK(!tls_cpu_intensive_work_disallowed)
       << "Function marked as CPU intensive was called from a scope that "
          "disallows this kind of work! Consider making this work "
          "asynchronous.\n"
@@ -216,21 +217,30 @@
 void DisallowUnresponsiveTasks() {
   DisallowBlocking();
   DisallowBaseSyncPrimitives();
-  tls_cpu_intensive_work_disallowed = BooleanWithOptionalStack(true);
+  tls_cpu_intensive_work_disallowed = BooleanWithStack(true);
 }
 
 // static
 void PermanentThreadAllowance::AllowBlocking() {
-  tls_blocking_disallowed = BooleanWithOptionalStack(false);
+  tls_blocking_disallowed = BooleanWithStack(false);
 }
 
 // static
 void PermanentThreadAllowance::AllowBaseSyncPrimitives() {
-  tls_base_sync_primitives_disallowed = BooleanWithOptionalStack(false);
+  tls_base_sync_primitives_disallowed = BooleanWithStack(false);
 }
 
+}  // namespace base
+
+#endif  // DCHECK_IS_ON()
+
+namespace base {
+
 ScopedAllowBlocking::ScopedAllowBlocking(const Location& from_here)
-    : resetter_(&tls_blocking_disallowed, BooleanWithOptionalStack(false)) {
+#if DCHECK_IS_ON()
+    : resetter_(&tls_blocking_disallowed, BooleanWithStack(false))
+#endif
+{
   TRACE_EVENT_BEGIN(
       "base", "ScopedAllowBlocking", [&](perfetto::EventContext ctx) {
         ctx.event()->set_source_location_iid(
@@ -241,16 +251,20 @@
 ScopedAllowBlocking::~ScopedAllowBlocking() {
   TRACE_EVENT_END0("base", "ScopedAllowBlocking");
 
+#if DCHECK_IS_ON()
   DCHECK(!tls_blocking_disallowed)
       << "~ScopedAllowBlocking() running while surprisingly already no longer "
          "allowed.\n"
       << "tls_blocking_disallowed " << tls_blocking_disallowed;
+#endif
 }
 
 ScopedAllowBaseSyncPrimitivesOutsideBlockingScope::
     ScopedAllowBaseSyncPrimitivesOutsideBlockingScope(const Location& from_here)
-    : resetter_(&tls_base_sync_primitives_disallowed,
-                BooleanWithOptionalStack(false)) {
+#if DCHECK_IS_ON()
+    : resetter_(&tls_base_sync_primitives_disallowed, BooleanWithStack(false))
+#endif
+{
   TRACE_EVENT_BEGIN(
       "base", "ScopedAllowBaseSyncPrimitivesOutsideBlockingScope",
       [&](perfetto::EventContext ctx) {
@@ -268,11 +282,13 @@
     ~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope() {
   TRACE_EVENT_END0("base", "ScopedAllowBaseSyncPrimitivesOutsideBlockingScope");
 
+#if DCHECK_IS_ON()
   DCHECK(!tls_base_sync_primitives_disallowed)
       << "~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope() running while "
          "surprisingly already no longer allowed.\n"
       << "tls_base_sync_primitives_disallowed "
       << tls_base_sync_primitives_disallowed;
+#endif
 }
 
 }  // namespace base
diff --git a/base/threading/thread_restrictions.h b/base/threading/thread_restrictions.h
index 0de909d..b40103d 100644
--- a/base/threading/thread_restrictions.h
+++ b/base/threading/thread_restrictions.h
@@ -5,16 +5,20 @@
 #ifndef BASE_THREADING_THREAD_RESTRICTIONS_H_
 #define BASE_THREADING_THREAD_RESTRICTIONS_H_
 
-#include <optional>
-
 #include "base/auto_reset.h"
 #include "base/base_export.h"
 #include "base/compiler_specific.h"
-#include "base/debug/stack_trace.h"
+#include "base/dcheck_is_on.h"
 #include "base/gtest_prod_util.h"
 #include "base/location.h"
 #include "build/build_config.h"
 
+#if DCHECK_IS_ON()
+#include <optional>
+
+#include "base/debug/stack_trace.h"
+#endif
+
 // -----------------------------------------------------------------------------
 // Usage documentation
 // -----------------------------------------------------------------------------
@@ -501,66 +505,76 @@
 class TestCustomDisallow;
 class Thread;
 
-// NaCL doesn't support stack capture.
-// Android can hang in stack capture (crbug.com/959139).
-#if BUILDFLAG(IS_NACL) || BUILDFLAG(IS_ANDROID)
-#define CAPTURE_THREAD_RESTRICTIONS_STACK_TRACES() false
-#else
-// Stack capture is slow. Only enable it in developer builds, to avoid user
-// visible jank when thread restrictions are set.
-#define CAPTURE_THREAD_RESTRICTIONS_STACK_TRACES() EXPENSIVE_DCHECKS_ARE_ON()
-#endif
+#if DCHECK_IS_ON()
+// NOT_TAIL_CALLED if dcheck-is-on so it's always evident who irrevocably
+// altered the allowance (dcheck-builds will provide the setter's stack on
+// assertion) or who made a failing Assert*() call.
+#define INLINE_OR_NOT_TAIL_CALLED NOT_TAIL_CALLED BASE_EXPORT
+#define EMPTY_BODY_IF_DCHECK_IS_OFF
+#define DEFAULT_IF_DCHECK_IS_OFF
 
-// A boolean and the stack from which it was set. Note: The stack is not
-// captured in all builds, see `CAPTURE_THREAD_RESTRICTIONS_STACK_TRACES()`.
-class BooleanWithOptionalStack {
+class BooleanWithStack {
  public:
   // Default value.
-  BooleanWithOptionalStack() = default;
+  BooleanWithStack() = default;
 
   // Value when explicitly set.
-  explicit BooleanWithOptionalStack(bool value);
+  explicit BooleanWithStack(bool value);
 
   explicit operator bool() const { return value_; }
 
   friend std::ostream& operator<<(std::ostream& out,
-                                  const BooleanWithOptionalStack& bws);
+                                  const BooleanWithStack& bws);
 
  private:
   bool value_ = false;
-#if CAPTURE_THREAD_RESTRICTIONS_STACK_TRACES()
   std::optional<debug::StackTrace> stack_;
-#endif
 };
 
+#else
+// inline if dcheck-is-off so it's no overhead
+#define INLINE_OR_NOT_TAIL_CALLED inline
+
+// The static_assert() eats follow-on semicolons.
+#define EMPTY_BODY_IF_DCHECK_IS_OFF \
+  {}                                \
+  static_assert(true)
+
+#define DEFAULT_IF_DCHECK_IS_OFF = default
+#endif  // DCHECK_IS_ON()
+
 namespace internal {
 
 // Asserts that blocking calls are allowed in the current scope. This is an
 // internal call, external code should use ScopedBlockingCall instead, which
 // serves as a precise annotation of the scope that may/will block.
-NOT_TAIL_CALLED BASE_EXPORT void AssertBlockingAllowed();
-NOT_TAIL_CALLED BASE_EXPORT void AssertBlockingDisallowedForTesting();
+INLINE_OR_NOT_TAIL_CALLED void AssertBlockingAllowed()
+    EMPTY_BODY_IF_DCHECK_IS_OFF;
+INLINE_OR_NOT_TAIL_CALLED void AssertBlockingDisallowedForTesting()
+    EMPTY_BODY_IF_DCHECK_IS_OFF;
 
 }  // namespace internal
 
 // Disallows blocking on the current thread.
-NOT_TAIL_CALLED BASE_EXPORT void DisallowBlocking();
+INLINE_OR_NOT_TAIL_CALLED void DisallowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
 
 // Disallows blocking calls within its scope.
-class BASE_EXPORT ScopedDisallowBlocking {
+class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowBlocking {
  public:
-  ScopedDisallowBlocking();
+  ScopedDisallowBlocking() DEFAULT_IF_DCHECK_IS_OFF;
 
   ScopedDisallowBlocking(const ScopedDisallowBlocking&) = delete;
   ScopedDisallowBlocking& operator=(const ScopedDisallowBlocking&) = delete;
 
-  ~ScopedDisallowBlocking();
+  ~ScopedDisallowBlocking() DEFAULT_IF_DCHECK_IS_OFF;
 
  private:
-  const AutoReset<BooleanWithOptionalStack> resetter_;
+#if DCHECK_IS_ON()
+  const AutoReset<BooleanWithStack> resetter_;
+#endif
 };
 
-class BASE_EXPORT ScopedAllowBlocking {
+class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedAllowBlocking {
  public:
   ScopedAllowBlocking(const ScopedAllowBlocking&) = delete;
   ScopedAllowBlocking& operator=(const ScopedAllowBlocking&) = delete;
@@ -691,10 +705,12 @@
   ScopedAllowBlocking(const Location& from_here = Location::Current());
   ~ScopedAllowBlocking();
 
-  const AutoReset<BooleanWithOptionalStack> resetter_;
+#if DCHECK_IS_ON()
+  const AutoReset<BooleanWithStack> resetter_;
+#endif
 };
 
-class ScopedAllowBlockingForTesting {
+class [[maybe_unused, nodiscard]] ScopedAllowBlockingForTesting {
  public:
   ScopedAllowBlockingForTesting() = default;
 
@@ -705,28 +721,33 @@
   ~ScopedAllowBlockingForTesting() = default;
 
  private:
+#if DCHECK_IS_ON()
   ScopedAllowBlocking scoped_allow_blocking_;
+#endif
 };
 
-NOT_TAIL_CALLED BASE_EXPORT void DisallowBaseSyncPrimitives();
+INLINE_OR_NOT_TAIL_CALLED void DisallowBaseSyncPrimitives()
+    EMPTY_BODY_IF_DCHECK_IS_OFF;
 
 // Disallows singletons within its scope.
-class BASE_EXPORT ScopedDisallowBaseSyncPrimitives {
+class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowBaseSyncPrimitives {
  public:
-  ScopedDisallowBaseSyncPrimitives();
+  ScopedDisallowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF;
 
   ScopedDisallowBaseSyncPrimitives(const ScopedDisallowBaseSyncPrimitives&) =
       delete;
   ScopedDisallowBaseSyncPrimitives& operator=(
       const ScopedDisallowBaseSyncPrimitives&) = delete;
 
-  ~ScopedDisallowBaseSyncPrimitives();
+  ~ScopedDisallowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF;
 
  private:
-  const AutoReset<BooleanWithOptionalStack> resetter_;
+#if DCHECK_IS_ON()
+  const AutoReset<BooleanWithStack> resetter_;
+#endif
 };
 
-class BASE_EXPORT ScopedAllowBaseSyncPrimitives {
+class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedAllowBaseSyncPrimitives {
  public:
   ScopedAllowBaseSyncPrimitives(const ScopedAllowBaseSyncPrimitives&) = delete;
   ScopedAllowBaseSyncPrimitives& operator=(
@@ -804,10 +825,12 @@
   friend class viz::SkiaOutputSurfaceImpl;       // http://crbug.com/341151462
   friend class viz::SharedImageInterfaceProvider;  // http://crbug.com/341151462
 
-  ScopedAllowBaseSyncPrimitives();
-  ~ScopedAllowBaseSyncPrimitives();
+  ScopedAllowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF;
+  ~ScopedAllowBaseSyncPrimitives() DEFAULT_IF_DCHECK_IS_OFF;
 
-  const AutoReset<BooleanWithOptionalStack> resetter_;
+#if DCHECK_IS_ON()
+  const AutoReset<BooleanWithStack> resetter_;
+#endif
 };
 
 class BASE_EXPORT
@@ -915,7 +938,9 @@
 
   ~ScopedAllowBaseSyncPrimitivesOutsideBlockingScope();
 
-  const AutoReset<BooleanWithOptionalStack> resetter_;
+#if DCHECK_IS_ON()
+  const AutoReset<BooleanWithStack> resetter_;
+#endif
 };
 
 // Allow base-sync-primitives in tests, doesn't require explicit friend'ing like
@@ -923,76 +948,89 @@
 // Note: For WaitableEvents in the test logic, base::TestWaitableEvent is
 // exposed as a convenience to avoid the need for
 // ScopedAllowBaseSyncPrimitivesForTesting.
-class BASE_EXPORT ScopedAllowBaseSyncPrimitivesForTesting {
+class BASE_EXPORT
+    [[maybe_unused, nodiscard]] ScopedAllowBaseSyncPrimitivesForTesting {
  public:
-  ScopedAllowBaseSyncPrimitivesForTesting();
+  ScopedAllowBaseSyncPrimitivesForTesting() DEFAULT_IF_DCHECK_IS_OFF;
 
   ScopedAllowBaseSyncPrimitivesForTesting(
       const ScopedAllowBaseSyncPrimitivesForTesting&) = delete;
   ScopedAllowBaseSyncPrimitivesForTesting& operator=(
       const ScopedAllowBaseSyncPrimitivesForTesting&) = delete;
 
-  ~ScopedAllowBaseSyncPrimitivesForTesting();
+  ~ScopedAllowBaseSyncPrimitivesForTesting() DEFAULT_IF_DCHECK_IS_OFF;
 
  private:
-  const AutoReset<BooleanWithOptionalStack> resetter_;
+#if DCHECK_IS_ON()
+  const AutoReset<BooleanWithStack> resetter_;
+#endif
 };
 
 // Counterpart to base::DisallowUnresponsiveTasks() for tests to allow them to
 // block their thread after it was banned.
-class BASE_EXPORT ScopedAllowUnresponsiveTasksForTesting {
+class BASE_EXPORT
+    [[maybe_unused, nodiscard]] ScopedAllowUnresponsiveTasksForTesting {
  public:
-  ScopedAllowUnresponsiveTasksForTesting();
+  ScopedAllowUnresponsiveTasksForTesting() DEFAULT_IF_DCHECK_IS_OFF;
 
   ScopedAllowUnresponsiveTasksForTesting(
       const ScopedAllowUnresponsiveTasksForTesting&) = delete;
   ScopedAllowUnresponsiveTasksForTesting& operator=(
       const ScopedAllowUnresponsiveTasksForTesting&) = delete;
 
-  ~ScopedAllowUnresponsiveTasksForTesting();
+  ~ScopedAllowUnresponsiveTasksForTesting() DEFAULT_IF_DCHECK_IS_OFF;
 
  private:
-  const AutoReset<BooleanWithOptionalStack> base_sync_resetter_;
-  const AutoReset<BooleanWithOptionalStack> blocking_resetter_;
-  const AutoReset<BooleanWithOptionalStack> cpu_resetter_;
+#if DCHECK_IS_ON()
+  const AutoReset<BooleanWithStack> base_sync_resetter_;
+  const AutoReset<BooleanWithStack> blocking_resetter_;
+  const AutoReset<BooleanWithStack> cpu_resetter_;
+#endif
 };
 
 namespace internal {
 
 // Asserts that waiting on a //base sync primitive is allowed in the current
 // scope.
-NOT_TAIL_CALLED BASE_EXPORT void AssertBaseSyncPrimitivesAllowed();
+INLINE_OR_NOT_TAIL_CALLED void AssertBaseSyncPrimitivesAllowed()
+    EMPTY_BODY_IF_DCHECK_IS_OFF;
 
 // Resets all thread restrictions on the current thread.
-BASE_EXPORT void ResetThreadRestrictionsForTesting();
+INLINE_OR_NOT_TAIL_CALLED void ResetThreadRestrictionsForTesting()
+    EMPTY_BODY_IF_DCHECK_IS_OFF;
 
 // Check whether the current thread is allowed to use singletons (Singleton /
 // LazyInstance).  DCHECKs if not.
-NOT_TAIL_CALLED BASE_EXPORT void AssertSingletonAllowed();
+INLINE_OR_NOT_TAIL_CALLED void AssertSingletonAllowed()
+    EMPTY_BODY_IF_DCHECK_IS_OFF;
 
 }  // namespace internal
 
 // Disallow using singleton on the current thread.
-NOT_TAIL_CALLED BASE_EXPORT void DisallowSingleton();
+INLINE_OR_NOT_TAIL_CALLED void DisallowSingleton() EMPTY_BODY_IF_DCHECK_IS_OFF;
 
 // Disallows singletons within its scope.
-class BASE_EXPORT ScopedDisallowSingleton {
+class BASE_EXPORT [[maybe_unused, nodiscard]] ScopedDisallowSingleton {
  public:
-  ScopedDisallowSingleton();
+  ScopedDisallowSingleton() DEFAULT_IF_DCHECK_IS_OFF;
 
   ScopedDisallowSingleton(const ScopedDisallowSingleton&) = delete;
   ScopedDisallowSingleton& operator=(const ScopedDisallowSingleton&) = delete;
 
-  ~ScopedDisallowSingleton();
+  ~ScopedDisallowSingleton() DEFAULT_IF_DCHECK_IS_OFF;
 
  private:
-  const AutoReset<BooleanWithOptionalStack> resetter_;
+#if DCHECK_IS_ON()
+  const AutoReset<BooleanWithStack> resetter_;
+#endif
 };
 
 // Asserts that running long CPU work is allowed in the current scope.
-NOT_TAIL_CALLED BASE_EXPORT void AssertLongCPUWorkAllowed();
+INLINE_OR_NOT_TAIL_CALLED void AssertLongCPUWorkAllowed()
+    EMPTY_BODY_IF_DCHECK_IS_OFF;
 
-NOT_TAIL_CALLED BASE_EXPORT void DisallowUnresponsiveTasks();
+INLINE_OR_NOT_TAIL_CALLED void DisallowUnresponsiveTasks()
+    EMPTY_BODY_IF_DCHECK_IS_OFF;
 
 // Friend-only methods to permanently allow the current thread to use
 // blocking/sync-primitives calls. Threads start out in the *allowed* state but
@@ -1016,10 +1054,14 @@
 #endif  // BUILDFLAG(IS_IOS)
   friend class web::WebMainLoop;
 
-  static void AllowBlocking();
-  static void AllowBaseSyncPrimitives();
+  static void AllowBlocking() EMPTY_BODY_IF_DCHECK_IS_OFF;
+  static void AllowBaseSyncPrimitives() EMPTY_BODY_IF_DCHECK_IS_OFF;
 };
 
+#undef INLINE_OR_NOT_TAIL_CALLED
+#undef EMPTY_BODY_IF_DCHECK_IS_OFF
+#undef DEFAULT_IF_DCHECK_IS_OFF
+
 }  // namespace base
 
 #endif  // BASE_THREADING_THREAD_RESTRICTIONS_H_
diff --git a/base/threading/thread_unittest.cc b/base/threading/thread_unittest.cc
index ccd31464..2f1c81a 100644
--- a/base/threading/thread_unittest.cc
+++ b/base/threading/thread_unittest.cc
@@ -167,8 +167,8 @@
   additional_space += 56 * 1024;
 #endif
 #if DCHECK_IS_ON()
-  // The thread restrictions add four BooleanWithOptionalStacks (~2k each).
-  additional_space += sizeof(BooleanWithOptionalStack) * 4;
+  // The thread restrictions add four BooleanWithStacks (which are ~2k each).
+  additional_space += sizeof(BooleanWithStack) * 4;
 #endif
 
   Thread a("StartWithStackSize");
diff --git a/build/config/unsafe_buffers_paths.txt b/build/config/unsafe_buffers_paths.txt
index 4ca2724..bec2a8a1 100644
--- a/build/config/unsafe_buffers_paths.txt
+++ b/build/config/unsafe_buffers_paths.txt
@@ -113,6 +113,7 @@
 -gpu/ipc/service/
 -ios/
 -ios_internal/
+-media/
 -native_client/
 -net/third_party/
 -printing/
diff --git a/build/fuchsia/test/browser_runner.py b/build/fuchsia/test/browser_runner.py
index a35102f2..ae4063b 100644
--- a/build/fuchsia/test/browser_runner.py
+++ b/build/fuchsia/test/browser_runner.py
@@ -9,8 +9,10 @@
 import tempfile
 import time
 from typing import List, Optional
+from urllib.parse import urlparse
 
 from common import run_continuous_ffx_command, ssh_run, REPO_ALIAS
+from compatible_utils import parse_host_port
 from ffx_integration import run_symbolizer
 
 WEB_ENGINE_SHELL = 'web-engine-shell'
@@ -77,13 +79,15 @@
         return self._browser_proc.pid
 
     def _read_devtools_port(self):
-        search_regex = r'Remote debugging port: (\d+)'
+        search_regex = r'DevTools listening on (.+)'
 
         def try_reading_port(log_file) -> int:
             for line in log_file:
                 tokens = re.search(search_regex, line)
                 if tokens:
-                    return int(tokens.group(1))
+                    url = urlparse(tokens.group(1))
+                    assert url.scheme == 'ws'
+                    return parse_host_port(url.netloc)[1]
             return None
 
         with open(self.log_file, encoding='utf-8') as log_file:
@@ -92,10 +96,12 @@
                 port = try_reading_port(log_file)
                 if port:
                     return port
+                self._browser_proc.poll()
+                assert not self._browser_proc.returncode, 'Browser stopped.'
                 time.sleep(1)
             assert False, 'Failed to wait for the devtools port.'
 
-    def start(self, extra_args: List[str]) -> None:
+    def start(self, extra_args: List[str] = None) -> None:
         """Starts the selected browser, |extra_args| are attached to the command
         line."""
         browser_cmd = ['test', 'run']
diff --git a/chrome/VERSION b/chrome/VERSION
index 79706ef..d868542 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=130
 MINOR=0
-BUILD=6709
+BUILD=6710
 PATCH=0
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
index 0c5e8e54..7e1ab91 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/NewTabPage.java
@@ -1048,6 +1048,11 @@
     public void updateForUrl(String url) {}
 
     @Override
+    public int getHeightOverlappedWithTopControls() {
+        return mBrowserControlsStateProvider.getTopControlsHeight();
+    }
+
+    @Override
     public void reload() {
         mFeedSurfaceProvider.reload();
         mNewTabPageLayout.reload();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPage.java b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPage.java
index 2419edf0..887a98b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPage.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ntp/RecentTabsPage.java
@@ -175,6 +175,11 @@
     @Override
     public void updateForUrl(String url) {}
 
+    @Override
+    public int getHeightOverlappedWithTopControls() {
+        return mBrowserControlsStateProvider.getTopControlsHeight();
+    }
+
     // View.OnAttachStateChangeListener
     @Override
     public void onViewAttachedToWindow(View view) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroidImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroidImpl.java
index ebe5b68..a8a862c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroidImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabWebContentsDelegateAndroidImpl.java
@@ -430,13 +430,12 @@
 
     @Override
     public boolean maybeCopyContentAreaAsBitmap(Callback<Bitmap> callback) {
-        return NativePageBitmapCapturer.maybeCaptureNativeView(
-                mTab, callback, getTopControlsHeight());
+        return NativePageBitmapCapturer.maybeCaptureNativeView(mTab, callback);
     }
 
     @Override
     public Bitmap maybeCopyContentAreaAsBitmapSync() {
-        return NativePageBitmapCapturer.maybeCaptureNativeViewSync(mTab, getTopControlsHeight());
+        return NativePageBitmapCapturer.maybeCaptureNativeViewSync(mTab);
     }
 
     @Override
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/ScreenshotCaptureTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/ScreenshotCaptureTest.java
index 1c29ac0..fcae7d79b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/ScreenshotCaptureTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/ScreenshotCaptureTest.java
@@ -184,6 +184,46 @@
     @MediumTest
     @Feature({"RenderTest"})
     @ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class)
+    public void testNavigatingAwayFromNativeBookmarkToNormalPage(boolean nightModeEnabled)
+            throws IOException, TimeoutException, InterruptedException {
+        mActivityTestRule.startMainActivityWithURL(UrlConstants.BOOKMARKS_URL);
+        UiUtils.settleDownUI(InstrumentationRegistry.getInstrumentation());
+
+        CallbackHelper callbackHelper = new CallbackHelper();
+        int currentNavIndex =
+                mActivityTestRule
+                        .getActivity()
+                        .getCurrentWebContents()
+                        .getNavigationController()
+                        .getNavigationHistory()
+                        .getCurrentEntryIndex();
+
+        mScreenshotCaptureTestHelper.setNavScreenshotCallbackForTesting(
+                new ScreenshotCaptureTestHelper.NavScreenshotCallback() {
+                    @Override
+                    public Bitmap onAvailable(int navIndex, Bitmap bitmap, boolean requested) {
+                        Assert.assertEquals(
+                                "Should capture the screenshot of the previous page.",
+                                currentNavIndex,
+                                navIndex);
+                        Assert.assertTrue(requested);
+                        mCapturedBitmap = bitmap;
+                        callbackHelper.notifyCalled();
+                        return null;
+                    }
+                });
+
+        mActivityTestRule.loadUrl(mTestServer.getURL(TEST_PAGE));
+
+        callbackHelper.waitForOnly();
+        mRenderTestRule.compareForResult(
+                mCapturedBitmap, "navigate_away_from_native_bookmark_to_normal_page");
+    }
+
+    @Test
+    @MediumTest
+    @Feature({"RenderTest"})
+    @ParameterAnnotations.UseMethodParameter(NightModeTestUtils.NightModeParams.class)
     public void testNavigatingAwayFromNtpToWebUiPage(boolean nightModeEnabled)
             throws IOException, TimeoutException, InterruptedException {
         mActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL);
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt
index d18b9e7d..306c2e4 100644
--- a/chrome/android/profiles/arm.newest.txt
+++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-130.0.6702.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-arm-130.0.6708.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app_shim/app_shim_controller.mm b/chrome/app_shim/app_shim_controller.mm
index 02f6e35..a4814b68 100644
--- a/chrome/app_shim/app_shim_controller.mm
+++ b/chrome/app_shim/app_shim_controller.mm
@@ -285,7 +285,7 @@
        "StandardCompliantHostCharacters",
        "StandardCompliantNonSpecialSchemeURLParsing",
        "UseAdHocSigningForWebAppShims", "UseIDNA2008NonTransitional",
-       "SonomaAccessibilityActivationRefinements"});
+       "SonomaAccessibilityActivationRefinements", "FeatureParamWithCache"});
 }
 
 // static
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index d36e905..5e67fc7 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -5029,6 +5029,7 @@
       "//chrome/browser/ash/login/users/avatar",
       "//chrome/browser/ash/magic_boost",
       "//chrome/browser/ash/mahi",
+      "//chrome/browser/ash/mahi:mahi_availability",
       "//chrome/browser/ash/multidevice_setup",
       "//chrome/browser/ash/nearby",
       "//chrome/browser/ash/nearby/presence",
@@ -5483,6 +5484,7 @@
       "//chrome/browser/ash/login/users/avatar",
       "//chrome/browser/ash/magic_boost",
       "//chrome/browser/ash/mahi",
+      "//chrome/browser/ash/mahi:mahi_availability",
       "//chrome/browser/ash/nearby",
       "//chrome/browser/ash/nearby/presence",
       "//chrome/browser/ash/net",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 89dd56c..3c8a235 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4669,6 +4669,10 @@
     {"enable-wifi-qos", flag_descriptions::kEnableWifiQosName,
      flag_descriptions::kEnableWifiQosDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kEnableWifiQos)},
+    {"enable-wifi-qos-enterprise",
+     flag_descriptions::kEnableWifiQosEnterpriseName,
+     flag_descriptions::kEnableWifiQosEnterpriseDescription, kOsCrOS,
+     FEATURE_VALUE_TYPE(ash::features::kEnableWifiQosEnterprise)},
     {"enforce-ash-extension-keeplist",
      flag_descriptions::kEnforceAshExtensionKeeplistName,
      flag_descriptions::kEnforceAshExtensionKeeplistDescription, kOsCrOS,
diff --git a/chrome/browser/ash/chrome_browser_main_parts_ash.cc b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
index 1898dc8..d3c6d69 100644
--- a/chrome/browser/ash/chrome_browser_main_parts_ash.cc
+++ b/chrome/browser/ash/chrome_browser_main_parts_ash.cc
@@ -1318,8 +1318,15 @@
                        shill::kDisconnectWiFiOnEthernetProperty));
 
     // Notify patchpanel and shill about QoS feature enabled flag.
-    const bool wifi_qos_enabled =
+    bool wifi_qos_enabled =
         base::FeatureList::IsEnabled(features::kEnableWifiQos);
+    if (InstallAttributes::Get()->IsEnterpriseManaged()) {
+      // For an Enterprise enrolled device, enable the feature only if the
+      // separate flag for enterprise is also on.
+      wifi_qos_enabled =
+          wifi_qos_enabled &&
+          base::FeatureList::IsEnabled(features::kEnableWifiQosEnterprise);
+    }
     ash::PatchPanelClient::Get()->SetFeatureFlag(
         patchpanel::SetFeatureFlagRequest::WIFI_QOS, wifi_qos_enabled);
     ash::ShillManagerClient::Get()->SetProperty(
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
index 6ef1026..1fdf6f49 100644
--- a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
+++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.cc
@@ -1980,56 +1980,6 @@
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-// AutotestPrivateStartArcFunction
-///////////////////////////////////////////////////////////////////////////////
-
-AutotestPrivateStartArcFunction::~AutotestPrivateStartArcFunction() = default;
-
-ExtensionFunction::ResponseAction AutotestPrivateStartArcFunction::Run() {
-  DVLOG(1) << "AutotestPrivateStartArcFunction";
-
-  arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get();
-  if (!arc_session_manager) {
-    return RespondNow(Error("Could not find ARC session manager"));
-  }
-
-  Profile* profile = Profile::FromBrowserContext(browser_context());
-  if (!arc::IsArcAllowedForProfile(profile)) {
-    return RespondNow(Error("ARC cannot be started for the current user"));
-  }
-
-  if (arc_session_manager->enable_requested()) {
-    return RespondNow(Error("ARC is already started"));
-  }
-
-  arc_session_manager->RequestEnable();
-
-  return RespondNow(NoArguments());
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// AutotestPrivateStopArcFunction
-///////////////////////////////////////////////////////////////////////////////
-
-AutotestPrivateStopArcFunction::~AutotestPrivateStopArcFunction() = default;
-
-ExtensionFunction::ResponseAction AutotestPrivateStopArcFunction::Run() {
-  DVLOG(1) << "AutotestPrivateStopArcFunction";
-
-  arc::ArcSessionManager* arc_session_manager = arc::ArcSessionManager::Get();
-  if (!arc_session_manager) {
-    return RespondNow(Error("Could not find ARC session manager"));
-  }
-
-  if (!arc_session_manager->enable_requested()) {
-    return RespondNow(Error("ARC is already stopped"));
-  }
-
-  arc_session_manager->RequestDisable();
-
-  return RespondNow(NoArguments());
-}
-///////////////////////////////////////////////////////////////////////////////
 // AutotestPrivateSetPlayStoreEnabledFunction
 ///////////////////////////////////////////////////////////////////////////////
 
diff --git a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h
index f100f49..0963a0f 100644
--- a/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h
+++ b/chrome/browser/ash/extensions/autotest_private/autotest_private_api.h
@@ -291,25 +291,6 @@
   ResponseAction Run() override;
 };
 
-class AutotestPrivateStartArcFunction : public ExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("autotestPrivate.startArc",
-                             AUTOTESTPRIVATE_STARTARC)
-
- private:
-  ~AutotestPrivateStartArcFunction() override;
-  ResponseAction Run() override;
-};
-
-class AutotestPrivateStopArcFunction : public ExtensionFunction {
- public:
-  DECLARE_EXTENSION_FUNCTION("autotestPrivate.stopArc", AUTOTESTPRIVATE_STOPARC)
-
- private:
-  ~AutotestPrivateStopArcFunction() override;
-  ResponseAction Run() override;
-};
-
 class AutotestPrivateSetPlayStoreEnabledFunction : public ExtensionFunction {
  public:
   DECLARE_EXTENSION_FUNCTION("autotestPrivate.setPlayStoreEnabled",
diff --git a/chrome/browser/ash/input_method/BUILD.gn b/chrome/browser/ash/input_method/BUILD.gn
index 165c315..555710a 100644
--- a/chrome/browser/ash/input_method/BUILD.gn
+++ b/chrome/browser/ash/input_method/BUILD.gn
@@ -217,6 +217,7 @@
     "//chromeos/ash/services/ime:constants",
     "//chromeos/components/editor_menu/public/cpp",
     "//chromeos/components/kiosk",
+    "//chromeos/components/magic_boost/public/cpp",
     "//chromeos/constants",
     "//chromeos/ime:gencode",
     "//chromeos/services/machine_learning/public/cpp",
diff --git a/chrome/browser/ash/input_method/editor_mediator.cc b/chrome/browser/ash/input_method/editor_mediator.cc
index c481dd1..8c1ce19 100644
--- a/chrome/browser/ash/input_method/editor_mediator.cc
+++ b/chrome/browser/ash/input_method/editor_mediator.cc
@@ -26,7 +26,7 @@
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.h"
 #include "chromeos/components/editor_menu/public/cpp/editor_helpers.h"
-#include "chromeos/constants/chromeos_features.h"
+#include "chromeos/components/magic_boost/public/cpp/magic_boost_state.h"
 #include "ui/base/ime/ash/ime_bridge.h"
 #include "ui/display/screen.h"
 #include "ui/display/tablet_state.h"
@@ -237,7 +237,7 @@
     case EditorMode::kConsentNeeded:
       query_context_ = EditorQueryContext(/*preset_query_id=*/preset_query_id,
                                           /*freeform_text=*/freeform_text);
-      if (chromeos::features::IsMagicBoostEnabled()) {
+      if (chromeos::MagicBoostState::Get()->IsMagicBoostAvailable()) {
         crosapi::CrosapiManager::Get()
             ->crosapi_ash()
             ->magic_boost_controller_ash()
diff --git a/chrome/browser/ash/magic_boost/BUILD.gn b/chrome/browser/ash/magic_boost/BUILD.gn
index eb2032428..8c467eb 100644
--- a/chrome/browser/ash/magic_boost/BUILD.gn
+++ b/chrome/browser/ash/magic_boost/BUILD.gn
@@ -22,6 +22,7 @@
     "//ash",
     "//ash/constants",
     "//base",
+    "//chrome/browser/ash/mahi:mahi_availability",
     "//chromeos/components/magic_boost/public/cpp",
     "//chromeos/components/mahi/public/cpp",
     "//chromeos/crosapi/mojom",
diff --git a/chrome/browser/ash/magic_boost/DEPS b/chrome/browser/ash/magic_boost/DEPS
index 4e43c64..72780b9 100644
--- a/chrome/browser/ash/magic_boost/DEPS
+++ b/chrome/browser/ash/magic_boost/DEPS
@@ -21,6 +21,9 @@
   # Magic Boost needs to access Orca code in input_method.
   "+chrome/browser/ash/input_method",
 
+  # Magic Boost needs to access Mahi code.
+  "+chrome/browser/ash/mahi",
+
   "+chrome/browser/profiles",
 ]
 
diff --git a/chrome/browser/ash/magic_boost/magic_boost_state_ash.cc b/chrome/browser/ash/magic_boost/magic_boost_state_ash.cc
index 416e560..29fde49 100644
--- a/chrome/browser/ash/magic_boost/magic_boost_state_ash.cc
+++ b/chrome/browser/ash/magic_boost/magic_boost_state_ash.cc
@@ -13,6 +13,7 @@
 #include "base/types/cxx23_to_underlying.h"
 #include "chrome/browser/ash/input_method/editor_mediator_factory.h"
 #include "chrome/browser/ash/input_method/editor_panel_manager.h"
+#include "chrome/browser/ash/mahi/mahi_availability.h"
 #include "chrome/browser/profiles/profile_manager.h"
 #include "chromeos/crosapi/mojom/editor_panel.mojom.h"
 #include "components/prefs/pref_service.h"
@@ -44,6 +45,10 @@
   RegisterPrefChanges(pref_service);
 }
 
+bool MagicBoostStateAsh::IsMagicBoostAvailable() {
+  return mahi_availability::IsMahiAvailable();
+}
+
 int32_t MagicBoostStateAsh::AsyncIncrementHMRConsentWindowDismissCount() {
   int32_t incremented_count = hmr_consent_window_dismiss_count() + 1;
   pref_change_registrar_->prefs()->SetInteger(
diff --git a/chrome/browser/ash/magic_boost/magic_boost_state_ash.h b/chrome/browser/ash/magic_boost/magic_boost_state_ash.h
index d1141750..732ea5f 100644
--- a/chrome/browser/ash/magic_boost/magic_boost_state_ash.h
+++ b/chrome/browser/ash/magic_boost/magic_boost_state_ash.h
@@ -33,6 +33,7 @@
   ~MagicBoostStateAsh() override;
 
   // MagicBoostState:
+  bool IsMagicBoostAvailable() override;
   int32_t AsyncIncrementHMRConsentWindowDismissCount() override;
   void AsyncWriteConsentStatus(
       chromeos::HMRConsentStatus consent_status) override;
diff --git a/chrome/browser/ash/mahi/BUILD.gn b/chrome/browser/ash/mahi/BUILD.gn
index 9c3332d6..37544ca 100644
--- a/chrome/browser/ash/mahi/BUILD.gn
+++ b/chrome/browser/ash/mahi/BUILD.gn
@@ -6,10 +6,28 @@
 
 assert(is_chromeos_ash)
 
-static_library("mahi") {
+static_library("mahi_availability") {
   sources = [
     "mahi_availability.cc",
     "mahi_availability.h",
+  ]
+
+  public_deps = [ "//chrome/browser:browser_public_dependencies" ]
+
+  deps = [
+    "//ash/constants",
+    "//base",
+    "//chrome/browser:browser_process",
+    "//chrome/browser/ash/login/demo_mode",
+    "//chromeos/constants",
+    "//components/manta",
+    "//components/user_manager",
+    "//components/variations/service:service",
+  ]
+}
+
+static_library("mahi") {
+  sources = [
     "mahi_browser_client_wrapper.cc",
     "mahi_browser_client_wrapper.h",
     "mahi_browser_delegate_ash.cc",
@@ -23,12 +41,11 @@
   public_deps = [ "//chrome/browser:browser_public_dependencies" ]
 
   deps = [
+    ":mahi_availability",
     "//ash",
     "//ash/constants",
     "//ash/webui/settings/public/constants:mojom",
     "//base",
-    "//chrome/browser:browser_process",
-    "//chrome/browser/ash/login/demo_mode",
     "//chrome/browser/ash/magic_boost",
     "//chrome/browser/feedback",
     "//chromeos/components/magic_boost/public/cpp:cpp",
@@ -37,7 +54,6 @@
     "//components/feedback",
     "//components/history/core/browser:browser",
     "//components/manta",
-    "//components/variations/service:service",
     "//ui/aura",
     "//ui/base",
     "//ui/gfx",
diff --git a/chrome/browser/ash/mahi/mahi_availability.cc b/chrome/browser/ash/mahi/mahi_availability.cc
index a475bf1..fe14a869 100644
--- a/chrome/browser/ash/mahi/mahi_availability.cc
+++ b/chrome/browser/ash/mahi/mahi_availability.cc
@@ -10,12 +10,14 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/manta/manta_service_factory.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chromeos/constants/chromeos_features.h"
 #include "chromeos/constants/chromeos_switches.h"
 #include "components/manta/features.h"
 #include "components/manta/manta_service.h"
+#include "components/user_manager/user_manager.h"
 #include "components/variations/service/variations_service.h"
 
-namespace ash {
+namespace ash::mahi_availability {
 
 bool CanUseMahiService() {
   if (!manta::features::IsMantaServiceEnabled()) {
@@ -28,6 +30,11 @@
   }
 
   if (!ash::DemoSession::IsDeviceInDemoMode()) {
+    if (!user_manager::UserManager::IsInitialized() ||
+        !user_manager::UserManager::Get()->IsUserLoggedIn()) {
+      return false;
+    }
+
     Profile* profile = ProfileManager::GetActiveUserProfile();
     if (!profile) {
       return false;
@@ -38,10 +45,11 @@
       return false;
     }
 
+    // MantaService might not be available in tests.
     if (manta::MantaService* service =
             manta::MantaServiceFactory::GetForProfile(profile);
-        service->CanAccessMantaFeaturesWithoutMinorRestrictions() !=
-        manta::FeatureSupportStatus::kSupported) {
+        service && service->CanAccessMantaFeaturesWithoutMinorRestrictions() !=
+                       manta::FeatureSupportStatus::kSupported) {
       return false;
     }
   }
@@ -80,4 +88,8 @@
   return kCountryAllowlist.contains(country_code);
 }
 
-}  // namespace ash
+bool IsMahiAvailable() {
+  return chromeos::features::IsMahiEnabled() && CanUseMahiService();
+}
+
+}  // namespace ash::mahi_availability
diff --git a/chrome/browser/ash/mahi/mahi_availability.h b/chrome/browser/ash/mahi/mahi_availability.h
index ee96ff6..cc21407 100644
--- a/chrome/browser/ash/mahi/mahi_availability.h
+++ b/chrome/browser/ash/mahi/mahi_availability.h
@@ -5,7 +5,7 @@
 #ifndef CHROME_BROWSER_ASH_MAHI_MAHI_AVAILABILITY_H_
 #define CHROME_BROWSER_ASH_MAHI_MAHI_AVAILABILITY_H_
 
-namespace ash {
+namespace ash::mahi_availability {
 
 // Check whether Mahi is allowed. This function checks following restrictions:
 //   * age: if not demo mode, the account must not hit minor restrictions
@@ -13,6 +13,10 @@
 //   * If not in demo mode, guest session is not allowed.
 bool CanUseMahiService();
 
-}  // namespace ash
+// Check if the feature is available to use. It can be unavailable if the
+// feature flag is disabled, or the age and country requirements are not met.
+bool IsMahiAvailable();
+
+}  // namespace ash::mahi_availability
 
 #endif  // CHROME_BROWSER_ASH_MAHI_MAHI_AVAILABILITY_H_
diff --git a/chrome/browser/ash/mahi/mahi_manager_impl.cc b/chrome/browser/ash/mahi/mahi_manager_impl.cc
index 9895115..321fef4 100644
--- a/chrome/browser/ash/mahi/mahi_manager_impl.cc
+++ b/chrome/browser/ash/mahi/mahi_manager_impl.cc
@@ -119,7 +119,7 @@
                                     base::OnceClosure on_declined_closure)
       : on_approved_closure_(std::move(on_approved_closure)),
         on_declined_closure_(std::move(on_declined_closure)) {
-    CHECK(chromeos::features::IsMagicBoostEnabled());
+    CHECK(chromeos::MagicBoostState::Get()->IsMagicBoostAvailable());
     magic_boost_state_observation_.Observe(chromeos::MagicBoostState::Get());
   }
 
@@ -228,7 +228,7 @@
 // 1. The magic boost feature is disabled; OR
 // 2. The Mahi feature has been approved before.
 bool IsMahiApproved() {
-  return !chromeos::features::IsMagicBoostEnabled() ||
+  return !chromeos::MagicBoostState::Get()->IsMagicBoostAvailable() ||
          chromeos::MagicBoostState::Get()->hmr_consent_status() ==
              chromeos::HMRConsentStatus::kApproved;
 }
@@ -509,9 +509,8 @@
 }
 
 bool MahiManagerImpl::IsEnabled() {
-  return chromeos::features::IsMahiEnabled() &&
-         chromeos::MagicBoostState::Get()->hmr_enabled().value_or(false) &&
-         CanUseMahiService();
+  return mahi_availability::IsMahiAvailable() &&
+         chromeos::MagicBoostState::Get()->hmr_enabled().value_or(false);
 }
 
 void MahiManagerImpl::SetMediaAppPDFFocused() {
@@ -649,7 +648,7 @@
 
 void MahiManagerImpl::InterrputRequestHandlingWithDisclaimerView(
     crosapi::mojom::MahiContextMenuRequestPtr context_menu_request) {
-  CHECK(chromeos::features::IsMagicBoostEnabled());
+  CHECK(chromeos::MagicBoostState::Get()->IsMagicBoostAvailable());
 
   // Cache the display id before moving `context_menu_request`.
   const int64_t display_id = context_menu_request->display_id;
diff --git a/chrome/browser/ash/mahi/mahi_test_util.cc b/chrome/browser/ash/mahi/mahi_test_util.cc
index 16c2458..3e214c1 100644
--- a/chrome/browser/ash/mahi/mahi_test_util.cc
+++ b/chrome/browser/ash/mahi/mahi_test_util.cc
@@ -78,7 +78,7 @@
 }  // namespace
 
 void ApplyHMRConsentStatusAndWait(chromeos::HMRConsentStatus status) {
-  CHECK(chromeos::features::IsMagicBoostEnabled());
+  CHECK(chromeos::MagicBoostState::Get()->IsMagicBoostAvailable());
 
   NiceMock<MockMagicBoostStateObserver> magic_boost_state_observer;
   base::ScopedObservation<chromeos::MagicBoostState,
diff --git a/chrome/browser/educational_tip/java/res/drawable/default_browser_promo_logo.xml b/chrome/browser/educational_tip/java/res/drawable/default_browser_promo_logo.xml
index 9c2dad7..a887a4e 100644
--- a/chrome/browser/educational_tip/java/res/drawable/default_browser_promo_logo.xml
+++ b/chrome/browser/educational_tip/java/res/drawable/default_browser_promo_logo.xml
@@ -64,7 +64,7 @@
   <path
       android:pathData="M10.5,30.5C10.5,30.5 1.975,45 7.5,53.5C13.025,62 23,55.5 23,55.5"
       android:strokeWidth="2"
-      android:fillColor="#00000000"
+      android:fillColor="@android:color/transparent"
       android:strokeColor="@color/material_primary_60"
       android:strokeLineCap="round"/>
   <path
@@ -73,7 +73,7 @@
   <path
       android:pathData="M55.5,47.5C55.5,47.5 71.941,27.028 66.416,18.528C60.891,10.028 50.917,16.528 50.917,16.528"
       android:strokeWidth="2"
-      android:fillColor="#00000000"
+      android:fillColor="@android:color/transparent"
       android:strokeColor="@color/material_primary_60"
       android:strokeLineCap="round"/>
   <path
diff --git a/chrome/browser/educational_tip/java/res/drawable/tab_group_promo_logo.xml b/chrome/browser/educational_tip/java/res/drawable/tab_group_promo_logo.xml
index e0865ae5..52558d18 100644
--- a/chrome/browser/educational_tip/java/res/drawable/tab_group_promo_logo.xml
+++ b/chrome/browser/educational_tip/java/res/drawable/tab_group_promo_logo.xml
@@ -12,18 +12,16 @@
         android:fillAlpha="0.05"
         android:pathData="M11.31,0L60.69,0A11.31,11.31 0,0 1,72 11.31L72,60.69A11.31,11.31 0,0 1,60.69 72L11.31,72A11.31,11.31 0,0 1,0 60.69L0,11.31A11.31,11.31 0,0 1,11.31 0z"/>
 
-    <path android:fillAlpha="0.05" android:fillColor="@color/gm3_baseline_surface_tint_light" android:pathData="M11.31,0L60.69,0A11.31,11.31 0,0 1,72 11.31L72,60.69A11.31,11.31 0,0 1,60.69 72L11.31,72A11.31,11.31 0,0 1,0 60.69L0,11.31A11.31,11.31 0,0 1,11.31 0z"/>
-
     <path android:fillColor="@android:color/transparent"
         android:pathData="M17.603,25C18.666,23.542 19.866,22.134 21.201,20.799C31.505,10.495 46.155,8.214 55,15.174M55,48.906C54.176,49.941 53.28,50.945 52.314,51.912C43.516,60.71 31.549,63.659 22.734,60"
-        android:strokeColor="#1B6EF3" android:strokeLineCap="round" android:strokeWidth="2"/>
+        android:strokeColor="@color/material_primary_50" android:strokeLineCap="round" android:strokeWidth="2"/>
 
     <path android:fillColor="@android:color/transparent"
         android:pathData="M55,15.174C49.207,10.615 40.922,10.021 33,13.05M43.175,58.5C35.948,62.057 28.134,62.54 22,59.677"
-        android:strokeColor="#1B6EF3" android:strokeLineCap="round" android:strokeWidth="2"/>
+        android:strokeColor="@color/material_primary_50" android:strokeLineCap="round" android:strokeWidth="2"/>
 
-    <path android:fillColor="#1B6EF3" android:pathData="M20.647,27.654C20.647,27.653 20.646,27.653 20.646,27.653C19.836,27.935 19.025,28.217 18.215,28.499C17.69,28.681 17.156,28.866 16.604,28.907C16.053,28.949 15.472,28.831 15.064,28.47C14.705,28.153 14.513,27.678 14.442,27.198C14.372,26.719 14.411,26.226 14.451,25.739C14.559,24.422 14.666,23.105 14.774,21.787C14.825,21.162 14.883,20.513 15.191,19.96C15.565,19.292 16.282,18.874 17.024,18.813C17.799,18.75 18.508,19.354 18.971,19.896C19.479,20.491 19.888,21.186 20.505,21.664C21.033,22.074 21.679,22.297 22.291,22.57C22.902,22.844 23.514,23.195 23.864,23.767C24.3,24.476 24.231,25.477 23.694,26.143C23.204,26.751 22.432,27.033 21.701,27.288C21.35,27.41 20.999,27.532 20.648,27.654C20.647,27.654 20.647,27.654 20.647,27.654Z"/>
-    <path android:fillColor="#1B6EF3" android:pathData="M49.603,47.141C49.604,47.141 49.604,47.141 49.604,47.141C50.35,46.719 51.097,46.296 51.844,45.873C52.328,45.599 52.82,45.322 53.355,45.182C53.89,45.041 54.482,45.054 54.949,45.335C55.359,45.583 55.633,46.015 55.789,46.474C55.944,46.934 55.994,47.426 56.042,47.912C56.173,49.227 56.305,50.542 56.435,51.857C56.497,52.481 56.557,53.131 56.352,53.73C56.105,54.453 55.475,54.994 54.756,55.187C54.004,55.389 53.199,54.922 52.646,54.471C52.039,53.977 51.512,53.368 50.819,53.008C50.226,52.699 49.55,52.596 48.899,52.437C48.249,52.278 47.584,52.043 47.137,51.543C46.581,50.923 46.469,49.926 46.877,49.174C47.25,48.489 47.959,48.072 48.632,47.69C48.955,47.508 49.279,47.324 49.603,47.141C49.603,47.141 49.603,47.141 49.603,47.141Z"/>
+    <path android:fillColor="@color/material_primary_50" android:pathData="M20.647,27.654C20.647,27.653 20.646,27.653 20.646,27.653C19.836,27.935 19.025,28.217 18.215,28.499C17.69,28.681 17.156,28.866 16.604,28.907C16.053,28.949 15.472,28.831 15.064,28.47C14.705,28.153 14.513,27.678 14.442,27.198C14.372,26.719 14.411,26.226 14.451,25.739C14.559,24.422 14.666,23.105 14.774,21.787C14.825,21.162 14.883,20.513 15.191,19.96C15.565,19.292 16.282,18.874 17.024,18.813C17.799,18.75 18.508,19.354 18.971,19.896C19.479,20.491 19.888,21.186 20.505,21.664C21.033,22.074 21.679,22.297 22.291,22.57C22.902,22.844 23.514,23.195 23.864,23.767C24.3,24.476 24.231,25.477 23.694,26.143C23.204,26.751 22.432,27.033 21.701,27.288C21.35,27.41 20.999,27.532 20.648,27.654C20.647,27.654 20.647,27.654 20.647,27.654Z"/>
+    <path android:fillColor="@color/material_primary_50" android:pathData="M49.603,47.141C49.604,47.141 49.604,47.141 49.604,47.141C50.35,46.719 51.097,46.296 51.844,45.873C52.328,45.599 52.82,45.322 53.355,45.182C53.89,45.041 54.482,45.054 54.949,45.335C55.359,45.583 55.633,46.015 55.789,46.474C55.944,46.934 55.994,47.426 56.042,47.912C56.173,49.227 56.305,50.542 56.435,51.857C56.497,52.481 56.557,53.131 56.352,53.73C56.105,54.453 55.475,54.994 54.756,55.187C54.004,55.389 53.199,54.922 52.646,54.471C52.039,53.977 51.512,53.368 50.819,53.008C50.226,52.699 49.55,52.596 48.899,52.437C48.249,52.278 47.584,52.043 47.137,51.543C46.581,50.923 46.469,49.926 46.877,49.174C47.25,48.489 47.959,48.072 48.632,47.69C48.955,47.508 49.279,47.324 49.603,47.141C49.603,47.141 49.603,47.141 49.603,47.141Z"/>
     <path android:fillColor="@color/material_primary_60"
         android:pathData="M44.693,16.782L67.41,20.38A2,2 67.185,0 1,69.072 22.668L66.569,38.471A2,2 111.915,0 1,64.281 40.134L41.564,36.536A2,2 55.112,0 1,39.902 34.248L42.405,18.445A2,2 55.112,0 1,44.693 16.782z"/>
 
diff --git a/chrome/browser/educational_tip/java/res/drawable/tab_group_sync_promo_logo.xml b/chrome/browser/educational_tip/java/res/drawable/tab_group_sync_promo_logo.xml
index 572fa9a..f57f568 100644
--- a/chrome/browser/educational_tip/java/res/drawable/tab_group_sync_promo_logo.xml
+++ b/chrome/browser/educational_tip/java/res/drawable/tab_group_sync_promo_logo.xml
@@ -12,7 +12,6 @@
         android:fillAlpha="0.05"
         android:pathData="M11.31,0L60.69,0A11.31,11.31 0,0 1,72 11.31L72,60.69A11.31,11.31 0,0 1,60.69 72L11.31,72A11.31,11.31 0,0 1,0 60.69L0,11.31A11.31,11.31 0,0 1,11.31 0z"/>
 
-    <path android:fillAlpha="0.05" android:fillColor="@color/gm3_baseline_surface_tint_light" android:pathData="M11.31,0L60.69,0A11.31,11.31 0,0 1,72 11.31L72,60.69A11.31,11.31 0,0 1,60.69 72L11.31,72A11.31,11.31 0,0 1,0 60.69L0,11.31A11.31,11.31 0,0 1,11.31 0z"/>
     <path android:fillColor="@color/material_primary_90" android:pathData="M19,10L53,10A4,4 0,0 1,57 14L57,58A4,4 0,0 1,53 62L19,62A4,4 0,0 1,15 58L15,14A4,4 0,0 1,19 10z"/>
 
     <path android:fillColor="@android:color/transparent"
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index c450856..5b6f8320 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -4380,7 +4380,12 @@
   {
     "name": "enable-wifi-qos",
     "owners": ["chuweih@chromium.org", "jiejiang@chromium.org", "cros-networking@google.com" ],
-    "expiry_milestone": 130
+    "expiry_milestone": 140
+  },
+  {
+    "name": "enable-wifi-qos-enterprise",
+    "owners": ["jiejiang@chromium.org", "cros-networking@google.com" ],
+    "expiry_milestone": 140
   },
   {
     "name": "enable-windows-gaming-input-data-fetcher",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index d092423..0aa982c 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -6732,6 +6732,12 @@
     "If enabled the system will start automatic prioritization of egress "
     "traffic with WiFi QoS/WMM.";
 
+const char kEnableWifiQosEnterpriseName[] = "Enable WiFi QoS enterprise";
+const char kEnableWifiQosEnterpriseDescription[] =
+    "If enabled the system will start automatic prioritization of egress "
+    "traffic with WiFi QoS/WMM. This flag only affects Enterprise enrolled "
+    "devices. Requires #enable-wifi-qos to be enabled.";
+
 const char kPanelSelfRefresh2Name[] = "Enable Panel Self Refresh 2";
 const char kPanelSelfRefresh2Description[] =
     "Enable Panel Self Refresh 2/Selective-Update where supported. "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 8ed8a69c..69476e0 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -3881,6 +3881,9 @@
 extern const char kEnableWifiQosName[];
 extern const char kEnableWifiQosDescription[];
 
+extern const char kEnableWifiQosEnterpriseName[];
+extern const char kEnableWifiQosEnterpriseDescription[];
+
 extern const char kEapGtcWifiAuthenticationName[];
 extern const char kEapGtcWifiAuthenticationDescription[];
 
diff --git a/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/NativePageBitmapCapturer.java b/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/NativePageBitmapCapturer.java
index 66c81c8..a9745ed 100644
--- a/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/NativePageBitmapCapturer.java
+++ b/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/NativePageBitmapCapturer.java
@@ -37,11 +37,10 @@
      * @param tab The target tab to be captured.
      * @param callback Executed with a non-null bitmap if the tab is presenting a native page. Empty
      *     bitmap if capturing fails, such as out of memory error.
-     * @param topControlsHeight Height of the top controls.
      * @return True if the capture is successfully triggered; otherwise false.
      */
     public static boolean maybeCaptureNativeView(
-            @NonNull Tab tab, @NonNull Callback<Bitmap> callback, int topControlsHeight) {
+            @NonNull Tab tab, @NonNull Callback<Bitmap> callback) {
         if (!isCapturable(tab)) {
             return false;
         }
@@ -52,25 +51,24 @@
         }
 
         // TODO(crbug.com/330230340): capture bitmap asynchronously.
-        Bitmap bitmap = capture(tab, topControlsHeight);
+        Bitmap bitmap = capture(tab);
         PostTask.postTask(TaskTraits.UI_USER_VISIBLE, () -> callback.onResult(bitmap));
         return true;
     }
 
     /**
-     * Synchronous version of {@link #maybeCaptureNativeView(Tab, Callback, int)}.
+     * Synchronous version of {@link #maybeCaptureNativeView(Tab, Callback)}.
      *
      * @param tab The target tab to be captured.
-     * @param topControlsHeight Height of the top controls.
      * @return Null if fails; otherwise, a Bitmap object.
      */
     @Nullable
-    public static Bitmap maybeCaptureNativeViewSync(@NonNull Tab tab, int topControlsHeight) {
+    public static Bitmap maybeCaptureNativeViewSync(@NonNull Tab tab) {
         if (!isCapturable(tab)) {
             return null;
         }
 
-        return capture(tab, topControlsHeight);
+        return capture(tab);
     }
 
     private static boolean isCapturable(Tab tab) {
@@ -88,10 +86,15 @@
         View view = tab.getView();
         // The view is not laid out yet.
         if (view.getWidth() == 0 || view.getHeight() == 0) return false;
+        if (tab.getWebContents() == null
+                || tab.getWebContents().getViewAndroidDelegate() == null
+                || tab.getWebContents().getViewAndroidDelegate().getContainerView() == null) {
+            return false;
+        }
         return true;
     }
 
-    private static Bitmap capture(Tab tab, int topControlsHeight) {
+    private static Bitmap capture(Tab tab) {
         UnownedUserDataHost host = tab.getWindowAndroid().getUnownedUserDataHost();
         if (CAPTURER_KEY.retrieveDataFromHost(host) == null) {
             CAPTURER_KEY.attachToHost(host, new NativePageBitmapCapturer());
@@ -99,16 +102,27 @@
         final var capturer = CAPTURER_KEY.retrieveDataFromHost(host);
 
         View view = tab.getView();
+        // The size of the webpage might be different from that of native pages.
+        // The former may also capture the area underneath the navigation bar while
+        // the latter sometimes does not. If their sizes don't match, a fallback screenshot will
+        // be used instead.
+        Bitmap bitmap =
+                CaptureUtils.createBitmap(
+                        view.getWidth(),
+                        tab.getWebContents()
+                                .getViewAndroidDelegate()
+                                .getContainerView()
+                                .getHeight());
 
-        Bitmap bitmap = CaptureUtils.createBitmap(view.getWidth(), view.getHeight());
         bitmap.eraseColor(tab.getNativePage().getBackgroundColor());
 
         Canvas canvas = new Canvas(bitmap);
         float scale = capturer.getScale();
 
         // TODO(crbug.com/330230340): capture bitmap asynchronously.
-        // Translate to exclude the area of the top controls.
-        canvas.translate(0, -topControlsHeight);
+
+        // Translate to exclude the area of the top controls if present.
+        canvas.translate(0, -tab.getNativePage().getHeightOverlappedWithTopControls());
         canvas.scale(scale, scale);
         view.draw(canvas);
         return bitmap;
diff --git a/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/NativePageBitmapCapturerTest.java b/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/NativePageBitmapCapturerTest.java
index 5e41deb..d978583f 100644
--- a/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/NativePageBitmapCapturerTest.java
+++ b/chrome/browser/gesturenav/android/java/src/org/chromium/chrome/browser/gesturenav/NativePageBitmapCapturerTest.java
@@ -19,8 +19,6 @@
 import org.chromium.base.test.util.Features;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
-import org.chromium.chrome.browser.tab.TabTestUtils;
-import org.chromium.chrome.browser.tab.TabWebContentsDelegateAndroid;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.chrome.test.ChromeTabbedActivityTestRule;
 import org.chromium.components.embedder_support.util.UrlConstants;
@@ -42,11 +40,6 @@
     public void testWithNativePage() throws TimeoutException {
         mTabbedActivityTestRule.startMainActivityWithURL(UrlConstants.NTP_URL);
 
-        final TabWebContentsDelegateAndroid delegate =
-                TabTestUtils.getTabWebContentsDelegate(
-                        mTabbedActivityTestRule.getActivity().getActivityTab());
-        final int topControlsHeight = delegate.getTopControlsHeight();
-
         CallbackHelper callbackHelper = new CallbackHelper();
         ThreadUtils.runOnUiThreadBlocking(
                 () -> {
@@ -55,8 +48,7 @@
                                     mTabbedActivityTestRule.getActivity().getActivityTab(),
                                     (bitmap) -> {
                                         callbackHelper.notifyCalled();
-                                    },
-                                    topControlsHeight));
+                                    }));
                 });
 
         callbackHelper.waitForOnly();
@@ -67,11 +59,6 @@
     public void testWithNonNativePage() {
         mTabbedActivityTestRule.startMainActivityOnBlankPage();
 
-        final TabWebContentsDelegateAndroid delegate =
-                TabTestUtils.getTabWebContentsDelegate(
-                        mTabbedActivityTestRule.getActivity().getActivityTab());
-        final int topControlsHeight = delegate.getTopControlsHeight();
-
         CallbackHelper callbackHelper = new CallbackHelper();
         ThreadUtils.runOnUiThreadBlocking(
                 () -> {
@@ -80,8 +67,7 @@
                                     mTabbedActivityTestRule.getActivity().getActivityTab(),
                                     (bitmap) -> {
                                         callbackHelper.notifyCalled();
-                                    },
-                                    topControlsHeight));
+                                    }));
                 });
 
         // Capture will be finished before the following task.
diff --git a/chrome/browser/lacros/magic_boost_state_lacros.cc b/chrome/browser/lacros/magic_boost_state_lacros.cc
index 51a0e70..0d9658c 100644
--- a/chrome/browser/lacros/magic_boost_state_lacros.cc
+++ b/chrome/browser/lacros/magic_boost_state_lacros.cc
@@ -38,6 +38,11 @@
 
 MagicBoostStateLacros::~MagicBoostStateLacros() = default;
 
+bool MagicBoostStateLacros::IsMagicBoostAvailable() {
+  // Magic Boost does not work in Lacros.
+  return false;
+}
+
 int32_t MagicBoostStateLacros::AsyncIncrementHMRConsentWindowDismissCount() {
   int count = hmr_consent_window_dismiss_count() + 1;
   SetPref(crosapi::mojom::PrefPath::kHMRConsentWindowDismissCount,
diff --git a/chrome/browser/lacros/magic_boost_state_lacros.h b/chrome/browser/lacros/magic_boost_state_lacros.h
index c18a323..efa04bc 100644
--- a/chrome/browser/lacros/magic_boost_state_lacros.h
+++ b/chrome/browser/lacros/magic_boost_state_lacros.h
@@ -20,6 +20,7 @@
   ~MagicBoostStateLacros() override;
 
   // MagicBoostState:
+  bool IsMagicBoostAvailable() override;
   int32_t AsyncIncrementHMRConsentWindowDismissCount() override;
   void AsyncWriteConsentStatus(
       chromeos::HMRConsentStatus consent_status) override;
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudFeatures.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudFeatures.java
index 9660493f..41afbe8 100644
--- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudFeatures.java
+++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/ReadAloudFeatures.java
@@ -183,6 +183,11 @@
         return ReadAloudFeaturesJni.get().getMetricsId();
     }
 
+    /** Returns IDs of all active server-visible experiments. */
+    public static int[] getExperimentIds() {
+        return ReadAloudFeaturesJni.get().getExperimentIds();
+    }
+
     @NativeMethods
     public interface Natives {
         // Create a native readaloud::SyntheticTrial and return its address. It must be
@@ -202,5 +207,8 @@
 
         // Get metrics client ID or empty string if it isn't available.
         String getMetricsId();
+
+        // Get the list of IDs for active server-visible experiments.
+        int[] getExperimentIds();
     }
 }
diff --git a/chrome/browser/readaloud/android/read_aloud_features.cc b/chrome/browser/readaloud/android/read_aloud_features.cc
index c3ff65f..95ff362 100644
--- a/chrome/browser/readaloud/android/read_aloud_features.cc
+++ b/chrome/browser/readaloud/android/read_aloud_features.cc
@@ -3,11 +3,13 @@
 // found in the LICENSE file.
 
 #include "base/android/jni_android.h"
+#include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
 #include "base/android/scoped_java_ref.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/readaloud/android/synthetic_trial.h"
 #include "components/metrics/metrics_service.h"
+#include "components/variations/variations_ids_provider.h"
 
 // Must come after all headers that specialize FromJniType() / ToJniType().
 #include "chrome/browser/readaloud/android/features_jni_headers/ReadAloudFeatures_jni.h"
@@ -60,4 +62,14 @@
   return ConvertUTF8ToJavaString(env, "");
 }
 
+ScopedJavaLocalRef<jintArray> JNI_ReadAloudFeatures_GetExperimentIds(
+    JNIEnv* env) {
+  auto* variations_ids_provider =
+      variations::VariationsIdsProvider::GetInstance();
+  DCHECK(variations_ids_provider);
+
+  return base::android::ToJavaIntArray(
+      env, variations_ids_provider->GetVariationsVectorForWebPropertiesKeys());
+}
+
 }  // namespace readaloud
diff --git a/chrome/browser/resources/ash/settings/os_reset_page/reset_settings_card.html b/chrome/browser/resources/ash/settings/os_reset_page/reset_settings_card.html
index 7d5e8e4f..ee27456 100644
--- a/chrome/browser/resources/ash/settings/os_reset_page/reset_settings_card.html
+++ b/chrome/browser/resources/ash/settings/os_reset_page/reset_settings_card.html
@@ -27,16 +27,15 @@
   </div>
   <template is="dom-if" if="[[isSanitizeAllowed_]]">
     <div class="settings-box two-line hr">
-      <div class="start" id="title" aria-hidden="true">
+      <div class="start" id="sanitizeTitle" aria-hidden="true">
         $i18n{sanitizeTitle}
-        <div class="secondary" id="secondaryText" aria-hidden="true">
+        <div class="secondary" aria-hidden="true">
           $i18n{sanitizeShortDescription}
         </div>
       </div>
       <cr-button id="sanitizeButton"
           on-click="onShowSanitizeDialog_"
-          aria-labelledby="title"
-          aria-describedby="secondaryText"
+          aria-labelledby="sanitizeTitle"
           deep-link-focus-id$="[[Setting.kSanitize]]">
         $i18n{sanitizeButton}
       </cr-button>
diff --git a/chrome/browser/resources/commerce/product_specifications/app.html b/chrome/browser/resources/commerce/product_specifications/app.html
index a2c409c..8167dd0 100644
--- a/chrome/browser/resources/commerce/product_specifications/app.html
+++ b/chrome/browser/resources/commerce/product_specifications/app.html
@@ -3,7 +3,6 @@
     align-items: flex-start;
     display: flex;
     flex-direction: column;
-    max-height: 100%;
     width: fit-content;
   }
 
@@ -24,7 +23,6 @@
   }
 
   :host([show-table-data-unavailable-container_]) #summaryContainer {
-    min-height: 621px;
     justify-content: center;
   }
 
diff --git a/chrome/browser/resources/commerce/product_specifications/horizontal_carousel.css b/chrome/browser/resources/commerce/product_specifications/horizontal_carousel.css
index edaeb34..43f7bee 100644
--- a/chrome/browser/resources/commerce/product_specifications/horizontal_carousel.css
+++ b/chrome/browser/resources/commerce/product_specifications/horizontal_carousel.css
@@ -81,9 +81,3 @@
         var(--color-product-specifications-horizontal-carousel-scrollbar-thumb);
     border-radius: 8px;
   }
-
-  #startProbe,
-  #endProbe {
-    position: sticky;
-    top: 0;
-  }
diff --git a/chrome/browser/resources/commerce/product_specifications/loading_state.css b/chrome/browser/resources/commerce/product_specifications/loading_state.css
index f21e075..2912327 100644
--- a/chrome/browser/resources/commerce/product_specifications/loading_state.css
+++ b/chrome/browser/resources/commerce/product_specifications/loading_state.css
@@ -7,10 +7,6 @@
  * #scheme=relative
  * #css_wrapper_metadata_end */
 
-:host {
-  overflow: hidden;
-}
-
 #loadingContainer {
   border: solid 1px var(--color-loading-gradient-border);
   border-radius: 8px;
diff --git a/chrome/browser/resources/commerce/product_specifications/product_specifications.html b/chrome/browser/resources/commerce/product_specifications/product_specifications.html
index 6267645..fa01aae 100644
--- a/chrome/browser/resources/commerce/product_specifications/product_specifications.html
+++ b/chrome/browser/resources/commerce/product_specifications/product_specifications.html
@@ -7,8 +7,6 @@
     <style>
       body {
         background-color: var(--color-product-specifications-page-background);
-        box-sizing: border-box;
-        height: 100vh;
         margin: 0;
         padding: 24px;
       }
diff --git a/chrome/browser/resources/commerce/product_specifications/table.html b/chrome/browser/resources/commerce/product_specifications/table.html
index 248651b4..8bf8d9081 100644
--- a/chrome/browser/resources/commerce/product_specifications/table.html
+++ b/chrome/browser/resources/commerce/product_specifications/table.html
@@ -4,7 +4,6 @@
     --detail-container-margin-bottom: 24px;
     --new-column-selector-width: 42px;
     --table-gap: 8px;
-    height: 100%;
   }
 
   #table {
@@ -15,7 +14,6 @@
     grid-auto-flow: column;
     grid-template-columns: repeat(var(--num-columns), var(--column-width));
     grid-template-rows: auto;
-    height: 100%;
     line-height: 16px;
     padding-inline-end: calc(var(--new-column-selector-width) + var(
         --table-gap)); /* Include space for selector. */
diff --git a/chrome/browser/resources/segmentation_internals/segmentation_survey.ts b/chrome/browser/resources/segmentation_internals/segmentation_survey.ts
index 374d7b9..98517d69 100644
--- a/chrome/browser/resources/segmentation_internals/segmentation_survey.ts
+++ b/chrome/browser/resources/segmentation_internals/segmentation_survey.ts
@@ -2,9 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {getTrustedHTML} from 'chrome://resources/js/static_types.js';
-import {getRequiredElement} from 'chrome://resources/js/util.js';
-
 import type {ClientInfo, SegmentInfo} from './segmentation_internals.mojom-webui.js';
 import {SegmentationInternalsBrowserProxy} from './segmentation_internals_browser_proxy.js';
 
@@ -38,20 +35,25 @@
           safeURL = safeURL! + '&option=' + encodeURIComponent(result);
         }
         window.location.href = safeURL;
+        return true;
       }
     }
   } catch (error) {
   }
-  const div = getRequiredElement('client-container');
-  div.innerHTML =
-      getTrustedHTML`Failed to open. Please check instructions in email.`;
+  return false;
+}
+
+function openError() {
+  window.location.href = 'chrome://network-error/-404';
 }
 
 function processPredictionResult(segmentInfo: SegmentInfo) {
   const result = String(segmentInfo.predictionResult) +
       ' Timestamp: ' + String(segmentInfo.predictionTimestamp.internalValue);
   const encoded = window.btoa(result);
-  openSurvey(encoded);
+  if (!openSurvey(encoded)) {
+    openError();
+  }
 }
 
 function processClientInfo(info: ClientInfo) {
@@ -61,11 +63,11 @@
 }
 
 function initialize() {
-  const div = getRequiredElement('client-container');
-  div.innerHTML = getTrustedHTML`Loading...`;
+  // Timeout to wait for segmentation results.
+  const timeoutSec = 3000;
   setTimeout(() => {
-    openSurvey(undefined);
-  }, 1000);
+    openError();
+  }, timeoutSec);
 
   getProxy().getCallbackRouter().onClientInfoAvailable.addListener(
       (clientInfos: ClientInfo[]) => {
diff --git a/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc b/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc
index 8196a5ed..b9fd3c6 100644
--- a/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc
+++ b/chrome/browser/segmentation_platform/segmentation_platform_service_factory_unittest.cc
@@ -669,7 +669,7 @@
   std::vector<std::string> result = {};
   ExpectGetClassificationResult(
       kEphemeralHomeModuleBackendKey, prediction_options, input_context,
-      /*expected_status=*/segmentation_platform::PredictionStatus::kFailed,
+      /*expected_status=*/segmentation_platform::PredictionStatus::kSucceeded,
       /*expected_labels=*/result);
 }
 
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
index bb6c51d6..27504fd4 100644
--- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
+++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/ChromeProvidedSharingOptionsProviderBase.java
@@ -320,7 +320,9 @@
     }
 
     private boolean isPdfTab() {
-        return mTabProvider.get().isNativePage() && mTabProvider.get().getNativePage().isPdf();
+        return mTabProvider.hasValue()
+                && mTabProvider.get().isNativePage()
+                && mTabProvider.get().getNativePage().isPdf();
     }
 
     private static boolean isAutomotive() {
diff --git a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
index 5ad92e2..085f2d0 100644
--- a/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
+++ b/chrome/browser/share/android/javatests/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProviderTest.java
@@ -161,6 +161,7 @@
     @Test
     public void getPropertyModels_printingEnabledNoTab_excludesPrinting() {
         Mockito.when(mTabProvider.hasValue()).thenReturn(false);
+        Mockito.when(mTabProvider.get()).thenReturn(null);
         setUpChromeProvidedSharingOptionsProviderTest(
                 /* isIncognito= */ false, /* printingEnabled= */ true, LinkGeneration.MAX);
         List<PropertyModel> propertyModels =
diff --git a/chrome/browser/site_protection/site_protection_metrics_observer.cc b/chrome/browser/site_protection/site_protection_metrics_observer.cc
index 67e4a65..2fcda26 100644
--- a/chrome/browser/site_protection/site_protection_metrics_observer.cc
+++ b/chrome/browser/site_protection/site_protection_metrics_observer.cc
@@ -67,22 +67,26 @@
 }
 
 void SiteProtectionMetricsObserver::PrimaryPageChanged(content::Page& page) {
+  std::optional<GotPointsNavigation> got_points_navigation =
+      std::move(got_points_navigation_);
+  got_points_navigation_ = std::nullopt;
+
   // HistoryService is null in tests.
   if (!history_service_) {
     return;
   }
 
-  std::optional<GotPointsNavigation> got_points_navigation =
-      std::move(got_points_navigation_);
-  got_points_navigation_ = std::nullopt;
+  GURL last_committed_url = page.GetMainDocument().GetLastCommittedURL();
+  if (!last_committed_url.SchemeIsHTTPOrHTTPS()) {
+    return;
+  }
 
   // Store any in-progress data in `metrics_data` so that we can still log the
   // matching heuristics even if the page navigates prior to the asynchronous
   // data fetches completing.
   auto metrics_data = std::make_unique<MetricsData>();
   metrics_data->ukm_source_id = page.GetMainDocument().GetPageUkmSourceId();
-  metrics_data->last_committed_url =
-      page.GetMainDocument().GetLastCommittedURL();
+  metrics_data->last_committed_url = last_committed_url;
   metrics_data->last_committed_origin =
       page.GetMainDocument().GetLastCommittedOrigin();
   metrics_data->data_fetch_start_time = base::Time::Now();
@@ -124,6 +128,10 @@
       &task_tracker_);
 }
 
+bool SiteProtectionMetricsObserver::HasPendingTasksForTesting() {
+  return weak_factory_.HasWeakPtrs();
+}
+
 void SiteProtectionMetricsObserver::OnGotVisitToOriginOlderThan4HoursAgo(
     std::unique_ptr<MetricsData> metrics_data,
     history::HistoryLastVisitResult last_visit_result) {
@@ -227,7 +235,10 @@
   for (SiteFamiliarityHeuristicName heuristic :
        metrics_data->matched_heuristics) {
     base::UmaHistogramEnumeration(
-        "SafeBrowsing.SiteProtection.FamiliarityHeuristic", heuristic);
+        profile_->IsOffTheRecord()
+            ? "SafeBrowsing.SiteProtection.FamiliarityHeuristic.OffTheRecord"
+            : "SafeBrowsing.SiteProtection.FamiliarityHeuristic",
+        heuristic);
   }
 
   ukm::builders::SiteFamiliarityHeuristicResult(metrics_data->ukm_source_id)
diff --git a/chrome/browser/site_protection/site_protection_metrics_observer.h b/chrome/browser/site_protection/site_protection_metrics_observer.h
index f5b3032..13cd851 100644
--- a/chrome/browser/site_protection/site_protection_metrics_observer.h
+++ b/chrome/browser/site_protection/site_protection_metrics_observer.h
@@ -54,6 +54,9 @@
   // content::WebContentsObserver:
   void PrimaryPageChanged(content::Page& page) override;
 
+  // Returns whether there are any pending asynchronous tasks.
+  bool HasPendingTasksForTesting();
+
  private:
   friend class content::WebContentsUserData<SiteProtectionMetricsObserver>;
 
diff --git a/chrome/browser/site_protection/site_protection_metrics_observer_unittest.cc b/chrome/browser/site_protection/site_protection_metrics_observer_unittest.cc
index ec40c2f..7361338 100644
--- a/chrome/browser/site_protection/site_protection_metrics_observer_unittest.cc
+++ b/chrome/browser/site_protection/site_protection_metrics_observer_unittest.cc
@@ -20,6 +20,7 @@
 #include "components/site_engagement/content/site_engagement_service.h"
 #include "components/ukm/test_ukm_recorder.h"
 #include "content/public/test/test_utils.h"
+#include "content/public/test/web_contents_tester.h"
 #include "services/metrics/public/cpp/ukm_builders.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -71,10 +72,7 @@
 
     browser_process_ = TestingBrowserProcess::GetGlobal();
 
-    // Create services which observe page navigation.
-    site_engagement::SiteEngagementService::Helper::CreateForWebContents(
-        web_contents());
-    SiteProtectionMetricsObserver::CreateForWebContents(web_contents());
+    SetUpForNewWebContents();
 
     safe_browsing_database_manager_ =
         base::MakeRefCounted<TestSafeBrowsingDatabaseManager>();
@@ -110,14 +108,54 @@
         HistoryServiceFactory::GetDefaultFactory()}};
   }
 
-  history::HistoryService* GetHistoryService() {
+  void SetIncognito() {
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+    auto* global_browser_process = TestingBrowserProcess::GetGlobal();
+    global_browser_process->SetLocalState(nullptr);
+#endif
+
+    Profile* const otr_profile =
+        profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true);
+    EXPECT_TRUE(otr_profile->IsIncognitoProfile());
+    scoped_refptr<content::SiteInstance> site_instance =
+        content::SiteInstance::Create(otr_profile);
+    SetContents(content::WebContentsTester::CreateTestWebContents(
+        otr_profile, std::move(site_instance)));
+
+    SetUpForNewWebContents();
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+    global_browser_process->SetLocalState(profile()->GetPrefs());
+#endif
+  }
+
+  void SetUpForNewWebContents() {
+    // Create services which observe page navigation.
+    site_engagement::SiteEngagementService::Helper::CreateForWebContents(
+        web_contents());
+    SiteProtectionMetricsObserver::CreateForWebContents(web_contents());
+  }
+
+  history::HistoryService* GetRegularProfileHistoryService() {
     return HistoryServiceFactory::GetForProfile(
         profile(), ServiceAccessType::IMPLICIT_ACCESS);
   }
 
-  void AddPageVisitedYesterday(const GURL& url) {
-    GetHistoryService()->AddPage(url, (base::Time::Now() - base::Hours(25)),
-                                 history::SOURCE_BROWSED);
+  void AddPageVisitedYesterdayToRegularProfile(const GURL& url) {
+    GetRegularProfileHistoryService()->AddPage(
+        url, (base::Time::Now() - base::Hours(25)), history::SOURCE_BROWSED);
+  }
+
+  void NavigateAndWaitForHistogram(const GURL& url,
+                                   const std::string& histogram_name) {
+    base::RunLoop run_loop;
+    base::StatisticsRecorder::ScopedHistogramSampleObserver observer(
+        histogram_name,
+        base::BindLambdaForTesting(
+            [&](const char* histogram_name, uint64_t name_hash,
+                base::HistogramBase::Sample sample) { run_loop.Quit(); }));
+    NavigateAndCommit(url);
+    run_loop.Run();
   }
 
   void NavigateAndCheckRecordedHeuristicHistograms(
@@ -127,15 +165,7 @@
         "SafeBrowsing.SiteProtection.FamiliarityHeuristic";
 
     base::HistogramTester histogram_tester;
-
-    base::RunLoop run_loop;
-    base::StatisticsRecorder::ScopedHistogramSampleObserver observer(
-        kFamiliarityHistogramName,
-        base::BindLambdaForTesting(
-            [&](const char* histogram_name, uint64_t name_hash,
-                base::HistogramBase::Sample sample) { run_loop.Quit(); }));
-    NavigateAndCommit(url);
-    run_loop.Run();
+    NavigateAndWaitForHistogram(url, kFamiliarityHistogramName);
 
     histogram_tester.ExpectTotalCount(kFamiliarityHistogramName,
                                       expected_heuristics.size());
@@ -182,9 +212,9 @@
   GURL kUrlVisitedToday("https://baz.com");
 
   ukm::TestAutoSetUkmRecorder ukm_recorder;
-  GetHistoryService()->AddPage(kUrlVisited8HoursAgo,
-                               (base::Time::Now() - base::Hours(8)),
-                               history::SOURCE_BROWSED);
+  GetRegularProfileHistoryService()->AddPage(
+      kUrlVisited8HoursAgo, (base::Time::Now() - base::Hours(8)),
+      history::SOURCE_BROWSED);
 
   NavigateAndCheckRecordedHeuristicHistograms(
       kUrlVisitedToday,
@@ -202,14 +232,14 @@
   GURL kUrlVisited8HoursAgo("https://bar.com");
   GURL kUrlVisited1HourAgo("https://baz.com");
 
-  GetHistoryService()->AddPage(kUrlVisitedYesterday,
-                               (base::Time::Now() - base::Hours(25)),
-                               history::SOURCE_BROWSED);
-  GetHistoryService()->AddPage(kUrlVisited8HoursAgo,
-                               (base::Time::Now() - base::Hours(8)),
-                               history::SOURCE_BROWSED);
-  GetHistoryService()->AddPage(kUrlVisited1HourAgo, base::Time::Now(),
-                               history::SOURCE_BROWSED);
+  GetRegularProfileHistoryService()->AddPage(
+      kUrlVisitedYesterday, (base::Time::Now() - base::Hours(25)),
+      history::SOURCE_BROWSED);
+  GetRegularProfileHistoryService()->AddPage(
+      kUrlVisited8HoursAgo, (base::Time::Now() - base::Hours(8)),
+      history::SOURCE_BROWSED);
+  GetRegularProfileHistoryService()->AddPage(
+      kUrlVisited1HourAgo, base::Time::Now(), history::SOURCE_BROWSED);
 
   {
     ukm::TestAutoSetUkmRecorder ukm_recorder;
@@ -249,7 +279,7 @@
 // Test the histograms which are logged by SiteProtectionMetricsObserver for
 // different levels of site engagement.
 TEST_F(SiteProtectionMetricsObserverTest, SiteEngagementScore) {
-  AddPageVisitedYesterday(GURL("https://bar.com"));
+  AddPageVisitedYesterdayToRegularProfile(GURL("https://bar.com"));
 
   GURL kUrl("https://foo.com");
   site_engagement::SiteEngagementService* site_engagement_service =
@@ -283,7 +313,7 @@
 // That that SiteProtectionMetricsObserver ignores engagement due to the
 // in-progress navigation.
 TEST_F(SiteProtectionMetricsObserverTest, IgnoreCurrentNavigationEngagement) {
-  AddPageVisitedYesterday(GURL("https://bar.com"));
+  AddPageVisitedYesterdayToRegularProfile(GURL("https://bar.com"));
 
   GURL kUrl("https://foo.com");
   base::HistogramTester histogram_tester;
@@ -317,8 +347,8 @@
   site_engagement::SiteEngagementService* site_engagement_service =
       site_engagement::SiteEngagementServiceFactory::GetForProfile(profile());
   site_engagement_service->ResetBaseScoreForURL(kUrl, kSiteEngagement);
-  GetHistoryService()->AddPage(kUrl, (base::Time::Now() - base::Hours(1)),
-                               history::SOURCE_BROWSED);
+  GetRegularProfileHistoryService()->AddPage(
+      kUrl, (base::Time::Now() - base::Hours(1)), history::SOURCE_BROWSED);
 
   NavigateAndCheckRecordedHeuristicUkm(kUrl, "SiteEngagementScore",
                                        kExpectedUkmSiteEngagement);
@@ -327,7 +357,7 @@
 // Test that SiteProtectionMetricsObserver logs the correct histograms and UKM
 // if the site is on the safe browsing global allowlist.
 TEST_F(SiteProtectionMetricsObserverTest, GlobalAllowlistMatch) {
-  AddPageVisitedYesterday(GURL("https://baz.com"));
+  AddPageVisitedYesterdayToRegularProfile(GURL("https://baz.com"));
 
   GURL kUrlOnHighConfidenceAllowlist("https://foo.com");
   GURL kRegularUrl("https://bar.com");
@@ -358,7 +388,7 @@
   GURL kUrlVisitedYesterday("https://foo.com");
   GURL kUrlVisitedNever("https://bar.com");
 
-  AddPageVisitedYesterday(kUrlVisitedYesterday);
+  AddPageVisitedYesterdayToRegularProfile(kUrlVisitedYesterday);
 
   NavigateAndCheckRecordedHeuristicUkm(kUrlVisitedYesterday,
                                        "AnyHeuristicsMatch", true);
@@ -366,4 +396,49 @@
                                        false);
 }
 
+// Test that the SiteProtectionMetricsObserver does not log any metrics for
+// file:// URLs.
+TEST_F(SiteProtectionMetricsObserverTest, FileUrlNoMetricsLogged) {
+  GURL kFileUrlVisitedNever("file:///usr/");
+  GURL kUrlVisitedNever("https://bar.com");
+
+  SiteProtectionMetricsObserver* site_protection_observer =
+      SiteProtectionMetricsObserver::FromWebContents(web_contents());
+
+  base::HistogramTester histogram_tester;
+
+  // Check that there are no pending asynchronous tasks which would perhaps log
+  // UMA when run.
+  NavigateAndCommit(kFileUrlVisitedNever);
+  EXPECT_FALSE(site_protection_observer->HasPendingTasksForTesting());
+
+  // Check that there are pending asynchronous tasks which would log UMA when
+  // run.
+  NavigateAndCommit(kUrlVisitedNever);
+  EXPECT_TRUE(site_protection_observer->HasPendingTasksForTesting());
+
+  histogram_tester.ExpectTotalCount(
+      "SafeBrowsing.SiteProtection.FamiliarityHeuristic", 0u);
+}
+
+// Test that SiteProtectionMetricsObserver logs to
+// SafeBrowsing.SiteProtection.FamiliarityHeuristic.OffTheRecord when in
+// incognito.
+TEST_F(SiteProtectionMetricsObserverTest, Incognito) {
+  const char kRegularProfileHistogramName[] =
+      "SafeBrowsing.SiteProtection.FamiliarityHeuristic";
+  const char kOffTheRecordHistogramName[] =
+      "SafeBrowsing.SiteProtection.FamiliarityHeuristic.OffTheRecord";
+  GURL kUrlVisitedNever("https://bar.com");
+
+  SetIncognito();
+
+  base::HistogramTester histogram_tester;
+  NavigateAndWaitForHistogram(kUrlVisitedNever, kOffTheRecordHistogramName);
+  histogram_tester.ExpectUniqueSample(
+      kOffTheRecordHistogramName,
+      SiteFamiliarityHeuristicName::kNoVisitsToAnySiteMoreThanADayAgo, 1);
+  histogram_tester.ExpectTotalCount(kRegularProfileHistogramName, 0u);
+}
+
 }  // namespace site_protection
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index 2dc0c8d..eda9dbe8 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1113,7 +1113,6 @@
       "collected_cookies_infobar_delegate.h",
       "confirm_bubble_model.cc",
       "confirm_bubble_model.h",
-      "customize_chrome/side_panel_controller.h",
       "download/download_bubble_contents_view_info.cc",
       "download/download_bubble_contents_view_info.h",
       "download/download_bubble_info.cc",
@@ -1990,6 +1989,7 @@
       "//chrome/browser/ui/color:mixers",
       "//chrome/browser/ui/content_settings",
       "//chrome/browser/ui/content_settings:impl",
+      "//chrome/browser/ui/customize_chrome",
       "//chrome/browser/ui/exclusive_access",
       "//chrome/browser/ui/permission_bubble",
       "//chrome/browser/ui/signin",
@@ -5262,7 +5262,6 @@
       "webauthn/user_actions.h",
       "webauthn/webauthn_ui_helpers.cc",
       "webauthn/webauthn_ui_helpers.h",
-      "webui/side_panel/customize_chrome/customize_chrome_section.h",
       "window_name_prompt/window_name_prompt.cc",
 
       # This test header is included because it contains forward declarations
@@ -5291,6 +5290,7 @@
       "//chrome/browser/ui/commerce:impl",
       "//chrome/browser/ui/views",
       "//chrome/browser/ui/views/bubble",
+      "//chrome/browser/ui/webui/side_panel/customize_chrome",
       "//components/commerce/core:metrics",
       "//components/commerce/core:pref_names",
       "//components/commerce/core:public",
diff --git a/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/BasicNativePage.java b/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/BasicNativePage.java
index bd190f7..38cf088 100644
--- a/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/BasicNativePage.java
+++ b/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/BasicNativePage.java
@@ -86,6 +86,11 @@
     }
 
     @Override
+    public int getHeightOverlappedWithTopControls() {
+        return 0;
+    }
+
+    @Override
     public void destroy() {
         if (mMarginSupplier != null) {
             mMarginSupplier.removeObserver(mMarginObserver);
diff --git a/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/NativePage.java b/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/NativePage.java
index cd6b9c9e..f224fa4 100644
--- a/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/NativePage.java
+++ b/chrome/browser/ui/android/native_page/java/src/org/chromium/chrome/browser/ui/native_page/NativePage.java
@@ -88,6 +88,11 @@
     /** Updates the native page based on the given url. */
     void updateForUrl(String url);
 
+    /** Get the height of the region of the native page view that overlaps top browser controls. */
+    default int getHeightOverlappedWithTopControls() {
+        return 0;
+    }
+
     /**
      * @return {@code true} if the native page is in inactive/frozen state.
      */
diff --git a/chrome/browser/ui/android/webid/account_selection_view_android.cc b/chrome/browser/ui/android/webid/account_selection_view_android.cc
index 878784a0..4bc3f3d9 100644
--- a/chrome/browser/ui/android/webid/account_selection_view_android.cc
+++ b/chrome/browser/ui/android/webid/account_selection_view_android.cc
@@ -37,21 +37,22 @@
 
 namespace {
 
-ScopedJavaLocalRef<jobject> ConvertToJavaAccount(JNIEnv* env,
-                                                 const Account& account) {
+ScopedJavaLocalRef<jobject> ConvertToJavaAccount(
+    JNIEnv* env,
+    content::IdentityRequestAccount* account) {
   ScopedJavaLocalRef<jobject> decoded_picture = nullptr;
-  if (!account.decoded_picture.IsEmpty()) {
+  if (!account->decoded_picture.IsEmpty()) {
     decoded_picture =
-        gfx::ConvertToJavaBitmap(*account.decoded_picture.ToSkBitmap());
+        gfx::ConvertToJavaBitmap(*account->decoded_picture.ToSkBitmap());
   }
   return Java_Account_Constructor(
-      env, ConvertUTF8ToJavaString(env, account.id),
-      ConvertUTF8ToJavaString(env, account.email),
-      ConvertUTF8ToJavaString(env, account.name),
-      ConvertUTF8ToJavaString(env, account.given_name),
-      url::GURLAndroid::FromNativeGURL(env, account.picture), decoded_picture,
-      account.login_state == Account::LoginState::kSignIn,
-      account.browser_trusted_login_state == Account::LoginState::kSignIn);
+      env, ConvertUTF8ToJavaString(env, account->id),
+      ConvertUTF8ToJavaString(env, account->email),
+      ConvertUTF8ToJavaString(env, account->name),
+      ConvertUTF8ToJavaString(env, account->given_name),
+      url::GURLAndroid::FromNativeGURL(env, account->picture), decoded_picture,
+      account->login_state == Account::LoginState::kSignIn,
+      account->browser_trusted_login_state == Account::LoginState::kSignIn);
 }
 
 ScopedJavaLocalRef<jobject> ConvertToJavaIdentityProviderMetadata(
@@ -92,7 +93,7 @@
 
 ScopedJavaLocalRef<jobjectArray> ConvertToJavaAccounts(
     JNIEnv* env,
-    const std::vector<Account>& accounts) {
+    const std::vector<IdentityRequestAccountPtr>& accounts) {
   ScopedJavaLocalRef<jclass> account_clazz = base::android::GetClass(
       env, "org/chromium/chrome/browser/ui/android/webid/data/Account");
   ScopedJavaLocalRef<jobjectArray> array(
@@ -101,7 +102,8 @@
   base::android::CheckException(env);
 
   for (size_t i = 0; i < accounts.size(); ++i) {
-    ScopedJavaLocalRef<jobject> item = ConvertToJavaAccount(env, accounts[i]);
+    ScopedJavaLocalRef<jobject> item =
+        ConvertToJavaAccount(env, accounts[i].get());
     env->SetObjectArrayElement(array.obj(), i, item.obj());
   }
   return array;
@@ -109,25 +111,21 @@
 
 ScopedJavaLocalRef<jobject> ConvertToJavaIdentityProviderData(
     JNIEnv* env,
-    const std::optional<content::IdentityProviderData>& new_accounts_idp) {
-  if (!new_accounts_idp) {
-    return ScopedJavaLocalRef<jobject>(env, nullptr);
-  }
+    content::IdentityProviderData* idp_data) {
   return Java_IdentityProviderData_Constructor(
-      env, new_accounts_idp->idp_for_display,
-      ConvertToJavaAccounts(env, new_accounts_idp->accounts),
-      ConvertToJavaIdentityProviderMetadata(env,
-                                            new_accounts_idp->idp_metadata),
-      ConvertToJavaClientIdMetadata(env, new_accounts_idp->client_metadata),
-      static_cast<jint>(new_accounts_idp->rp_context),
-      !new_accounts_idp->disclosure_fields.empty(),
-      new_accounts_idp->has_login_status_mismatch);
+      env, idp_data->idp_for_display,
+      ConvertToJavaIdentityProviderMetadata(env, idp_data->idp_metadata),
+      ConvertToJavaClientIdMetadata(env, idp_data->client_metadata),
+      static_cast<jint>(idp_data->rp_context),
+      !idp_data->disclosure_fields.empty(),
+      idp_data->has_login_status_mismatch);
 }
 
-Account ConvertFieldsToAccount(JNIEnv* env,
-                               const std::vector<std::string>& string_fields,
-                               const GURL& picture_url,
-                               bool is_sign_in) {
+IdentityRequestAccountPtr ConvertFieldsToAccount(
+    JNIEnv* env,
+    const std::vector<std::string>& string_fields,
+    const GURL& picture_url,
+    bool is_sign_in) {
   auto account_id = string_fields[0];
   auto email = string_fields[1];
   auto name = string_fields[2];
@@ -143,9 +141,10 @@
   Account::LoginState browser_trusted_login_state =
       Account::LoginState::kSignUp;
 
-  return Account(account_id, email, name, given_name, picture_url,
-                 std::move(login_hints), std::move(domain_hints),
-                 std::move(labels), login_state, browser_trusted_login_state);
+  return base::MakeRefCounted<Account>(
+      account_id, email, name, given_name, picture_url, std::move(login_hints),
+      std::move(domain_hints), std::move(labels), login_state,
+      browser_trusted_login_state);
 }
 // These values are persisted to logs. Entries should not be renumbered and
 // numeric values should never be reused.
@@ -190,10 +189,11 @@
 
 bool AccountSelectionViewAndroid::Show(
     const std::string& rp_for_display,
-    const std::vector<content::IdentityProviderData>& identity_provider_data,
+    const std::vector<IdentityProviderDataPtr>& idp_list,
+    const std::vector<IdentityRequestAccountPtr>& accounts,
     Account::SignInMode sign_in_mode,
     blink::mojom::RpMode rp_mode,
-    const std::optional<content::IdentityProviderData>& new_account_idp) {
+    const std::vector<IdentityRequestAccountPtr>& new_accounts) {
   if (!MaybeCreateJavaObject(rp_mode)) {
     // It's possible that the constructor cannot access the bottom sheet clank
     // component. That case may be temporary but we can't let users in a
@@ -202,33 +202,28 @@
     return false;
   }
 
-  // Serialize the `identity_provider_data.accounts` into a Java array and
+  // Serialize the `idp_list` and `accounts` into a Java array and
   // instruct the bridge to show it together with |url| to the user.
   JNIEnv* env = AttachCurrentThread();
-  // Multi IDP support does not currently work on mobile. Hence, we use the
-  // first index from the `identity_provider_data` for the IDP-specific
-  // information.
   ScopedJavaLocalRef<jobjectArray> accounts_obj =
-      ConvertToJavaAccounts(env, identity_provider_data[0].accounts);
-  ScopedJavaLocalRef<jobject> idp_metadata_obj =
-      ConvertToJavaIdentityProviderMetadata(
-          env, identity_provider_data[0].idp_metadata);
-  ScopedJavaLocalRef<jobject> client_id_metadata_obj =
-      ConvertToJavaClientIdMetadata(env,
-                                    identity_provider_data[0].client_metadata);
-  ScopedJavaLocalRef<jobject> new_account_idp_obj =
-      ConvertToJavaIdentityProviderData(env, new_account_idp);
+      ConvertToJavaAccounts(env, accounts);
+
+  ScopedJavaLocalRef<jobjectArray> new_accounts_obj =
+      ConvertToJavaAccounts(env, new_accounts);
+
+  // Multi IDP support does not currently work on mobile. Hence, we use the
+  // first index from the `idp_list` for the IDP-specific
+  // information.
+  ScopedJavaLocalRef<jobject> idp_obj =
+      ConvertToJavaIdentityProviderData(env, idp_list[0].get());
 
   // TODO(crbug.com/329235198): Support auto re-authn on Android.
   Java_AccountSelectionBridge_showAccounts(
-      env, java_object_internal_, rp_for_display,
-      identity_provider_data[0].idp_for_display, accounts_obj, idp_metadata_obj,
-      client_id_metadata_obj,
+      env, java_object_internal_, rp_for_display, idp_list[0]->idp_for_display,
+      accounts_obj, idp_obj,
       sign_in_mode == Account::SignInMode::kAuto &&
           rp_mode == blink::mojom::RpMode::kWidget,
-      static_cast<jint>(identity_provider_data[0].rp_context),
-      !identity_provider_data[0].disclosure_fields.empty(),
-      new_account_idp_obj);
+      new_accounts_obj);
   return true;
 }
 
@@ -363,8 +358,8 @@
     const GURL& account_picture_url,
     bool is_sign_in) {
   delegate_->OnAccountSelected(
-      idp_config_url, ConvertFieldsToAccount(env, account_string_fields,
-                                             account_picture_url, is_sign_in));
+      idp_config_url, *ConvertFieldsToAccount(env, account_string_fields,
+                                              account_picture_url, is_sign_in));
   // The AccountSelectionViewAndroid may be destroyed.
   // AccountSelectionView::Delegate::OnAccountSelected() might delete this.
   // See https://crbug.com/1393650 for details.
diff --git a/chrome/browser/ui/android/webid/account_selection_view_android.h b/chrome/browser/ui/android/webid/account_selection_view_android.h
index cb34188..6f3aa0b 100644
--- a/chrome/browser/ui/android/webid/account_selection_view_android.h
+++ b/chrome/browser/ui/android/webid/account_selection_view_android.h
@@ -12,6 +12,9 @@
 #include "content/public/browser/web_contents.h"
 #include "third_party/blink/public/mojom/webid/federated_auth_request.mojom-shared.h"
 
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
 using TokenError = content::IdentityCredentialTokenError;
 
 // This class provides an implementation of the AccountSelectionView interface
@@ -25,11 +28,11 @@
   // AccountSelectionView:
   bool Show(
       const std::string& rp_for_display,
-      const std::vector<content::IdentityProviderData>& identity_provider_data,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       Account::SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<content::IdentityProviderData>& new_account_idp)
-      override;
+      const std::vector<IdentityRequestAccountPtr>& new_accounts) override;
   bool ShowFailureDialog(
       const std::string& rp_for_display,
       const std::string& idp_for_display,
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionBridge.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionBridge.java
index 3776386..8c57747a 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionBridge.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionBridge.java
@@ -18,7 +18,6 @@
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.tab.TabUtils;
 import org.chromium.chrome.browser.ui.android.webid.data.Account;
-import org.chromium.chrome.browser.ui.android.webid.data.ClientIdMetadata;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityCredentialTokenError;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderData;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderMetadata;
@@ -105,36 +104,26 @@
      * @param rpForDisplay is the formatted RP URL to display in the FedCM prompt.
      * @param idpForDisplay is the formatted IDP URL to display in the FedCM prompt.
      * @param accounts is the list of accounts to be shown.
-     * @param idpMetadata is the metadata of the IDP.
-     * @param clientIdMetadata is the metadata of the RP.
+     * @param idpData is the data of the IDP.
      * @param isAutoReauthn represents whether this is an auto re-authn flow.
-     * @param rpContext is an enum representing the desired text to be used in the title of the
-     *     FedCM prompt: "signin", "continue", etc.
-     * @param requestPermission A {@link boolean} indicating whether we need to request permission
-     *     from the user to share their data with the IDP, if the user is not a returning user.
+     * @param newAccounts represents the newly logged in accounts.
      */
     @CalledByNative
     private void showAccounts(
             @JniType("std::string") String rpForDisplay,
             @JniType("std::string") String idpForDisplay,
             Account[] accounts,
-            IdentityProviderMetadata idpMetadata,
-            ClientIdMetadata clientIdMetadata,
+            IdentityProviderData idpData,
             boolean isAutoReauthn,
-            @RpContext.EnumType int rpContext,
-            boolean requestPermission,
-            @Nullable IdentityProviderData newAccountsIdp) {
+            Account[] newAccounts) {
         assert accounts != null && accounts.length > 0;
         mAccountSelectionComponent.showAccounts(
                 rpForDisplay,
                 idpForDisplay,
                 Arrays.asList(accounts),
-                idpMetadata,
-                clientIdMetadata,
+                idpData,
                 isAutoReauthn,
-                rpContext,
-                requestPermission,
-                newAccountsIdp);
+                Arrays.asList(newAccounts));
     }
 
     /**
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionButtonModeControllerTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionButtonModeControllerTest.java
index c45a301f..d3ec5ead 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionButtonModeControllerTest.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionButtonModeControllerTest.java
@@ -35,10 +35,10 @@
 import org.chromium.blink.mojom.RpMode;
 import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.HeaderProperties.HeaderType;
 import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.ItemProperties;
-import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderData;
 import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 /** Controller tests verify that the Account Selection Button Mode delegate modifies the model. */
 @RunWith(BaseRobolectricTestRunner.class)
@@ -55,16 +55,14 @@
         for (int rpContext : RP_CONTEXTS) {
             when(mMockBottomSheetController.requestShowContent(any(), anyBoolean()))
                     .thenReturn(true);
+            mIdpData.setRpContext(rpContext);
             mMediator.showAccounts(
                     mTestEtldPlusOne,
                     mTestEtldPlusOne2,
                     Arrays.asList(mNewUserAccount),
-                    mIdpMetadata,
-                    mClientIdMetadata,
+                    mIdpData,
                     /* isAutoReauthn= */ false,
-                    rpContext,
-                    /* requestPermission= */ true,
-                    /* newAccountsIdp= */ null);
+                    /* newAccounts= */ Collections.EMPTY_LIST);
             mMediator.showVerifySheet(mAnaAccount);
 
             // There is no account shown in the verify sheet on button mode.
@@ -80,17 +78,15 @@
         for (int rpContext : RP_CONTEXTS) {
             when(mMockBottomSheetController.requestShowContent(any(), anyBoolean()))
                     .thenReturn(true);
+            mIdpData.setRpContext(rpContext);
             // showVerifySheet is called in showAccounts when isAutoReauthn is true
             mMediator.showAccounts(
                     mTestEtldPlusOne,
                     mTestEtldPlusOne2,
                     Arrays.asList(mAnaAccount),
-                    mIdpMetadata,
-                    mClientIdMetadata,
+                    mIdpData,
                     /* isAutoReauthn= */ true,
-                    rpContext,
-                    /* requestPermission= */ true,
-                    /* newAccountsIdp= */ null);
+                    /* newAccounts= */ Collections.EMPTY_LIST);
 
             // There is no account shown in the verify sheet on button mode.
             assertEquals(0, mSheetAccountItems.size());
@@ -119,12 +115,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mBobAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         assertEquals(HeaderType.SIGN_IN, mModel.get(ItemProperties.HEADER).get(TYPE));
 
         // For accounts dialog, we expect header + two accounts.
@@ -139,12 +132,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mNewUserAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         mMediator.showRequestPermissionSheet(mNewUserAccount);
 
         // For request permission dialog, we expect header + account chip + disclosure text +
@@ -182,12 +172,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
 
         assertNotNull(mModel.get(ItemProperties.HEADER).get(RP_BRAND_ICON));
     }
@@ -211,12 +198,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
 
         PropertyModel headerModel = mModel.get(ItemProperties.HEADER);
         // Unlike widget mode, brand icons should not be available because we do not show any
@@ -232,12 +216,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                mNewAccountsIdpSingleNewAccount);
+                mNewAccountsSingleNewAccount);
 
         // Request permission dialog is NOT skipped for a single newly signed-in new account. Since
         // this is a new account and request permission is true, we need to show the request
@@ -248,18 +229,14 @@
     @Test
     public void testNewAccountsIdpRequestPermissionFalseShowsAccountChooserDialog() {
         mMediator.showLoadingDialog(mTestEtldPlusOne, mTestEtldPlusOne2, RpContext.SIGN_IN);
-        IdentityProviderData newAccountsIdp = mNewAccountsIdpSingleNewAccount;
-        newAccountsIdp.setRequestPermission(/* requestPermission= */ false);
+        mIdpData.setRequestPermission(false);
         mMediator.showAccounts(
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                mNewAccountsIdpSingleNewAccount);
+                mNewAccountsSingleNewAccount);
 
         // Account chooser dialog is shown for a single newly signed-in new account where request
         // permission is false. Since this is a new account and request permission is false, we need
@@ -274,12 +251,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                mNewAccountsIdpSingleReturningAccount);
+                mNewAccountsSingleReturningAccount);
 
         // Account chooser dialog is shown for a single newly signed-in returning account. Although
         // this is a returning account, we cannot skip directly to signing in because we have to
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionButtonModeIntegrationTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionButtonModeIntegrationTest.java
index 6323953..024d086 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionButtonModeIntegrationTest.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionButtonModeIntegrationTest.java
@@ -49,13 +49,13 @@
 import org.chromium.chrome.browser.ui.android.webid.AccountSelectionMediator.AccountChooserResult;
 import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.HeaderProperties.HeaderType;
 import org.chromium.chrome.browser.ui.android.webid.data.Account;
-import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderData;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetTestSupport;
 import org.chromium.content.webid.IdentityRequestDialogDismissReason;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Integration tests for the Account Selection Button Mode component check that the calls to the
@@ -82,12 +82,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -106,12 +103,9 @@
                                         EXAMPLE_ETLD_PLUS_ONE,
                                         TEST_ETLD_PLUS_ONE_2,
                                         Arrays.asList(NEW_BOB, RETURNING_ANA),
-                                        IDP_METADATA_WITH_ADD_ACCOUNT,
-                                        mClientIdMetadata,
+                                        mIdpDataWithAddAccount,
                                         /* isAutoReauthn= */ false,
-                                        RpContext.SIGN_IN,
-                                        /* requestPermission= */ true,
-                                        mNewAccountsIdpReturningAna);
+                                        mNewAccountsReturningAna);
                                 mAccountSelection.getMediator().setComponentShowTime(-1000);
                                 return null;
                             }
@@ -125,7 +119,7 @@
                     contentView.findViewById(R.id.account_selection_add_account_btn).performClick();
                 });
 
-        // Because of newAccountsIdp and the account is a returning user, user is now signed in and
+        // Because of newAccounts and the account is a returning user, user is now signed in and
         // shown the verifying UI.
         assertEquals(mAccountSelection.getMediator().getHeaderType(), HeaderType.VERIFY);
 
@@ -142,12 +136,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -166,12 +157,9 @@
                                         EXAMPLE_ETLD_PLUS_ONE,
                                         TEST_ETLD_PLUS_ONE_2,
                                         Arrays.asList(NEW_BOB, RETURNING_ANA),
-                                        IDP_METADATA_WITH_ADD_ACCOUNT,
-                                        mClientIdMetadata,
+                                        mIdpDataWithAddAccount,
                                         /* isAutoReauthn= */ false,
-                                        RpContext.SIGN_IN,
-                                        /* requestPermission= */ true,
-                                        mNewAccountsIdpNewBob);
+                                        mNewAccountsNewBob);
                                 mAccountSelection.getMediator().setComponentShowTime(-1000);
                                 return null;
                             }
@@ -185,7 +173,7 @@
                     contentView.findViewById(R.id.account_selection_add_account_btn).performClick();
                 });
 
-        // Because of newAccountsIdp and the account is a non-returning user which requires us to
+        // Because of newAccounts and the account is a non-returning user which requires us to
         // show disclosure text, the next dialog shown should be the request permission dialog with
         // only the newly signed-in account and the disclosure text shown.
         assertEquals(
@@ -221,15 +209,6 @@
                         null,
                         /* isSignIn= */ true,
                         /* isBrowserTrustedSignIn= */ false);
-        IdentityProviderData newAccountsIdp =
-                new IdentityProviderData(
-                        EXAMPLE_ETLD_PLUS_ONE,
-                        new Account[] {account},
-                        IDP_METADATA_WITH_ADD_ACCOUNT,
-                        mClientIdMetadata,
-                        RpContext.SIGN_IN,
-                        /* requestPermission= */ true,
-                        /* hasLoginStatusMismatch= */ false);
 
         runOnUiThreadBlocking(
                 () -> {
@@ -237,12 +216,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -261,12 +237,9 @@
                                         EXAMPLE_ETLD_PLUS_ONE,
                                         TEST_ETLD_PLUS_ONE_2,
                                         Arrays.asList(account, RETURNING_ANA),
-                                        IDP_METADATA_WITH_ADD_ACCOUNT,
-                                        mClientIdMetadata,
+                                        mIdpDataWithAddAccount,
                                         /* isAutoReauthn= */ false,
-                                        RpContext.SIGN_IN,
-                                        /* requestPermission= */ true,
-                                        newAccountsIdp);
+                                        Arrays.asList(account));
                                 mAccountSelection.getMediator().setComponentShowTime(-1000);
                                 return null;
                             }
@@ -280,7 +253,7 @@
                     contentView.findViewById(R.id.account_selection_add_account_btn).performClick();
                 });
 
-        // Because of newAccountsIdp and the account's IDP claimed login state does not match the
+        // Because of newAccounts and the account's IDP claimed login state does not match the
         // account's browser trusted login state, we show the account chooser UI since browser
         // trusted login state takes precedence. We do not show the request permission UI because
         // the IDP claimed login state tells us to not show the disclosure text.
@@ -305,12 +278,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -354,12 +324,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -386,12 +353,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -420,12 +384,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB, RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -494,12 +455,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -530,12 +488,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -555,18 +510,16 @@
     @Test
     @MediumTest
     public void testRpInApprovedClientsFlow() {
+        mIdpDataWithAddAccount.setRequestPermission(false);
         runOnUiThreadBlocking(
                 () -> {
                     mAccountSelection.showAccounts(
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ false,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -592,12 +545,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -626,12 +576,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -673,12 +620,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -726,12 +670,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -770,18 +711,16 @@
     @Test
     @MediumTest
     public void testAccountSelectionRecordsAccountChooserResultHistogram() {
+        mIdpDataWithAddAccount.setRequestPermission(false);
         runOnUiThreadBlocking(
                 () -> {
                     mAccountSelection.showAccounts(
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ false,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -805,12 +744,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -841,12 +777,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA, NEW_BOB),
-                            IDP_METADATA,
-                            mClientIdMetadata,
+                            mIdpData,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
 
@@ -873,12 +806,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -902,12 +832,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -936,12 +863,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
@@ -970,12 +894,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.HALF);
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java
index 28f31959..cabd6e6 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionControllerTest.java
@@ -55,6 +55,7 @@
 import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.IdpSignInProperties;
 import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.ItemProperties;
 import org.chromium.chrome.browser.ui.android.webid.data.ClientIdMetadata;
+import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderData;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderMetadata;
 import org.chromium.components.image_fetcher.ImageFetcher;
 import org.chromium.content.webid.IdentityRequestDialogDismissReason;
@@ -111,12 +112,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
 
         PropertyModel headerModel = mModel.get(ItemProperties.HEADER);
         assertEquals(HeaderType.SIGN_IN, headerModel.get(TYPE));
@@ -150,12 +148,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mBobAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
 
         PropertyModel headerModel = mModel.get(ItemProperties.HEADER);
         assertEquals(HeaderType.SIGN_IN, headerModel.get(TYPE));
@@ -183,16 +178,22 @@
         ClientIdMetadata clientMetadataNoBrandIconUrl =
                 new ClientIdMetadata(
                         mTestUrlTermsOfService, mTestUrlPrivacyPolicy, /* brandIconUrl= */ "");
+
+        IdentityProviderData idpData =
+                new IdentityProviderData(
+                        mTestEtldPlusOne2,
+                        idpMetadataNoBrandIconUrl,
+                        clientMetadataNoBrandIconUrl,
+                        RpContext.SIGN_IN,
+                        /* requestPermission= */ true,
+                        /* isAutoReauthn= */ false);
         mMediator.showAccounts(
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                idpMetadataNoBrandIconUrl,
-                clientMetadataNoBrandIconUrl,
+                idpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
 
         PropertyModel headerModel = mModel.get(ItemProperties.HEADER);
         assertNull(headerModel.get(IDP_BRAND_ICON));
@@ -207,12 +208,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mNewUserAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
 
         PropertyModel headerModel = mModel.get(ItemProperties.HEADER);
         assertEquals(HeaderType.SIGN_IN, headerModel.get(TYPE));
@@ -224,12 +222,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mBobAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         assertEquals(3, countAllItems()); // Header + two Accounts
         assertEquals("Incorrect item sheet count", 2, mSheetAccountItems.size());
     }
@@ -240,12 +235,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Collections.singletonList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         assertEquals(3, countAllItems()); // Header + Account + Continue Button
         assertEquals(1, mSheetAccountItems.size());
         assertEquals(
@@ -256,12 +248,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Collections.singletonList(mBobAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         assertEquals(3, countAllItems()); // Header + Account + Continue Button
         assertEquals(1, mSheetAccountItems.size());
         assertEquals(
@@ -275,12 +264,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mCarlAccount, mBobAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         verify(mMockBottomSheetController, times(1)).requestShowContent(any(), eq(true));
 
         assertFalse(mMediator.wasDismissed());
@@ -293,12 +279,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         // Do not let test inputs be ignored.
         mMediator.setComponentShowTime(-1000);
         assertFalse(mMediator.wasDismissed());
@@ -324,12 +307,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mCarlAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         // Do not let test inputs be ignored.
         mMediator.setComponentShowTime(-1000);
         assertFalse(mMediator.wasDismissed());
@@ -353,12 +333,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         pressBack();
         verify(mMockDelegate).onDismissed(IdentityRequestDialogDismissReason.OTHER);
         assertTrue(mMediator.wasDismissed());
@@ -371,12 +348,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mBobAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         pressBack();
         verify(mMockDelegate).onDismissed(IdentityRequestDialogDismissReason.OTHER);
         assertTrue(mMediator.wasDismissed());
@@ -389,12 +363,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mBobAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         mMediator.onAccountSelected(mAnaAccount);
         verify(mMockDelegate).onAccountSelected(mTestConfigUrl, mAnaAccount);
         assertFalse(mMediator.wasDismissed());
@@ -409,12 +380,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mNewUserAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         mMediator.onAccountSelected(mNewUserAccount);
 
         assertFalse(mMediator.wasDismissed());
@@ -430,12 +398,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mNewUserAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         mMediator.onAccountSelected(mNewUserAccount);
 
         pressBack();
@@ -456,12 +421,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount, mNewUserAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         assertEquals(2, mSheetAccountItems.size());
         mMediator.onAccountSelected(mAnaAccount);
 
@@ -476,12 +438,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ true,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         // Auto reauthenticates if no action is taken.
         ShadowLooper.runUiThreadTasksIncludingDelayedTasks();
         verify(mMockDelegate).onAccountSelected(mTestConfigUrl, mAnaAccount);
@@ -497,12 +456,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ true,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         // Auto reauthenticates even if dismissed.
         pressBack();
         verify(mMockDelegate).onDismissed(IdentityRequestDialogDismissReason.OTHER);
@@ -520,12 +476,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mNewUserAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         // For new user we expect header + account + consent text + continue btn
         assertEquals(4, countAllItems());
         assertEquals("Incorrect item sheet count", 1, mSheetAccountItems.size());
@@ -551,16 +504,14 @@
 
     @Test
     public void testNewUserWithoutRequestPermission() {
+        mIdpData.setRequestPermission(false);
         mMediator.showAccounts(
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mNewUserAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ false,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         // Because requestPermission is false, we expect header + account + continue btn
         assertEquals(3, countAllItems());
         assertEquals("Incorrect item sheet count", 1, mSheetAccountItems.size());
@@ -570,16 +521,14 @@
     @Test
     public void testMultiAccountSkipConsentSheetWithoutRequestPermission() {
         when(mMockBottomSheetController.requestShowContent(any(), anyBoolean())).thenReturn(true);
+        mIdpData.setRequestPermission(false);
         mMediator.showAccounts(
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mNewUserAccount, mBobAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ false,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         mMediator.onAccountSelected(mNewUserAccount);
         verify(mMockDelegate).onAccountSelected(mTestConfigUrl, mNewUserAccount);
         assertFalse(mMediator.wasDismissed());
@@ -722,12 +671,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         KeyboardVisibilityListener listener = mMediator.getKeyboardEventListener();
         listener.keyboardVisibilityChanged(true);
         verify(mMockBottomSheetController).hideContent(mBottomSheetContent, true);
@@ -744,12 +690,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         mMediator.getTabObserver().onInteractabilityChanged(mTab, false);
         verify(mMockBottomSheetController).hideContent(mBottomSheetContent, false);
         mMediator.getTabObserver().onInteractabilityChanged(mTab, true);
@@ -764,12 +707,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         // We pass null as |mMediatior| does not really care about where we navigate to.
         mMediator.getTabObserver().onDidStartNavigationInPrimaryMainFrame(mTab, null);
         assertTrue(mMediator.wasDismissed());
@@ -783,12 +723,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         KeyboardVisibilityListener listener = mMediator.getKeyboardEventListener();
         listener.keyboardVisibilityChanged(true);
         verify(mMockBottomSheetController).hideContent(mBottomSheetContent, true);
@@ -810,12 +747,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
         verify(mMockBottomSheetController, never()).requestShowContent(any(), anyBoolean());
         mMediator.getTabObserver().onInteractabilityChanged(mTab, true);
         verify(mMockBottomSheetController, times(1)).requestShowContent(mBottomSheetContent, true);
@@ -828,12 +762,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mNewUserAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
 
         assertNotNull(mModel.get(ItemProperties.HEADER).get(SET_FOCUS_VIEW_CALLBACK));
         assertNotNull(
@@ -847,17 +778,14 @@
     }
 
     @Test
-    public void testNewAccountsIdpMultipleAccountsShowsAccountChooser() {
+    public void testnewAccountsMultipleAccountsShowsAccountChooser() {
         mMediator.showAccounts(
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
-                Arrays.asList(),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mNewAccountsMultipleAccounts,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                mNewAccountsIdpMultipleAccounts);
+                mNewAccountsMultipleAccounts);
 
         // Account chooser is shown for multiple newly signed-in accounts.
         assertEquals(HeaderType.SIGN_IN, mModel.get(ItemProperties.HEADER).get(TYPE));
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionCoordinator.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionCoordinator.java
index efd3b5c..c87e27d 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionCoordinator.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionCoordinator.java
@@ -17,7 +17,6 @@
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
-import androidx.annotation.Nullable;
 import androidx.annotation.Px;
 import androidx.annotation.VisibleForTesting;
 import androidx.browser.customtabs.CustomTabsIntent;
@@ -33,7 +32,6 @@
 import org.chromium.chrome.browser.app.ChromeActivity;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.chrome.browser.ui.android.webid.data.Account;
-import org.chromium.chrome.browser.ui.android.webid.data.ClientIdMetadata;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityCredentialTokenError;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderData;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderMetadata;
@@ -207,22 +205,11 @@
             String rpEtldPlusOne,
             String idpEtldPlusOne,
             List<Account> accounts,
-            IdentityProviderMetadata idpMetadata,
-            ClientIdMetadata clientMetadata,
+            IdentityProviderData idpData,
             boolean isAutoReauthn,
-            @RpContext.EnumType int rpContext,
-            boolean requestPermission,
-            @Nullable IdentityProviderData newAccountsIdp) {
+            List<Account> newAccounts) {
         mMediator.showAccounts(
-                rpEtldPlusOne,
-                idpEtldPlusOne,
-                accounts,
-                idpMetadata,
-                clientMetadata,
-                isAutoReauthn,
-                rpContext,
-                requestPermission,
-                newAccountsIdp);
+                rpEtldPlusOne, idpEtldPlusOne, accounts, idpData, isAutoReauthn, newAccounts);
     }
 
     @Override
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTest.java
index 543c0a8..fc45889 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTest.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTest.java
@@ -61,6 +61,7 @@
 import org.chromium.content.webid.IdentityRequestDialogDismissReason;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -104,12 +105,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA, NEW_BOB),
-                            IDP_METADATA,
-                            mClientIdMetadata,
+                            mIdpData,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                 });
         pollUiThread(() -> getBottomSheetState() == mExpectedSheetState);
 
@@ -128,12 +126,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA, NEW_BOB),
-                            IDP_METADATA,
-                            mClientIdMetadata,
+                            mIdpData,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                 });
         pollUiThread(() -> getBottomSheetState() == mExpectedSheetState);
         BottomSheetTestSupport sheetSupport = new BottomSheetTestSupport(mBottomSheetController);
@@ -152,12 +147,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA,
-                            mClientIdMetadata,
+                            mIdpData,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                 });
         pollUiThread(() -> getBottomSheetState() == mExpectedSheetState);
 
@@ -229,12 +221,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(RETURNING_ANA, NEW_BOB),
-                            IDP_METADATA,
-                            mClientIdMetadata,
+                            mIdpData,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                 });
         waitForEvent(mMockBridge).onDismissed(IdentityRequestDialogDismissReason.OTHER);
         verify(mMockBridge, never()).onAccountSelected(any(), any());
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTestBase.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTestBase.java
index af1472bc..77b658c 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTestBase.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionIntegrationTestBase.java
@@ -32,6 +32,9 @@
 import org.chromium.url.GURL;
 import org.chromium.url.JUnitTestGURLs;
 
+import java.util.Arrays;
+import java.util.List;
+
 /** Common test fixtures for AccountSelectionIntegration Android Javatests. */
 public class AccountSelectionIntegrationTestBase {
     protected static final String EXAMPLE_ETLD_PLUS_ONE = "example.com";
@@ -90,9 +93,11 @@
     String mTestUrlTermsOfService;
     String mTestUrlPrivacyPolicy;
     ClientIdMetadata mClientIdMetadata;
-    IdentityProviderData mNewAccountsIdpReturningAna;
-    IdentityProviderData mNewAccountsIdpNewBob;
+    List<Account> mNewAccountsReturningAna;
+    List<Account> mNewAccountsNewBob;
     @RpMode.EnumType int mRpMode;
+    IdentityProviderData mIdpData;
+    IdentityProviderData mIdpDataWithAddAccount;
 
     @Before
     public void setUp() throws InterruptedException {
@@ -108,19 +113,20 @@
                         new GURL(mTestUrlTermsOfService),
                         new GURL(mTestUrlPrivacyPolicy),
                         EXAMPLE_ETLD_PLUS_ONE);
-        mNewAccountsIdpReturningAna =
+        mNewAccountsReturningAna = Arrays.asList(RETURNING_ANA);
+        mNewAccountsNewBob = Arrays.asList(NEW_BOB);
+
+        mIdpData =
                 new IdentityProviderData(
-                        EXAMPLE_ETLD_PLUS_ONE,
-                        new Account[] {RETURNING_ANA},
-                        IDP_METADATA_WITH_ADD_ACCOUNT,
+                        TEST_ETLD_PLUS_ONE_2,
+                        IDP_METADATA,
                         mClientIdMetadata,
                         RpContext.SIGN_IN,
                         /* requestPermission= */ true,
                         /* hasLoginStatusMismatch= */ false);
-        mNewAccountsIdpNewBob =
+        mIdpDataWithAddAccount =
                 new IdentityProviderData(
-                        EXAMPLE_ETLD_PLUS_ONE,
-                        new Account[] {NEW_BOB},
+                        TEST_ETLD_PLUS_ONE_2,
                         IDP_METADATA_WITH_ADD_ACCOUNT,
                         mClientIdMetadata,
                         RpContext.SIGN_IN,
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionJUnitTestBase.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionJUnitTestBase.java
index c89cfda6..17ebf61 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionJUnitTestBase.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionJUnitTestBase.java
@@ -40,6 +40,9 @@
 import org.chromium.url.GURL;
 import org.chromium.url.JUnitTestGURLs;
 
+import java.util.Arrays;
+import java.util.List;
+
 /** Common test fixtures for AccountSelection Robolectric JUnit tests. */
 public class AccountSelectionJUnitTestBase {
     @Parameter(0)
@@ -90,7 +93,6 @@
     Account mNewUserAccount;
     Account mNoOneAccount;
 
-    ClientIdMetadata mClientIdMetadata;
     IdentityCredentialTokenError mTokenError;
     IdentityCredentialTokenError mTokenErrorEmptyUrl;
 
@@ -99,9 +101,10 @@
     ModelList mSheetAccountItems;
     View mContentView;
     IdentityProviderMetadata mIdpMetadata;
-    IdentityProviderData mNewAccountsIdpSingleReturningAccount;
-    IdentityProviderData mNewAccountsIdpSingleNewAccount;
-    IdentityProviderData mNewAccountsIdpMultipleAccounts;
+    IdentityProviderData mIdpData;
+    List<Account> mNewAccountsSingleReturningAccount;
+    List<Account> mNewAccountsSingleNewAccount;
+    List<Account> mNewAccountsMultipleAccounts;
     AccountSelectionBottomSheetContent mBottomSheetContent;
     AccountSelectionMediator mMediator;
 
@@ -175,11 +178,6 @@
                         /* isSignIn= */ true,
                         /* isBrowserTrustedSignIn= */ true);
 
-        mClientIdMetadata =
-                new ClientIdMetadata(
-                        mTestUrlTermsOfService,
-                        mTestUrlPrivacyPolicy,
-                        mTestRpBrandIconUrl.getSpec());
         mTokenError = new IdentityCredentialTokenError(TEST_ERROR_CODE, mTestErrorUrl);
         mTokenErrorEmptyUrl = new IdentityCredentialTokenError(TEST_ERROR_CODE, mTestEmptyErrorUrl);
 
@@ -192,33 +190,21 @@
                         mTestLoginUrl,
                         /* supportsAddAccount= */ false);
 
-        mNewAccountsIdpSingleReturningAccount =
+        mIdpData =
                 new IdentityProviderData(
-                        mTestEtldPlusOne,
-                        new Account[] {mAnaAccount},
+                        mTestEtldPlusOne2,
                         mIdpMetadata,
-                        mClientIdMetadata,
+                        new ClientIdMetadata(
+                                mTestUrlTermsOfService,
+                                mTestUrlPrivacyPolicy,
+                                mTestRpBrandIconUrl.getSpec()),
                         RpContext.SIGN_IN,
-                        /* requestPermission= */ true,
-                        /* hasLoginStatusMismatch= */ false);
-        mNewAccountsIdpSingleNewAccount =
-                new IdentityProviderData(
-                        mTestEtldPlusOne,
-                        new Account[] {mNewUserAccount},
-                        mIdpMetadata,
-                        mClientIdMetadata,
-                        RpContext.SIGN_IN,
-                        /* requestPermission= */ true,
-                        /* hasLoginStatusMismatch= */ false);
-        mNewAccountsIdpMultipleAccounts =
-                new IdentityProviderData(
-                        mTestEtldPlusOne,
-                        new Account[] {mAnaAccount, mBobAccount},
-                        mIdpMetadata,
-                        mClientIdMetadata,
-                        RpContext.SIGN_IN,
-                        /* requestPermission= */ true,
-                        /* hasLoginStatusMismatch= */ false);
+                        /* request_permission= */ true,
+                        /* has_login_status_mismatch= */ false);
+
+        mNewAccountsSingleReturningAccount = Arrays.asList(mAnaAccount);
+        mNewAccountsSingleNewAccount = Arrays.asList(mNewUserAccount);
+        mNewAccountsMultipleAccounts = Arrays.asList(mAnaAccount, mBobAccount);
 
         mActivityScenarioRule
                 .getScenario()
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java
index 658a7b2c..58f34614 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionMediator.java
@@ -363,7 +363,7 @@
 
     private void handleBackPress() {
         mSelectedAccount = null;
-        showAccountsInternal(/* newAccountsIdp= */ null);
+        showAccountsInternal(/* newAccounts= */ null);
     }
 
     private PropertyModel createHeaderItem(
@@ -546,25 +546,22 @@
             String rpForDisplay,
             String idpForDisplay,
             List<Account> accounts,
-            IdentityProviderMetadata idpMetadata,
-            ClientIdMetadata clientMetadata,
+            IdentityProviderData idpData,
             boolean isAutoReauthn,
-            @RpContext.EnumType int rpContext,
-            boolean requestPermission,
-            @Nullable IdentityProviderData newAccountsIdp) {
+            List<Account> newAccounts) {
         // On widget mode, show placeholder icon to preserve header text wrapping when icon is
         // fetched.
         if (mRpMode == RpMode.WIDGET) {
-            showPlaceholderIcon(idpMetadata);
+            showPlaceholderIcon(idpData.getIdpMetadata());
         }
         mRpForDisplay = rpForDisplay;
         mIdpForDisplay = idpForDisplay;
         mAccounts = accounts;
-        mIdpMetadata = idpMetadata;
-        mClientMetadata = clientMetadata;
+        mIdpMetadata = idpData.getIdpMetadata();
+        mClientMetadata = idpData.getClientMetadata();
         mIsAutoReauthn = isAutoReauthn;
-        mRpContext = rpContext;
-        mRequestPermission = requestPermission;
+        mRpContext = idpData.getRpContext();
+        mRequestPermission = idpData.getRequestPermission();
         mSelectedAccount = null;
 
         fetchBrandIcon(mIdpMetadata.getBrandIconUrl(), bitmap -> updateIdpBrandIcon(bitmap));
@@ -573,11 +570,11 @@
             fetchBrandIcon(mClientMetadata.getBrandIconUrl(), bitmap -> updateRpBrandIcon(bitmap));
         }
 
-        if (accounts.size() == 1 && (isAutoReauthn || !idpMetadata.supportsAddAccount())) {
+        if (accounts.size() == 1 && (isAutoReauthn || !mIdpMetadata.supportsAddAccount())) {
             mSelectedAccount = accounts.get(0);
         }
 
-        showAccountsInternal(newAccountsIdp);
+        showAccountsInternal(newAccounts);
         setComponentShowTime(SystemClock.elapsedRealtime());
     }
 
@@ -664,12 +661,10 @@
         return mHeaderType;
     }
 
-    private void showAccountsInternal(@Nullable IdentityProviderData newAccountsIdp) {
+    private void showAccountsInternal(@Nullable List<Account> newAccounts) {
         // TODO(crbug.com/356665527): Handle multiple newly signed-in accounts.
         Account newlySignedInAccount =
-                newAccountsIdp != null && newAccountsIdp.getAccounts().size() == 1
-                        ? newAccountsIdp.getAccounts().get(0)
-                        : null;
+                newAccounts != null && newAccounts.size() == 1 ? newAccounts.get(0) : null;
 
         if (!mIsAutoReauthn && newlySignedInAccount != null && mRpMode == RpMode.BUTTON) {
             mSelectedAccount = newlySignedInAccount;
@@ -693,7 +688,7 @@
             // if we do not skip the next dialog. Also skip when request_permission
             // is false (controlled by the fields API).
             boolean shouldShowRequestPermissionDialog =
-                    !newlySignedInAccount.isSignIn() && newAccountsIdp.getRequestPermission();
+                    !newlySignedInAccount.isSignIn() && mRequestPermission;
             if (shouldShowRequestPermissionDialog) {
                 showRequestPermissionSheet(mSelectedAccount);
                 return;
@@ -982,7 +977,7 @@
         }
 
         // At this point, the account is a non-returning user and RP mode is widget.
-        showAccountsInternal(/* newAccountsIdp= */ null);
+        showAccountsInternal(/* newAccounts= */ null);
     }
 
     void onDismissed(@IdentityRequestDialogDismissReason int dismissReason) {
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionWidgetModeControllerTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionWidgetModeControllerTest.java
index e2cc696..5196652 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionWidgetModeControllerTest.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionWidgetModeControllerTest.java
@@ -29,13 +29,13 @@
 
 import org.chromium.base.Callback;
 import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.blink.mojom.RpContext;
 import org.chromium.blink.mojom.RpMode;
 import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.HeaderProperties.HeaderType;
 import org.chromium.chrome.browser.ui.android.webid.AccountSelectionProperties.ItemProperties;
 import org.chromium.ui.modelutil.PropertyModel;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 /** Controller tests verify that the Account Selection Widget Mode delegate modifies the model. */
 @RunWith(BaseRobolectricTestRunner.class)
@@ -52,16 +52,14 @@
         for (int rpContext : RP_CONTEXTS) {
             when(mMockBottomSheetController.requestShowContent(any(), anyBoolean()))
                     .thenReturn(true);
+            mIdpData.setRpContext(rpContext);
             mMediator.showAccounts(
                     mTestEtldPlusOne,
                     mTestEtldPlusOne2,
                     Arrays.asList(mNewUserAccount),
-                    mIdpMetadata,
-                    mClientIdMetadata,
+                    mIdpData,
                     /* isAutoReauthn= */ false,
-                    rpContext,
-                    /* requestPermission= */ true,
-                    /* newAccountsIdp= */ null);
+                    /* newAccounts= */ Collections.EMPTY_LIST);
             mMediator.showVerifySheet(mAnaAccount);
 
             assertEquals(1, mSheetAccountItems.size());
@@ -76,17 +74,15 @@
         for (int rpContext : RP_CONTEXTS) {
             when(mMockBottomSheetController.requestShowContent(any(), anyBoolean()))
                     .thenReturn(true);
+            mIdpData.setRpContext(rpContext);
             // showVerifySheet is called in showAccounts when isAutoReauthn is true
             mMediator.showAccounts(
                     mTestEtldPlusOne,
                     mTestEtldPlusOne2,
                     Arrays.asList(mAnaAccount),
-                    mIdpMetadata,
-                    mClientIdMetadata,
+                    mIdpData,
                     /* isAutoReauthn= */ true,
-                    rpContext,
-                    /* requestPermission= */ true,
-                    /* newAccountsIdp= */ null);
+                    /* newAccounts= */ Collections.EMPTY_LIST);
 
             assertEquals(1, mSheetAccountItems.size());
             assertEquals(
@@ -119,12 +115,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
 
         assertNull(mModel.get(ItemProperties.HEADER).get(RP_BRAND_ICON));
     }
@@ -148,12 +141,9 @@
                 mTestEtldPlusOne,
                 mTestEtldPlusOne2,
                 Arrays.asList(mAnaAccount),
-                mIdpMetadata,
-                mClientIdMetadata,
+                mIdpData,
                 /* isAutoReauthn= */ false,
-                RpContext.SIGN_IN,
-                /* requestPermission= */ true,
-                /* newAccountsIdp= */ null);
+                /* newAccounts= */ Collections.EMPTY_LIST);
 
         PropertyModel headerModel = mModel.get(ItemProperties.HEADER);
         // Brand icon should be transparent placeholder icon. This is useful so that the header text
diff --git a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionWidgetModeIntegrationTest.java b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionWidgetModeIntegrationTest.java
index 8885d8bb..34efac6 100644
--- a/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionWidgetModeIntegrationTest.java
+++ b/chrome/browser/ui/android/webid/internal/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionWidgetModeIntegrationTest.java
@@ -23,13 +23,13 @@
 
 import org.chromium.base.test.util.Batch;
 import org.chromium.base.test.util.CommandLineFlags;
-import org.chromium.blink.mojom.RpContext;
 import org.chromium.blink.mojom.RpMode;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
 import org.chromium.components.browser_ui.bottomsheet.BottomSheetController;
 
 import java.util.Arrays;
+import java.util.Collections;
 
 /**
  * Integration tests for the Account Selection Widget Mode component check that the calls to the
@@ -55,12 +55,9 @@
                             EXAMPLE_ETLD_PLUS_ONE,
                             TEST_ETLD_PLUS_ONE_2,
                             Arrays.asList(NEW_BOB),
-                            IDP_METADATA_WITH_ADD_ACCOUNT,
-                            mClientIdMetadata,
+                            mIdpDataWithAddAccount,
                             /* isAutoReauthn= */ false,
-                            RpContext.SIGN_IN,
-                            /* requestPermission= */ true,
-                            /* newAccountsIdp= */ null);
+                            /* newAccounts= */ Collections.EMPTY_LIST);
                     mAccountSelection.getMediator().setComponentShowTime(-1000);
                 });
         pollUiThread(() -> getBottomSheetState() == BottomSheetController.SheetState.FULL);
diff --git a/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionComponent.java b/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionComponent.java
index 9020f3b..e0fe416 100644
--- a/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionComponent.java
+++ b/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/AccountSelectionComponent.java
@@ -4,11 +4,8 @@
 
 package org.chromium.chrome.browser.ui.android.webid;
 
-import androidx.annotation.Nullable;
-
 import org.chromium.blink.mojom.RpContext;
 import org.chromium.chrome.browser.ui.android.webid.data.Account;
-import org.chromium.chrome.browser.ui.android.webid.data.ClientIdMetadata;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityCredentialTokenError;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderData;
 import org.chromium.chrome.browser.ui.android.webid.data.IdentityProviderMetadata;
@@ -70,24 +67,17 @@
      * @param rpEtldPlusOne The {@link String} for the relying party.
      * @param idpEtldPlusOne The {@link String} for the identity provider.
      * @param accounts A list of {@link Account}s that will be displayed.
-     * @param idpMetadata Metadata related to identity provider.
-     * @param clientMetadata Metadata related to relying party.
+     * @param idpData The information about the identity provider.
      * @param isAutoReauthn A {@link boolean} that represents whether this is an auto re-authn flow.
-     * @param rpContext is an enum representing the desired text to be used in the title of the
-     *     FedCM prompt: "signin", "continue", etc.
-     * @param requestPermission A {@link boolean} indicating whether we need to request permission
-     *     from the user to share their data with the IDP, if the user is not a returning user.
+     * @param newAccounts The newly logged in accounts.
      */
     void showAccounts(
             String rpEtldPlusOne,
             String idpEtldPlusOne,
             List<Account> accounts,
-            IdentityProviderMetadata idpMetadata,
-            ClientIdMetadata clientMetadata,
+            IdentityProviderData idpData,
             boolean isAutoReauthn,
-            @RpContext.EnumType int rpContext,
-            boolean requestPermission,
-            @Nullable IdentityProviderData newAccountsIdp);
+            List<Account> newAccounts);
 
     /**
      * Displays a dialog telling the user that they can sign in to an IDP for the purpose of
diff --git a/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/data/IdentityProviderData.java b/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/data/IdentityProviderData.java
index afca5dc..f5cafd5 100644
--- a/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/data/IdentityProviderData.java
+++ b/chrome/browser/ui/android/webid/java/src/org/chromium/chrome/browser/ui/android/webid/data/IdentityProviderData.java
@@ -11,33 +11,27 @@
 
 import org.chromium.blink.mojom.RpContext;
 
-import java.util.Arrays;
-import java.util.List;
-
 /**
  * Holds data associated with the identity provider in FedCM dialogs. Android counterpart of
  * IdentityProviderData in //content/public/browser/identity_request_dialog_controller.h
  */
 public class IdentityProviderData {
     private final String mIdpForDisplay;
-    private final List<Account> mAccounts;
     private final IdentityProviderMetadata mIdpMetadata;
     private final ClientIdMetadata mClientMetadata;
-    private final @RpContext.EnumType int mRpContext;
+    private @RpContext.EnumType int mRpContext;
     private boolean mRequestPermission;
     private final boolean mHasLoginStatusMismatch;
 
     @CalledByNative
     public IdentityProviderData(
             @JniType("std::string") String idpForDisplay,
-            Account[] accounts,
             IdentityProviderMetadata idpMetadata,
             ClientIdMetadata clientMetadata,
             @RpContext.EnumType int rpContext,
             boolean requestPermission,
             boolean hasLoginStatusMismatch) {
         mIdpForDisplay = idpForDisplay;
-        mAccounts = Arrays.asList(accounts);
         mIdpMetadata = idpMetadata;
         mClientMetadata = clientMetadata;
         mRpContext = rpContext;
@@ -49,10 +43,6 @@
         return mIdpForDisplay;
     }
 
-    public List<Account> getAccounts() {
-        return mAccounts;
-    }
-
     public IdentityProviderMetadata getIdpMetadata() {
         return mIdpMetadata;
     }
@@ -77,4 +67,9 @@
     public void setRequestPermission(boolean requestPermission) {
         mRequestPermission = requestPermission;
     }
+
+    @VisibleForTesting
+    public void setRpContext(@RpContext.EnumType int rpContext) {
+        mRpContext = rpContext;
+    }
 }
diff --git a/chrome/browser/ui/ash/BUILD.gn b/chrome/browser/ui/ash/BUILD.gn
index 128a222..ddb90439 100644
--- a/chrome/browser/ui/ash/BUILD.gn
+++ b/chrome/browser/ui/ash/BUILD.gn
@@ -13,8 +13,6 @@
     "crosapi_new_window_delegate.cc",
     "crosapi_new_window_delegate.h",
     "login_screen_shown_observer.h",
-    "management_disclosure_client_impl.cc",
-    "management_disclosure_client_impl.h",
     "screen_orientation_delegate_chromeos.cc",
     "screen_orientation_delegate_chromeos.h",
     "screenshot_area.cc",
@@ -220,6 +218,11 @@
     "//ui/events/ozone/evdev",
     "//ui/touch_selection",
     "//url",
+
+    # TODO(b/330527825): Remove this when management_disclosure source set
+    # becomes built by some build bots. //chrome/browser/ui/ash does not depend
+    # on this now, but we should make sure to build this for code health.
+    "//chrome/browser/ui/ash/management_disclosure",
   ]
 
   allow_circular_includes_from = [
diff --git a/chrome/browser/ui/ash/management_disclosure/BUILD.gn b/chrome/browser/ui/ash/management_disclosure/BUILD.gn
new file mode 100644
index 0000000..2afd309
--- /dev/null
+++ b/chrome/browser/ui/ash/management_disclosure/BUILD.gn
@@ -0,0 +1,19 @@
+# Copyright 2024 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//build/config/chromeos/ui_mode.gni")
+
+assert(is_chromeos_ash)
+
+static_library("management_disclosure") {
+  sources = [
+    "management_disclosure_client_impl.cc",
+    "management_disclosure_client_impl.h",
+  ]
+
+  deps = [
+    "//ash/public/cpp",
+    "//base",
+  ]
+}
diff --git a/chrome/browser/ui/ash/management_disclosure/DEPS b/chrome/browser/ui/ash/management_disclosure/DEPS
new file mode 100644
index 0000000..7a49cd5
--- /dev/null
+++ b/chrome/browser/ui/ash/management_disclosure/DEPS
@@ -0,0 +1,13 @@
+include_rules = [
+  # ChromeOS should not depend on //chrome. See //docs/chromeos/code.md for
+  # details.
+  "-chrome",
+
+  # This directory is in //chrome, which violates the rule above. Allow this
+  # directory to #include its own files.
+  "+chrome/browser/ui/ash/management_disclosure",
+
+  # Existing dependencies within //chrome. There is an active effort to
+  # refactor ash codes in //chrome to break these dependencies; see b/332804822.
+  # Whenever possible, avoid adding new //chrome dependencies to this list.
+]
diff --git a/chrome/browser/ui/ash/management_disclosure_client_impl.cc b/chrome/browser/ui/ash/management_disclosure/management_disclosure_client_impl.cc
similarity index 91%
rename from chrome/browser/ui/ash/management_disclosure_client_impl.cc
rename to chrome/browser/ui/ash/management_disclosure/management_disclosure_client_impl.cc
index 097a651..5d5efc0 100644
--- a/chrome/browser/ui/ash/management_disclosure_client_impl.cc
+++ b/chrome/browser/ui/ash/management_disclosure/management_disclosure_client_impl.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ui/ash/management_disclosure_client_impl.h"
+#include "chrome/browser/ui/ash/management_disclosure/management_disclosure_client_impl.h"
 
 #include "ash/public/cpp/login_screen.h"
 
diff --git a/chrome/browser/ui/ash/management_disclosure_client_impl.h b/chrome/browser/ui/ash/management_disclosure/management_disclosure_client_impl.h
similarity index 75%
rename from chrome/browser/ui/ash/management_disclosure_client_impl.h
rename to chrome/browser/ui/ash/management_disclosure/management_disclosure_client_impl.h
index f37a37b..5700e3b 100644
--- a/chrome/browser/ui/ash/management_disclosure_client_impl.h
+++ b/chrome/browser/ui/ash/management_disclosure/management_disclosure_client_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 CHROME_BROWSER_UI_ASH_MANAGEMENT_DISCLOSURE_CLIENT_IMPL_H_
-#define CHROME_BROWSER_UI_ASH_MANAGEMENT_DISCLOSURE_CLIENT_IMPL_H_
+#ifndef CHROME_BROWSER_UI_ASH_MANAGEMENT_DISCLOSURE_MANAGEMENT_DISCLOSURE_CLIENT_IMPL_H_
+#define CHROME_BROWSER_UI_ASH_MANAGEMENT_DISCLOSURE_MANAGEMENT_DISCLOSURE_CLIENT_IMPL_H_
 
 #include "ash/public/cpp/management_disclosure_client.h"
 #include "base/memory/raw_ptr.h"
@@ -27,4 +27,4 @@
   base::WeakPtrFactory<ManagementDisclosureClientImpl> weak_ptr_factory_{this};
 };
 
-#endif  // CHROME_BROWSER_UI_ASH_MANAGEMENT_DISCLOSURE_CLIENT_IMPL_H_
+#endif  // CHROME_BROWSER_UI_ASH_MANAGEMENT_DISCLOSURE_MANAGEMENT_DISCLOSURE_CLIENT_IMPL_H_
diff --git a/chrome/browser/ui/ash/picker/picker_accessibility_browsertest.cc b/chrome/browser/ui/ash/picker/picker_accessibility_browsertest.cc
index 744499f..855fdfc 100644
--- a/chrome/browser/ui/ash/picker/picker_accessibility_browsertest.cc
+++ b/chrome/browser/ui/ash/picker/picker_accessibility_browsertest.cc
@@ -576,6 +576,7 @@
           std::make_unique<views::ImageView>(
               ui::ImageModel::FromImage(gfx::test::CreateImage(1))),
           u"title1", base::DoNothing()));
+  item->SetAction(ash::PickerActionType::kInsert);
   section->AddImageRowItem(std::make_unique<ash::PickerImageItemView>(
       std::make_unique<views::ImageView>(
           ui::ImageModel::FromImage(gfx::test::CreateImage(1))),
@@ -583,8 +584,7 @@
 
   sm_.Call([item]() { item->RequestFocus(); });
 
-  // TODO: b/362129770 - Announce the action as well.
-  sm_.ExpectSpeechPattern("title1");
+  sm_.ExpectSpeechPattern("Insert title1");
   sm_.ExpectSpeechPattern("Button");
   sm_.ExpectSpeechPattern("row 1 column 1");
   sm_.ExpectSpeechPattern("Table Image Row, 1 by 3");
@@ -640,6 +640,7 @@
           std::make_unique<views::ImageView>(
               ui::ImageModel::FromImage(gfx::test::CreateImage(1))),
           u"title1", base::DoNothing()));
+  item->SetAction(ash::PickerActionType::kInsert);
   section->AddImageGridItem(std::make_unique<ash::PickerImageItemView>(
       std::make_unique<views::ImageView>(
           ui::ImageModel::FromImage(gfx::test::CreateImage(1))),
@@ -651,8 +652,7 @@
 
   sm_.Call([item]() { item->RequestFocus(); });
 
-  // TODO: b/362129770 - Announce the action as well.
-  sm_.ExpectSpeechPattern("title1");
+  sm_.ExpectSpeechPattern("Insert title1");
   sm_.ExpectSpeechPattern("Button");
   sm_.ExpectSpeechPattern("List item");
   sm_.ExpectSpeechPattern("1 of 3");
diff --git a/chrome/browser/ui/ash/shell_delegate/BUILD.gn b/chrome/browser/ui/ash/shell_delegate/BUILD.gn
index f923669..5b07435e 100644
--- a/chrome/browser/ui/ash/shell_delegate/BUILD.gn
+++ b/chrome/browser/ui/ash/shell_delegate/BUILD.gn
@@ -42,6 +42,7 @@
     "//chrome/browser/ui/ash/keyboard",
     "//chrome/browser/ui/ash/session",
     "//chrome/browser/ui/ash/user_education",
+    "//chrome/browser/ui/ash/wm",
     "//chrome/browser/ui/chromeos",
     "//chrome/browser/web_applications",
     "//chrome/common",
diff --git a/chrome/browser/ui/ash/shell_delegate/DEPS b/chrome/browser/ui/ash/shell_delegate/DEPS
index 1cfeab6..3ace5475 100644
--- a/chrome/browser/ui/ash/shell_delegate/DEPS
+++ b/chrome/browser/ui/ash/shell_delegate/DEPS
@@ -39,6 +39,7 @@
   "+chrome/browser/ui/ash/session",
   "+chrome/browser/ui/ash/system_sounds_delegate_impl.h",
   "+chrome/browser/ui/ash/user_education",
+  "+chrome/browser/ui/ash/wm",
   "+chrome/browser/ui/browser_command_controller.h",
   "+chrome/browser/ui/browser_commands.h",
   "+chrome/browser/ui/browser.h",
diff --git a/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.cc b/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.cc
index 381a049..218c10da 100644
--- a/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.cc
+++ b/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.cc
@@ -59,6 +59,7 @@
 #include "chrome/browser/ui/ash/session/session_util.h"
 #include "chrome/browser/ui/ash/system_sounds_delegate_impl.h"
 #include "chrome/browser/ui/ash/user_education/chrome_user_education_delegate.h"
+#include "chrome/browser/ui/ash/wm/coral_delegate_impl.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/browser_command_controller.h"
 #include "chrome/browser/ui/browser_commands.h"
@@ -159,6 +160,11 @@
   return std::make_unique<ClipboardHistoryControllerDelegateImpl>();
 }
 
+std::unique_ptr<ash::CoralDelegate> ChromeShellDelegate::CreateCoralDelegate()
+    const {
+  return std::make_unique<CoralDelegateImpl>();
+}
+
 std::unique_ptr<ash::GameDashboardDelegate>
 ChromeShellDelegate::CreateGameDashboardDelegate() const {
   return std::make_unique<ChromeGameDashboardDelegate>();
diff --git a/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.h b/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.h
index ef836303..b61495e6 100644
--- a/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.h
+++ b/chrome/browser/ui/ash/shell_delegate/chrome_shell_delegate.h
@@ -33,6 +33,7 @@
       const override;
   std::unique_ptr<ash::ClipboardHistoryControllerDelegate>
   CreateClipboardHistoryControllerDelegate() const override;
+  std::unique_ptr<ash::CoralDelegate> CreateCoralDelegate() const override;
   std::unique_ptr<ash::GameDashboardDelegate> CreateGameDashboardDelegate()
       const override;
   std::unique_ptr<ash::AcceleratorPrefsDelegate>
diff --git a/chrome/browser/ui/ash/wm/BUILD.gn b/chrome/browser/ui/ash/wm/BUILD.gn
index 2701115..8235f26 100644
--- a/chrome/browser/ui/ash/wm/BUILD.gn
+++ b/chrome/browser/ui/ash/wm/BUILD.gn
@@ -8,6 +8,8 @@
 
 static_library("wm") {
   sources = [
+    "coral_delegate_impl.cc",
+    "coral_delegate_impl.h",
     "tab_cluster_ui_client.cc",
     "tab_cluster_ui_client.h",
   ]
diff --git a/chrome/browser/ui/ash/wm/OWNERS b/chrome/browser/ui/ash/wm/OWNERS
new file mode 100644
index 0000000..055d2f7
--- /dev/null
+++ b/chrome/browser/ui/ash/wm/OWNERS
@@ -0,0 +1 @@
+file://ash/wm/OWNERS
\ No newline at end of file
diff --git a/chrome/browser/ui/ash/wm/coral_delegate_impl.cc b/chrome/browser/ui/ash/wm/coral_delegate_impl.cc
new file mode 100644
index 0000000..e6c0648
--- /dev/null
+++ b/chrome/browser/ui/ash/wm/coral_delegate_impl.cc
@@ -0,0 +1,19 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/ash/wm/coral_delegate_impl.h"
+
+CoralDelegateImpl::CoralDelegateImpl() = default;
+
+CoralDelegateImpl::~CoralDelegateImpl() = default;
+
+// ash::CoralDelegateImpl:
+void CoralDelegateImpl::LaunchPostLoginCluster(
+    const ash::coral_util::CoralCluster& cluster) {}
+
+void CoralDelegateImpl::OpenNewDeskWithCluster(
+    const ash::coral_util::CoralCluster& cluster) {}
+
+void CoralDelegateImpl::CreateSavedDeskFromCluster(
+    const ash::coral_util::CoralCluster& cluster) {}
diff --git a/chrome/browser/ui/ash/wm/coral_delegate_impl.h b/chrome/browser/ui/ash/wm/coral_delegate_impl.h
new file mode 100644
index 0000000..95e1c6c
--- /dev/null
+++ b/chrome/browser/ui/ash/wm/coral_delegate_impl.h
@@ -0,0 +1,26 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_ASH_WM_CORAL_DELEGATE_IMPL_H_
+#define CHROME_BROWSER_UI_ASH_WM_CORAL_DELEGATE_IMPL_H_
+
+#include "ash/public/cpp/coral_delegate.h"
+
+class CoralDelegateImpl : public ash::CoralDelegate {
+ public:
+  CoralDelegateImpl();
+  CoralDelegateImpl(const CoralDelegateImpl&) = delete;
+  CoralDelegateImpl& operator=(const CoralDelegateImpl&) = delete;
+  ~CoralDelegateImpl() override;
+
+  // ash::CoralDelegateImpl:
+  void LaunchPostLoginCluster(
+      const ash::coral_util::CoralCluster& cluster) override;
+  void OpenNewDeskWithCluster(
+      const ash::coral_util::CoralCluster& cluster) override;
+  void CreateSavedDeskFromCluster(
+      const ash::coral_util::CoralCluster& cluster) override;
+};
+
+#endif  // CHROME_BROWSER_UI_ASH_WM_CORAL_DELEGATE_IMPL_H_
diff --git a/chrome/browser/ui/browser_window/browser_window_features.cc b/chrome/browser/ui/browser_window/browser_window_features.cc
index bcb8f56..ac5ec3b1 100644
--- a/chrome/browser/ui/browser_window/browser_window_features.cc
+++ b/chrome/browser/ui/browser_window/browser_window_features.cc
@@ -26,7 +26,6 @@
 #include "chrome/browser/ui/toasts/toast_service.h"
 #include "chrome/browser/ui/toolbar/chrome_labs/chrome_labs_utils.h"
 #include "chrome/browser/ui/ui_features.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
 #include "chrome/browser/ui/views/toolbar/chrome_labs/chrome_labs_coordinator.h"
 #include "components/commerce/core/commerce_feature_list.h"
@@ -103,10 +102,6 @@
   lens_overlay_entry_point_controller_ =
       std::make_unique<lens::LensOverlayEntryPointController>();
 
-  // TODO(https://crbug.com/355485153): Move this into the normal window block.
-  read_anything_coordinator_ =
-      std::make_unique<ReadAnythingCoordinator>(browser);
-
   tab_strip_model_ = browser->tab_strip_model();
 }
 
@@ -143,8 +138,6 @@
       toast_service_ = std::make_unique<ToastService>(browser);
     }
   }
-
-  read_anything_coordinator_->Initialize();
 }
 
 void BrowserWindowFeatures::InitPostBrowserViewConstruction(
diff --git a/chrome/browser/ui/browser_window/public/browser_window_features.h b/chrome/browser/ui/browser_window/public/browser_window_features.h
index b2310e7..768b7272 100644
--- a/chrome/browser/ui/browser_window/public/browser_window_features.h
+++ b/chrome/browser/ui/browser_window/public/browser_window_features.h
@@ -12,7 +12,6 @@
 class Browser;
 class BrowserView;
 class ChromeLabsCoordinator;
-class ReadAnythingCoordinator;
 class SidePanelCoordinator;
 class SidePanelUI;
 class TabStripModel;
@@ -102,10 +101,6 @@
     return lens_overlay_entry_point_controller_.get();
   }
 
-  ReadAnythingCoordinator* read_anything_coordinator() {
-    return read_anything_coordinator_.get();
-  }
-
   tabs::TabDeclutterController* tab_declutter_controller() {
     return tab_declutter_controller_.get();
   }
@@ -148,8 +143,6 @@
 
   std::unique_ptr<SidePanelCoordinator> side_panel_coordinator_;
 
-  std::unique_ptr<ReadAnythingCoordinator> read_anything_coordinator_;
-
   std::unique_ptr<tab_groups::SessionServiceTabGroupSyncObserver>
       session_service_tab_group_sync_observer_;
 
diff --git a/chrome/browser/ui/chromeos/read_write_cards/read_write_cards_manager_impl.cc b/chrome/browser/ui/chromeos/read_write_cards/read_write_cards_manager_impl.cc
index e2e7858..71aeb2c 100644
--- a/chrome/browser/ui/chromeos/read_write_cards/read_write_cards_manager_impl.cc
+++ b/chrome/browser/ui/chromeos/read_write_cards/read_write_cards_manager_impl.cc
@@ -48,9 +48,6 @@
 
   if (chromeos::features::IsMahiEnabled()) {
     mahi_menu_controller_.emplace(ui_controller_);
-  }
-
-  if (chromeos::features::IsMagicBoostEnabled()) {
     magic_boost_card_controller_.emplace();
   }
 }
@@ -123,6 +120,7 @@
 
     // Always set the transition action to handle the edge case that this code
     // path is hit more than once with different actions.
+    CHECK(magic_boost_card_controller_);
     magic_boost_card_controller_->set_transition_action(action);
 
     magic_boost_card_controller_->SetOptInFeature(opt_in_features.value());
@@ -147,7 +145,8 @@
 
   base::expected<HMRConsentStatus, MagicBoostState::Error> hmr_consent_status =
       base::unexpected(MagicBoostState::Error::kUninitialized);
-  if (chromeos::features::IsMagicBoostEnabled()) {
+  if (magic_boost_card_controller_ &&
+      chromeos::MagicBoostState::Get()->IsMagicBoostAvailable()) {
     hmr_consent_status = MagicBoostState::Get()->hmr_consent_status();
 
     // Ensure the disclaimer view is closed before moving to the next step
@@ -206,7 +205,8 @@
 ReadWriteCardsManagerImpl::GetMagicBoostOptInFeatures(
     const content::ContextMenuParams& params,
     const editor_menu::EditorContext& editor_context) {
-  if (!magic_boost_card_controller_) {
+  if (!magic_boost_card_controller_ ||
+      !chromeos::MagicBoostState::Get()->IsMagicBoostAvailable()) {
     return std::nullopt;
   }
 
@@ -233,11 +233,7 @@
   // Check if we should go through Magic Boost opt-in flow when we should show
   // Quick Answers and/or Mahi card.
   base::expected<HMRConsentStatus, MagicBoostState::Error> hmr_consent_status =
-      base::unexpected(MagicBoostState::Error::kUninitialized);
-  if (chromeos::features::IsMagicBoostEnabled()) {
-    hmr_consent_status = MagicBoostState::Get()->hmr_consent_status();
-  }
-
+      MagicBoostState::Get()->hmr_consent_status();
   if ((ShouldShowQuickAnswers(params) || ShouldShowMahi(params)) &&
       hmr_consent_status == HMRConsentStatus::kUnset) {
     return should_opt_in_orca ? OptInFeatures::kOrcaAndHmr
diff --git a/chrome/browser/ui/chromeos/read_write_cards/read_write_cards_manager_impl_unittest.cc b/chrome/browser/ui/chromeos/read_write_cards/read_write_cards_manager_impl_unittest.cc
index 411e7d0..5540ce44 100644
--- a/chrome/browser/ui/chromeos/read_write_cards/read_write_cards_manager_impl_unittest.cc
+++ b/chrome/browser/ui/chromeos/read_write_cards/read_write_cards_manager_impl_unittest.cc
@@ -22,6 +22,7 @@
 #include "chromeos/components/magic_boost/public/cpp/magic_boost_state.h"
 #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h"
 #include "chromeos/constants/chromeos_features.h"
+#include "chromeos/constants/chromeos_switches.h"
 #include "content/public/browser/context_menu_params.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
@@ -84,6 +85,9 @@
                                  chromeos::features::kFeatureManagementMahi});
     }
 
+    base::CommandLine::ForCurrentProcess()->AppendSwitch(
+        chromeos::switches::kMahiRestrictionsOverride);
+
     ChromeAshTestBase::SetUp();
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/ui/customize_chrome/BUILD.gn b/chrome/browser/ui/customize_chrome/BUILD.gn
new file mode 100644
index 0000000..006ff49
--- /dev/null
+++ b/chrome/browser/ui/customize_chrome/BUILD.gn
@@ -0,0 +1,15 @@
+# Copyright 2024 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+assert(is_win || is_mac || is_linux || is_chromeos)
+
+source_set("customize_chrome") {
+  sources = [ "side_panel_controller.h" ]
+
+  public_deps = [
+    "//base",
+    "//chrome/browser/ui/views/side_panel:side_panel_enums",
+    "//chrome/browser/ui/webui/side_panel/customize_chrome/",
+  ]
+}
diff --git a/chrome/browser/ui/customize_chrome/side_panel_controller.h b/chrome/browser/ui/customize_chrome/side_panel_controller.h
index d664c46..1c952f9 100644
--- a/chrome/browser/ui/customize_chrome/side_panel_controller.h
+++ b/chrome/browser/ui/customize_chrome/side_panel_controller.h
@@ -6,6 +6,7 @@
 #define CHROME_BROWSER_UI_CUSTOMIZE_CHROME_SIDE_PANEL_CONTROLLER_H_
 
 #include "base/functional/callback_forward.h"
+#include "base/task/delay_policy.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_entry_observer.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_enums.h"
 #include "chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_section.h"
@@ -16,6 +17,12 @@
 // CustomizeChrome SidePanel. Features should use this class and not
 // SidePanelControllerViews unless they need direct access to creating the View
 // component for the SidePanel.
+//
+// This class an abstract-base-class that serves no purpose other than to
+// satisfy a historical constraint (no referencing views from outside of views)
+// which has since been deleted.
+// TODO(https://crbug.com/365591184) Clean up this abstraction by deleting this
+// class altogether.
 class SidePanelController : public SidePanelEntryObserver {
  public:
   using StateChangedCallBack = base::RepeatingCallback<void(bool)>;
diff --git a/chrome/browser/ui/quick_answers/quick_answers_browsertest_base.cc b/chrome/browser/ui/quick_answers/quick_answers_browsertest_base.cc
index 080113d..c01fcd6 100644
--- a/chrome/browser/ui/quick_answers/quick_answers_browsertest_base.cc
+++ b/chrome/browser/ui/quick_answers/quick_answers_browsertest_base.cc
@@ -4,11 +4,13 @@
 
 #include "chrome/browser/ui/quick_answers/quick_answers_browsertest_base.h"
 
+#include "base/command_line.h"
 #include "base/strings/strcat.h"
 #include "base/strings/stringprintf.h"
 #include "chrome/test/base/chrome_test_utils.h"
 #include "chromeos/components/quick_answers/public/cpp/quick_answers_state.h"
 #include "chromeos/constants/chromeos_features.h"
+#include "chromeos/constants/chromeos_switches.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test_utils.h"
@@ -29,6 +31,11 @@
   scoped_feature_list_.InitWithFeatureStates(
       {{chromeos::features::kMahi, IsMagicBoostEnabled()},
        {chromeos::features::kFeatureManagementMahi, IsMagicBoostEnabled()}});
+
+  if (IsMagicBoostEnabled()) {
+    base::CommandLine::ForCurrentProcess()->AppendSwitch(
+        chromeos::switches::kMahiRestrictionsOverride);
+  }
 }
 
 QuickAnswersBrowserTestBase::~QuickAnswersBrowserTestBase() = default;
diff --git a/chrome/browser/ui/views/editor_menu/BUILD.gn b/chrome/browser/ui/views/editor_menu/BUILD.gn
index 8ea0a98fa..7da80c9 100644
--- a/chrome/browser/ui/views/editor_menu/BUILD.gn
+++ b/chrome/browser/ui/views/editor_menu/BUILD.gn
@@ -52,6 +52,7 @@
     "//chrome/browser/profiles:profile",
     "//chrome/browser/ui/chromeos/read_write_cards",
     "//chromeos/components/editor_menu/public/cpp",
+    "//chromeos/components/magic_boost/public/cpp",
     "//chromeos/constants:constants",
     "//chromeos/crosapi/mojom",
     "//content/public/browser:browser",
diff --git a/chrome/browser/ui/views/editor_menu/editor_menu_controller_impl.cc b/chrome/browser/ui/views/editor_menu/editor_menu_controller_impl.cc
index 8ac2804a..de08e1a6 100644
--- a/chrome/browser/ui/views/editor_menu/editor_menu_controller_impl.cc
+++ b/chrome/browser/ui/views/editor_menu/editor_menu_controller_impl.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/ui/views/editor_menu/editor_menu_view.h"
 #include "chrome/browser/ui/views/editor_menu/utils/editor_types.h"
 #include "chromeos/components/editor_menu/public/cpp/preset_text_query.h"
+#include "chromeos/components/magic_boost/public/cpp/magic_boost_state.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "content/public/browser/browser_context.h"
 #include "ui/gfx/geometry/rect.h"
@@ -80,7 +81,8 @@
 void EditorMenuControllerImpl::OnSettingsButtonPressed() {
   GURL setting_url = GURL(base::StrCat(
       {"chrome://os-settings/",
-       chromeos::features::IsMagicBoostEnabled()
+       chromeos::MagicBoostState::Get() &&
+               chromeos::MagicBoostState::Get()->IsMagicBoostAvailable()
            ? chromeos::settings::mojom::kSystemPreferencesSectionPath
            : chromeos::settings::mojom::kInputSubpagePath,
        "?settingId=",
diff --git a/chrome/browser/ui/views/side_panel/BUILD.gn b/chrome/browser/ui/views/side_panel/BUILD.gn
index c448d2b..d286291 100644
--- a/chrome/browser/ui/views/side_panel/BUILD.gn
+++ b/chrome/browser/ui/views/side_panel/BUILD.gn
@@ -45,8 +45,6 @@
     "history_clusters/history_clusters_tab_helper.h",
     "lens/lens_core_tab_side_panel_helper.cc",
     "lens/lens_core_tab_side_panel_helper.h",
-    "read_anything/read_anything_coordinator.cc",
-    "read_anything/read_anything_coordinator.h",
     "read_anything/read_anything_service.cc",
     "read_anything/read_anything_service.h",
     "read_anything/read_anything_service_factory.cc",
@@ -123,6 +121,8 @@
     "//chrome/browser/profiles:profile",
     "//chrome/browser/ui/actions:actions_headers",
     "//chrome/browser/ui/color:color_headers",
+    "//chrome/browser/ui/customize_chrome",
+    "//chrome/browser/ui/webui/side_panel/customize_chrome",
     "//chrome/common",
     "//chrome/common/accessibility:mojo_bindings",
     "//components/lens",
@@ -214,5 +214,8 @@
     deps += [ "//chrome/common/extensions/api" ]
   }
 
-  allow_circular_includes_from = [ "//chrome/browser/ui/views/toolbar" ]
+  allow_circular_includes_from = [
+    "//chrome/browser/ui/views/toolbar",
+    "//chrome/browser/ui/customize_chrome",
+  ]
 }
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
deleted file mode 100644
index c02f5b7..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "base/check_is_test.h"
-#include "base/functional/bind.h"
-#include "base/metrics/field_trial_params.h"
-#include "base/time/time.h"
-#include "base/timer/timer.h"
-#include "build/chromeos_buildflags.h"
-#include "chrome/app/vector_icons/vector_icons.h"
-#include "chrome/browser/accessibility/embedded_a11y_extension_loader.h"
-#include "chrome/browser/extensions/component_loader.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
-#include "chrome/browser/ui/tabs/public/tab_features.h"
-#include "chrome/browser/ui/tabs/public/tab_interface.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_utils.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_web_view.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h"
-#include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_prefs.h"
-#include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_ui.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "chrome/grit/browser_resources.h"
-#include "chrome/grit/generated_resources.h"
-#include "components/accessibility/reading/distillable_pages.h"
-#include "components/feature_engagement/public/feature_constants.h"
-#include "extensions/browser/extension_system.h"
-#include "ui/accessibility/accessibility_features.h"
-#include "ui/base/l10n/l10n_util.h"
-
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "chrome/browser/lacros/embedded_a11y_manager_lacros.h"
-#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
-
-ReadAnythingCoordinator::ReadAnythingCoordinator(Browser* browser)
-    : browser_(browser) {}
-
-ReadAnythingCoordinator::~ReadAnythingCoordinator() {
-  // Deregister Read Anything from the global side panel registry. This removes
-  // Read Anything as a side panel entry observer.
-
-  if (features::IsDataCollectionModeForScreen2xEnabled()) {
-    BrowserList::GetInstance()->RemoveObserver(this);
-  }
-}
-
-void ReadAnythingCoordinator::Initialize() {
-  if (features::IsDataCollectionModeForScreen2xEnabled()) {
-    BrowserList::GetInstance()->AddObserver(this);
-  }
-}
-
-void ReadAnythingCoordinator::OnBrowserSetLastActive(Browser* browser) {
-  if (!features::IsDataCollectionModeForScreen2xEnabled() ||
-      browser != browser_) {
-    return;
-  }
-  // This code is called as part of a screen2x data generation workflow, where
-  // the browser is opened by a CLI and the read-anything side panel is
-  // automatically opened. Therefore we force the UI to show right away, as in
-  // tests.
-  auto* side_panel_ui = browser->GetFeatures().side_panel_ui();
-  if (side_panel_ui->GetCurrentEntryId() != SidePanelEntryId::kReadAnything) {
-    side_panel_ui->SetNoDelaysForTesting(true);  // IN-TEST
-    side_panel_ui->Show(SidePanelEntryId::kReadAnything);
-  }
-}
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h
deleted file mode 100644
index de7c4b0..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_COORDINATOR_H_
-#define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_COORDINATOR_H_
-
-#include "base/memory/weak_ptr.h"
-#include "chrome/browser/ui/browser_list_observer.h"
-
-class Browser;
-
-///////////////////////////////////////////////////////////////////////////////
-// ReadAnythingCoordinator
-//
-//  A class that coordinates the Read Anything feature. This class registers
-//  itself as a SidePanelEntry.
-//  The coordinator acts as the external-facing API for the Read Anything
-//  feature. Classes outside this feature should make calls to the coordinator.
-//  This class has the same lifetime as the browser.
-//
-class ReadAnythingCoordinator : public BrowserListObserver {
- public:
-  explicit ReadAnythingCoordinator(Browser* browser);
-  ~ReadAnythingCoordinator() override;
-
-  // This class does not do anything until Initialize is called.
-  void Initialize();
-
- private:
-  friend class ReadAnythingCoordinatorTest;
-  friend class ReadAnythingCoordinatorScreen2xDataCollectionModeTest;
-
-  // Owns this.
-  raw_ptr<Browser> browser_;
-
-  // BrowserListObserver:
-  void OnBrowserSetLastActive(Browser* browser) override;
-
-  base::WeakPtrFactory<ReadAnythingCoordinator> weak_ptr_factory_{this};
-};
-#endif  // CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_COORDINATOR_H_
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
deleted file mode 100644
index dcf3d8b..0000000
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc
+++ /dev/null
@@ -1,258 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/memory/raw_ptr.h"
-#include "chrome/browser/accessibility/embedded_a11y_extension_loader.h"
-#include "chrome/browser/companion/core/features.h"
-#include "chrome/browser/extensions/component_loader.h"
-#include "chrome/browser/extensions/extension_service.h"
-#include "chrome/browser/extensions/test_extension_system.h"
-#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
-#include "chrome/browser/ui/ui_features.h"
-#include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/frame/test_with_browser_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_web_view.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_entry.h"
-#include "chrome/browser/ui/views/side_panel/side_panel_registry.h"
-#include "chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_ui.h"
-#include "chrome/common/extensions/extension_constants.h"
-#include "content/public/test/scoped_web_ui_controller_factory_registration.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "ui/accessibility/accessibility_features.h"
-
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "chrome/browser/lacros/embedded_a11y_manager_lacros.h"
-#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
-
-using testing::_;
-
-class ReadAnythingCoordinatorTest : public TestWithBrowserView {
- public:
-  ReadAnythingCoordinatorTest()
-      : TestWithBrowserView(
-            content::BrowserTaskEnvironment::TimeSource::MOCK_TIME) {}
-
-  ReadAnythingCoordinatorTest(const ReadAnythingCoordinatorTest&) = delete;
-  ReadAnythingCoordinatorTest& operator=(const ReadAnythingCoordinatorTest&) =
-      delete;
-
-  void SetUp() override {
-    base::test::ScopedFeatureList features;
-    scoped_feature_list_.InitWithFeatures(
-        {
-            features::kReadAnythingDocsIntegration,
-        },
-        {});
-    TestWithBrowserView::SetUp();
-
-    InitExtensionSystem(profile());
-
-    side_panel_coordinator_ = browser()->GetFeatures().side_panel_coordinator();
-    read_anything_coordinator_ =
-        browser()->GetFeatures().read_anything_coordinator();
-
-    // Ensure a kReadAnything entry is added to the contextual registry for the
-    // first tab.
-    AddTabToBrowser(GURL("http://foo1.com"));
-    auto* tab_one_registry = SidePanelRegistry::GetDeprecated(
-        browser_view()->GetActiveWebContents());
-    contextual_registries_.push_back(tab_one_registry);
-
-    // Ensure a kReadAnything entry is added to the contextual registry for the
-    // second tab.
-    AddTabToBrowser(GURL("http://foo2.com"));
-    auto* tab_two_registry = SidePanelRegistry::GetDeprecated(
-        browser_view()->GetActiveWebContents());
-    contextual_registries_.push_back(tab_two_registry);
-
-    // Verify the first tab has one entry, kReadAnything.
-    browser_view()->browser()->tab_strip_model()->ActivateTabAt(0);
-    SidePanelRegistry* contextual_registry = SidePanelRegistry::GetDeprecated(
-        browser_view()->GetActiveWebContents());
-    ASSERT_EQ(contextual_registry->entries().size(), 1u);
-    EXPECT_EQ(contextual_registry->entries()[0]->key().id(),
-              SidePanelEntry::Id::kReadAnything);
-
-    // Verify the second tab has one entry, kReadAnything.
-    browser_view()->browser()->tab_strip_model()->ActivateTabAt(1);
-    contextual_registry = SidePanelRegistry::GetDeprecated(
-        browser_view()->GetActiveWebContents());
-    ASSERT_EQ(contextual_registry->entries().size(), 1u);
-    EXPECT_EQ(contextual_registry->entries()[0]->key().id(),
-              SidePanelEntry::Id::kReadAnything);
-  }
-
-  void InitExtensionSystem(Profile* profile) {
-    extensions::TestExtensionSystem* extension_system =
-        static_cast<extensions::TestExtensionSystem*>(
-            extensions::ExtensionSystem::Get(profile));
-    extension_system->CreateExtensionService(
-        base::CommandLine::ForCurrentProcess(), base::FilePath(), false);
-  }
-
-  // Wrapper methods around the ReadAnythingCoordinator. These do nothing more
-  // than keep the below tests less verbose (simple pass-throughs).
-
-  std::unique_ptr<views::View> CreateContainerView() {
-    return std::make_unique<ReadAnythingSidePanelWebView>(browser()->profile());
-  }
-
-  void OnBrowserSetLastActive(Browser* browser) {
-    read_anything_coordinator_->OnBrowserSetLastActive(browser);
-  }
-
-  void AddTabToBrowser(const GURL& tab_url) {
-    AddTab(browser_view()->browser(), tab_url);
-    // Remove the companion entry if it present.
-    auto* registry = SidePanelRegistry::GetDeprecated(
-        browser_view()->GetActiveWebContents());
-    registry->Deregister(
-        SidePanelEntry::Key(SidePanelEntry::Id::kSearchCompanion));
-  }
-
-#if !BUILDFLAG(IS_CHROMEOS_LACROS)
-  bool IsGDocsHelperExtensionLoaded() {
-#if BUILDFLAG(IS_CHROMEOS)
-    return EmbeddedA11yExtensionLoader::GetInstance()->IsExtensionInstalled(
-        extension_misc::kReadingModeGDocsHelperExtensionId);
-#else
-    extensions::ComponentLoader* component_loader =
-        extensions::ExtensionSystem::Get(profile())
-            ->extension_service()
-            ->component_loader();
-    return component_loader->Exists(
-        extension_misc::kReadingModeGDocsHelperExtensionId);
-#endif  // BUILDFLAG(IS_CHROMEOS)
-  }
-#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)
-
- protected:
-  content::ScopedWebUIConfigRegistration webui_config_registration_{
-      std::make_unique<ReadAnythingUIUntrustedConfig>()};
-
-  raw_ptr<SidePanelCoordinator, DanglingUntriaged> side_panel_coordinator_ =
-      nullptr;
-  std::vector<raw_ptr<SidePanelRegistry, DanglingUntriaged>>
-      contextual_registries_;
-  raw_ptr<ReadAnythingCoordinator, DanglingUntriaged>
-      read_anything_coordinator_ = nullptr;
-
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-// TODO(crbug.com/40853217): Fix the memory leak on destruction observed on
-// these tests on asan mac.
-#if !BUILDFLAG(IS_MAC) || !defined(ADDRESS_SANITIZER)
-
-#if !BUILDFLAG(IS_CHROMEOS_LACROS)
-TEST_F(ReadAnythingCoordinatorTest,
-       SidePanelShowAndHide_NonLacros_CallEmbeddedA11yExtensionLoader) {
-  SidePanelEntry* entry = contextual_registries_[0]->GetEntryForKey(
-      SidePanelEntry::Key(SidePanelEntry::Id::kReadAnything));
-  EXPECT_FALSE(IsGDocsHelperExtensionLoaded());
-
-  // If the local side panel entry is shown, install the helper extension.
-  entry->OnEntryShown();
-  EXPECT_TRUE(IsGDocsHelperExtensionLoaded());
-
-  // If the local side panel entry is hidden, remove the helper extension after
-  // a timeout.
-  entry->OnEntryHidden();
-  // The helper extension is not removed immediately.
-  EXPECT_TRUE(IsGDocsHelperExtensionLoaded());
-  // The helper extension is removed after a timeout.
-  task_environment()->FastForwardBy(base::Seconds(30));
-  EXPECT_FALSE(IsGDocsHelperExtensionLoaded());
-}
-#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)
-
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-TEST_F(
-    ReadAnythingCoordinatorTest,
-    SidePanelShowAndHide_Lacros_EmbeddedA11yManagerLacrosUpdateReadingModeState) {
-  SidePanelEntry* entry = contextual_registries_[0]->GetEntryForKey(
-      SidePanelEntry::Key(SidePanelEntry::Id::kReadAnything));
-  EXPECT_FALSE(
-      EmbeddedA11yManagerLacros::GetInstance()->IsReadingModeEnabled());
-
-  // If the local side panel entry is shown, set reading mode enabled to true.
-  entry->OnEntryShown();
-  EXPECT_TRUE(EmbeddedA11yManagerLacros::GetInstance()->IsReadingModeEnabled());
-
-  // If the local side panel entry is hidden, set reading mode enabled to false
-  // after a timeout.
-  entry->OnEntryHidden();
-  // The reading mode setting is not updated immediately.
-  EXPECT_TRUE(EmbeddedA11yManagerLacros::GetInstance()->IsReadingModeEnabled());
-  // The reading mode setting is updated after a timeout.
-  task_environment()->FastForwardBy(base::Seconds(30));
-  EXPECT_FALSE(
-      EmbeddedA11yManagerLacros::GetInstance()->IsReadingModeEnabled());
-}
-#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
-
-TEST_F(ReadAnythingCoordinatorTest,
-       OnBrowserSetLastActive_SidePanelIsNotVisible) {
-  Browser* browser = browser_view()->browser();
-  OnBrowserSetLastActive(browser);
-
-  EXPECT_FALSE(side_panel_coordinator_->IsSidePanelShowing());
-}
-
-TEST_F(ReadAnythingCoordinatorTest, WithWebUIFlagEnabled_ShowsWebUIToolbar) {
-  ASSERT_STREQ("ReadAnythingSidePanelWebView",
-               CreateContainerView()->GetClassName());
-}
-
-class ReadAnythingCoordinatorScreen2xDataCollectionModeTest
-    : public TestWithBrowserView {
- public:
-  void SetUp() override {
-    base::test::ScopedFeatureList features;
-    scoped_feature_list_.InitWithFeatures(
-        {features::kDataCollectionModeForScreen2x}, {});
-    TestWithBrowserView::SetUp();
-
-    side_panel_coordinator_ = browser()->GetFeatures().side_panel_coordinator();
-    read_anything_coordinator_ =
-        browser()->GetFeatures().read_anything_coordinator();
-
-    AddTab(browser_view()->browser(), GURL("http://foo1.com"));
-    browser_view()->browser()->tab_strip_model()->ActivateTabAt(0);
-  }
-
-  void OnBrowserSetLastActive(Browser* browser) {
-    read_anything_coordinator_->OnBrowserSetLastActive(browser);
-  }
-
- protected:
-  content::ScopedWebUIConfigRegistration webui_config_registration_{
-      std::make_unique<ReadAnythingUIUntrustedConfig>()};
-
-  raw_ptr<SidePanelCoordinator, DanglingUntriaged> side_panel_coordinator_ =
-      nullptr;
-  raw_ptr<ReadAnythingCoordinator, DanglingUntriaged>
-      read_anything_coordinator_ = nullptr;
-  base::test::ScopedFeatureList scoped_feature_list_;
-};
-
-TEST_F(ReadAnythingCoordinatorScreen2xDataCollectionModeTest,
-       OnBrowserSetLastActive_SidePanelIsVisible) {
-  Browser* browser = browser_view()->browser();
-  OnBrowserSetLastActive(browser);
-
-  EXPECT_TRUE(side_panel_coordinator_->IsSidePanelShowing());
-  EXPECT_EQ(browser->GetFeatures().side_panel_ui()->GetCurrentEntryId(),
-            SidePanelEntryId::kReadAnything);
-}
-
-#endif  // !defined(ADDRESS_SANITIZER)
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_service.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_service.cc
index 1fcc5cb..7048b32 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_service.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_service.cc
@@ -9,7 +9,12 @@
 #include "chrome/browser/extensions/component_loader.h"
 #include "chrome/browser/extensions/extension_service.h"
 #include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_service_factory.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_entry_id.h"
+#include "chrome/browser/ui/views/side_panel/side_panel_ui.h"
 #include "chrome/common/extensions/extension_constants.h"
 #include "chrome/grit/browser_resources.h"
 #include "extensions/browser/extension_system.h"
@@ -41,6 +46,9 @@
             &ReadAnythingService::OnLocalSidePanelSwitchDelayTimeout,
             weak_ptr_factory_.GetWeakPtr()));
   }
+  if (features::IsDataCollectionModeForScreen2xEnabled()) {
+    browser_list_observer_.Observe(BrowserList::GetInstance());
+  }
 }
 
 // The service is shutting down which means the profile is destroying, at which
@@ -129,3 +137,21 @@
 
   RemoveGDocsHelperExtension();
 }
+
+void ReadAnythingService::OnBrowserSetLastActive(Browser* browser) {
+  if (!features::IsDataCollectionModeForScreen2xEnabled() ||
+      browser->profile() != profile_) {
+    return;
+  }
+
+  // This code is called as part of a screen2x data generation workflow, where
+  // the browser is opened by a CLI and the read-anything side panel is
+  // automatically opened. Therefore we force the UI to show right away, as in
+  // tests.
+  // TODO(https://crbug.com/358191922): Remove this code.
+  auto* side_panel_ui = browser->GetFeatures().side_panel_ui();
+  if (side_panel_ui->GetCurrentEntryId() != SidePanelEntryId::kReadAnything) {
+    side_panel_ui->SetNoDelaysForTesting(true);  // IN-TEST
+    side_panel_ui->Show(SidePanelEntryId::kReadAnything);
+  }
+}
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_service.h b/chrome/browser/ui/views/side_panel/read_anything/read_anything_service.h
index 996c32fd..98d3de0 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_service.h
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_service.h
@@ -6,14 +6,17 @@
 #define CHROME_BROWSER_UI_VIEWS_SIDE_PANEL_READ_ANYTHING_READ_ANYTHING_SERVICE_H_
 
 #include "base/memory/raw_ptr.h"
+#include "base/scoped_observation.h"
 #include "base/timer/timer.h"
+#include "chrome/browser/ui/browser_list_observer.h"
 #include "components/keyed_service/core/keyed_service.h"
 
+class BrowserList;
 class Profile;
 
 // This per-profile class holds profile-scoped state for the read anything
 // feature.
-class ReadAnythingService : public KeyedService {
+class ReadAnythingService : public KeyedService, public BrowserListObserver {
  public:
   explicit ReadAnythingService(Profile* profile);
   ~ReadAnythingService() override;
@@ -29,6 +32,9 @@
   void RemoveGDocsHelperExtension();
   void OnLocalSidePanelSwitchDelayTimeout();
 
+  // BrowserListObserver:
+  void OnBrowserSetLastActive(Browser* browser) override;
+
   // The number of active local side panels that are currently shown. If there
   // is no active local side panel (count is 0) after a timeout, we can safely
   // remove the gdocs helper extension.
@@ -40,6 +46,9 @@
   // installations/uninstallations.
   base::RetainingOneShotTimer local_side_panel_switch_delay_timer_;
 
+  base::ScopedObservation<BrowserList, BrowserListObserver>
+      browser_list_observer_{this};
+
   raw_ptr<Profile> profile_;
   base::WeakPtrFactory<ReadAnythingService> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_service_interactive_uitest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_service_interactive_uitest.cc
new file mode 100644
index 0000000..abe19ebe
--- /dev/null
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_service_interactive_uitest.cc
@@ -0,0 +1,35 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ui/browser_element_identifiers.h"
+#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_service.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/interaction/interactive_browser_test.h"
+#include "content/public/test/browser_test.h"
+#include "ui/accessibility/accessibility_features.h"
+
+namespace {
+
+class ReadAnythingServiceDataCollectionCUJTest : public InteractiveBrowserTest {
+ public:
+  ReadAnythingServiceDataCollectionCUJTest() = default;
+  ~ReadAnythingServiceDataCollectionCUJTest() override = default;
+
+  void SetUp() override {
+    scoped_feature_list_.InitAndEnableFeature(
+        features::kDataCollectionModeForScreen2x);
+    InteractiveBrowserTest::SetUp();
+  }
+
+ private:
+  base::test::ScopedFeatureList scoped_feature_list_;
+};
+
+IN_PROC_BROWSER_TEST_F(ReadAnythingServiceDataCollectionCUJTest,
+                       SidePanelOpensAutomatically) {
+  RunTestSequence(WaitForShow(kSidePanelElementId));
+}
+
+}  // namespace
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.cc
index c984de399..673ba69 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller.cc
@@ -14,7 +14,6 @@
 #include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_window/public/browser_window_features.h"
 #include "chrome/browser/ui/views/frame/browser_view.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_service.h"
 #include "chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_web_view.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
diff --git a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_interactive_uitest.cc b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_interactive_uitest.cc
index 5f0a0c7..fffece16 100644
--- a/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_interactive_uitest.cc
+++ b/chrome/browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_interactive_uitest.cc
@@ -15,7 +15,6 @@
 #include "components/feature_engagement/public/feature_constants.h"
 #include "components/user_education/views/help_bubble_view.h"
 #include "content/public/test/browser_test.h"
-#include "read_anything_side_panel_controller.h"
 #include "testing/gmock/include/gmock/gmock.h"
 
 namespace {
diff --git a/chrome/browser/ui/views/side_panel/side_panel_util.cc b/chrome/browser/ui/views/side_panel/side_panel_util.cc
index 933ca51c..d6b90a2d 100644
--- a/chrome/browser/ui/views/side_panel/side_panel_util.cc
+++ b/chrome/browser/ui/views/side_panel/side_panel_util.cc
@@ -18,7 +18,6 @@
 #include "chrome/browser/ui/views/side_panel/bookmarks/bookmarks_side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/companion/companion_utils.h"
 #include "chrome/browser/ui/views/side_panel/history_clusters/history_clusters_side_panel_coordinator.h"
-#include "chrome/browser/ui/views/side_panel/read_anything/read_anything_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/reading_list/reading_list_side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/search_companion/search_companion_side_panel_coordinator.h"
 #include "chrome/browser/ui/views/side_panel/side_panel_content_proxy.h"
diff --git a/chrome/browser/ui/views/webid/account_selection_bubble_view.cc b/chrome/browser/ui/views/webid/account_selection_bubble_view.cc
index 685da9d..9ce6ef7 100644
--- a/chrome/browser/ui/views/webid/account_selection_bubble_view.cc
+++ b/chrome/browser/ui/views/webid/account_selection_bubble_view.cc
@@ -307,13 +307,14 @@
 }
 
 void AccountSelectionBubbleView::ShowMultiAccountPicker(
-    const std::vector<content::IdentityProviderData>& idp_data_list,
+    const std::vector<IdentityRequestAccountPtr>& accounts,
+    const std::vector<IdentityProviderDataPtr>& idp_list,
     bool show_back_button,
     bool is_choose_an_account) {
   // If there are multiple IDPs, then the content::IdentityProviderMetadata
   // passed will be unused since there will be no `header_icon_view_`.
   // Therefore, it is fine to pass the first one into UpdateHeader().
-  DCHECK(idp_data_list.size() == 1u || !header_icon_view_);
+  DCHECK(idp_list.size() == 1u || !header_icon_view_);
   DCHECK(!is_choose_an_account || show_back_button);
   std::u16string title =
       is_choose_an_account
@@ -321,15 +322,15 @@
                                        rp_for_display_)
           : webid::GetTitle(
                 rp_for_display_,
-                idp_data_list.size() > 1u
+                idp_list.size() > 1u
                     ? std::nullopt
                     : std::make_optional<std::u16string>(
-                          base::UTF8ToUTF16(idp_data_list[0].idp_for_display)),
+                          base::UTF8ToUTF16(idp_list[0]->idp_for_display)),
                 rp_context_);
-  UpdateHeader(idp_data_list[0].idp_metadata, title, show_back_button);
+  UpdateHeader(idp_list[0]->idp_metadata, title, show_back_button);
 
   RemoveNonHeaderChildViews();
-  AddSeparatorAndMultipleAccountChooser(idp_data_list);
+  AddSeparatorAndMultipleAccountChooser(accounts, idp_list);
 
   if (!has_sheet_) {
     has_sheet_ = true;
@@ -342,9 +343,8 @@
 
 void AccountSelectionBubbleView::ShowVerifyingSheet(
     const content::IdentityRequestAccount& account,
-    const content::IdentityProviderData& idp_display_data,
     const std::u16string& title) {
-  UpdateHeader(idp_display_data.idp_metadata, title,
+  UpdateHeader(account.identity_provider->idp_metadata, title,
                /*show_back_button=*/false);
 
   RemoveNonHeaderChildViews();
@@ -358,7 +358,7 @@
   row->SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kVertical,
       gfx::Insets::VH(kTopBottomPadding, kLeftRightPadding)));
-  row->AddChildView(CreateAccountRow(account, idp_display_data,
+  row->AddChildView(CreateAccountRow(account,
                                      /*clickable_position=*/std::nullopt,
                                      /*should_include_idp=*/false));
   AddChildView(std::move(row));
@@ -374,16 +374,17 @@
 
 void AccountSelectionBubbleView::ShowSingleAccountConfirmDialog(
     const content::IdentityRequestAccount& account,
-    const content::IdentityProviderData& idp_display_data,
     bool show_back_button) {
   std::u16string title = webid::GetTitle(
-      rp_for_display_, base::UTF8ToUTF16(idp_display_data.idp_for_display),
+      rp_for_display_,
+      base::UTF8ToUTF16(account.identity_provider->idp_for_display),
       rp_context_);
-  UpdateHeader(idp_display_data.idp_metadata, title, show_back_button);
+  UpdateHeader(account.identity_provider->idp_metadata, title,
+               show_back_button);
 
   RemoveNonHeaderChildViews();
   AddChildView(std::make_unique<views::Separator>());
-  AddChildView(CreateSingleAccountChooser(idp_display_data, account));
+  AddChildView(CreateSingleAccountChooser(account));
 
   if (!has_sheet_) {
     has_sheet_ = true;
@@ -529,16 +530,17 @@
 
 void AccountSelectionBubbleView::ShowRequestPermissionDialog(
     const content::IdentityRequestAccount& account,
-    const content::IdentityProviderData& idp_display_data) {
+    const content::IdentityProviderData& idp_data) {
   NOTREACHED_IN_MIGRATION()
       << "ShowRequestPermissionDialog is only implemented for "
          "AccountSelectionModalView";
 }
 
 void AccountSelectionBubbleView::ShowSingleReturningAccountDialog(
-    const std::vector<content::IdentityProviderData>& idp_data_list) {
+    const std::vector<IdentityRequestAccountPtr>& accounts,
+    const std::vector<IdentityProviderDataPtr>& idp_list) {
   // We currently only invoke this method in the multi IDP case.
-  DCHECK(idp_data_list.size() > 1u);
+  DCHECK_GT(idp_list.size(), 1u);
   // Since there are multiple IDPs, then the content::IdentityProviderMetadata
   // passed will be unused since there will be no `header_icon_view_`.
   UpdateHeader(content::IdentityProviderMetadata(),
@@ -547,7 +549,7 @@
 
   RemoveNonHeaderChildViews();
   AddChildView(std::make_unique<views::Separator>());
-  AddChildView(CreateSingleReturningAccountChooser(idp_data_list));
+  AddChildView(CreateSingleReturningAccountChooser(accounts, idp_list));
 
   if (!has_sheet_) {
     has_sheet_ = true;
@@ -705,28 +707,26 @@
 
 std::unique_ptr<views::View>
 AccountSelectionBubbleView::CreateSingleAccountChooser(
-    const content::IdentityProviderData& idp_display_data,
     const content::IdentityRequestAccount& account) {
   auto row = std::make_unique<views::View>();
   row->SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kVertical,
       gfx::Insets::VH(0, kLeftRightPadding), kVerticalSpacing));
-  row->AddChildView(CreateAccountRow(account, idp_display_data,
+  row->AddChildView(CreateAccountRow(account,
                                      /*clickable_position=*/std::nullopt,
                                      /*should_include_idp=*/false));
 
   // Prefer using the given name if it is provided, otherwise fallback to name.
   const std::string display_name =
       account.given_name.empty() ? account.name : account.given_name;
-  const content::IdentityProviderMetadata& idp_metadata =
-      idp_display_data.idp_metadata;
+  const content::IdentityProviderData& idp_data = *account.identity_provider;
+  const content::IdentityProviderMetadata& idp_metadata = idp_data.idp_metadata;
   // We can pass crefs to OnAccountSelected because the `observer_` owns the
   // data.
   auto button = std::make_unique<ContinueButton>(
       base::BindRepeating(
           &AccountSelectionViewBase::Observer::OnAccountSelected,
-          base::Unretained(observer_), std::cref(account),
-          std::cref(idp_display_data)),
+          base::Unretained(observer_), std::cref(account), std::cref(idp_data)),
       l10n_util::GetStringFUTF16(IDS_ACCOUNT_SELECTION_CONTINUE,
                                  base::UTF8ToUTF16(display_name)),
       this, idp_metadata, base::UTF8ToUTF16(account.email));
@@ -735,17 +735,18 @@
   // Do not add disclosure text if this is a sign in or if we were requested
   // to skip it.
   if (account.login_state == Account::LoginState::kSignIn ||
-      idp_display_data.disclosure_fields.empty()) {
+      idp_data.disclosure_fields.empty()) {
     return row;
   }
 
   // Add disclosure text.
-  row->AddChildView(CreateDisclosureLabel(idp_display_data));
+  row->AddChildView(CreateDisclosureLabel(idp_data));
   return row;
 }
 
 void AccountSelectionBubbleView::AddSeparatorAndMultipleAccountChooser(
-    const std::vector<content::IdentityProviderData>& idp_data_list) {
+    const std::vector<IdentityRequestAccountPtr>& accounts,
+    const std::vector<IdentityProviderDataPtr>& idp_list) {
   // We use a separate scroller for accounts vs for mismatches. This allows us
   // to show accounts at the top while still always showing mismatches in the UI
   // before any scrolling occurs.
@@ -756,17 +757,12 @@
       account_scroll_view->SetContents(std::make_unique<views::View>());
   accounts_content->SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kVertical));
-  bool is_multi_idp = idp_data_list.size() > 1u;
-  // Add returning accounts first and then other accounts.
-  int position = 0;
-  AddSignInAccounts(idp_data_list, accounts_content, position);
-  AddAccounts(idp_data_list, accounts_content, Account::LoginState::kSignUp,
-              position);
-  size_t num_account_rows = 0;
-  for (const auto& idp_display_data : idp_data_list) {
-    num_account_rows += idp_display_data.accounts.size();
+  bool is_multi_idp = idp_list.size() > 1u;
+  AddAccounts(accounts, accounts_content, is_multi_idp);
+  size_t num_account_rows = accounts.size();
+  for (const auto& idp_data : idp_list) {
     const content::IdentityProviderMetadata& idp_metadata =
-        idp_display_data.idp_metadata;
+        idp_data->idp_metadata;
     if (idp_metadata.supports_add_account) {
       accounts_content->AddChildView(std::make_unique<views::Separator>());
       accounts_content->AddChildView(CreateUseOtherAccountButton(idp_metadata));
@@ -811,12 +807,11 @@
 
   // Add mismatch rows.
   size_t num_mismatch_rows = 0;
-  for (const auto& idp_display_data : idp_data_list) {
-    if (idp_display_data.has_login_status_mismatch) {
-      DCHECK(idp_display_data.accounts.empty());
+  for (const auto& idp_data : idp_list) {
+    if (idp_data->has_login_status_mismatch) {
       mismatch_content->AddChildView(
-          CreateIdpLoginRow(base::UTF8ToUTF16(idp_display_data.idp_for_display),
-                            idp_display_data.idp_metadata));
+          CreateIdpLoginRow(base::UTF8ToUTF16(idp_data->idp_for_display),
+                            idp_data->idp_metadata));
       num_mismatch_rows += 1;
     }
   }
@@ -863,65 +858,22 @@
 }
 
 void AccountSelectionBubbleView::AddAccounts(
-    const std::vector<content::IdentityProviderData>& idp_data_list,
+    const std::vector<IdentityRequestAccountPtr>& accounts,
     views::View* accounts_content,
-    Account::LoginState login_state,
-    int& out_position) {
-  bool is_multi_idp = idp_data_list.size() > 1u;
-  for (const auto& idp_display_data : idp_data_list) {
-    for (const auto& account : idp_display_data.accounts) {
-      if (account.login_state == login_state) {
-        accounts_content->AddChildView(CreateAccountRow(
-            account, idp_display_data, /*clickable_position=*/out_position++,
-            /*should_include_idp=*/is_multi_idp));
-      }
-    }
-  }
-}
-
-void AccountSelectionBubbleView::AddSignInAccounts(
-    const std::vector<content::IdentityProviderData>& idp_data_list,
-    views::View* accounts_content,
-    int& out_position) {
-  bool is_multi_idp = idp_data_list.size() > 1u;
+    bool is_multi_idp) {
+  int out_position = 0;
   if (!is_multi_idp) {
-    // Optimization for single IDP case: no need to re-sort accounts.
-    AddAccounts(idp_data_list, accounts_content, Account::LoginState::kSignIn,
-                out_position);
+    for (const auto& account : accounts) {
+      accounts_content->AddChildView(
+          CreateAccountRow(*account, /*clickable_position=*/out_position++,
+                           /*should_include_idp=*/false));
+    }
     return;
   }
-
-  // Even though accounts are sorted in each IDP, we want to show accounts in
-  // order of timestamps, so we need to re-sort them in the multi IDP case. So
-  // we add all returning accounts and sort them by last used timestamp. Note:
-  // we avoid copying accounts and IDP data by storing pointers. It would be
-  // incorrect to copy them as otherwise they would be destroyed at the end of
-  // this method call since CreateAccountRow() does not take ownership.
-  std::vector<std::pair<const Account*, const content::IdentityProviderData*>>
-      sorted_accounts;
-  for (const auto& idp_display_data : idp_data_list) {
-    for (const auto& account : idp_display_data.accounts) {
-      if (account.login_state == Account::LoginState::kSignIn) {
-        sorted_accounts.emplace_back(&account, &idp_display_data);
-      }
-    }
-  }
-  std::stable_sort(sorted_accounts.begin(), sorted_accounts.end(),
-                   [](const auto& a, const auto& b) {
-                     if (!a.first->last_used_timestamp) {
-                       return false;
-                     }
-                     if (!b.first->last_used_timestamp) {
-                       return true;
-                     }
-                     return *a.first->last_used_timestamp >
-                            *b.first->last_used_timestamp;
-                   });
-
   std::optional<base::Time> now;
-  for (const auto& pair : sorted_accounts) {
+  for (const auto& account : accounts) {
     std::optional<std::u16string> last_used_string;
-    if (pair.first->last_used_timestamp) {
+    if (account->last_used_timestamp) {
       // For the most recently used account, we want to show "last used on this
       // site" while for all other accounts we want to show timing regarding
       // when it was last used ("last used 1 month ago"). |now| is set when the
@@ -934,8 +886,8 @@
       } else {
         // ui::TimeFormat::SimpleWithMonthAndYear does not support negative
         // values, so if the value is negative, make it 0.
-        base::TimeDelta delta = std::max(
-            *now - *pair.first->last_used_timestamp, base::TimeDelta());
+        base::TimeDelta delta =
+            std::max(*now - *account->last_used_timestamp, base::TimeDelta());
         last_used_string = l10n_util::GetStringFUTF16(
             IDS_MULTI_IDP_ACCOUNT_USED_TIME_AGO,
             ui::TimeFormat::SimpleWithMonthAndYear(
@@ -943,38 +895,28 @@
                 delta, true));
       }
     }
-    accounts_content->AddChildView(CreateAccountRow(
-        *pair.first, *pair.second, /*clickable_position=*/out_position++,
-        /*should_include_idp=*/is_multi_idp, /*is_modal_dialog=*/false,
-        /*additional_vertical_padding=*/0, last_used_string));
+    accounts_content->AddChildView(
+        CreateAccountRow(*account, /*clickable_position=*/out_position++,
+                         /*should_include_idp=*/true, /*is_modal_dialog=*/false,
+                         /*additional_vertical_padding=*/0, last_used_string));
   }
 }
 
 std::unique_ptr<views::View>
 AccountSelectionBubbleView::CreateSingleReturningAccountChooser(
-    const std::vector<content::IdentityProviderData>& idp_data_list) {
+    const std::vector<IdentityRequestAccountPtr>& accounts,
+    const std::vector<IdentityProviderDataPtr>& idp_list) {
   std::vector<std::u16string> mismatch_idps;
   std::vector<std::u16string> non_mismatch_idps;
-  const content::IdentityRequestAccount* returning_account = nullptr;
-  const content::IdentityProviderData* returning_idp = nullptr;
-  for (const auto& idp : idp_data_list) {
-    if (idp.has_login_status_mismatch) {
-      mismatch_idps.push_back(base::UTF8ToUTF16(idp.idp_for_display));
+  for (const auto& idp : idp_list) {
+    if (idp->has_login_status_mismatch) {
+      mismatch_idps.push_back(base::UTF8ToUTF16(idp->idp_for_display));
     } else {
-      non_mismatch_idps.push_back(base::UTF8ToUTF16(idp.idp_for_display));
-    }
-    if (returning_account) {
-      continue;
-    }
-    for (const auto& acc : idp.accounts) {
-      if (acc.login_state == Account::LoginState::kSignIn) {
-        returning_account = &acc;
-        returning_idp = &idp;
-        break;
-      }
+      non_mismatch_idps.push_back(base::UTF8ToUTF16(idp->idp_for_display));
     }
   }
-  CHECK(returning_account && returning_idp);
+  CHECK(!accounts.empty() &&
+        accounts[0]->login_state == Account::LoginState::kSignIn);
   auto content = std::make_unique<views::View>();
   // Add spacing at the top to make the total spacing between it and the
   // separator be kVertical spacing, and also add kVertical spacing between
@@ -984,11 +926,11 @@
       gfx::Insets::TLBR(kVerticalSpacing - kTopBottomPadding, 0, 0, 0),
       kVerticalSpacing));
   std::optional<std::u16string> last_used_string =
-      returning_account->last_used_timestamp
+      accounts[0]->last_used_timestamp
           ? std::make_optional<std::u16string>(l10n_util::GetStringUTF16(
                 IDS_MULTI_IDP_ACCOUNT_LAST_USED_ON_THIS_SITE))
           : std::nullopt;
-  content->AddChildView(CreateAccountRow(*returning_account, *returning_idp,
+  content->AddChildView(CreateAccountRow(*accounts[0],
                                          /*clickable_position=*/0,
                                          /*should_include_idp=*/true,
                                          /*is_modal_dialog=*/false,
diff --git a/chrome/browser/ui/views/webid/account_selection_bubble_view.h b/chrome/browser/ui/views/webid/account_selection_bubble_view.h
index 730ff69..cc81f0d 100644
--- a/chrome/browser/ui/views/webid/account_selection_bubble_view.h
+++ b/chrome/browser/ui/views/webid/account_selection_bubble_view.h
@@ -17,6 +17,9 @@
 #include "ui/views/bubble/bubble_dialog_delegate_view.h"
 #include "ui/views/view.h"
 
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
 using TokenError = content::IdentityCredentialTokenError;
 
 namespace views {
@@ -49,16 +52,15 @@
   void InitDialogWidget() override;
 
   void ShowMultiAccountPicker(
-      const std::vector<content::IdentityProviderData>& idp_data_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
       bool show_back_button,
       bool is_choose_an_account) override;
   void ShowVerifyingSheet(const content::IdentityRequestAccount& account,
-                          const content::IdentityProviderData& idp_display_data,
                           const std::u16string& title) override;
 
   void ShowSingleAccountConfirmDialog(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_display_data,
       bool show_back_button) override;
 
   void ShowFailureDialog(
@@ -71,10 +73,11 @@
 
   void ShowRequestPermissionDialog(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_display_data) override;
+      const content::IdentityProviderData& idp_data) override;
 
   void ShowSingleReturningAccountDialog(
-      const std::vector<content::IdentityProviderData>& idp_data_list) override;
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list) override;
 
   void ShowLoadingDialog() override;
 
@@ -99,41 +102,29 @@
 
   // Returns a View for single account chooser. It contains the account
   // information, disclosure text and a button for the user to confirm the
-  // selection. The size of the `idp_display_data.accounts` vector must be 1.
+  // selection.
   std::unique_ptr<views::View> CreateSingleAccountChooser(
-      const content::IdentityProviderData& idp_display_data,
       const content::IdentityRequestAccount& account);
 
   // Adds a separator as well as a multiple account chooser. The chooser
   // contains the info for each account in a button, so the user can pick an
   // account. It also contains mismatch login URLs in the multiple IDP case.
   void AddSeparatorAndMultipleAccountChooser(
-      const std::vector<content::IdentityProviderData>& idp_data_list);
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list);
 
-  // Adds the accounts matching the provided LoginState to the given view. This
-  // method does not reorder the accounts, and assumes they are provided in the
-  // correct order. Updates `out_position` to 1 + the last position of the
-  // accounts added.
-  void AddAccounts(
-      const std::vector<content::IdentityProviderData>& idp_data_list,
-      views::View* accounts_content,
-      content::IdentityRequestAccount::LoginState login_state,
-      int& out_position);
-
-  // Adds the signin accounts to the given view. In case there are multiple
-  // IDPs, the accounts are ordered first so that most recently used ones are
-  // used first. In the other case, AddAccounts() can be invoked directly.
-  // Updates `out_position` to 1 + the last position of the accounts added.
-  void AddSignInAccounts(
-      const std::vector<content::IdentityProviderData>& idp_data_list,
-      views::View* accounts_content,
-      int& out_position);
+  // Adds the accounts provided to the given view. This method does not reorder
+  // the accounts, and assumes they are provided in the correct order.
+  void AddAccounts(const std::vector<IdentityRequestAccountPtr>& accounts,
+                   views::View* accounts_content,
+                   bool is_multi_idp);
 
   // Returns a View containing a single returning account as well as a button to
   // 'choose an account' which will show all accounts and IDPs that are
   // available.
   std::unique_ptr<views::View> CreateSingleReturningAccountChooser(
-      const std::vector<content::IdentityProviderData>& idp_data_list);
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list);
 
   // Returns a view containing a button for the user to login to an IDP for
   // which there was a login status mismatch, to be used in the multiple account
diff --git a/chrome/browser/ui/views/webid/account_selection_bubble_view_unittest.cc b/chrome/browser/ui/views/webid/account_selection_bubble_view_unittest.cc
index 56cf8cdc..638c4c8 100644
--- a/chrome/browser/ui/views/webid/account_selection_bubble_view_unittest.cc
+++ b/chrome/browser/ui/views/webid/account_selection_bubble_view_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/ui/views/webid/account_selection_bubble_view.h"
 
+#include <array>
 #include <string>
 
 #include "base/feature_list.h"
@@ -42,12 +43,26 @@
 #include "ui/views/view.h"
 #include "ui/views/view_utils.h"
 
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
 using LoginState = content::IdentityRequestAccount::LoginState;
 
+namespace {
+constexpr char kAccountSuffix[] = "suffix";
+}  // namespace
+
 class AccountSelectionBubbleViewTest : public ChromeViewsTestBase,
                                        public AccountSelectionViewTestBase {
  public:
-  AccountSelectionBubbleViewTest() = default;
+  AccountSelectionBubbleViewTest()
+      : idp_data_(base::MakeRefCounted<content::IdentityProviderData>(
+            kIdpForDisplay,
+            content::IdentityProviderMetadata(),
+            CreateTestClientMetadata(kTermsOfServiceUrl),
+            blink::mojom::RpContext::kSignIn,
+            kDefaultDisclosureFields,
+            /*has_login_status_mismatch=*/false)) {}
 
  protected:
   void CreateAccountSelectionBubble(bool exclude_title) {
@@ -70,45 +85,35 @@
   }
 
   void CreateAndShowSingleAccountPicker(
-      bool show_back_button,
-      const content::IdentityRequestAccount& account,
-      const content::IdentityProviderMetadata& idp_metadata,
-      const std::string& terms_of_service_url,
-      const std::vector<content::IdentityRequestDialogDisclosureField>&
-          disclosure_fields = kDefaultDisclosureFields) {
+      LoginState login_state = LoginState::kSignUp) {
+    IdentityRequestAccountPtr account = CreateTestIdentityRequestAccount(
+        kAccountSuffix, idp_data_, login_state);
+
     CreateAccountSelectionBubble(/*exclude_title=*/false);
-    content::IdentityProviderData idp_data(
-        kIdpForDisplay, {account}, idp_metadata,
-        CreateTestClientMetadata(terms_of_service_url),
-        blink::mojom::RpContext::kSignIn, disclosure_fields,
-        /*has_login_status_mismatch=*/false);
-    dialog_->ShowSingleAccountConfirmDialog(
-        account, idp_data, show_back_button);
+    account->identity_provider = idp_data_;
+    dialog_->ShowSingleAccountConfirmDialog(*account,
+                                            /*show_back_button=*/false);
   }
 
   void CreateAndShowMultiAccountPicker(
       const std::vector<std::string>& account_suffixes,
       bool supports_add_account = false) {
-    std::vector<content::IdentityRequestAccount> account_list =
-        CreateTestIdentityRequestAccounts(account_suffixes);
+    idp_data_->idp_metadata.supports_add_account = supports_add_account;
+    std::vector<IdentityRequestAccountPtr> account_list =
+        CreateTestIdentityRequestAccounts(account_suffixes, idp_data_);
 
     CreateAccountSelectionBubble(/*exclude_title=*/false);
-    std::vector<content::IdentityProviderData> idp_data;
-    content::IdentityProviderMetadata metadata;
-    metadata.supports_add_account = supports_add_account;
-    idp_data.emplace_back(kIdpForDisplay, account_list, metadata,
-                          CreateTestClientMetadata(/*terms_of_service_url=*/""),
-                          blink::mojom::RpContext::kSignIn,
-                          kDefaultDisclosureFields,
-                          /*has_login_status_mismatch=*/false);
-    dialog_->ShowMultiAccountPicker(idp_data, /*show_back_button=*/false,
+    dialog_->ShowMultiAccountPicker(account_list, {idp_data_},
+                                    /*show_back_button=*/false,
                                     /*is_choose_an_account=*/false);
   }
 
   void CreateAndShowMultiIdpAccountPicker(
-      const std::vector<content::IdentityProviderData>& idp_data_list) {
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list) {
     CreateAccountSelectionBubble(/*exclude_title=*/true);
-    dialog_->ShowMultiAccountPicker(idp_data_list, /*show_back_button=*/false,
+    dialog_->ShowMultiAccountPicker(accounts, idp_list,
+                                    /*show_back_button=*/false,
                                     /*is_choose_an_account=*/false);
   }
 
@@ -213,12 +218,7 @@
 
   void TestSingleAccount(const std::u16string expected_title,
                          bool expect_idp_brand_icon_in_header) {
-    const std::string kAccountSuffix = "suffix";
-    content::IdentityRequestAccount account(
-        CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignUp));
-    CreateAndShowSingleAccountPicker(
-        /*show_back_button=*/false, account,
-        content::IdentityProviderMetadata(), kTermsOfServiceUrl);
+    CreateAndShowSingleAccountPicker();
 
     std::vector<raw_ptr<views::View, VectorExperimental>> children =
         dialog()->children();
@@ -273,10 +273,6 @@
 
   void TestFailureDialog(const std::u16string expected_title,
                          bool expect_idp_brand_icon_in_header) {
-    const std::string kAccountSuffix = "suffix";
-    content::IdentityRequestAccount account =
-        CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignIn);
-
     CreateAccountSelectionBubble(
         /*exclude_title=*/false);
     dialog_->ShowFailureDialog(
@@ -451,6 +447,8 @@
 
   raw_ptr<AccountSelectionBubbleView, DanglingUntriaged> dialog_;
 
+  IdentityProviderDataPtr idp_data_;
+
  private:
   base::test::ScopedFeatureList feature_list_;
   TestingProfile profile_;
@@ -471,12 +469,8 @@
 }
 
 TEST_F(AccountSelectionBubbleViewTest, SingleAccountNoTermsOfService) {
-  const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account =
-      CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignUp);
-  CreateAndShowSingleAccountPicker(
-      /*show_back_button=*/false, account, content::IdentityProviderMetadata(),
-      /*terms_of_service_url=*/"");
+  idp_data_->client_metadata.terms_of_service_url = GURL("");
+  CreateAndShowSingleAccountPicker();
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -502,15 +496,11 @@
 }
 
 TEST_F(AccountSelectionBubbleViewTest, SingleAccountOnlyTwoDisclosureFields) {
-  const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account =
-      CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignUp);
-  std::vector<content::IdentityRequestDialogDisclosureField> fields = {
+  idp_data_->disclosure_fields = {
       content::IdentityRequestDialogDisclosureField::kName,
       content::IdentityRequestDialogDisclosureField::kEmail};
-  CreateAndShowSingleAccountPicker(
-      /*show_back_button=*/false, account, content::IdentityProviderMetadata(),
-      /*terms_of_service_url=*/"", fields);
+  idp_data_->client_metadata.terms_of_service_url = GURL();
+  CreateAndShowSingleAccountPicker();
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -565,12 +555,7 @@
 }
 
 TEST_F(AccountSelectionBubbleViewTest, ReturningAccount) {
-  const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account =
-      CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignIn);
-  CreateAndShowSingleAccountPicker(
-      /*show_back_button=*/false, account, content::IdentityProviderMetadata(),
-      /*terms_of_service_url=*/"");
+  CreateAndShowSingleAccountPicker(LoginState::kSignIn);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -596,12 +581,8 @@
 }
 
 TEST_F(AccountSelectionBubbleViewTest, NewAccountWithoutRequestPermission) {
-  const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account =
-      CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignUp);
-  CreateAndShowSingleAccountPicker(
-      /*show_back_button=*/false, account, content::IdentityProviderMetadata(),
-      /*terms_of_service_url=*/"", /*disclosure_fields=*/{});
+  idp_data_->disclosure_fields = {};
+  CreateAndShowSingleAccountPicker();
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -628,10 +609,6 @@
 
 TEST_F(AccountSelectionBubbleViewTest,
        ContinueButtonWithProperBackgroundColor) {
-  const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account =
-      CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignIn);
-
   CreateAccountSelectionBubble(/*exclude_title=*/false);
 
   // Set the dialog background color to white.
@@ -641,17 +618,11 @@
   SkColor bg_color;
   // A blue background sufficiently contracts with the dialog background.
   content::ParseCssColorString(kDarkBlue, &bg_color);
-  content::IdentityProviderMetadata idp_metadata =
-      content::IdentityProviderMetadata();
-  idp_metadata.brand_background_color = SkColorSetA(bg_color, 0xff);
+  idp_data_->idp_metadata.brand_background_color = SkColorSetA(bg_color, 0xff);
+  IdentityRequestAccountPtr account = CreateTestIdentityRequestAccount(
+      kAccountSuffix, idp_data_, LoginState::kSignIn);
 
-  content::IdentityProviderData idp_data(
-      kIdpForDisplay, {account}, idp_metadata,
-      CreateTestClientMetadata(/*terms_of_service_url=*/""),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
-
-  dialog()->ShowSingleAccountConfirmDialog(account, idp_data,
+  dialog()->ShowSingleAccountConfirmDialog(*account,
                                            /*show_back_button=*/false);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
@@ -671,10 +642,6 @@
 
 TEST_F(AccountSelectionBubbleViewTest,
        ContinueButtonWithImproperBackgroundColor) {
-  const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account =
-      CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignIn);
-
   CreateAccountSelectionBubble(/*exclude_title=*/false);
 
   // Set the dialog background color to white.
@@ -687,15 +654,11 @@
   content::ParseCssColorString(kWhite, &bg_color);
   content::IdentityProviderMetadata idp_metadata =
       content::IdentityProviderMetadata();
-  idp_metadata.brand_background_color = SkColorSetA(bg_color, 0xff);
+  idp_data_->idp_metadata.brand_background_color = SkColorSetA(bg_color, 0xff);
+  IdentityRequestAccountPtr account = CreateTestIdentityRequestAccount(
+      kAccountSuffix, idp_data_, LoginState::kSignIn);
 
-  content::IdentityProviderData idp_data(
-      kIdpForDisplay, {account}, idp_metadata,
-      CreateTestClientMetadata(/*terms_of_service_url=*/""),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
-
-  dialog()->ShowSingleAccountConfirmDialog(account, idp_data,
+  dialog()->ShowSingleAccountConfirmDialog(*account,
                                            /*show_back_button=*/false);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
@@ -715,18 +678,12 @@
 }
 
 TEST_F(AccountSelectionBubbleViewTest, Verifying) {
-  const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account =
-      CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignIn);
-  content::IdentityProviderData idp_data(
-      kIdpForDisplay, {account}, content::IdentityProviderMetadata(),
-      content::ClientMetadata(GURL(), GURL(), GURL()),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
+  IdentityRequestAccountPtr account = CreateTestIdentityRequestAccount(
+      kAccountSuffix, idp_data_, LoginState::kSignIn);
 
   CreateAccountSelectionBubble(/*exclude_title=*/false);
   dialog_->ShowVerifyingSheet(
-      account, idp_data, l10n_util::GetStringUTF16(IDS_VERIFY_SHEET_TITLE));
+      *account, l10n_util::GetStringUTF16(IDS_VERIFY_SHEET_TITLE));
 
   const std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -741,19 +698,12 @@
 }
 
 TEST_F(AccountSelectionBubbleViewTest, VerifyingForAutoReauthn) {
-  const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account =
-      CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignIn);
-  content::IdentityProviderData idp_data(
-      kIdpForDisplay, {account}, content::IdentityProviderMetadata(),
-      content::ClientMetadata(GURL(), GURL(), GURL()),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
-
+  IdentityRequestAccountPtr account = CreateTestIdentityRequestAccount(
+      kAccountSuffix, idp_data_, LoginState::kSignIn);
   CreateAccountSelectionBubble(/*exclude_title=*/false);
   const auto title =
       l10n_util::GetStringUTF16(IDS_VERIFY_SHEET_TITLE_AUTO_REAUTHN);
-  dialog_->ShowVerifyingSheet(account, idp_data, title);
+  dialog_->ShowVerifyingSheet(*account, title);
 
   const std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -809,22 +759,23 @@
        MultipleAccountsMultipleIdps) {
   const std::vector<std::string> kAccountSuffixes1 = {"1", "2"};
   const std::vector<std::string> kAccountSuffixes2 = {"3", "4"};
-  std::vector<content::IdentityProviderData> idp_data;
-  std::vector<Account> accounts_first_idp =
-      CreateTestIdentityRequestAccounts(kAccountSuffixes1);
-  idp_data.emplace_back(
-      kIdpForDisplay, accounts_first_idp, content::IdentityProviderMetadata(),
-      CreateTestClientMetadata(kTermsOfServiceUrl),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
-  idp_data.emplace_back(kSecondIdpForDisplay,
-                        CreateTestIdentityRequestAccounts(kAccountSuffixes2),
-                        content::IdentityProviderMetadata(),
-                        CreateTestClientMetadata("https://tos-2.com"),
-                        blink::mojom::RpContext::kSignIn,
-                        kDefaultDisclosureFields,
-                        /*has_login_status_mismatch=*/false);
-  CreateAndShowMultiIdpAccountPicker(idp_data);
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata(kTermsOfServiceUrl),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kSecondIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata("https://tos-2.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false)};
+  std::vector<IdentityRequestAccountPtr> account_list = {
+      CreateTestIdentityRequestAccount(kAccountSuffixes1[0], idp_list[0]),
+      CreateTestIdentityRequestAccount(kAccountSuffixes1[1], idp_list[0]),
+      CreateTestIdentityRequestAccount(kAccountSuffixes2[0], idp_list[1]),
+      CreateTestIdentityRequestAccount(kAccountSuffixes2[1], idp_list[1])};
+  CreateAndShowMultiIdpAccountPicker(account_list, idp_list);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -850,23 +801,20 @@
 
 TEST_F(MultipleIdpAccountSelectionBubbleViewTest, OneIdpWithMismatch) {
   const std::vector<std::string> kAccountSuffixes1 = {"1", "2"};
-  std::vector<content::IdentityProviderData> idp_data;
-  std::vector<Account> accounts_first_idp =
-      CreateTestIdentityRequestAccounts(kAccountSuffixes1);
-  idp_data.emplace_back(
-      kIdpForDisplay, accounts_first_idp, content::IdentityProviderMetadata(),
-      CreateTestClientMetadata(kTermsOfServiceUrl),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
-  idp_data.emplace_back(kSecondIdpForDisplay,
-                        CreateTestIdentityRequestAccounts(
-                            /*account_suffixes=*/{}),
-                        content::IdentityProviderMetadata(),
-                        CreateTestClientMetadata("https://tos-2.com"),
-                        blink::mojom::RpContext::kSignIn,
-                        kDefaultDisclosureFields,
-                        /*has_login_status_mismatch=*/true);
-  CreateAndShowMultiIdpAccountPicker(idp_data);
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata(kTermsOfServiceUrl),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kSecondIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata("https://tos-2.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/true)};
+  std::vector<IdentityRequestAccountPtr> accounts_list =
+      CreateTestIdentityRequestAccounts(kAccountSuffixes1, idp_list[0]);
+  CreateAndShowMultiIdpAccountPicker(accounts_list, idp_list);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -893,24 +841,25 @@
 TEST_F(MultipleIdpAccountSelectionBubbleViewTest, MultiIdpUseOtherAccount) {
   const std::vector<std::string> kAccountSuffixes1 = {"1", "2"};
   const std::vector<std::string> kAccountSuffixes2 = {"3"};
-  std::vector<content::IdentityProviderData> idp_data;
-  std::vector<Account> accounts_first_idp =
-      CreateTestIdentityRequestAccounts(kAccountSuffixes1);
   content::IdentityProviderMetadata idp_with_supports_add =
       content::IdentityProviderMetadata();
   idp_with_supports_add.supports_add_account = true;
-  idp_data.emplace_back(
-      kIdpForDisplay, accounts_first_idp, idp_with_supports_add,
-      CreateTestClientMetadata(kTermsOfServiceUrl),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
-  idp_data.emplace_back(
-      kSecondIdpForDisplay,
-      CreateTestIdentityRequestAccounts(kAccountSuffixes2),
-      idp_with_supports_add, CreateTestClientMetadata("https://tos-2.com"),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
-  CreateAndShowMultiIdpAccountPicker(idp_data);
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kIdpForDisplay, idp_with_supports_add,
+          CreateTestClientMetadata(kTermsOfServiceUrl),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kSecondIdpForDisplay, idp_with_supports_add,
+          CreateTestClientMetadata("https://tos-2.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false)};
+  std::vector<IdentityRequestAccountPtr> accounts_list = {
+      CreateTestIdentityRequestAccount(kAccountSuffixes1[0], idp_list[0]),
+      CreateTestIdentityRequestAccount(kAccountSuffixes1[1], idp_list[0]),
+      CreateTestIdentityRequestAccount(kAccountSuffixes2[0], idp_list[1])};
+  CreateAndShowMultiIdpAccountPicker(accounts_list, idp_list);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -940,36 +889,34 @@
        ShowSingleReturningAccountDialog) {
   const std::vector<std::string> kAccountSuffixes1 = {"1", "2"};
   const std::vector<std::string> kAccountSuffixes2 = {"3"};
-  std::vector<content::IdentityProviderData> idp_data;
-  std::vector<Account> accounts_first_idp =
-      CreateTestIdentityRequestAccounts(kAccountSuffixes1);
-  idp_data.emplace_back(
-      kIdpForDisplay, accounts_first_idp, content::IdentityProviderMetadata(),
-      CreateTestClientMetadata(kTermsOfServiceUrl),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
-  idp_data.emplace_back(kSecondIdpForDisplay,
-                        CreateTestIdentityRequestAccounts(
-                            kAccountSuffixes2, {LoginState::kSignIn}),
-                        content::IdentityProviderMetadata(),
-                        CreateTestClientMetadata("https://tos-2.com"),
-                        blink::mojom::RpContext::kSignIn,
-                        kDefaultDisclosureFields,
-                        /*has_login_status_mismatch=*/false);
-  idp_data.emplace_back(
-      "idp3.com", CreateTestIdentityRequestAccounts(/*account_suffixes=*/{}),
-      content::IdentityProviderMetadata(),
-      CreateTestClientMetadata("https://tos-3.com"),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/true);
-  idp_data.emplace_back(
-      "idp4.com", CreateTestIdentityRequestAccounts(/*account_suffixes=*/{}),
-      content::IdentityProviderMetadata(),
-      CreateTestClientMetadata("https://tos-4.com"),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/true);
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata(kTermsOfServiceUrl),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kSecondIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata("https://tos-2.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          "idp3.com", content::IdentityProviderMetadata(),
+          CreateTestClientMetadata("https://tos-3.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/true),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          "idp4.com", content::IdentityProviderMetadata(),
+          CreateTestClientMetadata("https://tos-4.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/true)};
+  std::vector<IdentityRequestAccountPtr> accounts_list = {
+      CreateTestIdentityRequestAccount(kAccountSuffixes2[0], idp_list[1],
+                                       LoginState::kSignIn),
+      CreateTestIdentityRequestAccount(kAccountSuffixes1[0], idp_list[0]),
+      CreateTestIdentityRequestAccount(kAccountSuffixes1[1], idp_list[0])};
   CreateAccountSelectionBubble(/*exclude_title=*/true);
-  dialog_->ShowSingleReturningAccountDialog(idp_data);
+  dialog_->ShowSingleReturningAccountDialog(accounts_list, idp_list);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -999,7 +946,8 @@
                        u"idp3.com, idp4.com, idp-example.com");
 
   // Simulate clicking on the choose an account button.
-  dialog_->ShowMultiAccountPicker(idp_data, /*show_back_button=*/true,
+  dialog_->ShowMultiAccountPicker(accounts_list, idp_list,
+                                  /*show_back_button=*/true,
                                   /*is_choose_an_account=*/true);
 
   children = dialog()->children();
@@ -1014,22 +962,19 @@
 }
 
 TEST_F(MultipleIdpAccountSelectionBubbleViewTest, MultiIdpWithAllIdpsMismatch) {
-  std::vector<content::IdentityProviderData> idp_data;
-  idp_data.emplace_back(
-      kIdpForDisplay,
-      CreateTestIdentityRequestAccounts(/*account_suffixes=*/{}),
-      content::IdentityProviderMetadata(),
-      CreateTestClientMetadata(kTermsOfServiceUrl),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/true);
-  idp_data.emplace_back(
-      kSecondIdpForDisplay,
-      CreateTestIdentityRequestAccounts(/*account_suffixes=*/{}),
-      content::IdentityProviderMetadata(),
-      CreateTestClientMetadata("https://tos-2.com"),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/true);
-  CreateAndShowMultiIdpAccountPicker(idp_data);
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata(kTermsOfServiceUrl),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/true),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kSecondIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata("https://tos-2.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/true)};
+  CreateAndShowMultiIdpAccountPicker(std::vector<IdentityRequestAccountPtr>(),
+                                     idp_list);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -1048,26 +993,28 @@
 }
 
 TEST_F(MultipleIdpAccountSelectionBubbleViewTest, MultipleReturningAccounts) {
-  const std::vector<std::string> kAccountSuffixes1 = {"new1", "returning1"};
-  const std::vector<std::string> kAccountSuffixes2 = {"new2", "returning2"};
-  std::vector<content::IdentityProviderData> idp_data;
-  std::vector<Account> accounts_first_idp = CreateTestIdentityRequestAccounts(
-      kAccountSuffixes1, {LoginState::kSignUp, LoginState::kSignIn});
-  idp_data.emplace_back(
-      kIdpForDisplay, accounts_first_idp, content::IdentityProviderMetadata(),
-      CreateTestClientMetadata(kTermsOfServiceUrl),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata(kTermsOfServiceUrl),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kSecondIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata("https://tos-2.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false)};
+  // The UI code receives the accounts sorted in the order in which they should
+  // be displayed.
+  std::vector<IdentityRequestAccountPtr> accounts_list = {
+      CreateTestIdentityRequestAccount("returning1", idp_list[0],
+                                       LoginState::kSignIn),
+      CreateTestIdentityRequestAccount("returning2", idp_list[1],
+                                       LoginState::kSignIn),
+      CreateTestIdentityRequestAccount("new1", idp_list[0]),
+      CreateTestIdentityRequestAccount("new2", idp_list[1])};
 
-  std::vector<Account> accounts_second_idp = CreateTestIdentityRequestAccounts(
-      kAccountSuffixes2, {LoginState::kSignUp, LoginState::kSignIn});
-  idp_data.emplace_back(kSecondIdpForDisplay, accounts_second_idp,
-                        content::IdentityProviderMetadata(),
-                        CreateTestClientMetadata("https://tos-2.com"),
-                        blink::mojom::RpContext::kSignIn,
-                        kDefaultDisclosureFields,
-                        /*has_login_status_mismatch=*/false);
-  CreateAndShowMultiIdpAccountPicker(idp_data);
+  CreateAndShowMultiIdpAccountPicker(accounts_list, idp_list);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -1095,29 +1042,35 @@
                                                       "returning2"};
   const std::vector<std::string> kAccountSuffixes2 = {"new2", "returning3",
                                                       "returning4"};
-  std::vector<content::IdentityProviderData> idp_data;
-  std::vector<Account> accounts_first_idp = CreateTestIdentityRequestAccounts(
-      kAccountSuffixes1,
-      {LoginState::kSignUp, LoginState::kSignIn, LoginState::kSignIn},
-      {std::nullopt, base::Time() + base::Microseconds(1), base::Time()});
-  idp_data.emplace_back(
-      kIdpForDisplay, accounts_first_idp, content::IdentityProviderMetadata(),
-      CreateTestClientMetadata(kTermsOfServiceUrl),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata(kTermsOfServiceUrl),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kSecondIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata("https://tos-2.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false)};
+  // Note that `new2` is last despite having last_used_timestamp because it is
+  // not considered a returning account.
+  std::vector<IdentityRequestAccountPtr> accounts_list = {
+      CreateTestIdentityRequestAccount("returning3", idp_list[1],
+                                       LoginState::kSignIn,
+                                       base::Time() + base::Microseconds(2)),
+      CreateTestIdentityRequestAccount("returning1", idp_list[0],
+                                       LoginState::kSignIn,
+                                       base::Time() + base::Microseconds(1)),
+      CreateTestIdentityRequestAccount("returning2", idp_list[0],
+                                       LoginState::kSignIn, base::Time()),
+      CreateTestIdentityRequestAccount("returning4", idp_list[1],
+                                       LoginState::kSignIn, base::Time()),
+      CreateTestIdentityRequestAccount("new1", idp_list[0]),
+      CreateTestIdentityRequestAccount("new2", idp_list[1], LoginState::kSignUp,
+                                       base::Time() + base::Microseconds(3))};
 
-  std::vector<Account> accounts_second_idp = CreateTestIdentityRequestAccounts(
-      kAccountSuffixes2,
-      {LoginState::kSignUp, LoginState::kSignIn, LoginState::kSignIn},
-      {base::Time() + base::Microseconds(3),
-       base::Time() + base::Microseconds(2), base::Time()});
-  idp_data.emplace_back(kSecondIdpForDisplay, accounts_second_idp,
-                        content::IdentityProviderMetadata(),
-                        CreateTestClientMetadata("https://tos-2.com"),
-                        blink::mojom::RpContext::kSignIn,
-                        kDefaultDisclosureFields,
-                        /*has_login_status_mismatch=*/false);
-  CreateAndShowMultiIdpAccountPicker(idp_data);
+  CreateAndShowMultiIdpAccountPicker(accounts_list, idp_list);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -1132,12 +1085,6 @@
   std::vector<raw_ptr<views::View, VectorExperimental>> accounts =
       GetAccounts(children[1]);
 
-  // The expected order is as follows:
-  // 1. "returning3" since it is returning and has the latest timestamp.
-  // 2. "returning1": returning, has a timestamp.
-  // 3. "returning2" and "returning4": returning ones without timestamp.
-  // 4. "new1", "new2": non returning. Note that the last used timestamp from
-  // "new2" does not impact its place since it is considered not returning.
   const std::vector<std::string> expected_account_order = {
       "returning3", "returning1", "returning2", "returning4", "new1", "new2"};
   size_t accounts_index = 0;
@@ -1149,23 +1096,24 @@
 // the background circle containing the IDP icon.
 TEST_F(MultipleIdpAccountSelectionBubbleViewTest, HoverChangesIdpCircle) {
   // Need two IDPs to show the multi IDP UI.
-  const std::vector<std::string> kAccountSuffixes1 = {"1"};
-  const std::vector<std::string> kAccountSuffixes2 = {"2"};
-  std::vector<content::IdentityProviderData> idp_data;
-  idp_data.emplace_back(
-      kIdpForDisplay, CreateTestIdentityRequestAccounts(kAccountSuffixes1),
-      content::IdentityProviderMetadata(),
-      CreateTestClientMetadata(kTermsOfServiceUrl),
-      blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-      /*has_login_status_mismatch=*/false);
-  idp_data.emplace_back(kSecondIdpForDisplay,
-                        CreateTestIdentityRequestAccounts(kAccountSuffixes2),
-                        content::IdentityProviderMetadata(),
-                        CreateTestClientMetadata("https://tos-2.com"),
-                        blink::mojom::RpContext::kSignIn,
-                        kDefaultDisclosureFields,
-                        /*has_login_status_mismatch=*/false);
-  CreateAndShowMultiIdpAccountPicker(idp_data);
+  constexpr char kAccountSuffix1[] = "1";
+  constexpr char kAccountSuffix2[] = "2";
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata(kTermsOfServiceUrl),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false),
+      base::MakeRefCounted<content::IdentityProviderData>(
+          kSecondIdpForDisplay, content::IdentityProviderMetadata(),
+          CreateTestClientMetadata("https://tos-2.com"),
+          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+          /*has_login_status_mismatch=*/false)};
+  std::vector<IdentityRequestAccountPtr> accounts_list = {
+      CreateTestIdentityRequestAccount(kAccountSuffix1, idp_list[0]),
+      CreateTestIdentityRequestAccount(kAccountSuffix2, idp_list[1])};
+
+  CreateAndShowMultiIdpAccountPicker(accounts_list, idp_list);
 
   std::vector<raw_ptr<views::View, VectorExperimental>> children =
       dialog()->children();
@@ -1370,13 +1318,8 @@
 
 // Tests that the brand icon view is hidden if the brand icon URL is invalid.
 TEST_F(AccountSelectionBubbleViewTest, InvalidBrandIconUrlHidesBrandIcon) {
-  const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account(
-      CreateTestIdentityRequestAccount(kAccountSuffix, LoginState::kSignUp));
-  content::IdentityProviderMetadata idp_metadata;
-  idp_metadata.brand_icon_url = GURL("invalid url");
-  CreateAndShowSingleAccountPicker(
-      /*show_back_button=*/false, account, idp_metadata, kTermsOfServiceUrl);
+  idp_data_->idp_metadata.brand_icon_url = GURL("invalid url");
+  CreateAndShowSingleAccountPicker();
 
   views::View* brand_icon_image_view = static_cast<views::View*>(
       GetViewWithClassName(dialog()->children()[0], "BrandIconImageView"));
diff --git a/chrome/browser/ui/views/webid/account_selection_modal_view.cc b/chrome/browser/ui/views/webid/account_selection_modal_view.cc
index b1e5a68..d1f014d 100644
--- a/chrome/browser/ui/views/webid/account_selection_modal_view.cc
+++ b/chrome/browser/ui/views/webid/account_selection_modal_view.cc
@@ -388,7 +388,7 @@
 
 std::unique_ptr<views::View>
 AccountSelectionModalView::CreateMultipleAccountChooser(
-    const std::vector<content::IdentityProviderData>& idp_data_list) {
+    const std::vector<IdentityRequestAccountPtr>& accounts) {
   auto scroll_view = std::make_unique<views::ScrollView>();
   scroll_view->SetHorizontalScrollBarMode(
       views::ScrollView::ScrollBarMode::kDisabled);
@@ -404,17 +404,15 @@
 
   int num_rows = 0;
   constexpr int kMultipleAccountsVerticalPadding = 2;
-  for (const auto& idp_display_data : idp_data_list) {
-    for (const auto& account : idp_display_data.accounts) {
-      content->AddChildView(CreateAccountRow(
-          account, idp_display_data,
-          /*clickable_position=*/num_rows++,
-          /*should_include_idp=*/false,
-          /*is_modal_dialog=*/true,
-          /*additional_vertical_padding=*/kMultipleAccountsVerticalPadding));
-      // Add separator after each account row.
-      content->AddChildView(std::make_unique<views::Separator>());
-    }
+  for (const auto& account : accounts) {
+    content->AddChildView(CreateAccountRow(
+        *account,
+        /*clickable_position=*/num_rows++,
+        /*should_include_idp=*/false,
+        /*is_modal_dialog=*/true,
+        /*additional_vertical_padding=*/kMultipleAccountsVerticalPadding));
+    // Add separator after each account row.
+    content->AddChildView(std::make_unique<views::Separator>());
   }
 
   const int per_account_size = content->GetPreferredSize().height() / num_rows;
@@ -423,13 +421,14 @@
 }
 
 void AccountSelectionModalView::ShowMultiAccountPicker(
-    const std::vector<content::IdentityProviderData>& idp_data_list,
+    const std::vector<IdentityRequestAccountPtr>& accounts,
+    const std::vector<IdentityProviderDataPtr>& idp_list,
     bool show_back_button,
     bool is_choose_an_account) {
   DCHECK(!show_back_button);
   RemoveNonHeaderChildViews();
 
-  GURL idp_brand_icon_url = idp_data_list[0].idp_metadata.brand_icon_url;
+  GURL idp_brand_icon_url = idp_list[0]->idp_metadata.brand_icon_url;
   // If `idp_brand_icon_url` is invalid, a globe icon is shown instead.
   if (idp_brand_icon_url.is_valid()) {
     ConfigureBrandImageView(idp_brand_icon_, idp_brand_icon_url);
@@ -448,17 +447,17 @@
   CHECK(body_label_);
   body_label_->SetVisible(/*visible=*/true);
 
-  account_chooser_ = AddChildView(CreateMultipleAccountChooser(idp_data_list));
+  account_chooser_ = AddChildView(CreateMultipleAccountChooser(accounts));
 
   std::optional<views::Button::PressedCallback> use_other_account_callback =
       std::nullopt;
 
   // TODO(crbug.com/324052630): Support add account with multi IDP API.
-  if (idp_data_list[0].idp_metadata.supports_add_account) {
+  if (idp_list[0]->idp_metadata.supports_add_account) {
     use_other_account_callback = base::BindRepeating(
         &AccountSelectionViewBase::Observer::OnLoginToIdP,
-        base::Unretained(observer_), idp_data_list[0].idp_metadata.config_url,
-        idp_data_list[0].idp_metadata.idp_login_url);
+        base::Unretained(observer_), idp_list[0]->idp_metadata.config_url,
+        idp_list[0]->idp_metadata.idp_login_url);
   }
   AddChildView(CreateButtonRow(/*continue_callback=*/std::nullopt,
                                std::move(use_other_account_callback)));
@@ -470,7 +469,6 @@
 
 void AccountSelectionModalView::ShowVerifyingSheet(
     const content::IdentityRequestAccount& account,
-    const content::IdentityProviderData& idp_display_data,
     const std::u16string& title) {
   // A different type of sheet must have been shown prior to ShowVerifyingSheet.
   // This might change if we choose to integrate auto re-authn with button mode.
@@ -512,7 +510,6 @@
 
 std::unique_ptr<views::View>
 AccountSelectionModalView::CreateSingleAccountChooser(
-    const content::IdentityProviderData& idp_display_data,
     const content::IdentityRequestAccount& account,
     bool should_hover,
     bool show_disclosure_label,
@@ -530,8 +527,7 @@
 
   // Add account row.
   row->AddChildView(CreateAccountRow(
-      account, idp_display_data,
-      should_hover ? std::make_optional<int>(0) : std::nullopt,
+      account, should_hover ? std::make_optional<int>(0) : std::nullopt,
       /*should_include_idp=*/false,
       /*is_modal_dialog=*/true, additional_row_vertical_padding));
 
@@ -543,7 +539,7 @@
   // Add disclosure label.
   if (show_disclosure_label) {
     std::unique_ptr<views::StyledLabel> disclosure_label =
-        CreateDisclosureLabel(idp_display_data);
+        CreateDisclosureLabel(*account.identity_provider);
     disclosure_label->SetDefaultTextStyle(views::style::STYLE_BODY_4);
     disclosure_label->SizeToFit(views::LayoutProvider::Get()->GetDistanceMetric(
         views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH));
@@ -557,11 +553,11 @@
 
 void AccountSelectionModalView::ShowSingleAccountConfirmDialog(
     const content::IdentityRequestAccount& account,
-    const content::IdentityProviderData& idp_display_data,
     bool show_back_button) {
   RemoveNonHeaderChildViews();
 
-  GURL idp_brand_icon_url = idp_display_data.idp_metadata.brand_icon_url;
+  const content::IdentityProviderData& idp_data = *account.identity_provider;
+  GURL idp_brand_icon_url = idp_data.idp_metadata.brand_icon_url;
   // If `idp_brand_icon_url` is invalid, a globe icon is shown instead.
   if (idp_brand_icon_url.is_valid()) {
     ConfigureBrandImageView(idp_brand_icon_, idp_brand_icon_url);
@@ -581,7 +577,7 @@
   body_label_->SetVisible(/*visible=*/true);
 
   account_chooser_ = AddChildView(CreateSingleAccountChooser(
-      idp_display_data, account,
+      account,
       /*should_hover=*/true,
       /*show_disclosure_label=*/false,
       /*show_separator=*/true,
@@ -589,11 +585,11 @@
 
   std::optional<views::Button::PressedCallback> use_other_account_callback =
       std::nullopt;
-  if (idp_display_data.idp_metadata.supports_add_account) {
+  if (idp_data.idp_metadata.supports_add_account) {
     use_other_account_callback = base::BindRepeating(
         &AccountSelectionViewBase::Observer::OnLoginToIdP,
-        base::Unretained(observer_), idp_display_data.idp_metadata.config_url,
-        idp_display_data.idp_metadata.idp_login_url);
+        base::Unretained(observer_), idp_data.idp_metadata.config_url,
+        idp_data.idp_metadata.idp_login_url);
   }
   AddChildView(CreateButtonRow(/*continue_callback=*/std::nullopt,
                                std::move(use_other_account_callback)));
@@ -637,11 +633,11 @@
 
 void AccountSelectionModalView::ShowRequestPermissionDialog(
     const content::IdentityRequestAccount& account,
-    const content::IdentityProviderData& idp_display_data) {
+    const content::IdentityProviderData& idp_data) {
   RemoveNonHeaderChildViews();
 
-  GURL idp_brand_icon_url = idp_display_data.idp_metadata.brand_icon_url;
-  GURL rp_brand_icon_url = idp_display_data.client_metadata.brand_icon_url;
+  GURL idp_brand_icon_url = idp_data.idp_metadata.brand_icon_url;
+  GURL rp_brand_icon_url = idp_data.client_metadata.brand_icon_url;
   // Show RP icon if and only if both IDP and RP icons are available. The
   // combined icons view is only made visible when both IDP and RP icon fetches
   // succeed.
@@ -661,7 +657,7 @@
   body_label_->SetVisible(/*visible=*/false);
 
   account_chooser_ = AddChildView(CreateSingleAccountChooser(
-      idp_display_data, account,
+      account,
       /*should_hover=*/false,
       /*show_disclosure_label=*/account.login_state ==
           Account::LoginState::kSignUp,
@@ -670,8 +666,7 @@
   AddChildView(CreateButtonRow(
       base::BindRepeating(
           &AccountSelectionViewBase::Observer::OnAccountSelected,
-          base::Unretained(observer_), std::cref(account),
-          std::cref(idp_display_data)),
+          base::Unretained(observer_), std::cref(account), std::cref(idp_data)),
       /*use_other_account_callback=*/std::nullopt,
       base::BindRepeating(
           &AccountSelectionViewBase::Observer::OnBackButtonClicked,
@@ -681,7 +676,8 @@
 }
 
 void AccountSelectionModalView::ShowSingleReturningAccountDialog(
-    const std::vector<content::IdentityProviderData>& idp_data_list) {
+    const std::vector<IdentityRequestAccountPtr>& accounts,
+    const std::vector<IdentityProviderDataPtr>& idp_list) {
   NOTREACHED_IN_MIGRATION()
       << "ShowSingleReturningAccountDialog is only implemented for "
          "AccountSelectionBubbleView";
diff --git a/chrome/browser/ui/views/webid/account_selection_modal_view.h b/chrome/browser/ui/views/webid/account_selection_modal_view.h
index cf57efe..2c98cd7 100644
--- a/chrome/browser/ui/views/webid/account_selection_modal_view.h
+++ b/chrome/browser/ui/views/webid/account_selection_modal_view.h
@@ -42,17 +42,16 @@
   void InitDialogWidget() override;
 
   void ShowMultiAccountPicker(
-      const std::vector<content::IdentityProviderData>& idp_data_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
       bool show_back_button,
       bool is_choose_an_account) override;
 
   void ShowVerifyingSheet(const content::IdentityRequestAccount& account,
-                          const content::IdentityProviderData& idp_display_data,
                           const std::u16string& title) override;
 
   void ShowSingleAccountConfirmDialog(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_display_data,
       bool show_back_button) override;
 
   void ShowFailureDialog(
@@ -67,10 +66,11 @@
 
   void ShowRequestPermissionDialog(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_display_data) override;
+      const content::IdentityProviderData& idp_data) override;
 
   void ShowSingleReturningAccountDialog(
-      const std::vector<content::IdentityProviderData>& idp_data_list) override;
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list) override;
 
   void ShowLoadingDialog() override;
 
@@ -91,11 +91,9 @@
   std::unique_ptr<views::View> CreateHeader();
 
   // Returns a View for single account chooser. It contains a row of account
-  // information. `The size of the `idp_display_data.accounts` vector must be 1.
-  // `should_hover` determines whether the row is clickable.
+  // information. `should_hover` determines whether the row is clickable.
   // `show_disclosure_label` determines whether disclosure text is shown.
   std::unique_ptr<views::View> CreateSingleAccountChooser(
-      const content::IdentityProviderData& idp_display_data,
       const content::IdentityRequestAccount& account,
       bool should_hover,
       bool show_disclosure_label,
@@ -105,7 +103,7 @@
   // Returns a View for multiple account chooser. It contains the info for each
   // account in a button, so the user can pick an account.
   std::unique_ptr<views::View> CreateMultipleAccountChooser(
-      const std::vector<content::IdentityProviderData>& idp_data_list);
+      const std::vector<IdentityRequestAccountPtr>& accounts);
 
   // Returns a View for an account row that acts as a placeholder.
   std::unique_ptr<views::View> CreatePlaceholderAccountRow();
diff --git a/chrome/browser/ui/views/webid/account_selection_modal_view_browsertest.cc b/chrome/browser/ui/views/webid/account_selection_modal_view_browsertest.cc
index eb05653..b157678c 100644
--- a/chrome/browser/ui/views/webid/account_selection_modal_view_browsertest.cc
+++ b/chrome/browser/ui/views/webid/account_selection_modal_view_browsertest.cc
@@ -28,7 +28,14 @@
 class AccountSelectionModalViewTest : public DialogBrowserTest,
                                       public AccountSelectionViewTestBase {
  public:
-  AccountSelectionModalViewTest() {
+  AccountSelectionModalViewTest()
+      : idp_data_(base::MakeRefCounted<content::IdentityProviderData>(
+            kIdpForDisplay,
+            content::IdentityProviderMetadata(),
+            CreateTestClientMetadata(),
+            blink::mojom::RpContext::kSignIn,
+            kDefaultDisclosureFields,
+            /*has_login_status_mismatch=*/false)) {
     test_shared_url_loader_factory_ =
       base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
           &test_url_loader_factory_);
@@ -63,61 +70,41 @@
 
   void CreateAndShowSingleAccountPicker(
       bool show_back_button,
-      const content::IdentityRequestAccount& account,
-      const content::IdentityProviderMetadata& idp_metadata,
-      const content::ClientMetadata& client_metadata,
-      bool show_auto_reauthn_checkbox = false) {
+      content::IdentityRequestAccount& account) {
     CreateAccountSelectionModal();
-    content::IdentityProviderData idp_data(
-        kIdpForDisplay, {account}, idp_metadata, client_metadata,
-        blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-        /*has_login_status_mismatch=*/false);
-    dialog_->ShowSingleAccountConfirmDialog(account, idp_data,
-                                            show_back_button);
+    dialog_->ShowSingleAccountConfirmDialog(account, show_back_button);
   }
 
   void CreateAndShowMultiAccountPicker(
       const std::vector<std::string>& account_suffixes,
-      const content::ClientMetadata& client_metadata,
       bool supports_add_account = false) {
-    std::vector<content::IdentityRequestAccount> account_list =
-        CreateTestIdentityRequestAccounts(account_suffixes);
+    idp_data_->idp_metadata.supports_add_account = supports_add_account;
+    account_list_ =
+        CreateTestIdentityRequestAccounts(account_suffixes, idp_data_);
 
     CreateAccountSelectionModal();
-    std::vector<content::IdentityProviderData> idp_data;
-    content::IdentityProviderMetadata metadata;
-    metadata.supports_add_account = supports_add_account;
-    idp_data.emplace_back(kIdpForDisplay, account_list, metadata,
-                          client_metadata, blink::mojom::RpContext::kSignIn,
-                          kDefaultDisclosureFields,
-                          /*has_login_status_mismatch=*/false);
-    dialog_->ShowMultiAccountPicker(idp_data, /*show_back_button=*/false,
+    for (auto& account : account_list_) {
+      account->identity_provider = idp_data_;
+    }
+    dialog_->ShowMultiAccountPicker(account_list_, {idp_data_},
+                                    /*show_back_button=*/false,
                                     /*is_choose_an_account=*/false);
   }
 
   void CreateAndShowRequestPermissionDialog(
-      const content::IdentityRequestAccount& account,
-      const content::IdentityProviderMetadata& idp_metadata,
-      const content::ClientMetadata& client_metadata) {
+      content::IdentityRequestAccount& account) {
     CreateAccountSelectionModal();
-    content::IdentityProviderData idp_data(
-        kIdpForDisplay, {account}, idp_metadata, client_metadata,
-        blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-        /*has_login_status_mismatch=*/false);
-    dialog_->ShowRequestPermissionDialog(account, idp_data);
+    account.identity_provider = idp_data_;
+    dialog_->ShowRequestPermissionDialog(account, *idp_data_);
   }
 
   void CreateAndShowVerifyingSheet() {
     CreateAccountSelectionModal();
     const std::string kAccountSuffix = "suffix";
-    content::IdentityRequestAccount account(CreateTestIdentityRequestAccount(
-        kAccountSuffix, content::IdentityRequestAccount::LoginState::kSignUp));
-    content::IdentityProviderData idp_data(
-        kIdpForDisplay, {account}, content::IdentityProviderMetadata(),
-        CreateTestClientMetadata(), blink::mojom::RpContext::kSignIn,
-        kDefaultDisclosureFields,
-        /*has_login_status_mismatch=*/false);
-    dialog_->ShowVerifyingSheet(account, idp_data, kTitleSignIn);
+    IdentityRequestAccountPtr account(CreateTestIdentityRequestAccount(
+        kAccountSuffix, idp_data_,
+        content::IdentityRequestAccount::LoginState::kSignUp));
+    dialog_->ShowVerifyingSheet(*account, kTitleSignIn);
   }
 
   void CreateAndShowLoadingDialog() {
@@ -295,13 +282,12 @@
 
   void TestSingleAccount(bool supports_add_account = false) {
     const std::string kAccountSuffix = "suffix";
-    content::IdentityRequestAccount account(CreateTestIdentityRequestAccount(
-        kAccountSuffix, content::IdentityRequestAccount::LoginState::kSignUp));
-    content::IdentityProviderMetadata idp_metadata;
-    idp_metadata.supports_add_account = supports_add_account;
+    idp_data_->idp_metadata.supports_add_account = supports_add_account;
+    IdentityRequestAccountPtr account = CreateTestIdentityRequestAccount(
+        kAccountSuffix, idp_data_,
+        content::IdentityRequestAccount::LoginState::kSignUp);
     CreateAndShowSingleAccountPicker(
-        /*show_back_button=*/false, account, idp_metadata,
-        CreateTestClientMetadata());
+        /*show_back_button=*/false, *account);
 
     std::vector<raw_ptr<views::View, VectorExperimental>> children =
         dialog()->children();
@@ -323,8 +309,7 @@
 
   void TestMultipleAccounts(bool supports_add_account = false) {
     const std::vector<std::string> kAccountSuffixes = {"0", "1", "2"};
-    CreateAndShowMultiAccountPicker(
-        kAccountSuffixes, CreateTestClientMetadata(), supports_add_account);
+    CreateAndShowMultiAccountPicker(kAccountSuffixes, supports_add_account);
 
     std::vector<raw_ptr<views::View, VectorExperimental>> children =
         dialog()->children();
@@ -360,14 +345,11 @@
       const std::string& idp_brand_icon_url = kIdpBrandIconUrl,
       const std::string& rp_brand_icon_url = kRpBrandIconUrl) {
     const std::string kAccountSuffix = "suffix";
-    content::IdentityRequestAccount account(
-        CreateTestIdentityRequestAccount(kAccountSuffix, login_state));
-    content::IdentityProviderMetadata idp_metadata;
-    idp_metadata.brand_icon_url = GURL(idp_brand_icon_url);
-    CreateAndShowRequestPermissionDialog(
-        account, idp_metadata,
-        CreateTestClientMetadata(kTermsOfServiceUrl, kPrivacyPolicyUrl,
-                                 rp_brand_icon_url));
+    idp_data_->idp_metadata.brand_icon_url = GURL(idp_brand_icon_url);
+    idp_data_->client_metadata.brand_icon_url = GURL(rp_brand_icon_url);
+    IdentityRequestAccountPtr account(CreateTestIdentityRequestAccount(
+        kAccountSuffix, idp_data_, login_state));
+    CreateAndShowRequestPermissionDialog(*account);
 
     std::vector<raw_ptr<views::View, VectorExperimental>> children =
         dialog()->children();
@@ -477,16 +459,24 @@
 
   AccountSelectionModalView* dialog() { return dialog_; }
 
+  IdentityProviderDataPtr idp_data() { return idp_data_; }
+
   scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory()
       const {
     return test_shared_url_loader_factory_;
   }
 
+  void SetIdpBrandIcon(const std::string& url) {
+    idp_data_->idp_metadata.brand_icon_url = GURL(url);
+  }
+
  private:
   bool expect_visible_body_label_{true};
   bool should_focus_title_{true};
   ui::ImageModel idp_brand_icon_;
   raw_ptr<AccountSelectionModalView, DanglingUntriaged> dialog_;
+  std::vector<IdentityRequestAccountPtr> account_list_;
+  IdentityProviderDataPtr idp_data_;
   scoped_refptr<network::SharedURLLoaderFactory>
       test_shared_url_loader_factory_;
   network::TestURLLoaderFactory test_url_loader_factory_;
@@ -612,14 +602,13 @@
 // bubble. This is because we show a placeholder globe icon on modal.
 IN_PROC_BROWSER_TEST_F(AccountSelectionModalViewTest,
                        InvalidBrandIconUrlDoesNotHideBrandIcon) {
+  SetIdpBrandIcon("invalid url");
   const std::string kAccountSuffix = "suffix";
-  content::IdentityRequestAccount account(CreateTestIdentityRequestAccount(
-      kAccountSuffix, content::IdentityRequestAccount::LoginState::kSignUp));
-  content::IdentityProviderMetadata idp_metadata;
-  idp_metadata.brand_icon_url = GURL("invalid url");
+  IdentityRequestAccountPtr account = CreateTestIdentityRequestAccount(
+      kAccountSuffix, idp_data(),
+      content::IdentityRequestAccount::LoginState::kSignUp);
   CreateAndShowSingleAccountPicker(
-      /*show_back_button=*/false, account, idp_metadata,
-      CreateTestClientMetadata());
+      /*show_back_button=*/false, *account);
 
   // We check that the icon is visible in PerformHeaderChecks.
   PerformHeaderChecks(dialog()->children()[0]);
diff --git a/chrome/browser/ui/views/webid/account_selection_view_base.cc b/chrome/browser/ui/views/webid/account_selection_view_base.cc
index 0b82edc..57f6620 100644
--- a/chrome/browser/ui/views/webid/account_selection_view_base.cc
+++ b/chrome/browser/ui/views/webid/account_selection_view_base.cc
@@ -457,7 +457,6 @@
 
 std::unique_ptr<views::View> AccountSelectionViewBase::CreateAccountRow(
     const content::IdentityRequestAccount& account,
-    const content::IdentityProviderData& idp_display_data,
     std::optional<int> clickable_position,
     bool should_include_idp,
     bool is_modal_dialog,
@@ -475,6 +474,7 @@
   auto account_image_view = std::make_unique<AccountImageView>();
   account_image_view->SetImageSize({avatar_size, avatar_size});
   CHECK(clickable_position || !should_include_idp);
+  const content::IdentityProviderData& idp_data = *account.identity_provider;
   if (clickable_position) {
     BrandIconImageView* brand_icon_image_view_ptr = nullptr;
     if (should_include_idp) {
@@ -510,7 +510,7 @@
               background_color);
       brand_icon_image_view_ptr = brand_icon_image_view.get();
       ConfigureBrandImageView(brand_icon_image_view_ptr,
-                              idp_display_data.idp_metadata.brand_icon_url);
+                              idp_data.idp_metadata.brand_icon_url);
 
       icon_container->AddChildView(std::move(brand_icon_image_view));
 
@@ -540,10 +540,9 @@
       if (last_used_string) {
         footer = l10n_util::GetStringFUTF16(
             IDS_MULTI_IDP_ACCOUNT_ORIGIN_AND_LAST_USED,
-            base::UTF8ToUTF16(idp_display_data.idp_for_display),
-            *last_used_string);
+            base::UTF8ToUTF16(idp_data.idp_for_display), *last_used_string);
       } else {
-        footer = base::UTF8ToUTF16(idp_display_data.idp_for_display);
+        footer = base::UTF8ToUTF16(idp_data.idp_for_display);
       }
     }
     // We can pass crefs to OnAccountSelected because the `observer_` owns the
@@ -552,7 +551,7 @@
         base::BindRepeating(
             &AccountSelectionViewBase::Observer::OnAccountSelected,
             base::Unretained(observer_), std::cref(account),
-            std::cref(idp_display_data)),
+            std::cref(idp_data)),
         std::move(avatar_view),
         /*title=*/base::UTF8ToUTF16(account.name),
         /*subtitle=*/base::UTF8ToUTF16(account.email),
@@ -626,7 +625,7 @@
 
 std::unique_ptr<views::StyledLabel>
 AccountSelectionViewBase::CreateDisclosureLabel(
-    const content::IdentityProviderData& idp_display_data) {
+    const content::IdentityProviderData& idp_data) {
   // It requires a StyledLabel so that we can add the links
   // to the privacy policy and terms of service URLs.
   std::unique_ptr<views::StyledLabel> disclosure_label =
@@ -640,8 +639,7 @@
       views::CreateEmptyBorder(gfx::Insets::TLBR(5, 0, 0, 0)));
   disclosure_label->SetDefaultTextStyle(views::style::STYLE_SECONDARY);
 
-  const content::ClientMetadata& client_metadata =
-      idp_display_data.client_metadata;
+  const content::ClientMetadata& client_metadata = idp_data.client_metadata;
   int disclosure_resource_id = SelectDisclosureTextResourceId(
       client_metadata.privacy_policy_url, client_metadata.terms_of_service_url);
 
@@ -659,8 +657,8 @@
 
   // Each link has both <ph name="BEGIN_LINK"> and <ph name="END_LINK">.
   std::vector<std::u16string> replacements = {
-      base::UTF8ToUTF16(idp_display_data.idp_for_display),
-      GetPermissionFieldsString(idp_display_data.disclosure_fields)};
+      base::UTF8ToUTF16(idp_data.idp_for_display),
+      GetPermissionFieldsString(idp_data.disclosure_fields)};
   replacements.insert(replacements.end(), link_data.size() * 2,
                       std::u16string());
 
diff --git a/chrome/browser/ui/views/webid/account_selection_view_base.h b/chrome/browser/ui/views/webid/account_selection_view_base.h
index e734695c..2d90d6d 100644
--- a/chrome/browser/ui/views/webid/account_selection_view_base.h
+++ b/chrome/browser/ui/views/webid/account_selection_view_base.h
@@ -28,10 +28,13 @@
 #include "ui/views/controls/styled_label.h"
 #include "ui/views/widget/widget_observer.h"
 
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
 using TokenError = content::IdentityCredentialTokenError;
 
 namespace content {
-struct IdentityRequestAccount;
+class IdentityRequestAccount;
 }  // namespace content
 
 // The radius used for the corner of the "Continue as" button.
@@ -140,12 +143,12 @@
    public:
     // Called when a user either selects the account from the multi-account
     // chooser or clicks the "continue" button.
-    // Takes `account` as well as `idp_display_data` since passing `account_id`
+    // Takes `account` as well as `idp_data` since passing `account_id`
     // is insufficient in the multiple IDP case. The caller should pass a cref,
     // as these objects are owned by the observer.
     virtual void OnAccountSelected(
         const content::IdentityRequestAccount& account,
-        const content::IdentityProviderData& idp_display_data,
+        const content::IdentityProviderData& idp_data,
         const ui::Event& event) = 0;
 
     // Called when the user clicks "privacy policy" or "terms of service" link.
@@ -201,14 +204,14 @@
   // 'Choose an account'. This is currently only used on widget mode, when
   // clicking on the 'Choose an account' button.
   virtual void ShowMultiAccountPicker(
-      const std::vector<content::IdentityProviderData>& idp_data_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
       bool show_back_button,
       bool is_choose_an_account) = 0;
 
   // Updates the FedCM dialog to show the "verifying" sheet.
   virtual void ShowVerifyingSheet(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_data,
       const std::u16string& title) = 0;
 
   // Updates to show a single account. On widget mode, used when showing the
@@ -216,7 +219,6 @@
   // On button mode, used for the user to pick the single account.
   virtual void ShowSingleAccountConfirmDialog(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_data,
       bool show_back_button) = 0;
 
   // Updates the FedCM dialog to show the "failure" sheet.
@@ -233,13 +235,14 @@
   // Updates the FedCM dialog to show the "request permission" sheet.
   virtual void ShowRequestPermissionDialog(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_display_data) = 0;
+      const content::IdentityProviderData& idp_data) = 0;
 
   // Updates to show a single account along with a button to show all options.
   // Currently used when there are multiple IDPs and exactly one returning
   // account.
   virtual void ShowSingleReturningAccountDialog(
-      const std::vector<content::IdentityProviderData>& idp_data_list) = 0;
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list) = 0;
 
   // Updates the FedCM dialog to show the "loading" sheet.
   virtual void ShowLoadingDialog() = 0;
@@ -281,7 +284,6 @@
   // account in the overall dialog.
   std::unique_ptr<views::View> CreateAccountRow(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_display_data,
       std::optional<int> clickable_position,
       bool should_include_idp,
       bool is_modal_dialog = false,
@@ -291,7 +293,7 @@
   // Returns a StyledLabel containing a disclosure label. The label links to
   // privacy policy and terms of service URLs, if available.
   std::unique_ptr<views::StyledLabel> CreateDisclosureLabel(
-      const content::IdentityProviderData& idp_display_data);
+      const content::IdentityProviderData& idp_data);
 
   // Sets the brand views::ImageView visibility and image. Initiates the
   // download of the brand icon if necessary.
diff --git a/chrome/browser/ui/views/webid/account_selection_view_test_base.cc b/chrome/browser/ui/views/webid/account_selection_view_test_base.cc
index 0868b39..1cca7617 100644
--- a/chrome/browser/ui/views/webid/account_selection_view_test_base.cc
+++ b/chrome/browser/ui/views/webid/account_selection_view_test_base.cc
@@ -46,27 +46,32 @@
   return account->secondary_view();
 }
 
-content::IdentityRequestAccount
+IdentityRequestAccountPtr
 AccountSelectionViewTestBase::CreateTestIdentityRequestAccount(
     const std::string& account_suffix,
+    IdentityProviderDataPtr idp,
     content::IdentityRequestAccount::LoginState login_state,
     std::optional<base::Time> last_used_timestamp) {
-  return content::IdentityRequestAccount(
-      std::string(kIdBase) + account_suffix,
-      std::string(kEmailBase) + account_suffix,
-      std::string(kNameBase) + account_suffix,
-      std::string(kGivenNameBase) + account_suffix, GURL(),
-      /*login_hints=*/std::vector<std::string>(),
-      /*domain_hints=*/std::vector<std::string>(),
-      /*labels=*/std::vector<std::string>(), login_state,
-      /*browser_trusted_login_state=*/
-      content::IdentityRequestAccount::LoginState::kSignUp,
-      last_used_timestamp);
+  IdentityRequestAccountPtr account =
+      base::MakeRefCounted<content::IdentityRequestAccount>(
+          std::string(kIdBase) + account_suffix,
+          std::string(kEmailBase) + account_suffix,
+          std::string(kNameBase) + account_suffix,
+          std::string(kGivenNameBase) + account_suffix, GURL(),
+          /*login_hints=*/std::vector<std::string>(),
+          /*domain_hints=*/std::vector<std::string>(),
+          /*labels=*/std::vector<std::string>(), login_state,
+          /*browser_trusted_login_state=*/
+          content::IdentityRequestAccount::LoginState::kSignUp,
+          last_used_timestamp);
+  account->identity_provider = std::move(idp);
+  return account;
 }
 
-std::vector<content::IdentityRequestAccount>
+std::vector<IdentityRequestAccountPtr>
 AccountSelectionViewTestBase::CreateTestIdentityRequestAccounts(
     const std::vector<std::string>& account_suffixes,
+    IdentityProviderDataPtr idp,
     const std::vector<content::IdentityRequestAccount::LoginState>&
         login_states,
     const std::vector<std::optional<base::Time>>& last_used_timestamps) {
@@ -76,7 +81,7 @@
   if (!last_used_timestamps.empty()) {
     CHECK_EQ(account_suffixes.size(), last_used_timestamps.size());
   }
-  std::vector<content::IdentityRequestAccount> accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   size_t idx = 0;
   for (const std::string& account_suffix : account_suffixes) {
     content::IdentityRequestAccount::LoginState login_state =
@@ -86,7 +91,7 @@
     std::optional<base::Time> last_used_timestamp =
         last_used_timestamps.empty() ? std::nullopt : last_used_timestamps[idx];
     accounts.push_back(CreateTestIdentityRequestAccount(
-        account_suffix, login_state, last_used_timestamp));
+        account_suffix, idp, login_state, last_used_timestamp));
     ++idx;
   }
   return accounts;
diff --git a/chrome/browser/ui/views/webid/account_selection_view_test_base.h b/chrome/browser/ui/views/webid/account_selection_view_test_base.h
index e5c1eb7e..ef9aeec 100644
--- a/chrome/browser/ui/views/webid/account_selection_view_test_base.h
+++ b/chrome/browser/ui/views/webid/account_selection_view_test_base.h
@@ -41,6 +41,10 @@
 extern const std::vector<content::IdentityRequestDialogDisclosureField>
     kDefaultDisclosureFields;
 
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
+
 // A base class for FedCM account selection view unit tests.
 class AccountSelectionViewTestBase {
  public:
@@ -69,16 +73,18 @@
                            bool expect_terms_of_service,
                            bool expect_privacy_policy);
 
-  content::IdentityRequestAccount CreateTestIdentityRequestAccount(
+  IdentityRequestAccountPtr CreateTestIdentityRequestAccount(
       const std::string& account_suffix,
-      content::IdentityRequestAccount::LoginState login_state,
+      IdentityProviderDataPtr idp,
+      content::IdentityRequestAccount::LoginState login_state =
+          content::IdentityRequestAccount::LoginState::kSignUp,
       std::optional<base::Time> last_used_timestamp = std::nullopt);
   // Creates a vector of accounts. When `login_states` are not passed, sets the
   // accounts' login states to LoginState::kSignUp. When `last_used_timestamps`
   // are not passed, sets accounts' last used timestamp to std::nullopt.
-  std::vector<content::IdentityRequestAccount>
-  CreateTestIdentityRequestAccounts(
+  std::vector<IdentityRequestAccountPtr> CreateTestIdentityRequestAccounts(
       const std::vector<std::string>& account_suffixes,
+      IdentityProviderDataPtr idp,
       const std::vector<content::IdentityRequestAccount::LoginState>&
           login_states = {},
       const std::vector<std::optional<base::Time>>& last_used_timestamps = {});
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
index 14552c2..11963ad 100644
--- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
+++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.cc
@@ -95,10 +95,11 @@
 
 bool FedCmAccountSelectionView::Show(
     const std::string& rp_for_display,
-    const std::vector<content::IdentityProviderData>& idp_data_list,
+    const std::vector<IdentityProviderDataPtr>& idp_list,
+    const std::vector<IdentityRequestAccountPtr>& accounts,
     Account::SignInMode sign_in_mode,
     blink::mojom::RpMode rp_mode,
-    const std::optional<content::IdentityProviderData>& new_accounts_idp) {
+    const std::vector<IdentityRequestAccountPtr>& new_accounts) {
   // If IDP sign-in pop-up is open, we delay the showing of the accounts dialog
   // until the pop-up is destroyed.
   if (IsIdpSigninPopupOpen()) {
@@ -108,8 +109,8 @@
     // WeakPtrs to methods with return values.
     show_accounts_dialog_callback_ =
         base::BindOnce(base::IgnoreResult(&FedCmAccountSelectionView::Show),
-                       weak_ptr_factory_.GetWeakPtr(), rp_for_display,
-                       idp_data_list, sign_in_mode, rp_mode, new_accounts_idp);
+                       weak_ptr_factory_.GetWeakPtr(), rp_for_display, idp_list,
+                       accounts, sign_in_mode, rp_mode, new_accounts);
     // This is considered successful since we are intentionally delaying showing
     // the UI.
     return true;
@@ -124,36 +125,40 @@
   // modal is not yet implemented.
   bool has_modal_support = true;
 
-  idp_data_list_ = idp_data_list;
+  idp_list_ = idp_list;
+  accounts_ = accounts;
+  new_accounts_ = new_accounts;
   started_as_single_returning_account_ = false;
+  last_multi_account_is_choose_an_account_ = false;
 
-  size_t accounts_or_mismatches_size = 0u;
+  size_t accounts_or_mismatches_size = accounts.size();
   bool supports_add_account = false;
-  size_t returning_accounts_size = 0u;
   blink::mojom::RpContext rp_context = blink::mojom::RpContext::kSignIn;
-  for (const auto& identity_provider : idp_data_list) {
-    DCHECK(identity_provider.accounts.size() ||
-           identity_provider.has_login_status_mismatch);
+  for (const auto& identity_provider : idp_list) {
+    supports_add_account |=
+        identity_provider->idp_metadata.supports_add_account;
+    // If `identity_provider` has a login status mismatch, we show the login
+    // button for it. In this case, there should be no accounts from that
+    // provider.
+    if (identity_provider->has_login_status_mismatch) {
+      ++accounts_or_mismatches_size;
+    }
+
     // TODO(crbug.com/40252518): Decide what we should display if the IdPs use
     // different contexts here.
-    rp_context = identity_provider.rp_context;
-    // If `identity_provider` has no accounts, we show the login button for it.
-    accounts_or_mismatches_size += identity_provider.accounts.size()
-                                       ? identity_provider.accounts.size()
-                                       : 1u;
-    supports_add_account |= identity_provider.idp_metadata.supports_add_account;
-    returning_accounts_size += std::count_if(
-        identity_provider.accounts.begin(), identity_provider.accounts.end(),
-        [](const auto& account) {
-          return account.login_state ==
-                 content::IdentityRequestAccount::LoginState::kSignIn;
-        });
+    rp_context = identity_provider->rp_context;
   }
 
+  size_t returning_accounts_size =
+      std::count_if(accounts.begin(), accounts.end(), [](const auto& account) {
+        return account->login_state ==
+               content::IdentityRequestAccount::LoginState::kSignIn;
+      });
+
   std::optional<std::u16string> idp_title =
-      idp_data_list_.size() == 1u
+      idp_list_.size() == 1u
           ? std::make_optional<std::u16string>(
-                base::UTF8ToUTF16(idp_data_list_[0].idp_for_display))
+                base::UTF8ToUTF16(idp_list_[0]->idp_for_display))
           : std::nullopt;
   rp_for_display_ = base::UTF8ToUTF16(rp_for_display);
 
@@ -161,7 +166,7 @@
   // this type of dialog, reset account_selection_view_ to create a bubble
   // dialog instead. We also reset for widget multi IDP to recalculate the title
   // and other parts of the header.
-  if ((rp_mode == blink::mojom::RpMode::kWidget && idp_data_list_.size() > 1) ||
+  if ((rp_mode == blink::mojom::RpMode::kWidget && idp_list_.size() > 1) ||
       (rp_mode == blink::mojom::RpMode::kButton && !has_modal_support)) {
     MaybeResetAccountSelectionView();
   }
@@ -185,29 +190,28 @@
     if (GetDialogType() == DialogType::MODAL) {
       state_ = State::SINGLE_ACCOUNT_PICKER;
       account_selection_view_->ShowSingleAccountConfirmDialog(
-          idp_data_list_[0].accounts[0], idp_data_list_[0],
+          *accounts[0],
           /*show_back_button=*/false);
     }
 
     state_ = State::AUTO_REAUTHN;
 
     // When auto re-authn flow is triggered, the parameter
-    // `idp_data_list_` would only include the single returning
+    // `idp_list_` would only include the single returning
     // account and its IDP.
-    DCHECK_EQ(idp_data_list_.size(), 1u);
-    DCHECK_EQ(idp_data_list_[0].accounts.size(), 1u);
+    DCHECK_EQ(idp_list_.size(), 1u);
+    DCHECK_EQ(accounts.size(), 1u);
     // If ShowVerifyingSheet returns false, `this` got deleted, so just
     // return.
-    if (!ShowVerifyingSheet(idp_data_list_[0].accounts[0], idp_data_list_[0])) {
+    if (!ShowVerifyingSheet(*accounts[0], *idp_list_[0])) {
       return false;
     }
-  } else if (new_accounts_idp) {
+  } else if (!new_accounts.empty()) {
     // When we just logged in to an account that is not a single returning
     // account: on the modal, we'd show all the accounts and on the bubble, we'd
     // show only the new accounts.
-    new_accounts_idp_display_data_ = {*new_accounts_idp};
     const content::IdentityProviderData& new_idp_data =
-        new_accounts_idp_display_data_[0];
+        *new_accounts_[0]->identity_provider;
 
     if (GetDialogType() == DialogType::MODAL) {
       // The browser trusted login state controls whether we'd skip the next
@@ -216,27 +220,26 @@
       // skip the next UI when mediation mode is `required` because there was
       // not user mediation acquired yet in this case.
       bool should_show_verifying_sheet =
-          new_idp_data.accounts[0].browser_trusted_login_state ==
+          new_accounts_[0]->browser_trusted_login_state ==
               Account::LoginState::kSignIn &&
           state_ != State::LOADING;
       // The IDP claimed login state controls whether we show disclosure text,
       // if we do not skip the next dialog. Also skip when
       // `disclosure_fields` is empty (controlled by the fields API).
       bool should_show_request_permission_dialog =
-          new_idp_data.accounts[0].login_state !=
-              Account::LoginState::kSignIn &&
-          !new_accounts_idp->disclosure_fields.empty();
+          new_accounts_[0]->login_state != Account::LoginState::kSignIn &&
+          !new_idp_data.disclosure_fields.empty();
 
       if (should_show_verifying_sheet) {
         state_ = State::VERIFYING;
         // ShowVerifyingSheet will call delegate_->OnAccountSelected to proceed.
-        if (!ShowVerifyingSheet(new_idp_data.accounts[0], new_idp_data)) {
+        if (!ShowVerifyingSheet(*new_accounts_[0], new_idp_data)) {
           return false;
         }
       } else if (should_show_request_permission_dialog) {
         state_ = State::REQUEST_PERMISSION;
-        account_selection_view_->ShowRequestPermissionDialog(
-            new_idp_data.accounts[0], new_idp_data);
+        account_selection_view_->ShowRequestPermissionDialog(*new_accounts_[0],
+                                                             new_idp_data);
       } else {
         // Normally we'd show the request permission dialog but without the
         // disclosure text, there is no material difference between the account
@@ -244,54 +247,55 @@
         // with most recently signed in accounts at the top to reduce the
         // exposure of extra UI surfaces and to work around the account picker
         // not having a back button.
-        ShowMultiAccountPicker(idp_data_list_,
+        ShowMultiAccountPicker(accounts_, idp_list_,
                                /*show_back_button=*/false,
                                /*is_choose_an_account=*/false);
       }
     } else {
-      if (new_idp_data.accounts.size() == 1u) {
+      if (new_accounts_.size() == 1u) {
         state_ = State::SINGLE_ACCOUNT_PICKER;
         account_selection_view_->ShowSingleAccountConfirmDialog(
-            new_idp_data.accounts[0], new_idp_data,
+            *new_accounts_[0],
             /*show_back_button=*/accounts_or_mismatches_size > 1u ||
                 supports_add_account);
       } else {
         ShowMultiAccountPicker(
-            new_accounts_idp_display_data_,
+            new_accounts_, {new_accounts_[0]->identity_provider},
             /*show_back_button=*/accounts_or_mismatches_size >
-                new_idp_data.accounts.size(),
+                new_accounts_.size(),
             /*is_choose_an_account=*/false);
         // Override the state to NEWLY_LOGGED_IN_ACCOUNT_PICKER so the back
         // button works correctly.
         state_ = State::NEWLY_LOGGED_IN_ACCOUNT_PICKER;
       }
     }
-  } else if (idp_data_list_.size() == 1u && accounts_or_mismatches_size == 1u) {
+  } else if (idp_list_.size() == 1u && accounts_or_mismatches_size == 1u) {
     if (GetDialogType() == DialogType::MODAL) {
       state_ = State::SINGLE_ACCOUNT_PICKER;
       account_selection_view_->ShowSingleAccountConfirmDialog(
-          idp_data_list_[0].accounts[0], idp_data_list_[0],
+          *accounts_[0],
           /*show_back_button=*/false);
     } else if (supports_add_account) {
       // The logic to support add account is in ShowMultiAccountPicker for the
       // bubble dialog.
-      ShowMultiAccountPicker(idp_data_list_, /*show_back_button=*/false,
+      ShowMultiAccountPicker(accounts_, idp_list_, /*show_back_button=*/false,
                              /*is_choose_an_account=*/false);
     } else {
       state_ = State::SINGLE_ACCOUNT_PICKER;
       account_selection_view_->ShowSingleAccountConfirmDialog(
-          idp_data_list_[0].accounts[0], idp_data_list_[0],
+          *accounts_[0],
           /*show_back_button=*/false);
     }
-  } else if (idp_data_list.size() > 1u && returning_accounts_size == 1u) {
+  } else if (idp_list_.size() > 1u && returning_accounts_size == 1u) {
     // For now we only highlight the single returning account in the multi IDP
     // case, but in the future we may want to do so in the single IDP case as
     // well.
     state_ = State::SINGLE_RETURNING_ACCOUNT_PICKER;
     started_as_single_returning_account_ = true;
-    account_selection_view_->ShowSingleReturningAccountDialog(idp_data_list_);
+    account_selection_view_->ShowSingleReturningAccountDialog(accounts_,
+                                                              idp_list_);
   } else {
-    ShowMultiAccountPicker(idp_data_list_,
+    ShowMultiAccountPicker(accounts_, idp_list_,
                            /*show_back_button=*/false,
                            /*is_choose_an_account=*/false);
   }
@@ -372,7 +376,7 @@
   // this type of dialog, reset account_selection_view_ to create a bubble
   // dialog instead.  We also reset for widget multi IDP to recalculate the
   // title and other parts of the header.
-  if ((rp_mode == blink::mojom::RpMode::kWidget && idp_data_list_.size() > 1) ||
+  if ((rp_mode == blink::mojom::RpMode::kWidget && idp_list_.size() > 1) ||
       (rp_mode == blink::mojom::RpMode::kButton && !has_modal_support)) {
     MaybeResetAccountSelectionView();
   }
@@ -437,7 +441,7 @@
   // this type of dialog, reset account_selection_view_ to create a bubble
   // dialog instead. We also reset for widget multi IDP to recalculate the title
   // and other parts of the header.
-  if ((rp_mode == blink::mojom::RpMode::kWidget && idp_data_list_.size() > 1) ||
+  if ((rp_mode == blink::mojom::RpMode::kWidget && idp_list_.size() > 1) ||
       (rp_mode == blink::mojom::RpMode::kButton && !has_modal_support)) {
     MaybeResetAccountSelectionView();
   }
@@ -629,7 +633,7 @@
 
 void FedCmAccountSelectionView::OnAccountSelected(
     const Account& account,
-    const content::IdentityProviderData& idp_display_data,
+    const content::IdentityProviderData& idp_data,
     const ui::Event& event) {
   DCHECK(state_ != State::IDP_SIGNIN_STATUS_MISMATCH);
   DCHECK(state_ != State::AUTO_REAUTHN);
@@ -651,9 +655,9 @@
       state_ == State::REQUEST_PERMISSION ||
       (state_ == State::SINGLE_ACCOUNT_PICKER &&
        GetDialogType() == DialogType::BUBBLE) ||
-      idp_display_data.disclosure_fields.empty()) {
+      idp_data.disclosure_fields.empty()) {
     state_ = State::VERIFYING;
-    ShowVerifyingSheet(account, idp_display_data);
+    ShowVerifyingSheet(account, idp_data);
     return;
   }
 
@@ -661,8 +665,7 @@
   // we'd request permission through the request permission dialog.
   if (GetDialogType() == DialogType::MODAL) {
     state_ = State::REQUEST_PERMISSION;
-    account_selection_view_->ShowRequestPermissionDialog(account,
-                                                         idp_display_data);
+    account_selection_view_->ShowRequestPermissionDialog(account, idp_data);
     return;
   }
 
@@ -671,8 +674,7 @@
   // so we'd request permission through a single account dialog.
   state_ = State::SINGLE_ACCOUNT_PICKER;
   account_selection_view_->ShowSingleAccountConfirmDialog(
-      account, idp_display_data,
-      /*show_back_button=*/true);
+      account, /*show_back_button=*/true);
 }
 
 void FedCmAccountSelectionView::OnLinkClicked(LinkType link_type,
@@ -690,23 +692,23 @@
 
   // If the dialog type is modal and there is only one IDP and one account, show
   // the single account picker.
-  if (GetDialogType() == DialogType::MODAL && idp_data_list_.size() == 1u &&
-      idp_data_list_[0].accounts.size() == 1u) {
+  if (GetDialogType() == DialogType::MODAL && idp_list_.size() == 1u &&
+      accounts_.size() == 1u) {
     state_ = State::SINGLE_ACCOUNT_PICKER;
     account_selection_view_->ShowSingleAccountConfirmDialog(
-        idp_data_list_[0].accounts[0], idp_data_list_[0],
-        /*show_back_button=*/false);
+        *accounts_[0], /*show_back_button=*/false);
     return;
   }
   // If the back button was clicked while on the multi account picker, go back
   // to the single returning account.
   if (state_ == State::MULTI_ACCOUNT_PICKER) {
     state_ = State::SINGLE_RETURNING_ACCOUNT_PICKER;
-    account_selection_view_->ShowSingleReturningAccountDialog(idp_data_list_);
+    account_selection_view_->ShowSingleReturningAccountDialog(accounts_,
+                                                              idp_list_);
     return;
   }
   ShowMultiAccountPicker(
-      idp_data_list_,
+      accounts_, idp_list_,
       /*show_back_button=*/started_as_single_returning_account_,
       /*is_choose_an_account=*/last_multi_account_is_choose_an_account_);
 }
@@ -864,7 +866,7 @@
 }
 
 void FedCmAccountSelectionView::OnChooseAnAccountClicked() {
-  ShowMultiAccountPicker(idp_data_list_,
+  ShowMultiAccountPicker(accounts_, idp_list_,
                          /*show_back_button=*/true,
                          /*is_choose_an_account=*/true);
   base::UmaHistogramBoolean("Blink.FedCm.ChooseAnAccountSelected.Desktop",
@@ -884,14 +886,13 @@
 
 bool FedCmAccountSelectionView::ShowVerifyingSheet(
     const Account& account,
-    const content::IdentityProviderData& idp_display_data) {
+    const content::IdentityProviderData& idp_data) {
   DCHECK(state_ == State::VERIFYING || state_ == State::AUTO_REAUTHN);
   notify_delegate_of_dismiss_ = false;
 
   base::WeakPtr<FedCmAccountSelectionView> weak_ptr(
       weak_ptr_factory_.GetWeakPtr());
-  delegate_->OnAccountSelected(idp_display_data.idp_metadata.config_url,
-                               account);
+  delegate_->OnAccountSelected(idp_data.idp_metadata.config_url, account);
   // AccountSelectionView::Delegate::OnAccountSelected() might delete this.
   // See https://crbug.com/1393650 for details.
   if (!weak_ptr) {
@@ -902,7 +903,7 @@
       state_ == State::AUTO_REAUTHN
           ? l10n_util::GetStringUTF16(IDS_VERIFY_SHEET_TITLE_AUTO_REAUTHN)
           : l10n_util::GetStringUTF16(IDS_VERIFY_SHEET_TITLE);
-  account_selection_view_->ShowVerifyingSheet(account, idp_display_data, title);
+  account_selection_view_->ShowVerifyingSheet(account, title);
   return true;
 }
 
@@ -1111,11 +1112,12 @@
 }
 
 void FedCmAccountSelectionView::ShowMultiAccountPicker(
-    const std::vector<content::IdentityProviderData>& idp_data_list,
+    const std::vector<IdentityRequestAccountPtr>& accounts,
+    const std::vector<IdentityProviderDataPtr>& idp_list,
     bool show_back_button,
     bool is_choose_an_account) {
   state_ = State::MULTI_ACCOUNT_PICKER;
   last_multi_account_is_choose_an_account_ = is_choose_an_account;
   account_selection_view_->ShowMultiAccountPicker(
-      idp_data_list_, show_back_button, is_choose_an_account);
+      accounts, idp_list, show_back_button, is_choose_an_account);
 }
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.h b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.h
index 2c30223..10bf0da 100644
--- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.h
+++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop.h
@@ -16,6 +16,9 @@
 #include "ui/views/input_event_activation_protector.h"
 #include "ui/views/widget/widget_observer.h"
 
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
 using TokenError = content::IdentityCredentialTokenError;
 
 class AccountSelectionViewBase;
@@ -67,11 +70,11 @@
   // AccountSelectionView:
   bool Show(
       const std::string& rp_for_display,
-      const std::vector<content::IdentityProviderData>& identity_provider_data,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       Account::SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<content::IdentityProviderData>& new_accounts_idp)
-      override;
+      const std::vector<IdentityRequestAccountPtr>& new_accounts) override;
   bool ShowFailureDialog(
       const std::string& rp_for_display,
       const std::string& idp_etld_plus_one,
@@ -271,7 +274,7 @@
 
   // AccountSelectionBubbleView::Observer:
   void OnAccountSelected(const Account& account,
-                         const content::IdentityProviderData& idp_display_data,
+                         const content::IdentityProviderData& idp_data,
                          const ui::Event& event) override;
   void OnLinkClicked(LinkType link_type,
                      const GURL& url,
@@ -287,9 +290,8 @@
 
   // Returns false if `this` got deleted. In that case, the caller should not
   // access any further member variables.
-  bool ShowVerifyingSheet(
-      const Account& account,
-      const content::IdentityProviderData& idp_display_data);
+  bool ShowVerifyingSheet(const Account& account,
+                          const content::IdentityProviderData& idp_data);
 
   // Shows the dialog widget.
   void ShowDialogWidget();
@@ -327,18 +329,20 @@
 
   // Shows the multi account picker and updates the internal state.
   void ShowMultiAccountPicker(
-      const std::vector<content::IdentityProviderData>& idp_data_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
       bool show_back_button,
       bool is_choose_an_account);
 
-  std::vector<content::IdentityProviderData> idp_data_list_;
+  std::vector<IdentityProviderDataPtr> idp_list_;
+
+  std::vector<IdentityRequestAccountPtr> accounts_;
 
   // This class needs to own the IDP display data for a newly logged in account
   // since the AccountSelectionBubbleView does not take ownership. This is a
   // vector so it is easy to pass to CreateMultipleAccountChooser in case there
-  // are multiple accounts, but it is size 0 when there are no new accounts and
-  // size 1 when there are new accounts.
-  std::vector<content::IdentityProviderData> new_accounts_idp_display_data_;
+  // are multiple accounts, but it is size 0 when there are no new accounts.
+  std::vector<IdentityRequestAccountPtr> new_accounts_;
 
   std::u16string rp_for_display_;
 
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_browsertest.cc b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_browsertest.cc
index f7462ed..e270658 100644
--- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_browsertest.cc
+++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_browsertest.cc
@@ -42,19 +42,20 @@
   void ShowUi(const std::string& name) override { ShowAccounts(); }
 
   void ShowAccounts(Account::SignInMode mode = Account::SignInMode::kExplicit) {
-    std::vector<content::IdentityRequestAccount> accounts = {
-        {"id", "email", "name", "given_name", GURL(),
-         /*login_hints=*/std::vector<std::string>(),
-         /*domain_hints=*/std::vector<std::string>(),
-         /*labels=*/std::vector<std::string>()}};
+    idps_ = {base::MakeRefCounted<content::IdentityProviderData>(
+        "idp-example.com", content::IdentityProviderMetadata(),
+        content::ClientMetadata(GURL(), GURL(), GURL()),
+        blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
+        /*has_login_status_mismatch=*/false)};
+    accounts_ = {base::MakeRefCounted<Account>(
+        "id", "email", "name", "given_name", GURL(),
+        /*login_hints=*/std::vector<std::string>(),
+        /*domain_hints=*/std::vector<std::string>(),
+        /*labels=*/std::vector<std::string>())};
+    accounts_[0]->identity_provider = idps_[0];
     account_selection_view()->Show(
-        "rp-example.com",
-        {{"idp-example.com", accounts, content::IdentityProviderMetadata(),
-          content::ClientMetadata(GURL(), GURL(), GURL()),
-          blink::mojom::RpContext::kSignIn, kDefaultDisclosureFields,
-          /*has_login_status_mismatch=*/false}},
-        mode, blink::mojom::RpMode::kWidget,
-        /*new_account_idp*/ std::nullopt);
+        "rp-example.com", idps_, accounts_, mode, blink::mojom::RpMode::kWidget,
+        /*new_accounts=*/std::vector<IdentityRequestAccountPtr>());
   }
 
   void Show() {
@@ -77,6 +78,8 @@
  protected:
   base::test::ScopedFeatureList feature_list_;
   std::unique_ptr<FakeDelegate> delegate_;
+  std::vector<IdentityProviderDataPtr> idps_;
+  std::vector<IdentityRequestAccountPtr> accounts_;
   std::unique_ptr<FedCmAccountSelectionView> account_selection_view_;
 };
 
diff --git a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_unittest.cc b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_unittest.cc
index 52d5761..b1666d8d 100644
--- a/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_unittest.cc
+++ b/chrome/browser/ui/views/webid/fedcm_account_selection_view_desktop_unittest.cc
@@ -60,7 +60,8 @@
   TestAccountSelectionView& operator=(const TestAccountSelectionView&) = delete;
 
   void ShowMultiAccountPicker(
-      const std::vector<content::IdentityProviderData>& idp_data_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
       bool show_back_button,
       bool is_choose_an_account) override {
     CHECK(!is_choose_an_account || show_back_button);
@@ -69,15 +70,12 @@
     sheet_type_ = SheetType::kAccountPicker;
 
     account_ids_.clear();
-    for (const auto& idp : idp_data_list) {
-      for (const auto& account : idp.accounts) {
-        account_ids_.push_back(account.id);
-      }
+    for (const auto& account : accounts) {
+      account_ids_.push_back(account->id);
     }
   }
 
   void ShowVerifyingSheet(const content::IdentityRequestAccount& account,
-                          const content::IdentityProviderData& idp_data,
                           const std::u16string& title) override {
     sheet_type_ = SheetType::kVerifying;
     account_ids_ = {account.id};
@@ -87,7 +85,6 @@
 
   void ShowSingleAccountConfirmDialog(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_data,
       bool show_back_button) override {
     show_back_button_ = show_back_button;
     is_choose_an_account_ = false;
@@ -115,7 +112,7 @@
 
   void ShowRequestPermissionDialog(
       const content::IdentityRequestAccount& account,
-      const content::IdentityProviderData& idp_display_data) override {
+      const content::IdentityProviderData& idp_data) override {
     show_back_button_ = true;
     is_choose_an_account_ = false;
     sheet_type_ = SheetType::kRequestPermission;
@@ -123,19 +120,15 @@
   }
 
   void ShowSingleReturningAccountDialog(
-      const std::vector<content::IdentityProviderData>& idp_data_list)
-      override {
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      const std::vector<IdentityProviderDataPtr>& idp_list) override {
     show_back_button_ = false;
     is_choose_an_account_ = false;
     sheet_type_ = SheetType::kSingleReturningAccount;
-    for (const auto& idp : idp_data_list) {
-      for (const auto& account : idp.accounts) {
-        if (account.login_state == LoginState::kSignIn) {
-          account_ids_ = {account.id};
-          break;
-        }
-      }
-    }
+    CHECK(!accounts.empty());
+    CHECK_EQ(accounts[0]->login_state.value_or(LoginState::kSignUp),
+             LoginState::kSignIn);
+    account_ids_ = {accounts[0]->id};
   }
 
   void ShowLoadingDialog() override {
@@ -299,120 +292,84 @@
     account_selection_view_ =
         std::make_unique<TestAccountSelectionView>(dialog_widget_.get());
     histogram_tester_ = std::make_unique<base::HistogramTester>();
+
+    idp_data_ = CreateIdentityProviderData();
+    accounts_ = {CreateAccount(idp_data_)};
+    new_accounts_ = {CreateAccount(idp_data_)};
   }
 
-  content::IdentityProviderData CreateIdentityProviderData(
-      const std::vector<std::pair<std::string, LoginState>>& account_infos,
+  IdentityProviderDataPtr CreateIdentityProviderData(
       bool has_login_status_mismatch = false,
       const std::vector<content::IdentityRequestDialogDisclosureField>&
           disclosure_fields = kDefaultDisclosureFields) {
-    std::vector<content::IdentityRequestAccount> accounts;
-    for (const auto& account_info : account_infos) {
-      accounts.emplace_back(account_info.first, "", "", "", GURL(),
-                            /*login_hints=*/std::vector<std::string>(),
-                            /*domain_hints=*/std::vector<std::string>(),
-                            /*labels=*/std::vector<std::string>(),
-                            account_info.second);
-    }
-    return content::IdentityProviderData(
-        "", std::move(accounts), content::IdentityProviderMetadata(),
+    return base::MakeRefCounted<content::IdentityProviderData>(
+        /*idp_for_display=*/"", content::IdentityProviderMetadata(),
         content::ClientMetadata(GURL(), GURL(), GURL()),
         blink::mojom::RpContext::kSignIn, disclosure_fields,
         has_login_status_mismatch);
   }
 
-  std::vector<content::IdentityRequestAccount> CreateAccount(
-      LoginState idp_claimed_login_state,
-      LoginState browser_trusted_login_state,
+  IdentityRequestAccountPtr CreateAccount(
+      IdentityProviderDataPtr idp,
+      LoginState idp_claimed_login_state = LoginState::kSignUp,
+      LoginState browser_trusted_login_state = LoginState::kSignUp,
       std::string account_id = kAccountId1) {
-    return {{account_id, "", "", "", GURL(),
-             /*login_hints=*/std::vector<std::string>(),
-             /*domain_hints=*/std::vector<std::string>(),
-             /*labels=*/std::vector<std::string>(),
-             /*login_state=*/idp_claimed_login_state,
-             /*browser_trusted_login_state=*/browser_trusted_login_state}};
+    IdentityRequestAccountPtr account = base::MakeRefCounted<Account>(
+        account_id, "", "", "", GURL(),
+        /*login_hints=*/std::vector<std::string>(),
+        /*domain_hints=*/std::vector<std::string>(),
+        /*labels=*/std::vector<std::string>(),
+        /*login_state=*/idp_claimed_login_state,
+        /*browser_trusted_login_state=*/browser_trusted_login_state);
+    account->identity_provider = std::move(idp);
+    return account;
   }
 
-  std::vector<content::IdentityRequestAccount> CreateAccounts(
-      const std::vector<std::pair<std::string, LoginState>>& account_infos) {
-    std::vector<content::IdentityRequestAccount> accounts;
+  std::vector<IdentityRequestAccountPtr> CreateAccounts(
+      const std::vector<std::pair<std::string, LoginState>>& account_infos,
+      IdentityProviderDataPtr idp_data) {
+    std::vector<IdentityRequestAccountPtr> accounts;
     for (const auto& account_info : account_infos) {
-      accounts.emplace_back(
+      accounts.emplace_back(base::MakeRefCounted<Account>(
           account_info.first, "", "", "", GURL(),
           /*login_hints=*/std::vector<std::string>(),
           /*domain_hints=*/std::vector<std::string>(),
           /*labels=*/std::vector<std::string>(),
           /*login_state=*/account_info.second,
-          /*browser_trusted_login_state=*/account_info.second);
+          /*browser_trusted_login_state=*/account_info.second));
+      accounts.back()->identity_provider = idp_data;
     }
     return accounts;
   }
 
-  content::IdentityProviderData CreateNewIdpData(
-      std::vector<content::IdentityRequestAccount> accounts,
-      bool has_login_status_mismatch = false,
-      const std::vector<content::IdentityRequestDialogDisclosureField>&
-          disclosure_fields = kDefaultDisclosureFields) {
-    return {kIdpEtldPlusOne,
-            accounts,
-            content::IdentityProviderMetadata(),
-            content::ClientMetadata(GURL(), GURL(), GURL()),
-            blink::mojom::RpContext::kSignIn,
-            disclosure_fields,
-            has_login_status_mismatch};
-  }
-
   std::unique_ptr<TestFedCmAccountSelectionView> CreateAndShow(
-      const std::vector<content::IdentityRequestAccount>& accounts,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       SignInMode sign_in_mode,
-      blink::mojom::RpMode rp_mode = blink::mojom::RpMode::kWidget,
-      const std::optional<content::IdentityProviderData>& new_account_idp =
-          std::nullopt,
-      const std::vector<content::IdentityRequestDialogDisclosureField>&
-          disclosure_fields = kDefaultDisclosureFields,
-      content::IdentityProviderMetadata idp_metadata =
-          content::IdentityProviderMetadata()) {
+      blink::mojom::RpMode rp_mode = blink::mojom::RpMode::kWidget) {
     auto controller = std::make_unique<TestFedCmAccountSelectionView>(
         delegate_.get(), account_selection_view_.get());
-    Show(*controller, accounts, sign_in_mode, rp_mode, new_account_idp,
-         disclosure_fields, idp_metadata);
+    Show(*controller, accounts, sign_in_mode, rp_mode);
     return controller;
   }
 
   std::unique_ptr<TestFedCmAccountSelectionView> CreateAndShowWithLensOverlay(
-      const std::vector<content::IdentityRequestAccount>& accounts,
-      SignInMode sign_in_mode,
-      blink::mojom::RpMode rp_mode = blink::mojom::RpMode::kWidget,
-      const std::optional<content::IdentityProviderData>& new_account_idp =
-          std::nullopt,
-      const std::vector<content::IdentityRequestDialogDisclosureField>&
-          disclosure_fields = kDefaultDisclosureFields,
-      content::IdentityProviderMetadata idp_metadata =
-          content::IdentityProviderMetadata()) {
+      const std::vector<IdentityRequestAccountPtr>& accounts,
+      SignInMode sign_in_mode) {
     auto controller = std::make_unique<TestFedCmAccountSelectionView>(
         delegate_.get(), account_selection_view_.get());
     controller->SetIsLensOverlayShowingForTesting(true);
-    Show(*controller, accounts, sign_in_mode, rp_mode, new_account_idp,
-         disclosure_fields, idp_metadata);
+    Show(*controller, accounts, sign_in_mode, blink::mojom::RpMode::kWidget);
     return controller;
   }
 
   void Show(TestFedCmAccountSelectionView& controller,
-            const std::vector<content::IdentityRequestAccount>& accounts,
+            const std::vector<IdentityRequestAccountPtr>& accounts,
             SignInMode sign_in_mode,
             blink::mojom::RpMode rp_mode,
-            const std::optional<content::IdentityProviderData>&
-                new_account_idp = std::nullopt,
-            const std::vector<content::IdentityRequestDialogDisclosureField>&
-                disclosure_fields = kDefaultDisclosureFields,
-            content::IdentityProviderMetadata idp_metadata =
-                content::IdentityProviderMetadata()) {
-    controller.Show(kTopFrameEtldPlusOne,
-                    {{kIdpEtldPlusOne, accounts, idp_metadata,
-                      content::ClientMetadata(GURL(), GURL(), GURL()),
-                      blink::mojom::RpContext::kSignIn, disclosure_fields,
-                      /*has_login_status_mismatch=*/false}},
-                    sign_in_mode, rp_mode, new_account_idp);
+            const std::vector<IdentityRequestAccountPtr>& new_accounts =
+                std::vector<IdentityRequestAccountPtr>()) {
+    controller.Show(kTopFrameEtldPlusOne, {idp_data_}, accounts, sign_in_mode,
+                    rp_mode, new_accounts);
   }
 
   std::unique_ptr<TestFedCmAccountSelectionView> CreateAndShowMismatchDialog(
@@ -465,27 +422,22 @@
   }
 
   std::unique_ptr<TestFedCmAccountSelectionView> CreateAndShowMultiIdp(
-      const std::vector<content::IdentityProviderData>& idp_list,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode) {
     auto controller = std::make_unique<TestFedCmAccountSelectionView>(
         delegate_.get(), account_selection_view_.get());
-    std::vector<content::IdentityProviderData> idp_data;
-    for (const auto& idp : idp_list) {
-      idp_data.emplace_back(
-          idp.idp_for_display, idp.accounts, idp.idp_metadata,
-          idp.client_metadata, blink::mojom::RpContext::kSignIn,
-          idp.disclosure_fields, idp.has_login_status_mismatch);
-    }
-    controller->Show(kTopFrameEtldPlusOne, idp_data, sign_in_mode, rp_mode,
-                     /*new_accounts_idp=*/std::nullopt);
+    controller->Show(kTopFrameEtldPlusOne, idp_list, accounts, sign_in_mode,
+                     rp_mode,
+                     /*new_accounts=*/std::vector<IdentityRequestAccountPtr>());
     return controller;
   }
 
   std::unique_ptr<TestFedCmAccountSelectionView>
   CreateAndShowAccountsModalThroughPopupWindow(
-      std::vector<content::IdentityRequestAccount> all_accounts,
-      content::IdentityProviderData new_idp_data) {
+      const std::vector<IdentityRequestAccountPtr>& all_accounts,
+      const std::vector<IdentityRequestAccountPtr>& new_accounts) {
     std::unique_ptr<TestFedCmAccountSelectionView> controller =
         CreateAndShowLoadingDialog();
     AccountSelectionViewBase::Observer* observer =
@@ -501,7 +453,7 @@
     controller->CloseModalDialog();
 
     Show(*controller, all_accounts, SignInMode::kExplicit,
-         blink::mojom::RpMode::kButton, new_idp_data);
+         blink::mojom::RpMode::kButton, new_accounts);
 
     return controller;
   }
@@ -511,11 +463,9 @@
       const std::vector<std::pair<std::string, LoginState>>& old_account_infos,
       const std::vector<std::pair<std::string, LoginState>>& new_account_infos,
       blink::mojom::RpMode rp_mode = blink::mojom::RpMode::kWidget) {
-    content::IdentityProviderData idp_data =
-        CreateIdentityProviderData(old_account_infos);
-    const std::vector<Account>& accounts = idp_data.accounts;
+    accounts_ = CreateAccounts(old_account_infos, idp_data_);
     std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(accounts, SignInMode::kExplicit, rp_mode);
+        CreateAndShow(accounts_, SignInMode::kExplicit, rp_mode);
     AccountSelectionViewBase::Observer* observer =
         static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -528,9 +478,7 @@
     // pop-up window and sending new accounts.
     controller->CloseModalDialog();
 
-    std::vector<content::IdentityRequestAccount> new_accounts =
-        CreateAccounts(new_account_infos);
-    content::IdentityProviderData new_idp_data = CreateNewIdpData(new_accounts);
+    new_accounts_ = CreateAccounts(new_account_infos, idp_data_);
 
     std::vector<std::pair<std::string, LoginState>> combined_account_infos =
         old_account_infos;
@@ -544,11 +492,11 @@
       combined_account_infos.emplace_back(account_info);
     }
 
-    content::IdentityProviderData combined_idp_data =
-        CreateIdentityProviderData(combined_account_infos);
+    const std::vector<IdentityRequestAccountPtr> combined_accounts =
+        CreateAccounts(combined_account_infos, idp_data_);
 
-    Show(*controller, combined_idp_data.accounts, SignInMode::kExplicit,
-         rp_mode, new_idp_data);
+    Show(*controller, combined_accounts, SignInMode::kExplicit, rp_mode,
+         new_accounts_);
 
     return controller;
   }
@@ -570,14 +518,15 @@
   std::unique_ptr<TestAccountSelectionView> account_selection_view_;
   std::unique_ptr<StubAccountSelectionViewDelegate> delegate_;
   std::unique_ptr<base::HistogramTester> histogram_tester_;
+
+  IdentityProviderDataPtr idp_data_;
+  std::vector<IdentityRequestAccountPtr> accounts_;
+  std::vector<IdentityRequestAccountPtr> new_accounts_;
 };
 
 TEST_F(FedCmAccountSelectionViewDesktopTest, SingleAccountFlow) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -587,7 +536,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -595,11 +544,11 @@
 }
 
 TEST_F(FedCmAccountSelectionViewDesktopTest, MultipleAccountFlowReturning) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignIn}, {kAccountId2, LoginState::kSignIn}});
-  const std::vector<Account>& accounts = idp_data.accounts;
+  accounts_ = CreateAccounts(
+      {{kAccountId1, LoginState::kSignIn}, {kAccountId2, LoginState::kSignIn}},
+      idp_data_);
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -609,7 +558,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1, kAccountId2));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -617,13 +566,11 @@
 }
 
 TEST_F(FedCmAccountSelectionViewDesktopTest, MultipleAccountFlowBack) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignUp},
-      {kAccountId2, LoginState::kSignUp},
-  });
-  const std::vector<Account>& accounts = idp_data.accounts;
+  accounts_ = CreateAccounts(
+      {{kAccountId1, LoginState::kSignUp}, {kAccountId2, LoginState::kSignUp}},
+      idp_data_);
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -633,7 +580,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1, kAccountId2));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_TRUE(account_selection_view_->show_back_button_);
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
             account_selection_view_->sheet_type_);
@@ -647,14 +594,14 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1, kAccountId2));
 
-  observer->OnAccountSelected(accounts[1], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[1], *idp_data_, CreateMouseEvent());
   EXPECT_TRUE(account_selection_view_->show_back_button_);
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId2));
 
-  observer->OnAccountSelected(accounts[1], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[1], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -673,17 +620,12 @@
   EXPECT_EQ(TestAccountSelectionView::SheetType::kFailure,
             account_selection_view_->sheet_type_);
 
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignUp},
-  });
-  content::IdentityProviderData new_idp_data =
-      CreateNewIdpData(CreateAccount(LoginState::kSignUp, LoginState::kSignUp));
-  Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-       blink::mojom::RpMode::kWidget, new_idp_data);
+  Show(*controller, accounts_, SignInMode::kExplicit,
+       blink::mojom::RpMode::kWidget, new_accounts_);
 
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
             account_selection_view_->sheet_type_);
-  observer->OnAccountSelected(idp_data.accounts[0], idp_data,
+  observer->OnAccountSelected(*new_accounts_[0], *idp_data_,
                               CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
@@ -704,18 +646,13 @@
   EXPECT_EQ(TestAccountSelectionView::SheetType::kFailure,
             account_selection_view_->sheet_type_);
 
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignUp},
-  });
 
   // If the user switched tabs to sign-into the IdP, Show() may be called while
   // the associated FedCM tab is inactive. Show() should not show the
   // views::Widget in this case.
   controller->OnTabBackgrounded();
-  content::IdentityProviderData new_idp_data =
-      CreateNewIdpData(CreateAccount(LoginState::kSignUp, LoginState::kSignUp));
-  Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-       blink::mojom::RpMode::kWidget, new_idp_data);
+  Show(*controller, accounts_, SignInMode::kExplicit,
+       blink::mojom::RpMode::kWidget, new_accounts_);
   EXPECT_FALSE(dialog_widget_->IsVisible());
 
   controller->OnTabForegrounded();
@@ -723,8 +660,7 @@
 
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
             account_selection_view_->sheet_type_);
-  observer->OnAccountSelected(idp_data.accounts[0], idp_data,
-                              CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
 
@@ -732,11 +668,9 @@
 }
 
 TEST_F(FedCmAccountSelectionViewDesktopTest, AutoReauthnSingleAccountFlow) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignIn}});
-  const std::vector<Account>& accounts = idp_data.accounts;
+  accounts_[0]->browser_trusted_login_state = LoginState::kSignIn;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kAuto);
+      CreateAndShow(accounts_, SignInMode::kAuto);
 
   EXPECT_FALSE(account_selection_view_->show_back_button_);
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
@@ -783,30 +717,25 @@
   ViewDeletingAccountSelectionViewDelegate* view_deleting_delegate =
       static_cast<ViewDeletingAccountSelectionViewDelegate*>(delegate_.get());
 
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignIn},
-  });
-  const std::vector<Account>& accounts = idp_data.accounts;
+  accounts_ = {
+      CreateAccount(idp_data_, LoginState::kSignIn, LoginState::kSignIn)};
 
   AccountSelectionViewBase::Observer* observer = nullptr;
   {
     std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(accounts, SignInMode::kExplicit);
+        CreateAndShow(accounts_, SignInMode::kExplicit);
     observer =
         static_cast<AccountSelectionViewBase::Observer*>(controller.get());
     view_deleting_delegate->SetView(std::move(controller));
   }
 
   // Destroys FedCmAccountSelectionView. Should not cause crash.
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
 }
 
 TEST_F(FedCmAccountSelectionViewDesktopTest, ClickProtection) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -820,7 +749,7 @@
   controller->SetInputEventActivationProtectorForTesting(
       std::move(input_protector));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   // Nothing should change after first account selected.
   EXPECT_FALSE(account_selection_view_->show_back_button_);
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
@@ -828,7 +757,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   // Should show verifying sheet after first account selected.
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
@@ -839,11 +768,10 @@
 // Tests that when the auth re-authn dialog is closed, the relevant metric is
 // recorded.
 TEST_F(FedCmAccountSelectionViewDesktopTest, CloseAutoReauthnSheetMetric) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignIn}});
-  const std::vector<Account>& accounts = idp_data.accounts;
+  accounts_ = {
+      CreateAccount(idp_data_, LoginState::kSignIn, LoginState::kSignIn)};
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kAuto);
+      CreateAndShow(accounts_, SignInMode::kAuto);
   histogram_tester_->ExpectTotalCount("Blink.FedCm.ClosedSheetType.Desktop", 0);
 
   AccountSelectionViewBase::Observer* observer =
@@ -998,13 +926,8 @@
 
     // Emulate IdP sending the IdP sign-in status header which updates the
     // mismatch dialog to an accounts dialog.
-    content::IdentityProviderData idp_data = CreateIdentityProviderData({
-        {kAccountId1, LoginState::kSignUp},
-    });
-    content::IdentityProviderData new_idp_data = CreateNewIdpData(
-        CreateAccount(LoginState::kSignUp, LoginState::kSignUp));
-    Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-         blink::mojom::RpMode::kWidget, new_idp_data);
+    Show(*controller, accounts_, SignInMode::kExplicit,
+         blink::mojom::RpMode::kWidget, new_accounts_);
 
     // Accounts dialog should now be visible. One account is logged in, so no
     // back button is shown.
@@ -1045,13 +968,8 @@
 
     // Emulate IdP sending the IdP sign-in status header which updates the
     // mismatch dialog to an accounts dialog.
-    content::IdentityProviderData idp_data = CreateIdentityProviderData({
-        {kAccountId1, LoginState::kSignUp},
-    });
-    content::IdentityProviderData new_idp_data = CreateNewIdpData(
-        CreateAccount(LoginState::kSignUp, LoginState::kSignUp));
-    Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-         blink::mojom::RpMode::kWidget, new_idp_data);
+    Show(*controller, accounts_, SignInMode::kExplicit,
+         blink::mojom::RpMode::kWidget, new_accounts_);
 
     // Accounts dialog should remain hidden because the pop-up window has not
     // been closed yet.
@@ -1101,13 +1019,8 @@
 
     // Emulate IdP sending the IdP sign-in status header which updates the
     // failure dialog to an accounts dialog.
-    content::IdentityProviderData idp_data = CreateIdentityProviderData({
-        {kAccountId1, LoginState::kSignUp},
-    });
-    content::IdentityProviderData new_idp_data = CreateNewIdpData(
-        CreateAccount(LoginState::kSignUp, LoginState::kSignUp));
-    Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-         blink::mojom::RpMode::kWidget, new_idp_data);
+    Show(*controller, accounts_, SignInMode::kExplicit,
+         blink::mojom::RpMode::kWidget, new_accounts_);
 
     histogram_tester_->ExpectTotalCount(
         "Blink.FedCm.IdpSigninStatus.PopupWindowResult", 0);
@@ -1294,13 +1207,8 @@
 
   // Emulate IdP sending the IdP sign-in status header which updates the
   // mismatch dialog to an accounts dialog.
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignUp},
-  });
-  content::IdentityProviderData new_idp_data =
-      CreateNewIdpData(CreateAccount(LoginState::kSignUp, LoginState::kSignUp));
-  Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-       blink::mojom::RpMode::kWidget, new_idp_data);
+  Show(*controller, accounts_, SignInMode::kExplicit,
+       blink::mojom::RpMode::kWidget, new_accounts_);
   EXPECT_FALSE(dialog_widget_->IsVisible());
 
   controller->OnTabForegrounded();
@@ -1340,13 +1248,8 @@
 
   // Emulate IdP sending the IdP sign-in status header which updates the
   // mismatch dialog to an accounts dialog.
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignUp},
-  });
-  content::IdentityProviderData new_idp_data =
-      CreateNewIdpData(CreateAccount(LoginState::kSignUp, LoginState::kSignUp));
-  Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-       blink::mojom::RpMode::kWidget, new_idp_data);
+  Show(*controller, accounts_, SignInMode::kExplicit,
+       blink::mojom::RpMode::kWidget, new_accounts_);
 
   // The widget should now be visible.
   EXPECT_TRUE(dialog_widget_->IsVisible());
@@ -1363,14 +1266,13 @@
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignUp}, {kAccountId2, LoginState::kSignUp}});
-  std::vector<content::IdentityRequestAccount> new_accounts = CreateAccounts(
-      {{kAccountId1, LoginState::kSignUp}, {kAccountId2, LoginState::kSignUp}});
-  content::IdentityProviderData new_idp_data = CreateNewIdpData(new_accounts);
+  accounts_ = CreateAccounts(
+      {{kAccountId1, LoginState::kSignUp}, {kAccountId2, LoginState::kSignUp}},
+      idp_data_);
+  new_accounts_ = accounts_;
 
-  Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-       blink::mojom::RpMode::kWidget, new_idp_data);
+  Show(*controller, accounts_, SignInMode::kExplicit,
+       blink::mojom::RpMode::kWidget, new_accounts_);
 
   EXPECT_EQ(TestAccountSelectionView::SheetType::kAccountPicker,
             account_selection_view_->sheet_type_);
@@ -1380,12 +1282,12 @@
   // There are no other accounts, so back button should not be present.
   EXPECT_FALSE(account_selection_view_->show_back_button_);
 
-  observer->OnAccountSelected(new_idp_data.accounts[0], idp_data,
+  observer->OnAccountSelected(*new_accounts_[0], *idp_data_,
                               CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
             account_selection_view_->sheet_type_);
   EXPECT_TRUE(account_selection_view_->show_back_button_);
-  observer->OnAccountSelected(idp_data.accounts[0], idp_data,
+  observer->OnAccountSelected(*new_accounts_[0], *idp_data_,
                               CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
@@ -1395,38 +1297,6 @@
   EXPECT_EQ(1u, controller->num_dialogs_);
 }
 
-// Test going from mismatch dialog to multiple accounts.
-TEST_F(FedCmAccountSelectionViewDesktopTest,
-       IdpMismatchToMultipleLoggedInAccounts) {
-  // Trigger IdP sign-in status mismatch dialog.
-  std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowMismatchDialog();
-  AccountSelectionViewBase::Observer* observer =
-      static_cast<AccountSelectionViewBase::Observer*>(controller.get());
-
-  // Emulate user clicking on "Continue" button in the mismatch dialog.
-  observer->OnLoginToIdP(GURL(kConfigUrl), GURL(kLoginUrl), CreateMouseEvent());
-  CreateAndShowPopupWindow(*controller);
-  // Emulate user completing the sign-in flow and IdP prompts closing the
-  // pop-up window.
-  controller->CloseModalDialog();
-
-  // Emulate IdP sending the IdP sign-in status header which updates the
-  // mismatch dialog to an accounts dialog.
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignUp}, {kAccountId2, LoginState::kSignUp}});
-  content::IdentityProviderData new_idp_data =
-      CreateNewIdpData(CreateAccounts({{kAccountId1, LoginState::kSignUp},
-                                       {kAccountId2, LoginState::kSignUp}}));
-  Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-       blink::mojom::RpMode::kWidget, new_idp_data);
-  EXPECT_FALSE(account_selection_view_->show_back_button_);
-  EXPECT_EQ(TestAccountSelectionView::SheetType::kAccountPicker,
-            account_selection_view_->sheet_type_);
-  EXPECT_THAT(account_selection_view_->account_ids_,
-              testing::ElementsAre(kAccountId1, kAccountId2));
-}
-
 // Test the use another account flow, resulting in the new account being shown
 // after logging in.
 TEST_F(FedCmAccountSelectionViewDesktopTest, UseAnotherAccount) {
@@ -1541,15 +1411,12 @@
 // chooser UI if it's a returning account.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        LoginStatusLoggedOutModalForReturningAccount) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignIn}},
-      /*has_login_status_mismatch=*/false, /*disclosure_fields=*/{});
-  std::vector<content::IdentityRequestAccount> all_accounts =
-      CreateAccount(LoginState::kSignIn, LoginState::kSignIn);
-  content::IdentityProviderData new_idp_data = CreateNewIdpData(all_accounts);
+  accounts_ = {
+      CreateAccount(idp_data_, LoginState::kSignIn, LoginState::kSignIn)};
+  new_accounts_ = accounts_;
 
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowAccountsModalThroughPopupWindow(all_accounts, new_idp_data);
+      CreateAndShowAccountsModalThroughPopupWindow(accounts_, new_accounts_);
 
   // The account chooser UI is NOT skipped if user signed in from LOADING state.
   EXPECT_EQ(TestAccountSelectionView::SheetType::kAccountPicker,
@@ -1563,15 +1430,8 @@
 // chooser UI if it's a non-returning account.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        LoginStatusLoggedOutModalForNonReturningAccount) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignUp}},
-      /*has_login_status_mismatch=*/false, /*disclosure_fields=*/{});
-  std::vector<content::IdentityRequestAccount> all_accounts =
-      CreateAccount(LoginState::kSignUp, LoginState::kSignUp);
-  content::IdentityProviderData new_idp_data = CreateNewIdpData(all_accounts);
-
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowAccountsModalThroughPopupWindow(all_accounts, new_idp_data);
+      CreateAndShowAccountsModalThroughPopupWindow(accounts_, new_accounts_);
 
   // The permission UI is NOT skipped.
   EXPECT_EQ(TestAccountSelectionView::SheetType::kRequestPermission,
@@ -1584,16 +1444,13 @@
 // chooser UI when in conflict with login state.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        BrowserTrustedLoginStateTakesPrecedenceOverLoginState) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignUp}},
-      /*has_login_status_mismatch=*/false, /*disclosure_fields=*/{});
-  std::vector<content::IdentityRequestAccount> all_accounts =
-      CreateAccount(/*idp_claimed_login_state=*/LoginState::kSignIn,
-                    /*browser_trusted_login_state=*/LoginState::kSignUp);
-  content::IdentityProviderData new_idp_data = CreateNewIdpData(all_accounts);
+  accounts_ = {
+      CreateAccount(idp_data_, /*idp_claimed_login_state=*/LoginState::kSignIn,
+                    /*browser_trusted_login_state=*/LoginState::kSignUp)};
+  new_accounts_ = accounts_;
 
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowAccountsModalThroughPopupWindow(all_accounts, new_idp_data);
+      CreateAndShowAccountsModalThroughPopupWindow(accounts_, new_accounts_);
 
   // The account chooser UI is NOT skipped. Normally, this is permission UI but
   // because we do not want to show disclosure UI without disclosure text, we
@@ -1608,18 +1465,14 @@
 // Test user triggering the use another account flow twice in a modal, without
 // closing the pop-up from the first use another account flow.
 TEST_F(FedCmAccountSelectionViewDesktopTest, UseAnotherAccountTwiceModal) {
-  const char kAccountId[] = "account_id";
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
   EXPECT_FALSE(account_selection_view_->show_back_button_);
   EXPECT_THAT(account_selection_view_->account_ids_,
-              testing::ElementsAre(kAccountId));
+              testing::ElementsAre(kAccountId1));
 
   // Emulate the user clicking "use another account button".
   observer->OnLoginToIdP(GURL(kConfigUrl), GURL(kLoginUrl), CreateMouseEvent());
@@ -1638,18 +1491,14 @@
 // closing the pop-up from the first use another account flow.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        UseAnotherAccountCloseThenReopenModal) {
-  const char kAccountId[] = "account_id";
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
   EXPECT_FALSE(account_selection_view_->show_back_button_);
   EXPECT_THAT(account_selection_view_->account_ids_,
-              testing::ElementsAre(kAccountId));
+              testing::ElementsAre(kAccountId1));
 
   // Emulate the user clicking "use another account button".
   observer->OnLoginToIdP(GURL(kConfigUrl), GURL(kLoginUrl), CreateMouseEvent());
@@ -1673,18 +1522,14 @@
 // Test user triggering the use another account flow then clicking on the cancel
 // button in the modal without completing the use other account flow.
 TEST_F(FedCmAccountSelectionViewDesktopTest, UseAnotherAccountThenCancel) {
-  const char kAccountId[] = "account_id";
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
   EXPECT_FALSE(account_selection_view_->show_back_button_);
   EXPECT_THAT(account_selection_view_->account_ids_,
-              testing::ElementsAre(kAccountId));
+              testing::ElementsAre(kAccountId1));
 
   // Emulate the user clicking "use another account button".
   observer->OnLoginToIdP(GURL(kConfigUrl), GURL(kLoginUrl), CreateMouseEvent());
@@ -1768,12 +1613,13 @@
 }
 
 TEST_F(FedCmAccountSelectionViewDesktopTest, MultiIdpWithOneIdpMismatch) {
-  std::vector<content::IdentityProviderData> idp_list = {
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}}),
-      CreateIdentityProviderData(/*account_infos=*/{},
-                                 /*has_login_status_mismatch*/ true)};
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      CreateIdentityProviderData(),
+      CreateIdentityProviderData(/*has_login_status_mismatch*/ true)};
+  std::vector<IdentityRequestAccountPtr> accounts = {
+      CreateAccount(idp_list[0])};
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowMultiIdp(idp_list, SignInMode::kExplicit,
+      CreateAndShowMultiIdp(idp_list, accounts, SignInMode::kExplicit,
                             blink::mojom::RpMode::kWidget);
 
   AccountSelectionViewBase::Observer* observer =
@@ -1785,8 +1631,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(idp_list[0].accounts[0], idp_list[0],
-                              CreateMouseEvent());
+  observer->OnAccountSelected(*accounts[0], *idp_list[0], CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -1798,13 +1643,15 @@
 
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        MultiIdpWithSingleReturningAccount) {
-  std::vector<content::IdentityProviderData> idp_list = {
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignIn}}),
-      CreateIdentityProviderData({{kAccountId2, LoginState::kSignUp}}),
-      CreateIdentityProviderData({},
-                                 /*has_login_status_mismatch=*/true)};
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      CreateIdentityProviderData(), CreateIdentityProviderData(),
+      CreateIdentityProviderData(/*has_login_status_mismatch=*/true)};
+  std::vector<IdentityRequestAccountPtr> accounts = {
+      CreateAccount(idp_list[0], LoginState::kSignIn, LoginState::kSignIn),
+      CreateAccount(idp_list[1], LoginState::kSignUp, LoginState::kSignUp,
+                    kAccountId2)};
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowMultiIdp(idp_list, SignInMode::kExplicit,
+      CreateAndShowMultiIdp(idp_list, accounts, SignInMode::kExplicit,
                             blink::mojom::RpMode::kWidget);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
@@ -1826,8 +1673,7 @@
               testing::ElementsAre(kAccountId1, kAccountId2));
 
   // Simulate second account picked.
-  observer->OnAccountSelected(idp_list[1].accounts[0], idp_list[1],
-                              CreateMouseEvent());
+  observer->OnAccountSelected(*accounts[1], *idp_list[1], CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -1853,8 +1699,7 @@
               testing::ElementsAre(kAccountId1));
 
   // Simulate account picked
-  observer->OnAccountSelected(idp_list[0].accounts[0], idp_list[0],
-                              CreateMouseEvent());
+  observer->OnAccountSelected(*accounts[0], *idp_list[0], CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -1867,13 +1712,15 @@
 // does not cause a crash.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        MultiIdpWithSingleReturningAccountClose) {
-  std::vector<content::IdentityProviderData> idp_list = {
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignIn}}),
-      CreateIdentityProviderData({{kAccountId2, LoginState::kSignUp}}),
-      CreateIdentityProviderData({},
-                                 /*has_login_status_mismatch=*/true)};
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      CreateIdentityProviderData(), CreateIdentityProviderData(),
+      CreateIdentityProviderData(/*has_login_status_mismatch=*/true)};
+  std::vector<IdentityRequestAccountPtr> accounts = {
+      CreateAccount(idp_list[0], LoginState::kSignIn, LoginState::kSignIn),
+      CreateAccount(idp_list[1], LoginState::kSignUp, LoginState::kSignUp,
+                    kAccountId2)};
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowMultiIdp(idp_list, SignInMode::kExplicit,
+      CreateAndShowMultiIdp(idp_list, accounts, SignInMode::kExplicit,
                             blink::mojom::RpMode::kWidget);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
@@ -1915,12 +1762,13 @@
 }
 
 TEST_F(FedCmAccountSelectionViewDesktopTest, MultiIdpMismatchAndShow) {
-  std::vector<content::IdentityProviderData> idp_list = {
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}}),
-      CreateIdentityProviderData(/*account_infos=*/{},
-                                 /*has_login_status_mismatch=*/true)};
+  std::vector<IdentityProviderDataPtr> idp_list = {
+      CreateIdentityProviderData(),
+      CreateIdentityProviderData(/*has_login_status_mismatch=*/true)};
+  std::vector<IdentityRequestAccountPtr> accounts = {
+      CreateAccount(idp_list[0])};
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowMultiIdp(idp_list, SignInMode::kExplicit,
+      CreateAndShowMultiIdp(idp_list, accounts, SignInMode::kExplicit,
                             blink::mojom::RpMode::kWidget);
 
   // Emulate user clicking on "Continue" button in the mismatch dialog.
@@ -1931,13 +1779,13 @@
   controller->CloseModalDialog();
 
   // The backend will pass the accounts reordered.
-  std::vector<content::IdentityRequestAccount> all_accounts = CreateAccounts(
-      {{kAccountId2, LoginState::kSignUp}, {kAccountId1, LoginState::kSignUp}});
-  content::IdentityProviderData new_idp_data = CreateNewIdpData(
-      CreateAccount(LoginState::kSignUp, LoginState::kSignUp, kAccountId2));
+  std::vector<IdentityRequestAccountPtr> new_accounts = {CreateAccount(
+      idp_list[1], LoginState::kSignUp, LoginState::kSignUp, kAccountId2)};
+  std::vector<IdentityRequestAccountPtr> all_accounts = new_accounts;
+  all_accounts.emplace_back(accounts[0]);
 
   Show(*controller, all_accounts, SignInMode::kExplicit,
-       blink::mojom::RpMode::kButton, new_idp_data);
+       blink::mojom::RpMode::kButton, new_accounts);
 
   // Should show only the new account, with a back button for other account.
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
@@ -1960,11 +1808,8 @@
 // selecting an account shows the request permission sheet. Then, confirming the
 // account on the request permission sheet shows the verifying sheet.
 TEST_F(FedCmAccountSelectionViewDesktopTest, SingleAccountFlowModal) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -1974,13 +1819,13 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kRequestPermission,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -1991,11 +1836,11 @@
 // selecting an account shows the request permission sheet. Then, confirming the
 // account on the request permission sheet shows the verifying sheet.
 TEST_F(FedCmAccountSelectionViewDesktopTest, MultipleAccountFlowModal) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignUp}, {kAccountId2, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
+  accounts_ = CreateAccounts(
+      {{kAccountId1, LoginState::kSignUp}, {kAccountId2, LoginState::kSignUp}},
+      idp_data_);
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -2005,13 +1850,13 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1, kAccountId2));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kRequestPermission,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -2021,11 +1866,10 @@
 // Tests that if a single account chooser is opened in button flow mode,
 // selecting a returning account shows the verifying sheet.
 TEST_F(FedCmAccountSelectionViewDesktopTest, SingleAccountFlowReturningModal) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignIn}});
-  const std::vector<Account>& accounts = idp_data.accounts;
+  accounts_ = {
+      CreateAccount(idp_data_, LoginState::kSignIn, LoginState::kSignIn)};
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -2035,7 +1879,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -2046,11 +1890,11 @@
 // selecting a returning account shows the verifying sheet.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        MultipleAccountFlowReturningModal) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignIn}, {kAccountId2, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
+  accounts_ = CreateAccounts(
+      {{kAccountId1, LoginState::kSignIn}, {kAccountId2, LoginState::kSignUp}},
+      idp_data_);
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -2060,7 +1904,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1, kAccountId2));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -2071,11 +1915,8 @@
 // clicking the back button in the request permission dialog returns the user to
 // the single account chooser.
 TEST_F(FedCmAccountSelectionViewDesktopTest, SingleAccountFlowBackModal) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -2085,7 +1926,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_TRUE(account_selection_view_->show_back_button_);
   EXPECT_EQ(TestAccountSelectionView::SheetType::kRequestPermission,
             account_selection_view_->sheet_type_);
@@ -2099,14 +1940,14 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_TRUE(account_selection_view_->show_back_button_);
   EXPECT_EQ(TestAccountSelectionView::SheetType::kRequestPermission,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -2117,13 +1958,11 @@
 // clicking the back button in the request permission dialog returns the user to
 // the multiple account chooser.
 TEST_F(FedCmAccountSelectionViewDesktopTest, MultipleAccountFlowBackModal) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignUp},
-      {kAccountId2, LoginState::kSignUp},
-  });
-  const std::vector<Account>& accounts = idp_data.accounts;
+  accounts_ = CreateAccounts(
+      {{kAccountId1, LoginState::kSignUp}, {kAccountId2, LoginState::kSignUp}},
+      idp_data_);
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -2133,7 +1972,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1, kAccountId2));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_TRUE(account_selection_view_->show_back_button_);
   EXPECT_EQ(TestAccountSelectionView::SheetType::kRequestPermission,
             account_selection_view_->sheet_type_);
@@ -2147,14 +1986,14 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1, kAccountId2));
 
-  observer->OnAccountSelected(accounts[1], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[1], *idp_data_, CreateMouseEvent());
   EXPECT_TRUE(account_selection_view_->show_back_button_);
   EXPECT_EQ(TestAccountSelectionView::SheetType::kRequestPermission,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId2));
 
-  observer->OnAccountSelected(accounts[1], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[1], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -2168,10 +2007,9 @@
       CreateAndShowLoadingDialog();
 
   EXPECT_CALL(*controller, MaybeResetAccountSelectionView).Times(0);
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignIn},
-  });
-  Show(*controller, idp_data.accounts, SignInMode::kAuto,
+  accounts_ = {
+      CreateAccount(idp_data_, LoginState::kSignIn, LoginState::kSignIn)};
+  Show(*controller, accounts_, SignInMode::kAuto,
        blink::mojom::RpMode::kButton);
 
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
@@ -2228,11 +2066,8 @@
 // notifies the observer.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        UserClosingPopupAfterVerifyingSheetShouldNotify) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -2242,7 +2077,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
 
@@ -2255,11 +2090,8 @@
 // programmatically, does not notify the observer.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        CodeClosingPopupAfterVerifyingSheetShouldNotNotify) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -2269,7 +2101,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
 
@@ -2282,13 +2114,9 @@
 // shown.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        SkipRequestPermissionShowsVerifying) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignUp}},
-      /*has_login_status_mismatch=*/false, /*disclosure_fields=*/{});
-  const std::vector<Account>& accounts = idp_data.accounts;
+  idp_data_->disclosure_fields = {};
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kWidget,
-      /*new_account_idp=*/std::nullopt, /*disclosure_fields=*/{});
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kWidget);
   AccountSelectionViewBase::Observer* observer =
       static_cast<AccountSelectionViewBase::Observer*>(controller.get());
 
@@ -2298,7 +2126,7 @@
   EXPECT_THAT(account_selection_view_->account_ids_,
               testing::ElementsAre(kAccountId1));
 
-  observer->OnAccountSelected(accounts[0], idp_data, CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
   EXPECT_THAT(account_selection_view_->account_ids_,
@@ -2308,52 +2136,37 @@
 // Tests that if IDP supports add account, the correct sheet type is shown
 // depending on the number of accounts and the rp mode.
 TEST_F(FedCmAccountSelectionViewDesktopTest, SupportAddAccount) {
-  content::IdentityProviderData single_account_idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  content::IdentityProviderData multiple_accounts_idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignIn},
-                                  {kAccountId2, LoginState::kSignIn}});
-
-  content::IdentityProviderMetadata idp_metadata;
-  idp_metadata.supports_add_account = true;
-
+  idp_data_->idp_metadata.supports_add_account = true;
+  std::vector<IdentityRequestAccountPtr> multiple_accounts = CreateAccounts(
+      {{kAccountId1, LoginState::kSignIn}, {kAccountId2, LoginState::kSignIn}},
+      idp_data_);
   {
     // Single account widget flow.
-    std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(single_account_idp_data.accounts, SignInMode::kExplicit,
-                      blink::mojom::RpMode::kWidget,
-                      /*new_account_idp=*/std::nullopt,
-                      /*disclosure_fields=*/{}, idp_metadata);
+    std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
+        accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kWidget);
     EXPECT_EQ(TestAccountSelectionView::SheetType::kAccountPicker,
               account_selection_view_->sheet_type_);
   }
   {
     // Multiple account widget flow.
     std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(multiple_accounts_idp_data.accounts,
-                      SignInMode::kExplicit, blink::mojom::RpMode::kWidget,
-                      /*new_account_idp=*/std::nullopt,
-                      /*disclosure_fields=*/{}, idp_metadata);
+        CreateAndShow(multiple_accounts, SignInMode::kExplicit,
+                      blink::mojom::RpMode::kWidget);
     EXPECT_EQ(TestAccountSelectionView::SheetType::kAccountPicker,
               account_selection_view_->sheet_type_);
   }
   {
     // Single account button flow.
-    std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(single_account_idp_data.accounts, SignInMode::kExplicit,
-                      blink::mojom::RpMode::kButton,
-                      /*new_account_idp=*/std::nullopt,
-                      /*disclosure_fields=*/{}, idp_metadata);
+    std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
+        accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
     EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
               account_selection_view_->sheet_type_);
   }
   {
     // Multiple account button flow.
     std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(multiple_accounts_idp_data.accounts,
-                      SignInMode::kExplicit, blink::mojom::RpMode::kButton,
-                      /*new_account_idp=*/std::nullopt,
-                      /*disclosure_fields=*/{}, idp_metadata);
+        CreateAndShow(multiple_accounts, SignInMode::kExplicit,
+                      blink::mojom::RpMode::kButton);
     EXPECT_EQ(TestAccountSelectionView::SheetType::kAccountPicker,
               account_selection_view_->sheet_type_);
   }
@@ -2371,16 +2184,10 @@
   EXPECT_EQ(TestAccountSelectionView::SheetType::kFailure,
             account_selection_view_->sheet_type_);
 
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignUp},
-  });
-  content::IdentityProviderData new_idp_data =
-      CreateNewIdpData(CreateAccount(LoginState::kSignUp, LoginState::kSignUp));
-  content::IdentityProviderMetadata idp_metadata;
-  idp_metadata.supports_add_account = true;
-  Show(*controller, idp_data.accounts, SignInMode::kExplicit,
-       blink::mojom::RpMode::kWidget, new_idp_data, kDefaultDisclosureFields,
-       idp_metadata);
+  idp_data_->idp_metadata.supports_add_account = true;
+
+  Show(*controller, accounts_, SignInMode::kExplicit,
+       blink::mojom::RpMode::kWidget, new_accounts_);
 
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
             account_selection_view_->sheet_type_);
@@ -2389,12 +2196,10 @@
   EXPECT_EQ(TestAccountSelectionView::SheetType::kAccountPicker,
             account_selection_view_->sheet_type_);
 
-  observer->OnAccountSelected(idp_data.accounts[0], idp_data,
-                              CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kConfirmAccount,
             account_selection_view_->sheet_type_);
-  observer->OnAccountSelected(idp_data.accounts[0], idp_data,
-                              CreateMouseEvent());
+  observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   EXPECT_EQ(TestAccountSelectionView::SheetType::kVerifying,
             account_selection_view_->sheet_type_);
 
@@ -2403,8 +2208,6 @@
 
 // Tests that the correct account chooser result metrics are recorded.
 TEST_F(FedCmAccountSelectionViewDesktopTest, AccountChooserResultMetric) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
   auto CheckForSampleAndReset(
       [&](FedCmAccountSelectionView::AccountChooserResult result) {
         histogram_tester_->ExpectUniqueSample(
@@ -2418,22 +2221,19 @@
   // of scope.
   {
     // User clicks on account row.
-    std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(idp_data.accounts, SignInMode::kExplicit,
-                      blink::mojom::RpMode::kButton);
+    std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
+        accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
     AccountSelectionViewBase::Observer* observer =
         static_cast<AccountSelectionViewBase::Observer*>(controller.get());
-    observer->OnAccountSelected(idp_data.accounts[0], idp_data,
-                                CreateMouseEvent());
+    observer->OnAccountSelected(*accounts_[0], *idp_data_, CreateMouseEvent());
   }
   CheckForSampleAndReset(
       FedCmAccountSelectionView::AccountChooserResult::kAccountRow);
 
   {
     // User clicks on cancel button.
-    std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(idp_data.accounts, SignInMode::kExplicit,
-                      blink::mojom::RpMode::kButton);
+    std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
+        accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
     AccountSelectionViewBase::Observer* observer =
         static_cast<AccountSelectionViewBase::Observer*>(controller.get());
     observer->OnCloseButtonClicked(CreateMouseEvent());
@@ -2443,9 +2243,8 @@
 
   {
     // User clicks on use other account button.
-    std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(idp_data.accounts, SignInMode::kExplicit,
-                      blink::mojom::RpMode::kButton);
+    std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
+        accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
     AccountSelectionViewBase::Observer* observer =
         static_cast<AccountSelectionViewBase::Observer*>(controller.get());
     observer->OnLoginToIdP(GURL(kConfigUrl), GURL(kLoginUrl),
@@ -2456,9 +2255,8 @@
 
   {
     // User closes the tab or window.
-    std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(idp_data.accounts, SignInMode::kExplicit,
-                      blink::mojom::RpMode::kButton);
+    std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
+        accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
   }
   CheckForSampleAndReset(
       FedCmAccountSelectionView::AccountChooserResult::kTabClosed);
@@ -2466,18 +2264,17 @@
   {
     // Returning user signing in via IDP sign-in pop-up when signed-out should
     // record a sample.
-    std::vector<content::IdentityRequestAccount> all_accounts =
-        CreateAccount(LoginState::kSignIn, LoginState::kSignIn);
-    content::IdentityProviderData new_idp_data = CreateNewIdpData(all_accounts);
+    std::vector<IdentityRequestAccountPtr> accounts = {
+        CreateAccount(idp_data_, LoginState::kSignIn, LoginState::kSignIn)};
+    std::vector<IdentityRequestAccountPtr> new_accounts = accounts;
     std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShowAccountsModalThroughPopupWindow(all_accounts,
-                                                     new_idp_data);
+        CreateAndShowAccountsModalThroughPopupWindow(accounts, new_accounts);
     // User is shown the account chooser.
     EXPECT_EQ(TestAccountSelectionView::SheetType::kAccountPicker,
               account_selection_view_->sheet_type_);
     AccountSelectionViewBase::Observer* observer =
         static_cast<AccountSelectionViewBase::Observer*>(controller.get());
-    observer->OnAccountSelected(idp_data.accounts[0], idp_data,
+    observer->OnAccountSelected(*new_accounts[0], *idp_data_,
                                 CreateMouseEvent());
   }
   CheckForSampleAndReset(
@@ -2486,12 +2283,8 @@
   {
     // Non-returning user signing in via IDP sign-in pop-up should not record a
     // sample.
-    std::vector<content::IdentityRequestAccount> all_accounts =
-        CreateAccount(LoginState::kSignUp, LoginState::kSignUp);
-    content::IdentityProviderData new_idp_data = CreateNewIdpData(all_accounts);
     std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShowAccountsModalThroughPopupWindow(all_accounts,
-                                                     new_idp_data);
+        CreateAndShowAccountsModalThroughPopupWindow(accounts_, new_accounts_);
 
     // User is shown the request permission dialog, skipping the account
     // chooser.
@@ -2502,9 +2295,8 @@
                                       0);
   {
     // Widget flow should not record a sample.
-    std::unique_ptr<TestFedCmAccountSelectionView> controller =
-        CreateAndShow(idp_data.accounts, SignInMode::kExplicit,
-                      blink::mojom::RpMode::kWidget);
+    std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
+        accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kWidget);
   }
   histogram_tester_->ExpectTotalCount("Blink.FedCm.Button.AccountChooserResult",
                                       0);
@@ -2515,11 +2307,8 @@
 // bubble, since the error UI does not have a modal equivalent.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        AccountsToErrorButtonFlowResetsView) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller = CreateAndShow(
-      accounts, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
+      accounts_, SignInMode::kExplicit, blink::mojom::RpMode::kButton);
 
   EXPECT_CALL(*controller, MaybeResetAccountSelectionView).Times(1);
   controller->ShowErrorDialog(
@@ -2537,10 +2326,7 @@
       CreateAndShowLoadingDialog();
 
   EXPECT_CALL(*controller, MaybeResetAccountSelectionView).Times(0);
-  content::IdentityProviderData idp_data = CreateIdentityProviderData({
-      {kAccountId1, LoginState::kSignUp},
-  });
-  Show(*controller, idp_data.accounts, SignInMode::kExplicit,
+  Show(*controller, accounts_, SignInMode::kExplicit,
        blink::mojom::RpMode::kButton);
 }
 
@@ -2548,11 +2334,8 @@
 // on whether the dialog can fit within the web contents.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        ResizeWebContentsChangesDialogVisibility) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
   EXPECT_TRUE(dialog_widget_->IsVisible());
 
   // Emulate that the web contents is too small to fit the dialog, hiding the
@@ -2574,11 +2357,8 @@
 // the dialog is contained is visible.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        ResizeWebContentsWithWindowVisibilityChanges) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
 
   // Emulate user changing tabs, hiding the dialog.
   controller->OnTabBackgrounded();
@@ -2630,11 +2410,8 @@
 // hidden.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        VisibilityChangesUpdatesDialogPosition) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
 
   // Emulate user changing tabs, hiding the dialog.
   controller->OnTabBackgrounded();
@@ -2651,11 +2428,8 @@
 // Tests that the Lens overlay showing hides the dialog until the overlay is
 // closed.
 TEST_F(FedCmAccountSelectionViewDesktopTest, LensOverlayHidesDialog) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShow(accounts, SignInMode::kExplicit);
+      CreateAndShow(accounts_, SignInMode::kExplicit);
   EXPECT_TRUE(dialog_widget_->IsVisible());
 
   controller->OnLensOverlayDidShow();
@@ -2667,11 +2441,8 @@
 
 // Tests that the dialog does not open if the Lens overlay is already showing.
 TEST_F(FedCmAccountSelectionViewDesktopTest, LensOverlaySuppressesDialog) {
-  content::IdentityProviderData idp_data =
-      CreateIdentityProviderData({{kAccountId1, LoginState::kSignUp}});
-  const std::vector<Account>& accounts = idp_data.accounts;
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowWithLensOverlay(accounts, SignInMode::kExplicit);
+      CreateAndShowWithLensOverlay(accounts_, SignInMode::kExplicit);
   EXPECT_FALSE(dialog_widget_->IsVisible());
 
   controller->OnLensOverlayDidClose();
@@ -2685,16 +2456,9 @@
 // disclosure UI after logging in through the popup when logged out.
 TEST_F(FedCmAccountSelectionViewDesktopTest,
        RequestPermissionFalseAndNewIdpDataDisclosureText) {
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(
-      {{kAccountId1, LoginState::kSignUp}},
-      /*has_login_status_mismatch=*/false, /*disclosure_fields=*/{});
-  std::vector<content::IdentityRequestAccount> all_accounts =
-      CreateAccount(LoginState::kSignUp, LoginState::kSignUp);
-  content::IdentityProviderData new_idp_data = CreateNewIdpData(all_accounts);
-  new_idp_data.disclosure_fields = {};
-
+  idp_data_->disclosure_fields = {};
   std::unique_ptr<TestFedCmAccountSelectionView> controller =
-      CreateAndShowAccountsModalThroughPopupWindow(all_accounts, new_idp_data);
+      CreateAndShowAccountsModalThroughPopupWindow(accounts_, new_accounts_);
 
   // The account chooser UI is NOT skipped if user signed in from LOADING state.
   EXPECT_EQ(TestAccountSelectionView::SheetType::kAccountPicker,
diff --git a/chrome/browser/ui/webid/account_selection_view.h b/chrome/browser/ui/webid/account_selection_view.h
index 8b82802..307c9cd 100644
--- a/chrome/browser/ui/webid/account_selection_view.h
+++ b/chrome/browser/ui/webid/account_selection_view.h
@@ -12,6 +12,9 @@
 #include "ui/gfx/native_widget_types.h"
 
 using Account = content::IdentityRequestAccount;
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
 using LinkType = content::IdentityRequestDialogController::LinkType;
 using TokenError = content::IdentityCredentialTokenError;
 
@@ -58,19 +61,20 @@
 
   // Instructs the view to show the provided accounts to the user.
   // `rp_for_display` is the relying party's URL. All IDP-specific information,
-  // including user accounts, is stored in `idps_for_display`. `sign_in_mode`
+  // is stored in `idp_list`. `sign_in_mode`
   // represents whether this is an auto re-authn flow. If it is the auto
-  // re-authn flow, `idps_for_display` will only include the single returning
-  // account and its IDP. `new_accounts_idp` represents the account information
-  // of a newly logged in account that ought to be prioritized in the UI.
+  // re-authn flow, `idp_list` will only include the single
+  // returning account and its IDP. `new_accounts` is a vector where each member
+  // is a newly logged in account that ought to be prioritized in the UI.
   // Returns true if it was possible to show UI. If this method could not show
   // UI and called Dismiss, returns false.
   virtual bool Show(
       const std::string& rp_for_display,
-      const std::vector<content::IdentityProviderData>& identity_provider_data,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       Account::SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<content::IdentityProviderData>& new_accounts_idp) = 0;
+      const std::vector<IdentityRequestAccountPtr>& new_accounts) = 0;
 
   // Shows a failure UI when the accounts fetch is failed such that it is
   // observable by users. This could happen when an IDP claims that the user is
diff --git a/chrome/browser/ui/webid/identity_dialog_controller.cc b/chrome/browser/ui/webid/identity_dialog_controller.cc
index 216608701..76818a7 100644
--- a/chrome/browser/ui/webid/identity_dialog_controller.cc
+++ b/chrome/browser/ui/webid/identity_dialog_controller.cc
@@ -40,10 +40,11 @@
 
 bool IdentityDialogController::ShowAccountsDialog(
     const std::string& rp_for_display,
-    const std::vector<content::IdentityProviderData>& identity_provider_data,
+    const std::vector<IdentityProviderDataPtr>& identity_provider_data,
+    const std::vector<IdentityRequestAccountPtr>& accounts,
     content::IdentityRequestAccount::SignInMode sign_in_mode,
     blink::mojom::RpMode rp_mode,
-    const std::optional<content::IdentityProviderData>& new_account_idp,
+    const std::vector<IdentityRequestAccountPtr>& new_accounts,
     AccountSelectionCallback on_selected,
     LoginToIdPCallback on_add_account,
     DismissCallback dismiss_callback,
@@ -56,8 +57,8 @@
   if (!TrySetAccountView()) {
     return false;
   }
-  return account_view_->Show(rp_for_display, identity_provider_data,
-                             sign_in_mode, rp_mode, new_account_idp);
+  return account_view_->Show(rp_for_display, identity_provider_data, accounts,
+                             sign_in_mode, rp_mode, new_accounts);
 }
 
 bool IdentityDialogController::ShowFailureDialog(
diff --git a/chrome/browser/ui/webid/identity_dialog_controller.h b/chrome/browser/ui/webid/identity_dialog_controller.h
index 5873c5e..be08141 100644
--- a/chrome/browser/ui/webid/identity_dialog_controller.h
+++ b/chrome/browser/ui/webid/identity_dialog_controller.h
@@ -20,6 +20,9 @@
     content::IdentityRequestDialogController::AccountSelectionCallback;
 using DismissCallback =
     content::IdentityRequestDialogController::DismissCallback;
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
 using TokenError = content::IdentityCredentialTokenError;
 
 // The IdentityDialogController controls the views that are used across
@@ -42,10 +45,11 @@
   // content::IdentityRequestDialogController
   bool ShowAccountsDialog(
       const std::string& rp_for_display,
-      const std::vector<content::IdentityProviderData>& identity_provider_data,
+      const std::vector<IdentityProviderDataPtr>& identity_provider_data,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       content::IdentityRequestAccount::SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<content::IdentityProviderData>& new_account_idp,
+      const std::vector<IdentityRequestAccountPtr>& new_accounts,
       AccountSelectionCallback on_selected,
       LoginToIdPCallback on_add_account,
       DismissCallback dismiss_callback,
diff --git a/chrome/browser/ui/webid/identity_dialog_controller_unittest.cc b/chrome/browser/ui/webid/identity_dialog_controller_unittest.cc
index b610f213..e942d77 100644
--- a/chrome/browser/ui/webid/identity_dialog_controller_unittest.cc
+++ b/chrome/browser/ui/webid/identity_dialog_controller_unittest.cc
@@ -46,10 +46,11 @@
       bool,
       Show,
       (const std::string& rp_for_display,
-       const std::vector<content::IdentityProviderData>& identity_provider_data,
+       const std::vector<IdentityProviderDataPtr>& identity_provider_data,
+       const std::vector<IdentityRequestAccountPtr>& accounts,
        Account::SignInMode sign_in_mode,
        blink::mojom::RpMode rp_mode,
-       const std::optional<content::IdentityProviderData>& new_account_idp),
+       const std::vector<IdentityRequestAccountPtr>& new_accounts),
       (override));
 
   MOCK_METHOD(bool,
@@ -134,26 +135,29 @@
     task_environment()->RunUntilIdle();
   }
 
-  std::vector<content::IdentityRequestAccount> CreateAccount() {
-    return {
-        {"account_id1", "", "", "", GURL(),
-         /*login_hints=*/std::vector<std::string>(),
-         /*domain_hints=*/std::vector<std::string>(),
-         /*labels=*/std::vector<std::string>(),
-         /*login_state=*/content::IdentityRequestAccount::LoginState::kSignUp,
-         /*browser_trusted_login_state=*/
-         content::IdentityRequestAccount::LoginState::kSignUp}};
+  std::vector<IdentityRequestAccountPtr> CreateAccount() {
+    return {base::MakeRefCounted<Account>(
+        "account_id1", "", "", "", GURL(),
+        /*login_hints=*/std::vector<std::string>(),
+        /*domain_hints=*/std::vector<std::string>(),
+        /*labels=*/std::vector<std::string>(),
+        /*login_state=*/content::IdentityRequestAccount::LoginState::kSignUp,
+        /*browser_trusted_login_state=*/
+        content::IdentityRequestAccount::LoginState::kSignUp)};
   }
 
-  content::IdentityProviderData CreateIdentityProviderData(
-      std::vector<content::IdentityRequestAccount> accounts) {
-    return {kIdpEtldPlusOne,
-            accounts,
-            content::IdentityProviderMetadata(),
+  IdentityProviderDataPtr CreateIdentityProviderData(
+      std::vector<IdentityRequestAccountPtr>& accounts) {
+    IdentityProviderDataPtr idp_data =
+        base::MakeRefCounted<content::IdentityProviderData>(
+            kIdpEtldPlusOne, content::IdentityProviderMetadata(),
             content::ClientMetadata(GURL(), GURL(), GURL()),
-            blink::mojom::RpContext::kSignIn,
-            kDefaultPermissions,
-            /*has_login_status_mismatch=*/false};
+            blink::mojom::RpContext::kSignIn, kDefaultPermissions,
+            /*has_login_status_mismatch=*/false);
+    for (auto& account : accounts) {
+      account->identity_provider = idp_data;
+    }
+    return idp_data;
   }
 };
 
@@ -233,8 +237,8 @@
   controller.SetAccountSelectionViewForTesting(
       std::make_unique<MockAccountSelectionView>());
 
-  std::vector<content::IdentityRequestAccount> accounts = CreateAccount();
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(accounts);
+  std::vector<IdentityRequestAccountPtr> accounts = CreateAccount();
+  IdentityProviderDataPtr idp_data = CreateIdentityProviderData(accounts);
 
   // Dismiss callback should run once.
   base::MockCallback<DismissCallback> dismiss_callback;
@@ -242,16 +246,17 @@
 
   // Show button mode accounts dialog.
   controller.ShowAccountsDialog(
-      kTopFrameEtldPlusOne, {idp_data},
+      kTopFrameEtldPlusOne, {idp_data}, accounts,
       content::IdentityRequestAccount::SignInMode::kExplicit,
-      blink::mojom::RpMode::kButton, /*new_account_idp=*/std::nullopt,
+      blink::mojom::RpMode::kButton,
+      /*new_accounts=*/std::vector<IdentityRequestAccountPtr>(),
       /*on_selected=*/base::DoNothing(), /*on_add_account=*/base::DoNothing(),
       /*dismiss_callback=*/dismiss_callback.Get(),
       /*accounts_displayed_callback=*/base::DoNothing());
 
   // User selects an account, and then dismisses it. The expectation set for
   // dismiss callback should pass.
-  controller.OnAccountSelected(GURL(kIdpEtldPlusOne), accounts[0]);
+  controller.OnAccountSelected(GURL(kIdpEtldPlusOne), *accounts[0]);
   controller.OnDismiss(IdentityDialogController::DismissReason::kOther);
 }
 
@@ -262,8 +267,8 @@
   controller.SetAccountSelectionViewForTesting(
       std::make_unique<MockAccountSelectionView>());
 
-  std::vector<content::IdentityRequestAccount> accounts = CreateAccount();
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(accounts);
+  std::vector<IdentityRequestAccountPtr> accounts = CreateAccount();
+  IdentityProviderDataPtr idp_data = CreateIdentityProviderData(accounts);
 
   // Dismiss callback should not be run.
   base::MockCallback<DismissCallback> dismiss_callback;
@@ -271,30 +276,32 @@
 
   // Show widget mode accounts dialog.
   controller.ShowAccountsDialog(
-      kTopFrameEtldPlusOne, {idp_data},
+      kTopFrameEtldPlusOne, {idp_data}, accounts,
       content::IdentityRequestAccount::SignInMode::kExplicit,
-      blink::mojom::RpMode::kWidget, /*new_account_idp=*/std::nullopt,
+      blink::mojom::RpMode::kWidget,
+      /*new_accounts=*/std::vector<IdentityRequestAccountPtr>(),
       /*on_selected=*/base::DoNothing(), /*on_add_account=*/base::DoNothing(),
       /*dismiss_callback=*/dismiss_callback.Get(),
       /*accounts_displayed_callback=*/base::DoNothing());
 
   // User selects an account, and then dismisses it. The expectation set for
   // dismiss callback should pass.
-  controller.OnAccountSelected(GURL(kIdpEtldPlusOne), accounts[0]);
+  controller.OnAccountSelected(GURL(kIdpEtldPlusOne), *accounts[0]);
   controller.OnDismiss(IdentityDialogController::DismissReason::kOther);
 }
 
 // Crash test for crbug.com/358302105.
 TEST_F(IdentityDialogControllerTest, NoTabDoesNotCrash) {
   IdentityDialogController controller(web_contents());
-  std::vector<content::IdentityRequestAccount> accounts = CreateAccount();
-  content::IdentityProviderData idp_data = CreateIdentityProviderData(accounts);
+  std::vector<IdentityRequestAccountPtr> accounts = CreateAccount();
+  IdentityProviderDataPtr idp_data = CreateIdentityProviderData(accounts);
 
   // Show button mode accounts dialog.
   EXPECT_FALSE(controller.ShowAccountsDialog(
-      kTopFrameEtldPlusOne, {idp_data},
+      kTopFrameEtldPlusOne, {idp_data}, accounts,
       content::IdentityRequestAccount::SignInMode::kExplicit,
-      blink::mojom::RpMode::kButton, /*new_account_idp=*/std::nullopt,
+      blink::mojom::RpMode::kButton,
+      /*new_accounts=*/std::vector<IdentityRequestAccountPtr>(),
       /*on_selected=*/base::DoNothing(), /*on_add_account=*/base::DoNothing(),
       /*dismiss_callback=*/base::DoNothing(),
       /*accounts_displayed_callback=*/base::DoNothing()));
diff --git a/chrome/browser/ui/webui/ash/mako/BUILD.gn b/chrome/browser/ui/webui/ash/mako/BUILD.gn
index 8aca44d..6f4d2648 100644
--- a/chrome/browser/ui/webui/ash/mako/BUILD.gn
+++ b/chrome/browser/ui/webui/ash/mako/BUILD.gn
@@ -27,6 +27,7 @@
     "//chrome/browser/ui/views/bubble",
     "//chrome/browser/ui/webui/top_chrome",
     "//chromeos/ash/services/orca/public/mojom",
+    "//chromeos/components/magic_boost/public/cpp",
     "//skia:skia_core_public_headers",
     "//third_party/abseil-cpp:absl",
     "//ui/base/cursor",
diff --git a/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc b/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc
index 13c85467..83801d36 100644
--- a/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc
+++ b/chrome/browser/ui/webui/ash/mako/mako_bubble_coordinator.cc
@@ -19,6 +19,7 @@
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/orca_resources.h"
 #include "chrome/grit/orca_resources_map.h"
+#include "chromeos/components/magic_boost/public/cpp/magic_boost_state.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "content/public/common/url_constants.h"
 #include "net/base/url_util.h"
@@ -82,9 +83,12 @@
                                            GetSystemLocale());
   url = net::AppendOrReplaceQueryParameter(url, kOrcaFeedbackEnabledParamKey,
                                            feedback_enabled ? "true" : "false");
+  auto* magic_boost_state = chromeos::MagicBoostState::Get();
   url = net::AppendOrReplaceQueryParameter(
       url, kOrcaMagicBoostParamKey,
-      chromeos::features::IsMagicBoostEnabled() ? "true" : "false");
+      magic_boost_state && magic_boost_state->IsMagicBoostAvailable()
+          ? "true"
+          : "false");
 
   if (base::FeatureList::IsEnabled(ash::features::kOrcaResizingSupport)) {
     url = net::AppendOrReplaceQueryParameter(url, kOrcaResizingEnabledParamKey,
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/BUILD.gn b/chrome/browser/ui/webui/ash/settings/pages/device/BUILD.gn
index 05a9c14..a3f86299 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/BUILD.gn
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/BUILD.gn
@@ -55,6 +55,7 @@
     "//chrome/browser/ui/webui/ash/settings/search",
     "//chrome/common",
     "//chrome/common:chrome_features",
+    "//chromeos/components/magic_boost/public/cpp",
     "//chromeos/constants",
     "//components/spellcheck/browser",
     "//components/user_manager",
@@ -95,6 +96,7 @@
     "//chrome/browser/ui/webui/ash/settings/search",
     "//chrome/test:test_support",
     "//chrome/test:test_support_unit",
+    "//chromeos/components/magic_boost/test:fake_magic_boost_state",
     "//chromeos/constants",
     "//components/prefs:test_support",
     "//components/spellcheck/browser",
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.cc b/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.cc
index 095c65d0..579505b 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.cc
@@ -15,6 +15,7 @@
 #include "chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
+#include "chromeos/components/magic_boost/public/cpp/magic_boost_state.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "components/prefs/pref_service.h"
 #include "components/spellcheck/browser/pref_names.h"
@@ -133,8 +134,9 @@
 }
 
 bool ShouldShowOrcaSettings(input_method::EditorMediator* editor_mediator) {
-  return !chromeos::features::IsMagicBoostEnabled() && editor_mediator &&
-         editor_mediator->IsAllowedForUse();
+  auto* magic_boost_state = chromeos::MagicBoostState::Get();
+  return (!magic_boost_state || !magic_boost_state->IsMagicBoostAvailable()) &&
+         editor_mediator && editor_mediator->IsAllowedForUse();
 }
 
 void AddInputMethodOptionsLoadTimeData(
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section_unittest.cc b/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section_unittest.cc
index 293b2c2b..32502f7 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section_unittest.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section_unittest.cc
@@ -6,6 +6,7 @@
 
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
+#include "base/command_line.h"
 #include "base/memory/raw_ptr.h"
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ash/input_method/editor_geolocation_mock_provider.h"
@@ -17,7 +18,9 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
+#include "chromeos/components/magic_boost/test/fake_magic_boost_state.h"
 #include "chromeos/constants/chromeos_features.h"
+#include "chromeos/constants/chromeos_switches.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/spellcheck/browser/pref_names.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
@@ -123,6 +126,10 @@
           ash::features::kOrcaUseAccountCapabilities,
       });
 
+  chromeos::test::FakeMagicBoostState magic_boost_state;
+  base::CommandLine::ForCurrentProcess()->AppendSwitch(
+      chromeos::switches::kMahiRestrictionsOverride);
+
   auto mock_geolocation_provider =
       std::make_unique<input_method::EditorGeolocationMockProvider>("us");
   input_method::EditorMediator editor_mediator(
diff --git a/chrome/browser/ui/webui/ash/settings/pages/search/search_section.cc b/chrome/browser/ui/webui/ash/settings/pages/search/search_section.cc
index 930f13c..ac404a23 100644
--- a/chrome/browser/ui/webui/ash/settings/pages/search/search_section.cc
+++ b/chrome/browser/ui/webui/ash/settings/pages/search/search_section.cc
@@ -326,7 +326,7 @@
   }
 
   auto* magic_boost_state = chromeos::MagicBoostState::Get();
-  if (chromeos::features::IsMagicBoostEnabled() && magic_boost_state) {
+  if (magic_boost_state && magic_boost_state->IsMagicBoostAvailable()) {
     updater.AddSearchTags(GetMagicBoostSearchConcepts(GetSectionPath()));
     magic_boost_state->AddObserver(this);
     UpdateSubMagicBoostSearchTags();
@@ -372,12 +372,14 @@
                          chrome::kHelpMeReadWriteLearnMoreURL);
 
   html_source->AddBoolean("isQuickAnswersSupported", IsQuickAnswersSupported());
-  html_source->AddBoolean("isMahiEnabled",
-                          chromeos::features::IsMahiEnabled() &&
-                              !chromeos::features::IsMagicBoostEnabled());
+  html_source->AddBoolean(
+      "isMahiEnabled",
+      chromeos::features::IsMahiEnabled() &&
+          !chromeos::MagicBoostState::Get()->IsMagicBoostAvailable());
 
-  html_source->AddBoolean("isMagicBoostFeatureEnabled",
-                          chromeos::features::IsMagicBoostEnabled());
+  html_source->AddBoolean(
+      "isMagicBoostFeatureEnabled",
+      chromeos::MagicBoostState::Get()->IsMagicBoostAvailable());
 
   const bool is_assistant_allowed = IsAssistantAllowed();
   html_source->AddBoolean("isAssistantAllowed", is_assistant_allowed);
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/BUILD.gn b/chrome/browser/ui/webui/side_panel/customize_chrome/BUILD.gn
index 8e23455..f645982f 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/BUILD.gn
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/BUILD.gn
@@ -19,3 +19,7 @@
     "//url/mojom:url_mojom_gurl",
   ]
 }
+
+source_set("customize_chrome") {
+  sources = [ "customize_chrome_section.h" ]
+}
diff --git a/chrome/browser/ui/webui/sync_internals/chrome_sync_internals_message_handler.cc b/chrome/browser/ui/webui/sync_internals/chrome_sync_internals_message_handler.cc
index d6ba26ac..e6da4695 100644
--- a/chrome/browser/ui/webui/sync_internals/chrome_sync_internals_message_handler.cc
+++ b/chrome/browser/ui/webui/sync_internals/chrome_sync_internals_message_handler.cc
@@ -35,7 +35,7 @@
   // std::vector<const base::ValueView> above is not an option, because
   // vector elements must be mutable.
   web_ui()->CallJavascriptFunctionUnsafe("cr.webUIListenerCallback",
-                                         std::move(mutable_span));
+                                         mutable_span);
 }
 
 void ChromeSyncInternalsMessageHandler::ResolvePageCallback(
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 59a253f..b271542 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1725911957-d6559fd3d4100ee9887808b7f4d9541e99f20206-c791a4048c09bea65037bcfe806d178cfd27e548.profdata
+chrome-mac-arm-main-1725933369-099d116bfa1d505d00186c57672b499da9f0fb9a-23d28a850fdf854f56ba6d8f47a4a099b96ed86b.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index f717b41..3636b0d 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1725904596-9a2c2bd76c11810e875a41676a96a75fb468e691-8657dcac1fc3418467121adbb7e32735bf2853f2.profdata
+chrome-win32-main-1725926018-6bc87efffee3f711baf58b36822cdc1e9da1f6cd-6db0b0a036ea422a74009b5c196bf01c15476234.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 1c5c19b8..ec4028c 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1725904596-53b332dd12e5ce022fdd42f1d796891f918d7b81-8657dcac1fc3418467121adbb7e32735bf2853f2.profdata
+chrome-win64-main-1725926018-93f8a7ff893b19fe845023cbeb3509da5edfa5c8-6db0b0a036ea422a74009b5c196bf01c15476234.profdata
diff --git a/chrome/common/extensions/api/autotest_private.idl b/chrome/common/extensions/api/autotest_private.idl
index 4e1c4007..a940625 100644
--- a/chrome/common/extensions/api/autotest_private.idl
+++ b/chrome/common/extensions/api/autotest_private.idl
@@ -1040,16 +1040,6 @@
     // Remove printer.
     static void removePrinter(DOMString printerId);
 
-    // Start ARC directly, note this differs from |setPlayStoreEnabled|. It is
-    // used to restart ARC in tests.
-    // |callback|: Called when the operation has completed.
-    static void startArc(VoidCallback callback);
-
-    // Stop ARC directly, note this differs from |setPlayStoreEnabled|. It is
-    // used to restart ARC in tests. Note, this preserves ARC data.
-    // |callback|: Called when the operation has completed.
-    static void stopArc(VoidCallback callback);
-
     // Enable/disable the Play Store.
     // |enabled|: if set, enable the Play Store.
     // |callback|: Called when the operation has completed.
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 9fc83e0..1b175ea 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1981,6 +1981,7 @@
       "//chrome/browser/ui/color:color_headers",
       "//chrome/browser/ui/content_settings",
       "//chrome/browser/ui/content_settings:browser_tests",
+      "//chrome/browser/ui/customize_chrome",
       "//chrome/browser/ui/exclusive_access",
       "//chrome/browser/ui/find_bar:browser_tests",
       "//chrome/browser/ui/omnibox",
@@ -8295,6 +8296,7 @@
       "//chrome/browser/ui/webui/downloads:mojo_bindings",
       "//chrome/browser/ui/webui/new_tab_page:mojo_bindings",
       "//chrome/browser/ui/webui/searchbox",
+      "//chrome/browser/ui/webui/side_panel/customize_chrome",
       "//chrome/browser/ui/webui/side_panel/customize_chrome:mojo_bindings",
       "//chrome/browser/ui/webui/signin",
       "//chrome/browser/ui/webui/top_chrome",
@@ -10189,7 +10191,6 @@
       "../browser/ui/views/relaunch_notification/relaunch_required_timer_internal_unittest.cc",
       "../browser/ui/views/send_tab_to_self/send_tab_to_self_device_picker_bubble_view_unittest.cc",
       "../browser/ui/views/send_tab_to_self/send_tab_to_self_toolbar_bubble_view_unittest.cc",
-      "../browser/ui/views/side_panel/read_anything/read_anything_coordinator_unittest.cc",
       "../browser/ui/views/side_panel/side_panel_coordinator_unittest.cc",
       "../browser/ui/views/site_data/page_specific_site_data_dialog_unittest.cc",
       "../browser/ui/views/tab_contents/chrome_web_contents_view_delegate_views_unittest.cc",
@@ -10961,6 +10962,7 @@
       "../browser/ui/views/permissions/permission_rhs_indicators_interactive_uitest.cc",
       "../browser/ui/views/plus_addresses/plus_address_creation_dialog_interactive_uitest.cc",
       "../browser/ui/views/privacy_sandbox/privacy_sandbox_dialog_view_interactive_ui_test.cc",
+      "../browser/ui/views/side_panel/read_anything/read_anything_service_interactive_uitest.cc",
       "../browser/ui/views/side_panel/read_anything/read_anything_side_panel_controller_interactive_uitest.cc",
       "../browser/ui/views/web_apps/frame_toolbar/web_app_frame_toolbar_interactive_uitest.cc",
       "../browser/ui/views/web_dialog_view_browsertest.cc",
diff --git a/chrome/test/data/extensions/api_test/autotest_private/test.js b/chrome/test/data/extensions/api_test/autotest_private/test.js
index ae64a35b..582ade16 100644
--- a/chrome/test/data/extensions/api_test/autotest_private/test.js
+++ b/chrome/test/data/extensions/api_test/autotest_private/test.js
@@ -238,16 +238,6 @@
     });
   },
 
-  async function douleStopArc() {
-    try {
-      await promisify(chrome.autotestPrivate.stopArc);
-      chrome.test.fail();
-    } catch (error) {
-      chrome.test.assertEq("ARC is already stopped", error.message);
-      chrome.test.succeed();
-    }
-  },
-
   // This test verifies that Play Store window is not shown by default but
   // Chrome is shown.
   function isAppShown() {
@@ -1369,27 +1359,6 @@
           chrome.test.assertEq(false, packageInfo.vpnProvider);
           chrome.test.succeed();
         }));
-  },
-
-  async function douleStartArc() {
-    try {
-      await promisify(
-          chrome.autotestPrivate.startArc);
-          chrome.test.fail();
-    } catch (error) {
-      chrome.test.assertEq("ARC is already started", error.message);
-      chrome.test.succeed();
-    }
-  },
-
-  // This test verifies restating ARC.
-  function restartArc() {
-    chrome.autotestPrivate.stopArc(function() {
-          chrome.test.assertNoLastError();
-          chrome.autotestPrivate.startArc(
-              chrome.test.callbackPass(function() {
-          }));
-    });
   }
 ];
 
diff --git a/chrome/test/enterprise/e2e/policy/encrypted_reporting/report_cbcm_events_webdriver.py b/chrome/test/enterprise/e2e/policy/encrypted_reporting/report_cbcm_events_webdriver.py
index dfc5fa4..88d8c56 100644
--- a/chrome/test/enterprise/e2e/policy/encrypted_reporting/report_cbcm_events_webdriver.py
+++ b/chrome/test/enterprise/e2e/policy/encrypted_reporting/report_cbcm_events_webdriver.py
@@ -16,39 +16,42 @@
 
 def main(argv):
   options = webdriver.ChromeOptions()
-  os.environ["CHROME_LOG_FILE"] = r"C:\temp\chrome_log.txt"
+  os.environ['CHROME_LOG_FILE'] = r"C:\temp\chrome_log.txt"
 
   # This flag tells Chrome to send heartbeat events on start up.
   options.add_argument(
-      "--enable-features=EncryptedReportingManualTestHeartbeatEvent,EncryptedReportingPipeline"
+      '--enable-features=EncryptedReportingManualTestHeartbeatEvent,EncryptedReportingPipeline'
   )
 
   driver = create_chrome_webdriver(chrome_options=options)
 
   try:
-
-    # Verify Policy status legend in chrome://policy page
-    policy_url = "chrome://policy"
-    driver.get(policy_url)
-    # Give the page 2 seconds to render the legend
-    time.sleep(2)
-    driver.find_element(By.ID, 'reload-policies').click
-    time.sleep(2)
     wait = WebDriverWait(driver, 10)
-    # Wait for the status box to appear after policy reload
-    wait.until(
-        expected_conditions.presence_of_element_located((By.CSS_SELECTOR, "status-box"))
-    )
-    status_box = driver.find_element(By.CSS_SELECTOR, "status-box")
-    el = getElementFromShadowRoot(driver, status_box, ".status-box-fields")
+    policy_url = 'chrome://policy'
+    driver.get(policy_url)
 
+    wait.until(
+        expected_conditions.visibility_of_element_located((By.ID, 'reload-policies'))
+    )
+
+    # Reload policies
+    driver.find_element(By.ID, 'reload-policies').click
+
+    wait.until(
+        expected_conditions.visibility_of_element_located((By.CSS_SELECTOR, 'status-box'))
+    )
+    status_box = driver.find_element(By.CSS_SELECTOR, 'status-box')
+
+    el = getElementFromShadowRoot(driver, status_box, '.status-box-fields')
+
+    # Verify policy status legend in chrome://policy page
     print(el.find_element(By.CLASS_NAME, 'status-box-heading').text)
     print(el.find_element(By.CLASS_NAME, 'machine-enrollment-name').text)
     print(el.find_element(By.CLASS_NAME, 'machine-enrollment-token').text)
     print(el.find_element(By.CLASS_NAME, 'status').text)
     device_id = el.find_element(By.CLASS_NAME,
                                 'machine-enrollment-device-id').text
-    print("DEVICE_ID=" + device_id.strip())
+    print('DEVICE_ID=' + device_id.strip())
   except Exception as error:
     print(error)
   finally:
@@ -56,11 +59,11 @@
     time.sleep(20)
 
     # Print CHROME_LOG_FILE
-    print("PRINTING CHROME LOG FILE....")
-    with open(os.environ["CHROME_LOG_FILE"]) as file:
+    print('PRINTING CHROME LOG FILE....')
+    with open(os.environ['CHROME_LOG_FILE']) as file:
       content = file.read()
       print(content)
-    print("DONE PRINTING CHROME LOG FILE.")
+    print('DONE PRINTING CHROME LOG FILE.')
 
     driver.quit()
 
diff --git a/chromecast/media/audio/cast_audio_renderer.cc b/chromecast/media/audio/cast_audio_renderer.cc
index 43261c478..89e6760 100644
--- a/chromecast/media/audio/cast_audio_renderer.cc
+++ b/chromecast/media/audio/cast_audio_renderer.cc
@@ -208,8 +208,8 @@
   NOTIMPLEMENTED();
 }
 
-void CastAudioRenderer::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
+void CastAudioRenderer::SetWasPlayedWithUserActivationAndHighMediaEngagement(
+    bool was_played_with_user_activation_and_high_media_engagement) {
   NOTIMPLEMENTED();
 }
 
diff --git a/chromecast/media/audio/cast_audio_renderer.h b/chromecast/media/audio/cast_audio_renderer.h
index 70581e3b..902b5026 100644
--- a/chromecast/media/audio/cast_audio_renderer.h
+++ b/chromecast/media/audio/cast_audio_renderer.h
@@ -85,8 +85,8 @@
   void SetVolume(float volume) override;
   void SetLatencyHint(std::optional<base::TimeDelta> latency_hint) override;
   void SetPreservesPitch(bool preserves_pitch) override;
-  void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) override;
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) override;
 
   // ::media::TimeSource implementation:
   void StartTicking() override;
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 439bd6e1..136dcb7 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-16023.0.0-1062828
\ No newline at end of file
+16026.0.0-1062900
\ No newline at end of file
diff --git a/chromeos/ash/services/ime/ime_sandbox_hook.cc b/chromeos/ash/services/ime/ime_sandbox_hook.cc
index e5a4593..ff5716d0 100644
--- a/chromeos/ash/services/ime/ime_sandbox_hook.cc
+++ b/chromeos/ash/services/ime/ime_sandbox_hook.cc
@@ -47,10 +47,11 @@
 }
 
 std::vector<BrokerFilePermission> GetImeFilePermissions() {
-  // These 2 paths are needed before creating IME service.
+  // These paths are needed before creating IME service.
   std::vector<BrokerFilePermission> permissions{
       BrokerFilePermission::ReadOnly("/dev/urandom"),
-      BrokerFilePermission::ReadOnly("/sys/devices/system/cpu")};
+      BrokerFilePermission::ReadOnly("/sys/devices/system/cpu"),
+      BrokerFilePermission::ReadOnly("/sys/devices/system/cpu/possible")};
 
   AddBundleFolder(&permissions);
   AddUserDataFolder(&permissions);
diff --git a/chromeos/components/magic_boost/public/cpp/magic_boost_state.h b/chromeos/components/magic_boost/public/cpp/magic_boost_state.h
index 042a0f5..4d6c239 100644
--- a/chromeos/components/magic_boost/public/cpp/magic_boost_state.h
+++ b/chromeos/components/magic_boost/public/cpp/magic_boost_state.h
@@ -73,6 +73,10 @@
   void AddObserver(Observer* observer);
   void RemoveObserver(Observer* observer);
 
+  // Check if the feature is available to use. It will be unavailable in lacros
+  // and if mahi is not available.
+  virtual bool IsMagicBoostAvailable() = 0;
+
   // Increments HMRWindowDismissCount count and returns an incremented value.
   // Note that this method is not thread safe, i.e., this increment does NOT
   // operate as an atomic operation. Reading HMRWindowDismissCount immediately
diff --git a/chromeos/components/magic_boost/test/fake_magic_boost_state.cc b/chromeos/components/magic_boost/test/fake_magic_boost_state.cc
index 7b47079..ba2c5d7 100644
--- a/chromeos/components/magic_boost/test/fake_magic_boost_state.cc
+++ b/chromeos/components/magic_boost/test/fake_magic_boost_state.cc
@@ -9,6 +9,10 @@
 namespace chromeos {
 namespace test {
 
+bool FakeMagicBoostState::IsMagicBoostAvailable() {
+  return true;
+}
+
 int32_t FakeMagicBoostState::AsyncIncrementHMRConsentWindowDismissCount() {
   return 0;
 }
diff --git a/chromeos/components/magic_boost/test/fake_magic_boost_state.h b/chromeos/components/magic_boost/test/fake_magic_boost_state.h
index 478fef1..d16dce11 100644
--- a/chromeos/components/magic_boost/test/fake_magic_boost_state.h
+++ b/chromeos/components/magic_boost/test/fake_magic_boost_state.h
@@ -12,6 +12,7 @@
 
 class FakeMagicBoostState : public chromeos::MagicBoostState {
  public:
+  bool IsMagicBoostAvailable() override;
   int32_t AsyncIncrementHMRConsentWindowDismissCount() override;
   void AsyncWriteConsentStatus(
       chromeos::HMRConsentStatus consent_status) override;
diff --git a/chromeos/components/quick_answers/public/cpp/quick_answers_state.cc b/chromeos/components/quick_answers/public/cpp/quick_answers_state.cc
index 938e720..00e22129 100644
--- a/chromeos/components/quick_answers/public/cpp/quick_answers_state.cc
+++ b/chromeos/components/quick_answers/public/cpp/quick_answers_state.cc
@@ -82,7 +82,10 @@
 
 // static
 QuickAnswersState::FeatureType QuickAnswersState::GetFeatureType() {
-  return chromeos::features::IsMagicBoostEnabled()
+  auto* magic_boost_state = chromeos::MagicBoostState::Get();
+
+  // `magic_boost_state` might be null in tests
+  return magic_boost_state && magic_boost_state->IsMagicBoostAvailable()
              ? QuickAnswersState::FeatureType::kHmr
              : QuickAnswersState::FeatureType::kQuickAnswers;
 }
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc
index 78d75fa..8bf71a5 100644
--- a/chromeos/constants/chromeos_features.cc
+++ b/chromeos/constants/chromeos_features.cc
@@ -165,7 +165,7 @@
              base::FEATURE_DISABLED_BY_DEFAULT);
 
 // Controls enabling / disabling the mahi feature.
-BASE_FEATURE(kMahi, "Mahi", base::FEATURE_DISABLED_BY_DEFAULT);
+BASE_FEATURE(kMahi, "Mahi", base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Controls enabling / disabling the mahi feature from the feature management
 // module.
@@ -444,15 +444,6 @@
   return IsJellyEnabled() && base::FeatureList::IsEnabled(kJellyroll);
 }
 
-bool IsMagicBoostEnabled() {
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  // Magic Boost does not work in Lacros.
-  return false;
-#else
-  return IsMahiEnabled();
-#endif
-}
-
 // Sparkly depends on Mahi, so we turn on Mahi if the sparky flag is enabled.
 // Sparky doesn't work on LACROS so that case is ignored.
 bool IsMahiEnabled() {
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h
index 017c893..2fba0dd 100644
--- a/chromeos/constants/chromeos_features.h
+++ b/chromeos/constants/chromeos_features.h
@@ -21,10 +21,6 @@
 // alongside the definition of their values in the .cc file. If a feature is
 // being rolled out via Finch, add a comment in the .cc file.
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
-BASE_DECLARE_FEATURE(kAppInstallServiceUri);
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kApnPolicies);
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS)
 BASE_DECLARE_FEATURE(kBatteryBadgeIcon);
@@ -153,7 +149,6 @@
 bool IsFileSystemProviderContentCacheEnabled();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsJellyEnabled();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsJellyrollEnabled();
-COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsMagicBoostEnabled();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsMahiEnabled();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsMahiSendingUrl();
 COMPONENT_EXPORT(CHROMEOS_CONSTANTS) bool IsMahiDebuggingEnabled();
diff --git a/clank b/clank
index e5ba0da..f7ba534 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit e5ba0da2a173ac40347c806053698ca2624857ea
+Subproject commit f7ba534d8096b3224d4e77b886988aa1128e1f28
diff --git a/components/browser_ui/styles/android/java/res/values-v31/colors.xml b/components/browser_ui/styles/android/java/res/values-v31/colors.xml
index 009643fe..2b91bce9 100644
--- a/components/browser_ui/styles/android/java/res/values-v31/colors.xml
+++ b/components/browser_ui/styles/android/java/res/values-v31/colors.xml
@@ -10,6 +10,7 @@
   <color name="material_primary_10">@color/material_dynamic_primary10</color>
   <color name="material_primary_20">@color/material_dynamic_primary20</color>
   <color name="material_primary_40">@color/material_dynamic_primary40</color>
+  <color name="material_primary_50">@color/material_dynamic_primary50</color>
   <color name="material_primary_60">@color/material_dynamic_primary60</color>
   <color name="material_primary_80">@color/material_dynamic_primary80</color>
   <color name="material_primary_90">@color/material_dynamic_primary90</color>
diff --git a/components/cast_streaming/browser/cast_streaming_session.h b/components/cast_streaming/browser/cast_streaming_session.h
index 3d99a70..85b01e0c 100644
--- a/components/cast_streaming/browser/cast_streaming_session.h
+++ b/components/cast_streaming/browser/cast_streaming_session.h
@@ -25,9 +25,9 @@
 #include "media/base/video_decoder_config.h"
 #include "media/mojo/mojom/media_types.mojom.h"
 #include "mojo/public/cpp/system/data_pipe.h"
-#include "third_party/openscreen/src/cast/streaming/receiver.h"
-#include "third_party/openscreen/src/cast/streaming/receiver_constraints.h"
-#include "third_party/openscreen/src/cast/streaming/receiver_session.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver_constraints.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver_session.h"
 
 namespace cast_streaming {
 
diff --git a/components/cast_streaming/browser/control/playback_command_dispatcher.h b/components/cast_streaming/browser/control/playback_command_dispatcher.h
index 41a9366..12c485f 100644
--- a/components/cast_streaming/browser/control/playback_command_dispatcher.h
+++ b/components/cast_streaming/browser/control/playback_command_dispatcher.h
@@ -23,8 +23,8 @@
 #include "media/base/video_decoder_config.h"
 #include "media/mojo/mojom/renderer.mojom.h"
 #include "mojo/public/cpp/bindings/associated_remote.h"
-#include "third_party/openscreen/src/cast/streaming/receiver_session.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver_session.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 namespace openscreen {
 namespace cast {
diff --git a/components/cast_streaming/browser/control/remoting/remoting_decoder_buffer_factory.cc b/components/cast_streaming/browser/control/remoting/remoting_decoder_buffer_factory.cc
index f5e6f41..de0ed80 100644
--- a/components/cast_streaming/browser/control/remoting/remoting_decoder_buffer_factory.cc
+++ b/components/cast_streaming/browser/control/remoting/remoting_decoder_buffer_factory.cc
@@ -9,7 +9,7 @@
 #include "base/logging.h"
 #include "media/base/decoder_buffer.h"
 #include "media/cast/openscreen/remoting_proto_utils.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 namespace cast_streaming {
 
diff --git a/components/cast_streaming/browser/control/remoting/remoting_session_client.h b/components/cast_streaming/browser/control/remoting/remoting_session_client.h
index 9589aa3..18ee30c 100644
--- a/components/cast_streaming/browser/control/remoting/remoting_session_client.h
+++ b/components/cast_streaming/browser/control/remoting/remoting_session_client.h
@@ -6,7 +6,7 @@
 #define COMPONENTS_CAST_STREAMING_BROWSER_CONTROL_REMOTING_REMOTING_SESSION_CLIENT_H_
 
 #include "components/cast_streaming/browser/common/streaming_initialization_info.h"
-#include "third_party/openscreen/src/cast/streaming/receiver_session.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver_session.h"
 
 namespace openscreen::cast {
 class RpcMessenger;
diff --git a/components/cast_streaming/browser/control/remoting/rpc_demuxer_stream_handler.h b/components/cast_streaming/browser/control/remoting/rpc_demuxer_stream_handler.h
index 5190bfe..6ee76e4 100644
--- a/components/cast_streaming/browser/control/remoting/rpc_demuxer_stream_handler.h
+++ b/components/cast_streaming/browser/control/remoting/rpc_demuxer_stream_handler.h
@@ -17,7 +17,7 @@
 #include "media/base/audio_decoder_config.h"
 #include "media/base/video_decoder_config.h"
 #include "media/cast/openscreen/rpc_call_message_handler.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 namespace base {
 class SequencedTaskRunner;
diff --git a/components/cast_streaming/browser/control/remoting/rpc_demuxer_stream_handler_unittests.cc b/components/cast_streaming/browser/control/remoting/rpc_demuxer_stream_handler_unittests.cc
index 787ae245..28ec153 100644
--- a/components/cast_streaming/browser/control/remoting/rpc_demuxer_stream_handler_unittests.cc
+++ b/components/cast_streaming/browser/control/remoting/rpc_demuxer_stream_handler_unittests.cc
@@ -20,7 +20,7 @@
 #include "media/base/video_types.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 using testing::_;
 using testing::Invoke;
diff --git a/components/cast_streaming/browser/control/remoting/rpc_initialization_call_handler_base.h b/components/cast_streaming/browser/control/remoting/rpc_initialization_call_handler_base.h
index 5edaa7e8..119e44d8 100644
--- a/components/cast_streaming/browser/control/remoting/rpc_initialization_call_handler_base.h
+++ b/components/cast_streaming/browser/control/remoting/rpc_initialization_call_handler_base.h
@@ -10,7 +10,7 @@
 #include "base/functional/callback.h"
 #include "base/memory/weak_ptr.h"
 #include "media/cast/openscreen/rpc_call_message_handler.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 namespace openscreen::cast {
 class RpcMessage;
diff --git a/components/cast_streaming/browser/frame/mirroring_decoder_buffer_factory.cc b/components/cast_streaming/browser/frame/mirroring_decoder_buffer_factory.cc
index 8eb205f..43919ad 100644
--- a/components/cast_streaming/browser/frame/mirroring_decoder_buffer_factory.cc
+++ b/components/cast_streaming/browser/frame/mirroring_decoder_buffer_factory.cc
@@ -10,7 +10,7 @@
 #include "components/cast_streaming/common/public/features.h"
 #include "media/base/decoder_buffer.h"
 #include "media/base/media_util.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 namespace cast_streaming {
 
diff --git a/components/cast_streaming/browser/frame/stream_consumer.h b/components/cast_streaming/browser/frame/stream_consumer.h
index 32837b31..62874a5 100644
--- a/components/cast_streaming/browser/frame/stream_consumer.h
+++ b/components/cast_streaming/browser/frame/stream_consumer.h
@@ -12,8 +12,8 @@
 #include "media/mojo/mojom/media_types.mojom.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
-#include "third_party/openscreen/src/cast/streaming/receiver.h"
-#include "third_party/openscreen/src/cast/streaming/receiver_session.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver_session.h"
 
 namespace cast_streaming {
 
diff --git a/components/cast_streaming/browser/receiver_config_conversions.cc b/components/cast_streaming/browser/receiver_config_conversions.cc
index de25c93..a3271336 100644
--- a/components/cast_streaming/browser/receiver_config_conversions.cc
+++ b/components/cast_streaming/browser/receiver_config_conversions.cc
@@ -11,7 +11,7 @@
 #include "media/base/channel_layout.h"
 #include "media/base/video_codecs.h"
 #include "media/cast/openscreen/config_conversions.h"
-#include "third_party/openscreen/src/cast/streaming/constants.h"
+#include "third_party/openscreen/src/cast/streaming/public/constants.h"
 #include "ui/gfx/geometry/rect.h"
 
 namespace cast_streaming {
diff --git a/components/cast_streaming/browser/receiver_config_conversions.h b/components/cast_streaming/browser/receiver_config_conversions.h
index 06546ce9b..d96e1ab 100644
--- a/components/cast_streaming/browser/receiver_config_conversions.h
+++ b/components/cast_streaming/browser/receiver_config_conversions.h
@@ -5,7 +5,7 @@
 #ifndef COMPONENTS_CAST_STREAMING_BROWSER_RECEIVER_CONFIG_CONVERSIONS_H_
 #define COMPONENTS_CAST_STREAMING_BROWSER_RECEIVER_CONFIG_CONVERSIONS_H_
 
-#include "third_party/openscreen/src/cast/streaming/receiver_constraints.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver_constraints.h"
 
 namespace cast_streaming {
 
diff --git a/components/cast_streaming/browser/receiver_session_impl.cc b/components/cast_streaming/browser/receiver_session_impl.cc
index 07548aad..e300c48a 100644
--- a/components/cast_streaming/browser/receiver_session_impl.cc
+++ b/components/cast_streaming/browser/receiver_session_impl.cc
@@ -11,7 +11,7 @@
 #include "components/cast_streaming/common/public/features.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/video_decoder_config.h"
-#include "third_party/openscreen/src/cast/streaming/receiver_constraints.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver_constraints.h"
 
 namespace cast_streaming {
 
diff --git a/components/cast_streaming/test/cast_streaming_test_sender.h b/components/cast_streaming/test/cast_streaming_test_sender.h
index baa5c17..a45fd845 100644
--- a/components/cast_streaming/test/cast_streaming_test_sender.h
+++ b/components/cast_streaming/test/cast_streaming_test_sender.h
@@ -13,7 +13,7 @@
 #include "media/base/decoder_buffer.h"
 #include "media/base/video_decoder_config.h"
 #include "net/base/ip_address.h"
-#include "third_party/openscreen/src/cast/streaming/sender_session.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender_session.h"
 
 namespace cast_streaming {
 
diff --git a/components/memory_system/initializer.cc b/components/memory_system/initializer.cc
index 4e829e8..e05e5e2 100644
--- a/components/memory_system/initializer.cc
+++ b/components/memory_system/initializer.cc
@@ -16,7 +16,7 @@
 
 Initializer& Initializer::SetGwpAsanParameters(bool boost_sampling,
                                                std::string_view process_type) {
-  gwp_asan_parameters_.emplace(boost_sampling, std::move(process_type));
+  gwp_asan_parameters_.emplace(boost_sampling, process_type);
   return *this;
 }
 
diff --git a/components/mirroring/service/media_remoter.cc b/components/mirroring/service/media_remoter.cc
index 91e1120..c285d51 100644
--- a/components/mirroring/service/media_remoter.cc
+++ b/components/mirroring/service/media_remoter.cc
@@ -9,7 +9,7 @@
 #include "components/mirroring/service/remoting_sender.h"
 #include "components/mirroring/service/rpc_dispatcher.h"
 #include "media/base/media_switches.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 
 using media::cast::FrameSenderConfig;
 
diff --git a/components/mirroring/service/media_remoter.h b/components/mirroring/service/media_remoter.h
index e4164f8b..8f7aa06 100644
--- a/components/mirroring/service/media_remoter.h
+++ b/components/mirroring/service/media_remoter.h
@@ -15,7 +15,7 @@
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/system/data_pipe.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 
 namespace media::cast {
 class CastEnvironment;
diff --git a/components/mirroring/service/media_remoter_unittest.cc b/components/mirroring/service/media_remoter_unittest.cc
index 8b1e9f7..ef4c10bb 100644
--- a/components/mirroring/service/media_remoter_unittest.cc
+++ b/components/mirroring/service/media_remoter_unittest.cc
@@ -22,8 +22,8 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/environment.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/environment.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 #include "third_party/openscreen/src/cast/streaming/sender_packet_router.h"
 #include "third_party/openscreen/src/platform/api/time.h"
 #include "third_party/openscreen/src/platform/base/trivial_clock_traits.h"
diff --git a/components/mirroring/service/openscreen_session_host.cc b/components/mirroring/service/openscreen_session_host.cc
index 34f8923..06fc296f8 100644
--- a/components/mirroring/service/openscreen_session_host.cc
+++ b/components/mirroring/service/openscreen_session_host.cc
@@ -59,10 +59,10 @@
 #include "mojo/public/cpp/system/platform_handle.h"
 #include "net/base/ip_endpoint.h"
 #include "services/viz/public/cpp/gpu/gpu.h"
-#include "third_party/openscreen/src/cast/streaming/answer_messages.h"
-#include "third_party/openscreen/src/cast/streaming/capture_recommendations.h"
-#include "third_party/openscreen/src/cast/streaming/environment.h"
-#include "third_party/openscreen/src/cast/streaming/offer_messages.h"
+#include "third_party/openscreen/src/cast/streaming/public/answer_messages.h"
+#include "third_party/openscreen/src/cast/streaming/public/capture_recommendations.h"
+#include "third_party/openscreen/src/cast/streaming/public/environment.h"
+#include "third_party/openscreen/src/cast/streaming/public/offer_messages.h"
 
 using media::cast::FrameEvent;
 using media::cast::FrameSenderConfig;
diff --git a/components/mirroring/service/openscreen_session_host.h b/components/mirroring/service/openscreen_session_host.h
index c01867b6..f5a3742 100644
--- a/components/mirroring/service/openscreen_session_host.h
+++ b/components/mirroring/service/openscreen_session_host.h
@@ -31,7 +31,7 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "services/network/public/mojom/network_context.mojom.h"
-#include "third_party/openscreen/src/cast/streaming/sender_session.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender_session.h"
 
 using openscreen::cast::capture_recommendations::Recommendations;
 
diff --git a/components/mirroring/service/openscreen_session_host_unittest.cc b/components/mirroring/service/openscreen_session_host_unittest.cc
index eb0dca0..e6ef130 100644
--- a/components/mirroring/service/openscreen_session_host_unittest.cc
+++ b/components/mirroring/service/openscreen_session_host_unittest.cc
@@ -39,7 +39,7 @@
 #include "third_party/jsoncpp/source/include/json/reader.h"
 #include "third_party/jsoncpp/source/include/json/writer.h"
 #include "third_party/openscreen/src/cast/streaming/message_fields.h"
-#include "third_party/openscreen/src/cast/streaming/offer_messages.h"
+#include "third_party/openscreen/src/cast/streaming/public/offer_messages.h"
 #include "third_party/openscreen/src/cast/streaming/remoting_capabilities.h"
 #include "third_party/openscreen/src/cast/streaming/sender_message.h"
 #include "third_party/openscreen/src/cast/streaming/ssrc.h"
diff --git a/components/mirroring/service/openscreen_stats_client.h b/components/mirroring/service/openscreen_stats_client.h
index 215983af..c39b604 100644
--- a/components/mirroring/service/openscreen_stats_client.h
+++ b/components/mirroring/service/openscreen_stats_client.h
@@ -7,8 +7,8 @@
 
 #include "base/component_export.h"
 #include "base/values.h"
-#include "third_party/openscreen/src/cast/streaming/sender_session.h"
-#include "third_party/openscreen/src/cast/streaming/statistics.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender_session.h"
+#include "third_party/openscreen/src/cast/streaming/public/statistics.h"
 
 namespace mirroring {
 
diff --git a/components/mirroring/service/openscreen_stats_client_unittest.cc b/components/mirroring/service/openscreen_stats_client_unittest.cc
index e59e8a1..c37c21b 100644
--- a/components/mirroring/service/openscreen_stats_client_unittest.cc
+++ b/components/mirroring/service/openscreen_stats_client_unittest.cc
@@ -8,8 +8,8 @@
 #include "media/cast/logging/stats_event_subscriber.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/sender_session.h"
-#include "third_party/openscreen/src/cast/streaming/statistics.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender_session.h"
+#include "third_party/openscreen/src/cast/streaming/public/statistics.h"
 
 namespace mirroring {
 
diff --git a/components/mirroring/service/remoting_sender.cc b/components/mirroring/service/remoting_sender.cc
index 11b51702b..01e7af1 100644
--- a/components/mirroring/service/remoting_sender.cc
+++ b/components/mirroring/service/remoting_sender.cc
@@ -24,8 +24,8 @@
 #include "media/cast/openscreen/decoder_buffer_reader.h"
 #include "media/cast/openscreen/remoting_proto_utils.h"
 #include "media/cast/sender/openscreen_frame_sender.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 
 using Dependency = openscreen::cast::EncodedFrame::Dependency;
 
diff --git a/components/mirroring/service/rpc_dispatcher_impl.h b/components/mirroring/service/rpc_dispatcher_impl.h
index 1e49340..6c37cf9 100644
--- a/components/mirroring/service/rpc_dispatcher_impl.h
+++ b/components/mirroring/service/rpc_dispatcher_impl.h
@@ -13,9 +13,9 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ref.h"
 #include "components/mirroring/service/rpc_dispatcher.h"
-#include "third_party/openscreen/src/cast/streaming/receiver_message.h"
+#include "third_party/openscreen/src/cast/streaming/public/receiver_message.h"
+#include "third_party/openscreen/src/cast/streaming/public/session_messenger.h"
 #include "third_party/openscreen/src/cast/streaming/sender_message.h"
-#include "third_party/openscreen/src/cast/streaming/session_messenger.h"
 #include "third_party/openscreen/src/platform/base/error.h"
 
 namespace mirroring {
diff --git a/components/mirroring/service/rpc_dispatcher_impl_unittest.cc b/components/mirroring/service/rpc_dispatcher_impl_unittest.cc
index 4940efc..762b2d7 100644
--- a/components/mirroring/service/rpc_dispatcher_impl_unittest.cc
+++ b/components/mirroring/service/rpc_dispatcher_impl_unittest.cc
@@ -17,7 +17,7 @@
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/openscreen/src/cast/common/public/message_port.h"
 #include "third_party/openscreen/src/cast/streaming/message_fields.h"
-#include "third_party/openscreen/src/cast/streaming/session_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/session_messenger.h"
 #include "third_party/openscreen/src/platform/base/error.h"
 
 using ::testing::_;
diff --git a/components/openscreen_platform/message_port_tls_connection.cc b/components/openscreen_platform/message_port_tls_connection.cc
index d94c109..84fc0fd 100644
--- a/components/openscreen_platform/message_port_tls_connection.cc
+++ b/components/openscreen_platform/message_port_tls_connection.cc
@@ -43,11 +43,10 @@
 
   if (client_) {
     if (!task_runner_->IsRunningOnTaskRunner()) {
-      task_runner_->PostTask([ptr = weak_ptr_factory_.GetWeakPtr(),
-                              m = std::move(message)]() {
+      task_runner_->PostTask([ptr = weak_ptr_factory_.GetWeakPtr(), message]() {
         if (ptr) {
           ptr->OnMessage(
-              std::move(m),
+              message,
               std::vector<std::unique_ptr<cast_api_bindings::MessagePort>>());
         }
       });
diff --git a/components/segmentation_platform/components_unittests.filter b/components/segmentation_platform/components_unittests.filter
index fc42714b..08336f2 100644
--- a/components/segmentation_platform/components_unittests.filter
+++ b/components/segmentation_platform/components_unittests.filter
@@ -18,6 +18,7 @@
 *DummyModelProviderFactoryImplTest.*
 *DummySegmentationPlatformServiceTest.*
 *EphemeralHomeModuleBackendTest.*
+*EphemeralHomeModuleBackendWithTestCard.*
 *FailedUkmDatabaseTest.*
 *FeatureAggregatorImplTest.*
 *FeatureListQueryProcessorNoDbCacheTest.*
diff --git a/components/segmentation_platform/embedder/home_modules/card_selection_info.cc b/components/segmentation_platform/embedder/home_modules/card_selection_info.cc
index 5f82f4c..33df4d8 100644
--- a/components/segmentation_platform/embedder/home_modules/card_selection_info.cc
+++ b/components/segmentation_platform/embedder/home_modules/card_selection_info.cc
@@ -7,6 +7,11 @@
 namespace segmentation_platform::home_modules {
 
 CardSelectionInfo::ShowResult::ShowResult() = default;
+CardSelectionInfo::ShowResult::ShowResult(EphemeralHomeModuleRank position)
+    : position(position) {}
+CardSelectionInfo::ShowResult::ShowResult(EphemeralHomeModuleRank position,
+                                          const std::string& result_label)
+    : position(position), result_label(result_label) {}
 CardSelectionInfo::ShowResult::ShowResult(const ShowResult& result) = default;
 CardSelectionInfo::ShowResult::~ShowResult() = default;
 
diff --git a/components/segmentation_platform/embedder/home_modules/card_selection_info.h b/components/segmentation_platform/embedder/home_modules/card_selection_info.h
index f41cc67..276ab714 100644
--- a/components/segmentation_platform/embedder/home_modules/card_selection_info.h
+++ b/components/segmentation_platform/embedder/home_modules/card_selection_info.h
@@ -22,6 +22,13 @@
 
   struct ShowResult {
     ShowResult();
+
+    // Select position for the default label (card_name).
+    explicit ShowResult(EphemeralHomeModuleRank position);
+    // Select position with the card label variation.
+    ShowResult(EphemeralHomeModuleRank position,
+               const std::string& result_label);
+
     ShowResult(const ShowResult& result);
     ~ShowResult();
 
diff --git a/components/segmentation_platform/embedder/home_modules/card_selection_signals.cc b/components/segmentation_platform/embedder/home_modules/card_selection_signals.cc
index 96ad7294..767a77c 100644
--- a/components/segmentation_platform/embedder/home_modules/card_selection_signals.cc
+++ b/components/segmentation_platform/embedder/home_modules/card_selection_signals.cc
@@ -8,17 +8,6 @@
 
 namespace segmentation_platform::home_modules {
 
-float EphemeralHomeModuleRankToScore(EphemeralHomeModuleRank rank) {
-  switch (rank) {
-    case EphemeralHomeModuleRank::kTop:
-      return 1;
-    case EphemeralHomeModuleRank::kLast:
-      return 0.01;
-    case EphemeralHomeModuleRank::kNotShown:
-      return -1;
-  }
-}
-
 AllCardSignals::AllCardSignals(CardSignalMap signal_map,
                                std::vector<float> signals)
     : signal_map_(std::move(signal_map)), signals_(std::move(signals)) {}
diff --git a/components/segmentation_platform/embedder/home_modules/card_selection_signals.h b/components/segmentation_platform/embedder/home_modules/card_selection_signals.h
index 5c55530..9a8551b 100644
--- a/components/segmentation_platform/embedder/home_modules/card_selection_signals.h
+++ b/components/segmentation_platform/embedder/home_modules/card_selection_signals.h
@@ -21,7 +21,16 @@
 // Where the position of the card should be placed.
 enum class EphemeralHomeModuleRank { kTop, kLast, kNotShown };
 
-float EphemeralHomeModuleRankToScore(EphemeralHomeModuleRank rank);
+constexpr float EphemeralHomeModuleRankToScore(EphemeralHomeModuleRank rank) {
+  switch (rank) {
+    case EphemeralHomeModuleRank::kTop:
+      return 1;
+    case EphemeralHomeModuleRank::kLast:
+      return 0.01;
+    case EphemeralHomeModuleRank::kNotShown:
+      return -1;
+  }
+}
 
 using CardSignalMap = std::map<CardName, std::map<SignalKey, /*index=*/size_t>>;
 
diff --git a/components/segmentation_platform/embedder/home_modules/constants.h b/components/segmentation_platform/embedder/home_modules/constants.h
index 3171f091..8e0a7e5b 100644
--- a/components/segmentation_platform/embedder/home_modules/constants.h
+++ b/components/segmentation_platform/embedder/home_modules/constants.h
@@ -11,6 +11,9 @@
 const char kIsNewUser[] = "is_new_user";
 const char kIsSynced[] = "is_sycned";
 
+// Placeholder output label for segmentation model executor.
+const char kPlaceholderEphemeralModuleLabel[] = "placeholder_module";
+
 // Labels for emphemeral IOS modules.
 const char kPriceTrackingNotificationPromo[] = "price_tracking_promo";
 
diff --git a/components/segmentation_platform/embedder/home_modules/ephemeral_home_module_backend.cc b/components/segmentation_platform/embedder/home_modules/ephemeral_home_module_backend.cc
index 2330fa2..1990bb4 100644
--- a/components/segmentation_platform/embedder/home_modules/ephemeral_home_module_backend.cc
+++ b/components/segmentation_platform/embedder/home_modules/ephemeral_home_module_backend.cc
@@ -81,9 +81,13 @@
   // Set output config.
   const std::vector<std::string>& output_labels =
       home_modules_card_registry_->all_output_labels();
+  // Use a threshold slightly greater than the kNotShown value since the
+  // threshold checks for strictly less than value.
+  float dont_show_threshold =
+      EphemeralHomeModuleRankToScore(EphemeralHomeModuleRank::kNotShown) +
+      0.001f;
   writer.AddOutputConfigForMultiClassClassifier(
-      output_labels, kMaxOutputLabelsToRank,
-      EphemeralHomeModuleRankToScore(EphemeralHomeModuleRank::kNotShown));
+      output_labels, kMaxOutputLabelsToRank, dont_show_threshold);
   writer.AddPredictedResultTTLInOutputConfig(
       /*top_label_to_ttl_list=*/{},
       /*default_ttl=*/kResultTTLDays, proto::TimeUnit::DAY);
@@ -124,7 +128,9 @@
       home_modules_card_registry_->get_all_cards_by_priority();
   const float dont_show_result =
       EphemeralHomeModuleRankToScore(EphemeralHomeModuleRank::kNotShown);
-  ModelProvider::Request result(all_cards.size(), dont_show_result);
+  ModelProvider::Request result(
+      home_modules_card_registry_->all_output_labels().size(),
+      dont_show_result);
 
   for (const auto& card : all_cards) {
     CardSelectionSignals card_signals(&all_signals, card->card_name());
diff --git a/components/segmentation_platform/embedder/home_modules/ephemeral_home_module_backend_unittest.cc b/components/segmentation_platform/embedder/home_modules/ephemeral_home_module_backend_unittest.cc
index e9e51fc..b980c29 100644
--- a/components/segmentation_platform/embedder/home_modules/ephemeral_home_module_backend_unittest.cc
+++ b/components/segmentation_platform/embedder/home_modules/ephemeral_home_module_backend_unittest.cc
@@ -8,11 +8,61 @@
 #include "components/commerce/core/commerce_feature_list.h"
 #include "components/prefs/testing_pref_service.h"
 #include "components/segmentation_platform/embedder/default_model/default_model_test_base.h"
+#include "components/segmentation_platform/embedder/home_modules/card_selection_info.h"
+#include "components/segmentation_platform/embedder/home_modules/card_selection_signals.h"
 #include "components/segmentation_platform/embedder/home_modules/home_modules_card_registry.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace segmentation_platform::home_modules {
 
+namespace {
+
+// Test card info, with 4 signals, and 3 card variations. Shows label2 when
+// first signal is non-zero, otherwise does not show.
+class TestCardInfo : public CardSelectionInfo {
+ public:
+  static constexpr char kCountUma[] = "count_uma";
+  static constexpr char kLatestUma[] = "latest_uma";
+  static constexpr char kSumUma[] = "sum_uma";
+  static constexpr char kInputShopping[] = "input_shopping";
+
+  static constexpr char kLabel1[] = "label1";
+  static constexpr char kLabel2[] = "label2";
+  static constexpr char kLabel3[] = "label3";
+
+  TestCardInfo() : CardSelectionInfo("test") {}
+  ~TestCardInfo() override = default;
+
+  std::vector<std::string> OutputLabels() override {
+    return {kLabel1, kLabel2, kLabel3};
+  }
+
+  std::map<SignalKey, FeatureQuery> GetInputs() override {
+    std::map<SignalKey, FeatureQuery> result;
+
+    DEFINE_UMA_FEATURE_COUNT(count, "Uma.Metric", 7);
+    result.emplace(kCountUma, std::move(count));
+    DEFINE_UMA_FEATURE_LATEST(latest_uma, "Uma.Metric");
+    result.emplace(kLatestUma, std::move(latest_uma));
+    DEFINE_UMA_FEATURE_SUM(sum_uma, "Uma.Metric", 7);
+    result.emplace(kSumUma, std::move(sum_uma));
+    DEFINE_INPUT_CONTEXT(input_shopping, "shopping_input_count");
+    result.emplace(kInputShopping, std::move(input_shopping));
+    return result;
+  }
+
+  ShowResult ComputeCardResult(
+      const CardSelectionSignals& signals) const override {
+    if (signals.GetSignal(kCountUma) > 0) {
+      return ShowResult(EphemeralHomeModuleRank::kTop, kLabel2);
+    }
+    return ShowResult(EphemeralHomeModuleRank::kNotShown);
+  }
+};
+
+constexpr float kNotShownResultValue =
+    EphemeralHomeModuleRankToScore(EphemeralHomeModuleRank::kNotShown);
+
 class EphemeralHomeModuleBackendTest : public DefaultModelTestBase {
  public:
   EphemeralHomeModuleBackendTest()
@@ -27,7 +77,6 @@
   ~EphemeralHomeModuleBackendTest() override = default;
 
  protected:
-  // TODO(ssid): Maybe use mock class here;
   TestingPrefServiceSimple pref_service_;
   std::unique_ptr<HomeModulesCardRegistry> registry_;
   base::test::ScopedFeatureList feature_list_;
@@ -39,14 +88,66 @@
 
 TEST_F(EphemeralHomeModuleBackendTest, ExecuteModelWithInput) {
 #if BUILDFLAG(IS_IOS)
-  ExpectExecutionWithInput(
-      {0, 0, 0}, /*expected_error=*/false,
-      /*expected_result=*/
-      {EphemeralHomeModuleRankToScore(EphemeralHomeModuleRank::kNotShown)});
+  ExpectExecutionWithInput({0, 0, 0}, /*expected_error=*/false,
+                           /*expected_result=*/
+                           {kNotShownResultValue, kNotShownResultValue});
 #else
   ExpectExecutionWithInput(/*inputs=*/{}, /*expected_error=*/false,
-                           /*expected_result=*/{});
+                           /*expected_result=*/{kNotShownResultValue});
 #endif
 }
 
+// Test with adding a TestCardInfo to the registry.
+class EphemeralHomeModuleBackendWithTestCard : public DefaultModelTestBase {
+ public:
+  EphemeralHomeModuleBackendWithTestCard()
+      : DefaultModelTestBase(
+            std::make_unique<EphemeralHomeModuleBackend>(nullptr)) {
+    std::vector<std::unique_ptr<CardSelectionInfo>> cards;
+    cards.emplace_back(std::make_unique<TestCardInfo>());
+    registry_ = std::make_unique<HomeModulesCardRegistry>(&pref_service_,
+                                                          std::move(cards));
+    static_cast<EphemeralHomeModuleBackend*>(model_.get())
+        ->set_home_modules_card_registry_for_testing(registry_.get());
+  }
+  ~EphemeralHomeModuleBackendWithTestCard() override = default;
+
+ protected:
+  TestingPrefServiceSimple pref_service_;
+  std::unique_ptr<HomeModulesCardRegistry> registry_;
+};
+
+TEST_F(EphemeralHomeModuleBackendWithTestCard, InitAndFetchModel) {
+  // Validate model config.
+  ExpectInitAndFetchModel();
+}
+
+TEST_F(EphemeralHomeModuleBackendWithTestCard, ExecuteModelWithInput) {
+  ExpectInitAndFetchModel();
+
+  // Run with all signals 0, no card should be shown.
+  ModelProvider::Request inputs =
+      ModelProvider::Request(registry_->all_cards_input_size(), 0);
+  ExpectExecutionWithInput(
+      inputs,
+      /*expected_error=*/false,
+      /*expected_result=*/
+      ModelProvider::Response(registry_->all_output_labels().size(),
+                              kNotShownResultValue));
+  ExpectClassifierResults(inputs, {});
+
+  // Run with first signal non-zero, label2 should be shown.
+  inputs = ModelProvider::Request(registry_->all_cards_input_size(), 0);
+  inputs[0] = 1;
+  ModelProvider::Response expected_output = ModelProvider::Response(
+      registry_->all_output_labels().size(), kNotShownResultValue);
+  expected_output[registry_->get_label_index(TestCardInfo::kLabel2)] =
+      EphemeralHomeModuleRankToScore(EphemeralHomeModuleRank::kTop);
+  ExpectExecutionWithInput(inputs,
+                           /*expected_error=*/false, expected_output);
+  ExpectClassifierResults(inputs, {TestCardInfo::kLabel2});
+}
+
+}  // namespace
+
 }  // namespace segmentation_platform::home_modules
diff --git a/components/segmentation_platform/embedder/home_modules/home_modules_card_registry.cc b/components/segmentation_platform/embedder/home_modules/home_modules_card_registry.cc
index 8c6a749..4e00ee0 100644
--- a/components/segmentation_platform/embedder/home_modules/home_modules_card_registry.cc
+++ b/components/segmentation_platform/embedder/home_modules/home_modules_card_registry.cc
@@ -6,6 +6,7 @@
 
 #include "base/metrics/field_trial_params.h"
 #include "components/commerce/core/commerce_feature_list.h"
+#include "components/segmentation_platform/embedder/home_modules/card_selection_info.h"
 #include "components/segmentation_platform/embedder/home_modules/constants.h"
 #include "components/segmentation_platform/embedder/home_modules/price_tracking_notification_promo.h"
 
@@ -24,33 +25,14 @@
 HomeModulesCardRegistry::HomeModulesCardRegistry(PrefService* profile_prefs)
     : profile_prefs_(profile_prefs) {
   CreateAllCards();
+}
 
-  size_t input_counter = 0;
-  size_t label_counter = 0;
-  for (std::unique_ptr<CardSelectionInfo>& card : all_cards_by_priority_) {
-    std::map<SignalKey, size_t> card_signals;
-    const auto& card_inputs = card->GetInputs();
-    for (const auto& key_and_input : card_inputs) {
-      card_signals[key_and_input.first] = input_counter;
-      input_counter++;
-    }
-    card_signal_map_[card->card_name()] = card_signals;
-
-    std::vector<std::string> card_labels = card->OutputLabels();
-    if (!card_labels.empty()) {
-      all_output_labels_.insert(all_output_labels_.end(), card_labels.begin(),
-                                card_labels.end());
-      for (const auto& label : card_labels) {
-        label_to_output_index_[label] = label_counter;
-        label_counter++;
-      }
-    } else {
-      all_output_labels_.push_back(card->card_name());
-      label_to_output_index_[card->card_name()] = label_counter;
-      label_counter++;
-    }
-  }
-  all_cards_input_size_ = input_counter;
+HomeModulesCardRegistry::HomeModulesCardRegistry(
+    PrefService* profile_prefs,
+    std::vector<std::unique_ptr<CardSelectionInfo>> cards)
+    : profile_prefs_(profile_prefs) {
+  all_cards_by_priority_.swap(cards);
+  InitializeAfterAddingCards();
 }
 
 HomeModulesCardRegistry::~HomeModulesCardRegistry() = default;
@@ -83,11 +65,39 @@
         std::make_unique<PriceTrackingNotificationPromo>(
             price_tracking_promo_count));
   }
-#else
-  // Add all cards
-  label_to_output_index_["label"] = 0;
-  all_output_labels_ = {"label"};
 #endif
+  InitializeAfterAddingCards();
+}
+
+void HomeModulesCardRegistry::InitializeAfterAddingCards() {
+  size_t input_counter = 0;
+  AddCardLabels({kPlaceholderEphemeralModuleLabel});
+  for (std::unique_ptr<CardSelectionInfo>& card : all_cards_by_priority_) {
+    std::map<SignalKey, size_t> card_signals;
+    const auto& card_inputs = card->GetInputs();
+    for (const auto& key_and_input : card_inputs) {
+      card_signals[key_and_input.first] = input_counter;
+      input_counter++;
+    }
+    card_signal_map_[card->card_name()] = card_signals;
+
+    std::vector<std::string> card_labels = card->OutputLabels();
+    if (!card_labels.empty()) {
+      AddCardLabels(card_labels);
+    } else {
+      AddCardLabels({card->card_name()});
+    }
+  }
+  all_cards_input_size_ = input_counter;
+}
+
+void HomeModulesCardRegistry::AddCardLabels(
+    const std::vector<std::string>& card_labels) {
+  for (const std::string& label : card_labels) {
+    CHECK(!label_to_output_index_.count(label));
+    label_to_output_index_[label] = all_output_labels_.size();
+    all_output_labels_.push_back(label);
+  }
 }
 
 base::WeakPtr<HomeModulesCardRegistry> HomeModulesCardRegistry::GetWeakPtr() {
diff --git a/components/segmentation_platform/embedder/home_modules/home_modules_card_registry.h b/components/segmentation_platform/embedder/home_modules/home_modules_card_registry.h
index 30755339..1c5d883 100644
--- a/components/segmentation_platform/embedder/home_modules/home_modules_card_registry.h
+++ b/components/segmentation_platform/embedder/home_modules/home_modules_card_registry.h
@@ -20,6 +20,10 @@
 class HomeModulesCardRegistry : public base::SupportsUserData::Data {
  public:
   explicit HomeModulesCardRegistry(PrefService* profile_prefs);
+  // For testing.
+  HomeModulesCardRegistry(
+      PrefService* profile_prefs,
+      std::vector<std::unique_ptr<CardSelectionInfo>> cards);
   ~HomeModulesCardRegistry() override;
 
   HomeModulesCardRegistry(const HomeModulesCardRegistry&) = delete;
@@ -54,6 +58,12 @@
   // Populats `all_cards_by_priority_`.
   void CreateAllCards();
 
+  // Initializes the registry after all cards are added.
+  void InitializeAfterAddingCards();
+
+  // Adds `card_labels` to the registry.
+  void AddCardLabels(const std::vector<std::string>& card_labels);
+
   const raw_ptr<PrefService> profile_prefs_;
 
   // Maps a card label to its output index order.
diff --git a/components/segmentation_platform/embedder/home_modules/home_modules_card_registry_unittest.cc b/components/segmentation_platform/embedder/home_modules/home_modules_card_registry_unittest.cc
index 0cad204..07db45a 100644
--- a/components/segmentation_platform/embedder/home_modules/home_modules_card_registry_unittest.cc
+++ b/components/segmentation_platform/embedder/home_modules/home_modules_card_registry_unittest.cc
@@ -37,8 +37,9 @@
   feature_list_.InitWithFeatures({commerce::kPriceTrackingPromo}, {});
   registry_ = std::make_unique<HomeModulesCardRegistry>(&pref_service_);
 
-  ASSERT_EQ(1u, registry_->all_output_labels().size());
-  ASSERT_EQ(0u, registry_->get_label_index(kPriceTrackingNotificationPromo));
+  ASSERT_EQ(2u, registry_->all_output_labels().size());
+  ASSERT_EQ(0u, registry_->get_label_index(kPlaceholderEphemeralModuleLabel));
+  ASSERT_EQ(1u, registry_->get_label_index(kPriceTrackingNotificationPromo));
   ASSERT_EQ(3u, registry_->all_cards_input_size());
   const std::vector<std::unique_ptr<CardSelectionInfo>>& all_cards =
       registry_->get_all_cards_by_priority();
diff --git a/components/segmentation_platform/internal/metadata/feature_query.h b/components/segmentation_platform/internal/metadata/feature_query.h
index c188551..ad751a2 100644
--- a/components/segmentation_platform/internal/metadata/feature_query.h
+++ b/components/segmentation_platform/internal/metadata/feature_query.h
@@ -10,6 +10,35 @@
 
 namespace segmentation_platform {
 
+inline constexpr std::array<float, 1> kZeroDefaultValue{0};
+
+#define DEFINE_UMA_FEATURE_LATEST(var_name, uma_name)          \
+  FeatureQuery var_name = FeatureQuery::FromUMAFeature(        \
+      MetadataWriter::UMAFeature::FromValueHistogram(          \
+          uma_name, 28, proto::Aggregation::LATEST_OR_DEFAULT, \
+          kZeroDefaultValue.size(), kZeroDefaultValue.data()))
+
+#define DEFINE_UMA_FEATURE_COUNT(var_name, uma_name, days) \
+  FeatureQuery var_name = FeatureQuery::FromUMAFeature(    \
+      MetadataWriter::UMAFeature::FromValueHistogram(      \
+          uma_name, days, proto::Aggregation::COUNT))
+
+#define DEFINE_UMA_FEATURE_SUM(var_name, uma_name, days)             \
+  FeatureQuery var_name = FeatureQuery::FromUMAFeature(              \
+      MetadataWriter::UMAFeature::FromValueHistogram(uma_name, days, \
+                                                     proto::Aggregation::SUM))
+
+#define DEFINE_INPUT_CONTEXT(var_name, input_name)                          \
+  constexpr std::array<MetadataWriter::CustomInput::Arg, 1> kArg##__LINE__{ \
+      std::make_pair("name", input_name)};                                  \
+  FeatureQuery var_name =                                                   \
+      FeatureQuery::FromCustomInput(MetadataWriter::CustomInput{            \
+          .tensor_length = 1,                                               \
+          .fill_policy = proto::CustomInput::FILL_FROM_INPUT_CONTEXT,       \
+          .name = input_name,                                               \
+          .arg = kArg##__LINE__.data(),                                     \
+          .arg_size = kArg##__LINE__.size()})
+
 struct FeatureQuery {
   STACK_ALLOCATED();
 
diff --git a/components/sync/engine/nigori/cross_user_sharing_public_private_key_pair.cc b/components/sync/engine/nigori/cross_user_sharing_public_private_key_pair.cc
index fe78d52..b4db8309 100644
--- a/components/sync/engine/nigori/cross_user_sharing_public_private_key_pair.cc
+++ b/components/sync/engine/nigori/cross_user_sharing_public_private_key_pair.cc
@@ -39,7 +39,7 @@
   if (private_key.size() != X25519_PRIVATE_KEY_LEN) {
     return std::nullopt;
   }
-  return CrossUserSharingPublicPrivateKeyPair(std::move(private_key));
+  return CrossUserSharingPublicPrivateKeyPair(private_key);
 }
 
 CrossUserSharingPublicPrivateKeyPair::CrossUserSharingPublicPrivateKeyPair(
diff --git a/content/browser/devtools/protocol/fedcm_handler.cc b/content/browser/devtools/protocol/fedcm_handler.cc
index 64db61b0..394b8ee 100644
--- a/content/browser/devtools/protocol/fedcm_handler.cc
+++ b/content/browser/devtools/protocol/fedcm_handler.cc
@@ -38,20 +38,6 @@
   }
 }
 
-std::optional<std::pair<IdentityProviderData, IdentityRequestAccount>>
-GetAccountAt(const std::vector<IdentityProviderData>& idp_data, int index) {
-  int current = 0;
-  for (const auto& data : idp_data) {
-    for (const IdentityRequestAccount& account : data.accounts) {
-      if (current == index) {
-        return std::make_pair(data, account);
-      }
-      ++current;
-    }
-  }
-  return std::nullopt;
-}
-
 }  // namespace
 
 namespace protocol {
@@ -109,59 +95,48 @@
   dialog_id_ = base::NumberToString(next_dialog_id_++);
 
   auto* auth_request = GetFederatedAuthRequest();
-  const auto* idp_data = GetIdentityProviderData(auth_request);
-  // idp_data can be empty if this is an IDP Signin Confirmation dialog.
-
-  // We flatten the two-level IDP->account list into a single
-  // list of accounts because:
-  // - It's easier to work with for callers
-  // - When used for automated testing by IDPs, I expect most of their
-  //   tests to involve just one IDP (themselves), and the single level
-  //   list is easier to use in that case
-  // - If we decide to show, for example, returning accounts across IDPs
-  //   at the top and remaining accounts below that, the two-level list
-  //   requires the same IDP to be present more than once; a single-level
-  //   list is less confusing.
-  // The idpConfigUrl field allows callers to identify which IDP an account
-  // belongs to.
-  auto accounts = std::make_unique<Array<FedCm::Account>>();
-  if (idp_data) {
-    for (const auto& data : *idp_data) {
-      for (const IdentityRequestAccount& account : data.accounts) {
-        FedCm::LoginState login_state;
-        std::optional<std::string> tos_url;
-        std::optional<std::string> pp_url;
-        switch (*account.login_state) {
-          case IdentityRequestAccount::LoginState::kSignUp:
-            login_state = FedCm::LoginStateEnum::SignUp;
-            // Because TOS and PP URLs are only used when the login state is
-            // sign up, we only populate them in that case.
-            pp_url = data.client_metadata.privacy_policy_url.spec();
-            tos_url = data.client_metadata.terms_of_service_url.spec();
-            break;
-          case IdentityRequestAccount::LoginState::kSignIn:
-            login_state = FedCm::LoginStateEnum::SignIn;
-            break;
-        }
-        std::unique_ptr<FedCm::Account> entry =
-            FedCm::Account::Create()
-                .SetAccountId(account.id)
-                .SetEmail(account.email)
-                .SetName(account.name)
-                .SetGivenName(account.given_name)
-                .SetPictureUrl(account.picture.spec())
-                .SetIdpConfigUrl(data.idp_metadata.config_url.spec())
-                .SetIdpLoginUrl(data.idp_metadata.idp_login_url.spec())
-                .SetLoginState(login_state)
-                .Build();
-        if (pp_url) {
-          entry->SetPrivacyPolicyUrl(*pp_url);
-        }
-        if (tos_url) {
-          entry->SetTermsOfServiceUrl(*tos_url);
-        }
-        accounts->push_back(std::move(entry));
+  const auto* accounts = GetAccounts(auth_request);
+  // `accounts` can be empty if this is an IDP Signin Confirmation dialog.
+  auto accounts_array = std::make_unique<Array<FedCm::Account>>();
+  if (accounts) {
+    for (const auto& account : *accounts) {
+      FedCm::LoginState login_state;
+      std::optional<std::string> tos_url;
+      std::optional<std::string> pp_url;
+      switch (*account->login_state) {
+        case IdentityRequestAccount::LoginState::kSignUp:
+          login_state = FedCm::LoginStateEnum::SignUp;
+          // Because TOS and PP URLs are only used when the login state is
+          // sign up, we only populate them in that case.
+          pp_url = account->identity_provider->client_metadata
+                       .privacy_policy_url.spec();
+          tos_url = account->identity_provider->client_metadata
+                        .terms_of_service_url.spec();
+          break;
+        case IdentityRequestAccount::LoginState::kSignIn:
+          login_state = FedCm::LoginStateEnum::SignIn;
+          break;
       }
+      std::unique_ptr<FedCm::Account> entry =
+          FedCm::Account::Create()
+              .SetAccountId(account->id)
+              .SetEmail(account->email)
+              .SetName(account->name)
+              .SetGivenName(account->given_name)
+              .SetPictureUrl(account->picture.spec())
+              .SetIdpConfigUrl(
+                  account->identity_provider->idp_metadata.config_url.spec())
+              .SetIdpLoginUrl(
+                  account->identity_provider->idp_metadata.idp_login_url.spec())
+              .SetLoginState(login_state)
+              .Build();
+      if (pp_url) {
+        entry->SetPrivacyPolicyUrl(*pp_url);
+      }
+      if (tos_url) {
+        entry->SetTermsOfServiceUrl(*tos_url);
+      }
+      accounts_array->push_back(std::move(entry));
     }
   }
   IdentityRequestDialogController* dialog = auth_request->GetDialogController();
@@ -174,7 +149,7 @@
   if (subtitle) {
     maybe_subtitle = *subtitle;
   }
-  frontend_->DialogShown(dialog_id_, dialog_type, std::move(accounts),
+  frontend_->DialogShown(dialog_id_, dialog_type, std::move(accounts_array),
                          dialog->GetTitle(), std::move(maybe_subtitle));
 }
 
@@ -194,18 +169,19 @@
   }
 
   auto* auth_request = GetFederatedAuthRequest();
-  const auto* idp_data = GetIdentityProviderData(auth_request);
-  if (!idp_data) {
+  if (!GetIdentityProviderData(auth_request)) {
     return DispatchResponse::ServerError(
         "selectAccount called while no FedCm dialog is shown");
   }
-  auto account = GetAccountAt(*idp_data, in_accountIndex);
-  if (!account) {
+  const auto* accounts = GetAccounts(auth_request);
+  if (!accounts || in_accountIndex < 0 ||
+      static_cast<size_t>(in_accountIndex) >= accounts->size()) {
     return DispatchResponse::InvalidParams("Invalid account index");
   }
 
+  const auto& account = accounts->at(in_accountIndex);
   auth_request->AcceptAccountsDialogForDevtools(
-      account->first.idp_metadata.config_url, account->second);
+      account->identity_provider->idp_metadata.config_url, *account);
   return DispatchResponse::Success();
 }
 
@@ -219,30 +195,31 @@
   }
 
   auto* auth_request = GetFederatedAuthRequest();
-  const auto* idp_data = GetIdentityProviderData(auth_request);
-  if (!idp_data) {
+  if (!GetIdentityProviderData(auth_request)) {
     return DispatchResponse::ServerError(
         "openUrl called while no FedCm dialog is shown");
   }
 
-  auto account = GetAccountAt(*idp_data, in_accountIndex);
-  if (!account) {
+  const auto* accounts = GetAccounts(auth_request);
+  if (!accounts || in_accountIndex < 0 ||
+      static_cast<size_t>(in_accountIndex) >= accounts->size()) {
     return DispatchResponse::InvalidParams("Invalid account index");
   }
 
+  const auto& account = accounts->at(in_accountIndex);
   IdentityRequestDialogController::LinkType type;
   GURL url;
   if (in_accountUrlType == FedCm::AccountUrlTypeEnum::TermsOfService) {
     type = IdentityRequestDialogController::LinkType::TERMS_OF_SERVICE;
-    url = account->first.client_metadata.terms_of_service_url;
+    url = account->identity_provider->client_metadata.terms_of_service_url;
   } else if (in_accountUrlType == FedCm::AccountUrlTypeEnum::PrivacyPolicy) {
     type = IdentityRequestDialogController::LinkType::PRIVACY_POLICY;
-    url = account->first.client_metadata.privacy_policy_url;
+    url = account->identity_provider->client_metadata.privacy_policy_url;
   } else {
     return DispatchResponse::InvalidParams("Invalid account URL type");
   }
-  if (!url.is_valid() || account->second.login_state !=
-                             IdentityRequestAccount::LoginState::kSignUp) {
+  if (!url.is_valid() ||
+      account->login_state != IdentityRequestAccount::LoginState::kSignUp) {
     return DispatchResponse::InvalidParams(
         "Account does not have requested URL");
   }
@@ -279,7 +256,7 @@
               "Multi-IDP not supported for ConfirmIdpLogin yet "
               "(crbug.com/328115461)");
         }
-        if (!auth_request->UseAnotherAccountForDevtools(idp_data->at(0))) {
+        if (!auth_request->UseAnotherAccountForDevtools(*idp_data->at(0))) {
           return DispatchResponse::ServerError(
               "'Use another account' not supported for this IDP");
         }
@@ -378,8 +355,8 @@
   return page_data->PendingWebIdentityRequest();
 }
 
-const std::vector<IdentityProviderData>* FedCmHandler::GetIdentityProviderData(
-    FederatedAuthRequestImpl* auth_request) {
+const std::vector<IdentityProviderDataPtr>*
+FedCmHandler::GetIdentityProviderData(FederatedAuthRequestImpl* auth_request) {
   if (!auth_request) {
     return nullptr;
   }
@@ -391,6 +368,18 @@
   return &idp_data;
 }
 
+const std::vector<IdentityRequestAccountPtr>* FedCmHandler::GetAccounts(
+    FederatedAuthRequestImpl* auth_request) {
+  if (!auth_request) {
+    return nullptr;
+  }
+  const auto& accounts = auth_request->GetAccounts();
+  if (accounts.empty()) {
+    return nullptr;
+  }
+  return &accounts;
+}
+
 FederatedIdentityApiPermissionContextDelegate*
 FedCmHandler::GetApiPermissionContext() {
   if (!frame_host_) {
diff --git a/content/browser/devtools/protocol/fedcm_handler.h b/content/browser/devtools/protocol/fedcm_handler.h
index a562d68c..13011bc 100644
--- a/content/browser/devtools/protocol/fedcm_handler.h
+++ b/content/browser/devtools/protocol/fedcm_handler.h
@@ -17,9 +17,14 @@
 class FederatedAuthRequestImpl;
 class FederatedAuthRequestPageData;
 class FederatedIdentityApiPermissionContextDelegate;
-struct IdentityProviderData;
+class IdentityProviderData;
+class IdentityRequestAccount;
 }  // namespace content
 
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
+
 namespace content::protocol {
 
 class FedCmHandler : public DevToolsDomainHandler, public FedCm::Backend {
@@ -72,7 +77,9 @@
 
   FederatedAuthRequestPageData* GetPageData();
   FederatedAuthRequestImpl* GetFederatedAuthRequest();
-  const std::vector<IdentityProviderData>* GetIdentityProviderData(
+  const std::vector<IdentityProviderDataPtr>* GetIdentityProviderData(
+      FederatedAuthRequestImpl* auth_request);
+  const std::vector<IdentityRequestAccountPtr>* GetAccounts(
       FederatedAuthRequestImpl* auth_request);
   FederatedIdentityApiPermissionContextDelegate* GetApiPermissionContext();
 
diff --git a/content/browser/renderer_host/back_forward_cache_metrics.cc b/content/browser/renderer_host/back_forward_cache_metrics.cc
index 8c3e3d18..269cd7f 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics.cc
+++ b/content/browser/renderer_host/back_forward_cache_metrics.cc
@@ -528,6 +528,19 @@
   if (back_forward_cache_allowed) {
     UMA_HISTOGRAM_ENUMERATION("BackForwardCache.HistoryNavigationOutcome",
                               outcome);
+    int nav_offset = navigation->GetNavigationEntryOffset();
+    HistoryNavigationDirection direction =
+        nav_offset == 0
+            ? HistoryNavigationDirection::kSameEntry
+            : (nav_offset < 0 ? HistoryNavigationDirection::kBack
+                              : HistoryNavigationDirection::kForward);
+    if (navigation->IsServedFromBackForwardCache()) {
+      base::UmaHistogramEnumeration(
+          "BackForwardCache.RestoredNavigationDirection", direction);
+    } else {
+      base::UmaHistogramEnumeration(
+          "BackForwardCache.NonRestoredNavigationDirection", direction);
+    }
   }
 
   UMA_HISTOGRAM_ENUMERATION(
diff --git a/content/browser/renderer_host/back_forward_cache_metrics.h b/content/browser/renderer_host/back_forward_cache_metrics.h
index 3b8a2585..040ac7d 100644
--- a/content/browser/renderer_host/back_forward_cache_metrics.h
+++ b/content/browser/renderer_host/back_forward_cache_metrics.h
@@ -50,6 +50,18 @@
                                            NotRestoredReason::kMinValue,
                                            NotRestoredReason::kMaxValue>;
 
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  //
+  // LINT.IfChange(HistoryNavigationDirection)
+  enum class HistoryNavigationDirection {
+    kBack = 0,
+    kForward = 1,
+    kSameEntry = 2,
+    kMaxValue = kSameEntry,
+  };
+  // LINT.ThenChange(//tools/metrics/histograms/metadata/navigation/enums.xml:HistoryNavigationDirection)
+
   // Please keep in sync with BackForwardCacheHistoryNavigationOutcome in
   // tools/metrics/histograms/enums.xml. These values should not be renumbered.
   enum class HistoryNavigationOutcome {
diff --git a/content/browser/webid/fake_identity_request_dialog_controller.cc b/content/browser/webid/fake_identity_request_dialog_controller.cc
index 2ba9d59..becc361a 100644
--- a/content/browser/webid/fake_identity_request_dialog_controller.cc
+++ b/content/browser/webid/fake_identity_request_dialog_controller.cc
@@ -21,24 +21,21 @@
 
 bool FakeIdentityRequestDialogController::ShowAccountsDialog(
     const std::string& rp_for_display,
-    const std::vector<content::IdentityProviderData>& identity_provider_data,
-    IdentityRequestAccount::SignInMode sign_in_mode,
+    const std::vector<IdentityProviderDataPtr>& idp_list,
+    const std::vector<IdentityRequestAccountPtr>& accounts,
+    content::IdentityRequestAccount::SignInMode sign_in_mode,
     blink::mojom::RpMode rp_mode,
-    const std::optional<content::IdentityProviderData>& new_account_idp,
+    const std::vector<IdentityRequestAccountPtr>& new_accounts,
     AccountSelectionCallback on_selected,
     LoginToIdPCallback on_add_account,
     DismissCallback dismiss_callback,
     AccountsDisplayedCallback accounts_displayed_callback) {
-  // TODO(crbug.com/40233285): Temporarily support only the first IDP, extend to
-  // support multiple IDPs.
-  std::vector<IdentityRequestAccount> accounts =
-      identity_provider_data[0].accounts;
   CHECK_GT(accounts.size(), 0ul);
-  CHECK_GT(identity_provider_data.size(), 0ul);
+  CHECK_GT(idp_list.size(), 0ul);
 
   // We're faking this so that browser automation and tests can verify that
   // the RP context was read properly.
-  switch (identity_provider_data[0].rp_context) {
+  switch (idp_list[0]->rp_context) {
     case blink::mojom::RpContext::kSignIn:
       title_ = "Sign in";
       break;
@@ -56,14 +53,15 @@
   // Use the provided account, if any. Otherwise do not run the callback right
   // away.
   if (selected_account_ && !is_interception_enabled_) {
+    // TODO(crbug.com/364578201): This needs to be augmented to provide the
+    // selected IDP. For now use the first one.
     std::move(on_selected)
-        .Run(identity_provider_data[0].idp_metadata.config_url,
-             *selected_account_,
+        .Run(idp_list[0]->idp_metadata.config_url, *selected_account_,
              /* is_sign_in= */ true);
   } else if (sign_in_mode == IdentityRequestAccount::SignInMode::kAuto) {
     std::move(on_selected)
-        .Run(identity_provider_data[0].idp_metadata.config_url,
-             identity_provider_data[0].accounts[0].id, /* is_sign_in= */ true);
+        .Run(accounts[0]->identity_provider->idp_metadata.config_url,
+             accounts[0]->id, /* is_sign_in= */ true);
   }
   return true;
 }
diff --git a/content/browser/webid/fake_identity_request_dialog_controller.h b/content/browser/webid/fake_identity_request_dialog_controller.h
index 0871eff..838c2a6c 100644
--- a/content/browser/webid/fake_identity_request_dialog_controller.h
+++ b/content/browser/webid/fake_identity_request_dialog_controller.h
@@ -11,6 +11,9 @@
 #include "content/public/browser/identity_request_dialog_controller.h"
 #include "content/public/browser/web_contents_observer.h"
 
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
 using TokenError = content::IdentityCredentialTokenError;
 
 namespace content {
@@ -30,10 +33,11 @@
 
   bool ShowAccountsDialog(
       const std::string& rp_for_display,
-      const std::vector<content::IdentityProviderData>& identity_provider_data,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       IdentityRequestAccount::SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<content::IdentityProviderData>& new_account_idp,
+      const std::vector<IdentityRequestAccountPtr>& new_accounts,
       AccountSelectionCallback on_selected,
       LoginToIdPCallback on_add_account,
       DismissCallback dismmiss_callback,
diff --git a/content/browser/webid/fedcm_metrics.cc b/content/browser/webid/fedcm_metrics.cc
index 5fb6a18..7e8091360 100644
--- a/content/browser/webid/fedcm_metrics.cc
+++ b/content/browser/webid/fedcm_metrics.cc
@@ -45,7 +45,7 @@
 }
 
 void FedCmMetrics::RecordShowAccountsDialogTime(
-    const std::vector<IdentityProviderData>& providers,
+    const std::vector<IdentityProviderDataPtr>& providers,
     base::TimeDelta duration) {
   DCHECK_GT(session_id_, 0);
   auto RecordUkm = [&](auto& ukm_builder) {
@@ -59,9 +59,9 @@
   for (const auto& provider : providers) {
     // A provider may have no accounts, for instance if present due to IDP
     // mismatch.
-    if (!provider.accounts.empty()) {
+    if (!provider->has_login_status_mismatch) {
       ukm::builders::Blink_FedCmIdp fedcm_idp_builder(
-          GetOrCreateProviderSourceId(provider.idp_metadata.config_url));
+          GetOrCreateProviderSourceId(provider->idp_metadata.config_url));
       RecordUkm(fedcm_idp_builder);
     }
   }
@@ -142,7 +142,7 @@
 }
 
 void FedCmMetrics::RecordCancelOnDialogTime(
-    const std::vector<IdentityProviderData>& providers,
+    const std::vector<IdentityProviderDataPtr>& providers,
     base::TimeDelta duration) {
   DCHECK_GT(session_id_, 0);
   auto RecordUkm = [&](auto& ukm_builder) {
@@ -156,7 +156,7 @@
 
   for (const auto& provider : providers) {
     ukm::builders::Blink_FedCmIdp fedcm_idp_builder(
-        GetOrCreateProviderSourceId(provider.idp_metadata.config_url));
+        GetOrCreateProviderSourceId(provider->idp_metadata.config_url));
     RecordUkm(fedcm_idp_builder);
   }
 
@@ -164,7 +164,7 @@
 }
 
 void FedCmMetrics::RecordAccountsDialogShownDuration(
-    const std::vector<IdentityProviderData>& providers,
+    const std::vector<IdentityProviderDataPtr>& providers,
     base::TimeDelta duration) {
   DCHECK_GT(session_id_, 0);
   auto RecordUkm = [&](auto& ukm_builder) {
@@ -178,12 +178,11 @@
 
   for (const auto& provider : providers) {
     ukm::builders::Blink_FedCmIdp fedcm_idp_builder(
-        GetOrCreateProviderSourceId(provider.idp_metadata.config_url));
+        GetOrCreateProviderSourceId(provider->idp_metadata.config_url));
     // A provider may have no accounts and be present due to IDP mismatch.
-    if (!provider.accounts.empty()) {
+    if (!provider->has_login_status_mismatch) {
       RecordUkm(fedcm_idp_builder);
     } else {
-      DCHECK(provider.has_login_status_mismatch);
       fedcm_idp_builder.SetTiming_MismatchDialogShownDuration(
           ukm::GetExponentialBucketMinForUserTiming(duration.InMilliseconds()));
       fedcm_idp_builder.SetFedCmSessionID(session_id_);
@@ -200,7 +199,7 @@
 }
 
 void FedCmMetrics::RecordMismatchDialogShownDuration(
-    const std::vector<IdentityProviderData>& providers,
+    const std::vector<IdentityProviderDataPtr>& providers,
     base::TimeDelta duration) {
   DCHECK_GT(session_id_, 0);
   auto RecordUkm = [&](auto& ukm_builder) {
@@ -215,7 +214,7 @@
   for (const auto& provider : providers) {
     // We should only reach this if all `providers` are a mismatch.
     ukm::builders::Blink_FedCmIdp fedcm_idp_builder(
-        GetOrCreateProviderSourceId(provider.idp_metadata.config_url));
+        GetOrCreateProviderSourceId(provider->idp_metadata.config_url));
     RecordUkm(fedcm_idp_builder);
   }
 
@@ -465,7 +464,7 @@
 }
 
 void FedCmMetrics::RecordAccountsDialogShown(
-    const std::vector<IdentityProviderData>& providers) {
+    const std::vector<IdentityProviderDataPtr>& providers) {
   auto RecordUkm = [&](auto& ukm_builder) {
     ukm_builder.SetAccountsDialogShown(true);
     ukm_builder.SetFedCmSessionID(session_id_);
@@ -476,12 +475,12 @@
 
   for (const auto& provider : providers) {
     ukm::builders::Blink_FedCmIdp fedcm_idp_builder(
-        GetOrCreateProviderSourceId(provider.idp_metadata.config_url));
+        GetOrCreateProviderSourceId(provider->idp_metadata.config_url));
     // A provider may have no accounts and be present due to IDP mismatch.
-    if (!provider.accounts.empty()) {
+    if (!provider->has_login_status_mismatch) {
       RecordUkm(fedcm_idp_builder);
     } else {
-      DCHECK(provider.has_login_status_mismatch);
+      DCHECK(provider->has_login_status_mismatch);
       fedcm_idp_builder.SetMismatchDialogShown(true);
       fedcm_idp_builder.SetFedCmSessionID(session_id_);
       fedcm_idp_builder.Record(ukm::UkmRecorder::Get());
@@ -768,14 +767,14 @@
   CHECK_GT(size, 0);
   base::UmaHistogramCustomCounts("Blink.FedCm.AccountsSize.Raw", size,
                                  /*min=*/1,
-                                 /*max=*/10, /*buckets=*/10);
+                                 /*exclusive_max=*/10, /*buckets=*/10);
 }
 
 void RecordReadyToShowAccountsSize(int size) {
   CHECK_GT(size, 0);
   base::UmaHistogramCustomCounts("Blink.FedCm.AccountsSize.ReadyToShow", size,
                                  /*min=*/1,
-                                 /*max=*/10, /*buckets=*/10);
+                                 /*exclusive_max=*/10, /*buckets=*/10);
 }
 
 }  // namespace content
diff --git a/content/browser/webid/fedcm_metrics.h b/content/browser/webid/fedcm_metrics.h
index dcbbac4..e2b27d7c 100644
--- a/content/browser/webid/fedcm_metrics.h
+++ b/content/browser/webid/fedcm_metrics.h
@@ -19,6 +19,7 @@
 
 namespace content {
 
+using IdentityProviderDataPtr = scoped_refptr<IdentityProviderData>;
 using MediationRequirement = ::password_manager::CredentialMediationRequirement;
 using RpMode = blink::mojom::RpMode;
 
@@ -274,7 +275,7 @@
   // dialog is shown. This does not include flows that involve LoginToIdP. e.g.
   // mismatch flow or button flow with users whose login status is "logged-out".
   void RecordShowAccountsDialogTime(
-      const std::vector<IdentityProviderData>& providers,
+      const std::vector<IdentityProviderDataPtr>& providers,
       base::TimeDelta duration);
 
   // Records the time from when a call to the API was made to when the accounts
@@ -300,19 +301,19 @@
   // selecting any accounts. `duration` is the time from when the accounts
   // dialog was shown to when the user closed the dialog.
   void RecordCancelOnDialogTime(
-      const std::vector<IdentityProviderData>& providers,
+      const std::vector<IdentityProviderDataPtr>& providers,
       base::TimeDelta duration);
 
   // Records the duration from when an accounts dialog is shown to when it is
   // destroyed.
   void RecordAccountsDialogShownDuration(
-      const std::vector<IdentityProviderData>& providers,
+      const std::vector<IdentityProviderDataPtr>& providers,
       base::TimeDelta duration);
 
   // Records the duration from when a mismatch dialog is shown to when it is
   // destroyed or user triggers IDP sign-in pop-up window.
   void RecordMismatchDialogShownDuration(
-      const std::vector<IdentityProviderData>& providers,
+      const std::vector<IdentityProviderDataPtr>& providers,
       base::TimeDelta duration);
 
   // Records the reason that closed accounts dialog without selecting any
@@ -383,7 +384,7 @@
 
   // Records a sample when an accounts dialog is shown.
   void RecordAccountsDialogShown(
-      const std::vector<IdentityProviderData>& providers);
+      const std::vector<IdentityProviderDataPtr>& providers);
 
   // This enum is used in histograms. Do not remove or modify existing entries.
   // You may add entries at the end, and update |kMaxValue|.
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc
index 4dd0ce4..27422683 100644
--- a/content/browser/webid/federated_auth_request_impl.cc
+++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -379,7 +379,7 @@
 // Returns whether there are accounts remaining after applying the account label
 // filter.
 bool FilterAccountsWithLabel(const std::string& label,
-                             IdpNetworkRequestManager::AccountList& accounts) {
+                             std::vector<IdentityRequestAccountPtr>& accounts) {
   if (label.empty()) {
     return true;
   }
@@ -390,8 +390,8 @@
   // shown.
   size_t accounts_remaining = 0u;
   for (auto& account : accounts) {
-    if (!base::Contains(account.labels, label)) {
-      account.is_filtered_out = true;
+    if (!base::Contains(account->labels, label)) {
+      account->is_filtered_out = true;
     } else {
       ++accounts_remaining;
     }
@@ -407,7 +407,7 @@
 // filter.
 bool FilterAccountsWithLoginHint(
     const std::string& login_hint,
-    IdpNetworkRequestManager::AccountList& accounts) {
+    std::vector<IdentityRequestAccountPtr>& accounts) {
   if (login_hint.empty()) {
     return true;
   }
@@ -418,11 +418,11 @@
   // shown.
   size_t accounts_remaining = 0u;
   for (auto& account : accounts) {
-    if (account.is_filtered_out) {
+    if (account->is_filtered_out) {
       continue;
     }
-    if (!base::Contains(account.login_hints, login_hint)) {
-      account.is_filtered_out = true;
+    if (!base::Contains(account->login_hints, login_hint)) {
+      account->is_filtered_out = true;
     } else {
       ++accounts_remaining;
     }
@@ -439,23 +439,23 @@
 // filter.
 bool FilterAccountsWithDomainHint(
     const std::string& domain_hint,
-    IdpNetworkRequestManager::AccountList& accounts) {
+    std::vector<IdentityRequestAccountPtr>& accounts) {
   if (domain_hint.empty()) {
     return true;
   }
 
   size_t accounts_remaining = 0u;
   for (auto& account : accounts) {
-    if (account.is_filtered_out) {
+    if (account->is_filtered_out) {
       continue;
     }
     if (domain_hint == FederatedAuthRequestImpl::kWildcardDomainHint) {
-      if (account.domain_hints.empty()) {
-        account.is_filtered_out = true;
+      if (account->domain_hints.empty()) {
+        account->is_filtered_out = true;
         continue;
       }
-    } else if (!base::Contains(account.domain_hints, domain_hint)) {
-      account.is_filtered_out = true;
+    } else if (!base::Contains(account->domain_hints, domain_hint)) {
+      account->is_filtered_out = true;
       continue;
     }
     ++accounts_remaining;
@@ -1436,7 +1436,7 @@
 
 void FederatedAuthRequestImpl::OnClientMetadataResponseReceived(
     std::unique_ptr<IdentityProviderInfo> idp_info,
-    const IdpNetworkRequestManager::AccountList& accounts,
+    std::vector<IdentityRequestAccountPtr>&& accounts,
     IdpNetworkRequestManager::FetchStatus status,
     IdpNetworkRequestManager::ClientMetadata client_metadata) {
   client_metadata_fetched_time_ = base::TimeTicks::Now();
@@ -1464,7 +1464,8 @@
           "with the provided background color");
     }
   }
-  FetchAccountPictures(std::move(idp_info), accounts, client_metadata);
+  FetchAccountPictures(std::move(idp_info), std::move(accounts),
+                       client_metadata);
 }
 
 std::vector<IdentityRequestDialogDisclosureField>
@@ -1525,7 +1526,7 @@
 
 void FederatedAuthRequestImpl::OnFetchDataForIdpSucceeded(
     std::unique_ptr<IdentityProviderInfo> idp_info,
-    const IdpNetworkRequestManager::AccountList& accounts,
+    std::vector<IdentityRequestAccountPtr>&& accounts,
     const IdpNetworkRequestManager::ClientMetadata& client_metadata) {
   fetch_data_.did_succeed_for_at_least_one_idp = true;
 
@@ -1536,14 +1537,26 @@
 
   const std::string idp_for_display =
       webid::FormatUrlForDisplay(idp_config_url);
-  idp_info->data =
-      IdentityProviderData(idp_for_display, accounts, idp_info->metadata,
-                           ClientMetadata{client_metadata.terms_of_service_url,
-                                          client_metadata.privacy_policy_url,
-                                          client_metadata.brand_icon_url},
-                           idp_info->rp_context, disclosure_fields,
-                           /*has_login_status_mismatch=*/false);
+  idp_info->data = base::MakeRefCounted<IdentityProviderData>(
+      idp_for_display, idp_info->metadata,
+      ClientMetadata{client_metadata.terms_of_service_url,
+                     client_metadata.privacy_policy_url,
+                     client_metadata.brand_icon_url},
+      idp_info->rp_context, disclosure_fields,
+      /*has_login_status_mismatch=*/false);
+  for (auto& account : accounts) {
+    account->identity_provider = idp_info->data;
+  }
+  // If the IDP data existed before, we need to remove the old accounts data.
+  // This can happen with the 'use other account' feature.
+  if (idp_infos_.find(idp_config_url) != idp_infos_.end()) {
+    std::erase_if(accounts_, [&idp_config_url](const auto& account) {
+      return account->identity_provider->idp_metadata.config_url ==
+             idp_config_url;
+    });
+  }
   idp_infos_[idp_config_url] = std::move(idp_info);
+  idp_accounts_[idp_config_url] = std::move(accounts);
 
   fetch_data_.pending_idps.erase(idp_config_url);
   MaybeShowAccountsDialog();
@@ -1603,58 +1616,52 @@
   // Account" flow or the IDP login mismatch in multiple IDP case.
   idp_data_for_display_.clear();
 
-  // If this method call occurs after a login, we'd like to show the account
-  // that was logged in.
-  std::optional<IdentityProviderData> new_account_idp;
   for (const auto& idp : idp_order_) {
     auto idp_info_it = idp_infos_.find(idp);
-    if (idp_infos_.size() > 1u ||
-        IsFedCmUseOtherAccountEnabled(rp_mode_ == RpMode::kButton)) {
-      if (!login_url_.is_empty() &&
-          login_url_ == idp_info_it->second->metadata.idp_login_url) {
-        std::vector<IdentityRequestAccount> new_accounts_list;
-        std::vector<IdentityRequestAccount> old_accounts_list;
-        for (const auto& account : idp_info_it->second->data->accounts) {
-          if (!account_ids_before_login_.contains(account.id)) {
-            new_accounts_list.emplace_back(account);
-          } else {
-            old_accounts_list.emplace_back(account);
-          }
-        }
-        account_ids_before_login_.clear();
-        if (!new_accounts_list.empty()) {
-          new_account_idp = idp_info_it->second->data;
-          new_account_idp->accounts = new_accounts_list;
-          new_accounts_list.insert(
-              new_accounts_list.end(),
-              std::make_move_iterator(old_accounts_list.begin()),
-              std::make_move_iterator(old_accounts_list.end()));
-          idp_info_it->second->data->accounts = std::move(new_accounts_list);
-        }
-      }
-    }
     if (idp_info_it != idp_infos_.end() && idp_info_it->second->data) {
-      idp_data_for_display_.push_back(*idp_info_it->second->data);
+      idp_data_for_display_.push_back(idp_info_it->second->data);
+    }
+    auto accounts_it = idp_accounts_.find(idp);
+    if (accounts_it != idp_accounts_.end()) {
+      accounts_.insert(accounts_.end(),
+                       std::make_move_iterator(accounts_it->second.begin()),
+                       std::make_move_iterator(accounts_it->second.end()));
     }
   }
-
-  // We want to show IDPs in the following order in the UI:
-  // 1. IDPs for which there was a mismatch.
-  // 2. IDPs for which there were returning accounts.
-  // 3. IDPs for which there weren't returning accounts.
-  base::ranges::stable_sort(idp_data_for_display_, [](const auto& idp1,
-                                                      const auto& idp2) {
-    if (idp1.has_login_status_mismatch != idp2.has_login_status_mismatch) {
-      // The IDP with mismatch should go first.
-      return idp1.has_login_status_mismatch > idp2.has_login_status_mismatch;
+  idp_accounts_.clear();
+  std::stable_sort(
+      accounts_.begin(), accounts_.end(),
+      [&](const auto& account1, const auto& account2) {
+        // First, show newly logged in accounts, if any.
+        bool is_account1_new = IsNewlyLoggedIn(*account1);
+        bool is_account2_new = IsNewlyLoggedIn(*account2);
+        if (is_account1_new || is_account2_new) {
+          return !is_account2_new;
+        }
+        // Show returning accounts before non-returning.
+        if (account1->login_state == LoginState::kSignUp ||
+            account2->login_state == LoginState::kSignUp) {
+          return account1->login_state == LoginState::kSignIn;
+        }
+        // Within returning accounts, prefer those with last used
+        // timestamp.
+        if (!account1->last_used_timestamp || !account2->last_used_timestamp) {
+          return !!account1->last_used_timestamp;
+        }
+        // If both have last used timestamp, prefer the latest.
+        return *account1->last_used_timestamp > *account2->last_used_timestamp;
+      });
+  // Copy the newly logged in accounts into `new_accounts_`, if there are any.
+  new_accounts_.clear();
+  for (const auto& account : accounts_) {
+    if (IsNewlyLoggedIn(*account)) {
+      new_accounts_.push_back(account);
+    } else {
+      // Since this is sorted, once not newly logged in, exit.
+      break;
     }
-    LoginState state1 = idp1.accounts.empty() ? LoginState::kSignIn
-                                              : *idp1.accounts[0].login_state;
-    LoginState state2 = idp2.accounts.empty() ? LoginState::kSignIn
-                                              : *idp2.accounts[0].login_state;
-    // LoginState::kSignIn should go first.
-    return state1 < state2;
-  });
+  }
+  account_ids_before_login_.clear();
 
   // TODO(crbug.com/40246099): Handle auto_reauthn_ for multi IDP.
   bool auto_reauthn_enabled =
@@ -1665,8 +1672,8 @@
   bool is_auto_reauthn_embargoed = false;
   std::optional<base::TimeDelta> time_from_embargo;
   bool requires_user_mediation = false;
-  const IdentityProviderData* auto_reauthn_idp = nullptr;
-  const IdentityRequestAccount* auto_reauthn_account = nullptr;
+  IdentityProviderDataPtr auto_reauthn_idp = nullptr;
+  IdentityRequestAccountPtr auto_reauthn_account = nullptr;
   bool has_single_returning_account = false;
   if (auto_reauthn_enabled) {
     is_auto_reauthn_setting_enabled =
@@ -1699,7 +1706,7 @@
     if (!has_single_returning_account &&
         mediation_requirement_ == MediationRequirement::kSilent) {
       fedcm_metrics_->RecordAutoReauthnMetrics(
-          has_single_returning_account, auto_reauthn_account,
+          has_single_returning_account, auto_reauthn_account.get(),
           dialog_type_ == kAutoReauth, !is_auto_reauthn_setting_enabled,
           is_auto_reauthn_embargoed, time_from_embargo,
           requires_user_mediation);
@@ -1725,10 +1732,10 @@
     }
 
     if (dialog_type_ == kAutoReauth) {
-      IdentityRequestAccount account{*auto_reauthn_account};
-      IdentityProviderData idp{*auto_reauthn_idp};
-      idp.accounts = {account};
-      idp_data_for_display_ = {idp};
+      accounts_ = {auto_reauthn_account};
+      idp_data_for_display_ = {auto_reauthn_idp};
+      new_accounts_.clear();
+      accounts_[0]->identity_provider = idp_data_for_display_[0];
     }
   }
 
@@ -1743,7 +1750,7 @@
 
   if (auto_reauthn_enabled) {
     fedcm_metrics_->RecordAutoReauthnMetrics(
-        has_single_returning_account, auto_reauthn_account,
+        has_single_returning_account, auto_reauthn_account.get(),
         dialog_type_ == kAutoReauth, !is_auto_reauthn_setting_enabled,
         is_auto_reauthn_embargoed, time_from_embargo, requires_user_mediation);
   }
@@ -1816,10 +1823,10 @@
   // been cleaned up.
   if (!request_dialog_controller_->ShowAccountsDialog(
           GetTopFrameOriginForDisplay(GetEmbeddingOrigin()),
-          idp_data_for_display_,
+          idp_data_for_display_, accounts_,
           identity_selection_type_ == kExplicit ? SignInMode::kExplicit
                                                 : SignInMode::kAuto,
-          rp_mode_, new_account_idp,
+          rp_mode_, new_accounts_,
           base::BindOnce(&FederatedAuthRequestImpl::OnAccountSelected,
                          weak_ptr_factory_.GetWeakPtr()),
           base::BindRepeating(&FederatedAuthRequestImpl::LoginToIdP,
@@ -1907,10 +1914,10 @@
 
   const std::string idp_for_display =
       webid::FormatUrlForDisplay(idp_config_url);
-  idp_info->data = IdentityProviderData(
-      idp_for_display, std::vector<IdentityRequestAccount>(),
-      idp_info->metadata, ClientMetadata{GURL(), GURL(), GURL()},
-      idp_info->rp_context, GetDisclosureFields(*idp_info->provider),
+  idp_info->data = base::MakeRefCounted<IdentityProviderData>(
+      idp_for_display, idp_info->metadata,
+      ClientMetadata{GURL(), GURL(), GURL()}, idp_info->rp_context,
+      GetDisclosureFields(*idp_info->provider),
       /*has_login_status_mismatch=*/true);
   idp_infos_[idp_config_url] = std::move(idp_info);
 
@@ -1955,8 +1962,8 @@
 
   // Set `idp_data_for_display_` so it is always the case that we can rely on it
   // to know which IDPs have been seen in the UI.
-  CHECK(idp_info->data.has_value());
-  idp_data_for_display_ = {*idp_info->data};
+  CHECK(idp_info->data);
+  idp_data_for_display_ = {idp_info->data};
 
   // If IdP login status mismatch dialog is already visible, calling
   // ShowFailureDialog() a 2nd time should notify the user that login
@@ -1986,7 +1993,7 @@
 
   CHECK(idp_data_for_display_.size() == 1u);
   fedcm_metrics_->RecordSingleIdpMismatchDialogShown(
-      idp_data_for_display_[0], has_shown_mismatch, has_hints);
+      *idp_data_for_display_[0], has_shown_mismatch, has_hints);
   mismatch_dialog_shown_time_ = base::TimeTicks::Now();
   has_shown_mismatch_ = true;
   devtools_instrumentation::DidShowFedCmDialog(render_frame_host());
@@ -2005,7 +2012,7 @@
 void FederatedAuthRequestImpl::OnAccountsResponseReceived(
     std::unique_ptr<IdentityProviderInfo> idp_info,
     IdpNetworkRequestManager::FetchStatus status,
-    IdpNetworkRequestManager::AccountList accounts) {
+    std::vector<IdentityRequestAccountPtr> accounts) {
   accounts_fetched_time_ = base::TimeTicks::Now();
 
   GURL idp_config_url = idp_info->provider->config->config_url;
@@ -2108,22 +2115,21 @@
         return;
       }
       // TODO(crbug.com/354977893): pass filtered out accounts to UI.
-      auto filter = [](const IdentityRequestAccount& account) {
-        return account.is_filtered_out;
+      auto filter = [](const IdentityRequestAccountPtr& account) {
+        return account->is_filtered_out;
       };
       std::erase_if(accounts, filter);
       RecordReadyToShowAccountsSize(accounts.size());
-      ComputeLoginStateAndReorderAccounts(
-          idp_info->provider->config->config_url, accounts);
+      ComputeLoginStates(idp_info->provider->config->config_url, accounts);
 
       bool need_client_metadata = false;
 
       if (!GetDisclosureFields(*idp_info->provider).empty()) {
-        for (const IdentityRequestAccount& account : accounts) {
-          // ComputeLoginStateAndReorderAccounts() should have populated
+        for (const auto& account : accounts) {
+          // ComputeLoginStates() should have populated
           // IdentityRequestAccount::login_state.
-          DCHECK(account.login_state);
-          if (*account.login_state == LoginState::kSignUp) {
+          DCHECK(account->login_state);
+          if (*account->login_state == LoginState::kSignUp) {
             need_client_metadata = true;
             break;
           }
@@ -2149,7 +2155,7 @@
                 weak_ptr_factory_.GetWeakPtr(), std::move(idp_info),
                 std::move(accounts)));
       } else {
-        FetchAccountPictures(std::move(idp_info), accounts,
+        FetchAccountPictures(std::move(idp_info), std::move(accounts),
                              IdpNetworkRequestManager::ClientMetadata());
       }
     }
@@ -2158,7 +2164,7 @@
 
 void FederatedAuthRequestImpl::FetchAccountPictures(
     std::unique_ptr<IdentityProviderInfo> idp_info,
-    const IdpNetworkRequestManager::AccountList& accounts,
+    const std::vector<IdentityRequestAccountPtr>& accounts,
     const IdpNetworkRequestManager::ClientMetadata& client_metadata) {
   auto callback = BarrierClosure(
       accounts.size(),
@@ -2166,12 +2172,12 @@
                      weak_ptr_factory_.GetWeakPtr(), std::move(idp_info),
                      accounts, client_metadata));
   for (const auto& account : accounts) {
-    if (account.picture.is_valid()) {
+    if (account->picture.is_valid()) {
       network_manager_->DownloadAndDecodeImage(
-          account.picture,
+          account->picture,
           base::BindOnce(&FederatedAuthRequestImpl::OnAccountPictureReceived,
                          weak_ptr_factory_.GetWeakPtr(), callback,
-                         account.picture));
+                         account->picture));
     } else {
       // We have to still call the callback to make sure the barrier
       // callback gets the right number of calls.
@@ -2190,32 +2196,34 @@
 
 void FederatedAuthRequestImpl::OnAllAccountPicturesReceived(
     std::unique_ptr<IdentityProviderInfo> idp_info,
-    IdpNetworkRequestManager::AccountList accounts,
+    std::vector<IdentityRequestAccountPtr>&& accounts,
     const IdpNetworkRequestManager::ClientMetadata& client_metadata) {
   for (auto& account : accounts) {
-    auto it = downloaded_images_.find(account.picture);
+    auto it = downloaded_images_.find(account->picture);
     if (it != downloaded_images_.end()) {
       // We do not use std::move here in case multiple accounts use the same
       // picture URL, and the underlying gfx::Image data is refcounted anyway.
-      account.decoded_picture = it->second;
+      account->decoded_picture = it->second;
     }
   }
+
   downloaded_images_.clear();
-  OnFetchDataForIdpSucceeded(std::move(idp_info), accounts, client_metadata);
+  OnFetchDataForIdpSucceeded(std::move(idp_info), std::move(accounts),
+                             client_metadata);
 }
 
-void FederatedAuthRequestImpl::ComputeLoginStateAndReorderAccounts(
+void FederatedAuthRequestImpl::ComputeLoginStates(
     const GURL& idp_config_url,
-    IdpNetworkRequestManager::AccountList& accounts) {
+    std::vector<IdentityRequestAccountPtr>& accounts) {
   url::Origin idp_origin = url::Origin::Create(idp_config_url);
   // Populate the accounts login state.
   for (auto& account : accounts) {
     // Record when IDP and browser have different user sign-in states.
-    bool idp_claimed_sign_in = account.login_state == LoginState::kSignIn;
-    account.last_used_timestamp = permission_delegate_->GetLastUsedTimestamp(
-        origin(), GetEmbeddingOrigin(), idp_origin, account.id);
+    bool idp_claimed_sign_in = account->login_state == LoginState::kSignIn;
+    account->last_used_timestamp = permission_delegate_->GetLastUsedTimestamp(
+        origin(), GetEmbeddingOrigin(), idp_origin, account->id);
 
-    if (idp_claimed_sign_in == account.last_used_timestamp.has_value()) {
+    if (idp_claimed_sign_in == account->last_used_timestamp.has_value()) {
       fedcm_metrics_->RecordSignInStateMatchStatus(
           idp_config_url, SignInStateMatchStatus::kMatch);
     } else if (idp_claimed_sign_in) {
@@ -2229,46 +2237,24 @@
     // We set the login state based on the IDP response if it sends
     // back an approved_clients list. If it does not, we need to set
     // it here based on browser state.
-    if (!account.login_state) {
+    if (!account->login_state) {
       // Consider this a sign-in if we have seen a successful sign-up for
       // this account before.
-      account.login_state = account.last_used_timestamp.has_value()
-                                ? LoginState::kSignIn
-                                : LoginState::kSignUp;
+      account->login_state = account->last_used_timestamp.has_value()
+                                 ? LoginState::kSignIn
+                                 : LoginState::kSignUp;
     }
 
     if (webid::HasSharingPermissionOrIdpHasThirdPartyCookiesAccess(
             render_frame_host(), /*provider_url=*/idp_config_url,
-            GetEmbeddingOrigin(), origin(), account.id, permission_delegate_,
+            GetEmbeddingOrigin(), origin(), account->id, permission_delegate_,
             api_permission_delegate_)) {
       // At this moment we can trust login_state even though it's controlled
       // by IdP. If it's kSignUp, it could mean that the browser's sharing
       // permission is obsolete.
-      account.browser_trusted_login_state = account.login_state.value();
+      account->browser_trusted_login_state = account->login_state.value();
     }
   }
-
-  // Now that the login states have been computed, order accounts so that the
-  // returning accounts go first and the other accounts go afterwards. Within
-  // returning accounts, most recently used accounts go first. In particular,
-  // returning accounts for which we do not have a last used timestamp go last.
-  // Since the number of accounts is likely very small, sorting by login_state
-  // should be fast.
-  std::stable_sort(accounts.begin(), accounts.end(),
-                   [](const auto& a, const auto& b) {
-                     if (a.login_state != b.login_state) {
-                       return a.login_state < b.login_state;
-                     }
-                     // Within accounts with the same `login_state`, prefer to
-                     // put first those with timestamps, the higher the better.
-                     if (!a.last_used_timestamp) {
-                       return false;
-                     }
-                     if (!b.last_used_timestamp) {
-                       return true;
-                     }
-                     return *a.last_used_timestamp > *b.last_used_timestamp;
-                   });
 }
 
 void FederatedAuthRequestImpl::OnAccountSelected(const GURL& idp_config_url,
@@ -2765,7 +2751,7 @@
   if (token_status) {
     int num_idps_mismatch = std::count_if(
         idp_data_for_display_.begin(), idp_data_for_display_.end(),
-        [](auto& provider) { return provider.has_login_status_mismatch; });
+        [](auto& provider) { return provider->has_login_status_mismatch; });
     fedcm_metrics_->RecordRequestTokenStatus(
         *token_status, mediation_requirement_, idp_order_, num_idps_mismatch,
         selected_idp_config_url, rp_mode_);
@@ -2887,6 +2873,9 @@
   accounts_dialog_shown_time_ = std::nullopt;
   mismatch_dialog_shown_time_ = std::nullopt;
   has_shown_mismatch_ = false;
+  idp_accounts_.clear();
+  new_accounts_.clear();
+  accounts_.clear();
   idp_login_infos_.clear();
   idp_infos_.clear();
   idp_data_for_display_.clear();
@@ -3194,8 +3183,8 @@
 }
 
 bool FederatedAuthRequestImpl::GetAccountForAutoReauthn(
-    const IdentityProviderData** out_idp_data,
-    const IdentityRequestAccount** out_account) {
+    IdentityProviderDataPtr* out_idp_data,
+    IdentityRequestAccountPtr* out_account) {
   for (const auto& idp_info : idp_infos_) {
     if (idp_info.second->data->has_login_status_mismatch) {
       // If we need to show IDP login status mismatch UI, we cannot
@@ -3203,27 +3192,29 @@
       // account.
       return false;
     }
-    for (const auto& account : idp_info.second->data->accounts) {
-      if (account.login_state == LoginState::kSignUp) {
-        continue;
-      }
-      // account.login_state could be set to kSignIn if the client is on the
-      // `approved_clients` list provided by IDP. However, in this case we have
-      // to trust the browser observed sign-in unless the IDP can be exempted.
-      // For example, they have third party cookies access on the RP site.
-      if (!webid::HasSharingPermissionOrIdpHasThirdPartyCookiesAccess(
-              render_frame_host(), /*provider_url=*/idp_info.first,
-              GetEmbeddingOrigin(), origin(), account.id, permission_delegate_,
-              api_permission_delegate_)) {
-        continue;
-      }
-
-      if (*out_account) {
-        return false;
-      }
-      *out_idp_data = &(*idp_info.second->data);
-      *out_account = &account;
+  }
+  for (const auto& account : accounts_) {
+    if (account->login_state == LoginState::kSignUp) {
+      continue;
     }
+    // account.login_state could be set to kSignIn if the client is on the
+    // `approved_clients` list provided by IDP. However, in this case we have
+    // to trust the browser observed sign-in unless the IDP can be exempted.
+    // For example, they have third party cookies access on the RP site.
+    if (!webid::HasSharingPermissionOrIdpHasThirdPartyCookiesAccess(
+            render_frame_host(),
+            /*provider_url=*/
+            account->identity_provider->idp_metadata.config_url,
+            GetEmbeddingOrigin(), origin(), account->id, permission_delegate_,
+            api_permission_delegate_)) {
+      continue;
+    }
+
+    if (*out_account) {
+      return false;
+    }
+    *out_idp_data = account->identity_provider;
+    *out_account = account;
   }
 
   if (*out_account) {
@@ -3328,12 +3319,9 @@
   if (idp_infos_.size() > 1u ||
       IsFedCmUseOtherAccountEnabled(rp_mode_ == RpMode::kButton)) {
     account_ids_before_login_.clear();
-    for (const auto& idp_data : idp_data_for_display_) {
-      if (idp_data.idp_metadata.idp_login_url == login_url) {
-        for (const auto& account : idp_data.accounts) {
-          account_ids_before_login_.insert(account.id);
-        }
-        break;
+    for (const auto& account : accounts_) {
+      if (account->identity_provider->idp_metadata.idp_login_url == login_url) {
+        account_ids_before_login_.insert(account->id);
       }
     }
   }
@@ -3442,4 +3430,17 @@
   }
 }
 
+bool FederatedAuthRequestImpl::IsNewlyLoggedIn(
+    const IdentityRequestAccount& account) {
+  if (idp_infos_.size() <= 1u &&
+      !IsFedCmUseOtherAccountEnabled(rp_mode_ == RpMode::kButton)) {
+    return false;
+  }
+  if (login_url_.is_empty() ||
+      login_url_ != account.identity_provider->idp_metadata.idp_login_url) {
+    return false;
+  }
+  return !account_ids_before_login_.contains(account.id);
+}
+
 }  // namespace content
diff --git a/content/browser/webid/federated_auth_request_impl.h b/content/browser/webid/federated_auth_request_impl.h
index f8316f4b..5dbec2d 100644
--- a/content/browser/webid/federated_auth_request_impl.h
+++ b/content/browser/webid/federated_auth_request_impl.h
@@ -12,6 +12,7 @@
 #include "base/containers/queue.h"
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/time/time.h"
 #include "content/browser/webid/fedcm_metrics.h"
 #include "content/browser/webid/federated_provider_fetcher.h"
@@ -42,9 +43,12 @@
 class FederatedIdentityPermissionContextDelegate;
 class RenderFrameHost;
 
+using IdentityProviderDataPtr = scoped_refptr<content::IdentityProviderData>;
+using IdentityRequestAccountPtr =
+    scoped_refptr<content::IdentityRequestAccount>;
 using MediationRequirement = ::password_manager::CredentialMediationRequirement;
-using TokenError = IdentityCredentialTokenError;
 using RpMode = blink::mojom::RpMode;
+using TokenError = IdentityCredentialTokenError;
 
 // FederatedAuthRequestImpl handles mojo connections from the renderer to
 // fulfill WebID-related requests.
@@ -156,7 +160,7 @@
     bool has_failing_idp_signin_status{false};
     blink::mojom::RpContext rp_context{blink::mojom::RpContext::kSignIn};
     blink::mojom::RpMode rp_mode{blink::mojom::RpMode::kWidget};
-    std::optional<IdentityProviderData> data;
+    IdentityProviderDataPtr data;
   };
 
   struct IdentityProviderLoginUrlInfo {
@@ -169,10 +173,14 @@
     return request_dialog_controller_.get();
   }
 
-  const std::vector<IdentityProviderData>& GetSortedIdpData() const {
+  const std::vector<IdentityProviderDataPtr>& GetSortedIdpData() const {
     return idp_data_for_display_;
   }
 
+  const std::vector<IdentityRequestAccountPtr>& GetAccounts() const {
+    return accounts_;
+  }
+
   // These values are persisted to logs. Entries should not be renumbered and
   // numeric values should never be reused.
   enum DialogType {
@@ -253,7 +261,7 @@
       std::vector<FederatedProviderFetcher::FetchResult> fetch_results);
   void OnClientMetadataResponseReceived(
       std::unique_ptr<IdentityProviderInfo> idp_info,
-      const IdpNetworkRequestManager::AccountList& accounts,
+      std::vector<IdentityRequestAccountPtr>&& accounts,
       IdpNetworkRequestManager::FetchStatus status,
       IdpNetworkRequestManager::ClientMetadata client_metadata);
 
@@ -261,7 +269,7 @@
   // fetched for `idp_info`.
   void OnFetchDataForIdpSucceeded(
       std::unique_ptr<IdentityProviderInfo> idp_info,
-      const IdpNetworkRequestManager::AccountList& accounts,
+      std::vector<IdentityRequestAccountPtr>&& accounts,
       const IdpNetworkRequestManager::ClientMetadata& client_metadata);
 
   // Called when there is an error in fetching information to show the prompt
@@ -305,19 +313,19 @@
   void OnAccountsResponseReceived(
       std::unique_ptr<IdentityProviderInfo> idp_info,
       IdpNetworkRequestManager::FetchStatus status,
-      IdpNetworkRequestManager::AccountList accounts);
+      std::vector<IdentityRequestAccountPtr> accounts);
   // Fetches the account pictures for |accounts| and calls
   // OnFetchDataForIdpSucceeded when done.
   void FetchAccountPictures(
       std::unique_ptr<IdentityProviderInfo> idp_info,
-      const IdpNetworkRequestManager::AccountList& accounts,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       const IdpNetworkRequestManager::ClientMetadata& client_metadata);
   void OnAccountPictureReceived(base::RepeatingClosure cb,
                                 GURL url,
                                 const gfx::Image& image);
   void OnAllAccountPicturesReceived(
       std::unique_ptr<IdentityProviderInfo> idp_info,
-      IdpNetworkRequestManager::AccountList accounts,
+      std::vector<IdentityRequestAccountPtr>&& accounts,
       const IdpNetworkRequestManager::ClientMetadata& client_metadata);
   void OnAccountSelected(const GURL& idp_config_url,
                          const std::string& account_id,
@@ -397,20 +405,17 @@
 
   // Computes the login state of accounts. It uses the IDP-provided signal, if
   // it had been populated. Otherwise, it uses the browser knowledge on which
-  // accounts are returning and which are not. In either case, this method also
-  // reorders accounts so that those that are considered returning users are
-  // before users that are not returning.
-  void ComputeLoginStateAndReorderAccounts(
-      const GURL& idp_config_url,
-      IdpNetworkRequestManager::AccountList& accounts);
+  // accounts are returning and which are not.
+  void ComputeLoginStates(const GURL& idp_config_url,
+                          std::vector<IdentityRequestAccountPtr>& accounts);
 
   url::Origin GetEmbeddingOrigin() const;
 
   // Returns true and the `IdentityProviderData` + `IdentityRequestAccount` for
   // the only returning account. Returns false if there are multiple returning
   // accounts or no returning account.
-  bool GetAccountForAutoReauthn(const IdentityProviderData** out_idp_data,
-                                const IdentityRequestAccount** out_account);
+  bool GetAccountForAutoReauthn(IdentityProviderDataPtr* out_idp_data,
+                                IdentityRequestAccountPtr* out_account);
 
   // Check if auto re-authn is available so we can skip fetching accounts if the
   // auto re-authn flow is guaranteed to fail.
@@ -448,6 +453,8 @@
                                        bool accepted);
   void MaybeCreateFedCmMetrics();
 
+  bool IsNewlyLoggedIn(const IdentityRequestAccount& account);
+
   RpMode GetRpMode() const { return rp_mode_; }
 
   std::unique_ptr<IdpNetworkRequestManager> network_manager_;
@@ -467,7 +474,17 @@
   // Populated by OnFetchDataForIdpSucceeded() and OnIdpMismatch().
   base::flat_map<GURL, std::unique_ptr<IdentityProviderInfo>> idp_infos_;
   // Populated by MaybeShowAccountsDialog().
-  std::vector<IdentityProviderData> idp_data_for_display_;
+  std::vector<IdentityProviderDataPtr> idp_data_for_display_;
+
+  // Populated by OnFetchDataForIdpSucceeded(). Contains the accounts of each
+  // IDP. Used to later set accounts_ in the order in which the IDPs are
+  // requested.
+  base::flat_map<GURL, std::vector<IdentityRequestAccountPtr>> idp_accounts_;
+  // The accounts to be displayed by the UI.
+  std::vector<IdentityRequestAccountPtr> accounts_;
+  // The newly logged in accounts, to be prioritized by the UI. Subset of
+  // `accounts_`.
+  std::vector<IdentityRequestAccountPtr> new_accounts_;
 
   // Contains the set of account IDs of an IDP before a login URL is displayed
   // to the user. Used to compute the account ID of the account that the user
diff --git a/content/browser/webid/federated_auth_request_impl_multiple_frames_unittest.cc b/content/browser/webid/federated_auth_request_impl_multiple_frames_unittest.cc
index 7b163fef..cad6e2c 100644
--- a/content/browser/webid/federated_auth_request_impl_multiple_frames_unittest.cc
+++ b/content/browser/webid/federated_auth_request_impl_multiple_frames_unittest.cc
@@ -69,16 +69,7 @@
 constexpr char kAccountId[] = "1234";
 constexpr char kToken[] = "[not a real token]";
 
-static const std::vector<IdentityRequestAccount> kAccounts{{
-    kAccountId,                  // id
-    "ken@idp.example",           // email
-    "Ken R. Example",            // name
-    "Ken",                       // given_name
-    GURL(),                      // picture
-    std::vector<std::string>(),  // login_hints
-    std::vector<std::string>(),  // domain_hints
-    std::vector<std::string>()   // labels
-}};
+static std::vector<IdentityRequestAccountPtr> kAccounts;
 
 // IdpNetworkRequestManager which returns valid data from IdP.
 class TestIdpNetworkRequestManager : public MockIdpNetworkRequestManager {
@@ -163,10 +154,11 @@
 
   bool ShowAccountsDialog(
       const std::string& rp_for_display,
-      const std::vector<IdentityProviderData>& identity_provider_data,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       IdentityRequestAccount::SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<content::IdentityProviderData>& new_account_idp,
+      const std::vector<IdentityRequestAccountPtr>& new_accounts,
       IdentityRequestDialogController::AccountSelectionCallback on_selected,
       IdentityRequestDialogController::LoginToIdPCallback on_add_account,
       IdentityRequestDialogController::DismissCallback dismiss_callback,
@@ -216,6 +208,18 @@
 
   void SetUp() override {
     RenderViewHostImplTestHarness::SetUp();
+    // Initialize `kAccounts` on SetUp() to ensure it is initialized correctly
+    // in every test.
+    kAccounts = {base::MakeRefCounted<IdentityRequestAccount>(
+        kAccountId,                  // id
+        "ken@idp.example",           // email
+        "Ken R. Example",            // name
+        "Ken",                       // given_name
+        GURL(),                      // picture
+        std::vector<std::string>(),  // login_hints
+        std::vector<std::string>(),  // domain_hints
+        std::vector<std::string>()   // labels
+        )};
     test_api_permission_delegate_ =
         std::make_unique<TestApiPermissionDelegate>();
     mock_auto_reauthn_permission_delegate_ =
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc
index 0b9cb534..24bb981968 100644
--- a/content/browser/webid/federated_auth_request_impl_unittest.cc
+++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -13,6 +13,7 @@
 
 #include "base/functional/callback_forward.h"
 #include "base/memory/raw_ptr.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "base/run_loop.h"
 #include "base/task/sequenced_task_runner.h"
@@ -48,7 +49,6 @@
 
 using blink::mojom::FederatedAuthRequestResult;
 using blink::mojom::RequestTokenStatus;
-using AccountList = content::IdpNetworkRequestManager::AccountList;
 using ApiPermissionStatus =
     content::FederatedIdentityApiPermissionContextDelegate::PermissionStatus;
 using AuthRequestCallbackHelper =
@@ -125,133 +125,25 @@
 constexpr char kDomainHintNoMatchMessage[] =
     "Accounts were received, but none matched the domainHint.";
 
-static const std::vector<IdentityRequestAccount> kSingleAccount{{
-    kAccountId,                  // id
-    kEmail,                      // email
-    "Ken R. Example",            // name
-    "Ken",                       // given_name
-    GURL(),                      // picture
-    std::vector<std::string>(),  // login_hints
-    std::vector<std::string>(),  // domain_hints
-    std::vector<std::string>()   // labels
-}};
+static const std::vector<std::string> kDomainHintVector = {kDomainHint};
+static const std::vector<std::string> kLabelVector = {"label"};
+static const std::vector<std::string> kLoginHints = {kAccountId, kEmail};
+static const std::vector<std::string> kNicolasHints = {kAccountIdNicolas,
+                                                       kAccountEmailNicolas};
+static const std::vector<std::string> kPeterHints = {kAccountIdPeter,
+                                                     kAccountEmailPeter};
+static const std::vector<std::string> kTwoDomainHints = {kDomainHint,
+                                                         kOtherDomainHint};
+static const std::vector<std::string> kZachHints = {kAccountIdZach,
+                                                    kAccountEmailZach};
 
-static const std::vector<IdentityRequestAccount> kSingleAccountWithHint{{
-    kAccountId,                  // id
-    kEmail,                      // email
-    "Ken R. Example",            // name
-    "Ken",                       // given_name
-    GURL(),                      // picture
-    {kAccountId, kEmail},        // login_hints
-    std::vector<std::string>(),  // domain_hints
-    std::vector<std::string>()   // labels
-}};
-
-static const std::vector<IdentityRequestAccount> kSingleAccountWithDomainHint{{
-    kAccountId,                  // id
-    kEmail,                      // email
-    "Ken R. Example",            // name
-    "Ken",                       // given_name
-    GURL(),                      // picture
-    std::vector<std::string>(),  // login_hints
-    {kDomainHint},               // domain_hints
-    std::vector<std::string>()   // labels
-}};
-
-static const std::vector<IdentityRequestAccount> kTwoAccounts{
-    {
-        kAccountIdNicolas,           // id
-        kAccountEmailNicolas,        // email
-        "Nicolas P",                 // name
-        "Nicolas",                   // given_name
-        GURL(),                      // picture
-        std::vector<std::string>(),  // login_hints
-        std::vector<std::string>(),  // domain_hints
-        std::vector<std::string>(),  // labels
-        LoginState::kSignUp          // login_state
-    },
-    {
-        kAccountIdZach,              // id
-        "zach@email.com",            // email
-        "Zachary T",                 // name
-        "Zach",                      // given_name
-        GURL(),                      // picture
-        std::vector<std::string>(),  // login_hints
-        std::vector<std::string>(),  // domain_hints
-        std::vector<std::string>(),  // labels
-        LoginState::kSignUp          // login_state
-    }};
-
-static const std::vector<IdentityRequestAccount> kMultipleAccounts{
-    {
-        kAccountIdNicolas,           // id
-        kAccountEmailNicolas,        // email
-        "Nicolas P",                 // name
-        "Nicolas",                   // given_name
-        GURL(),                      // picture
-        std::vector<std::string>(),  // login_hints
-        std::vector<std::string>(),  // domain_hints
-        std::vector<std::string>(),  // labels
-        LoginState::kSignUp          // login_state
-    },
-    {
-        kAccountIdPeter,             // id
-        kAccountEmailPeter,          // email
-        "Peter K",                   // name
-        "Peter",                     // given_name
-        GURL(),                      // picture
-        std::vector<std::string>(),  // login_hints
-        std::vector<std::string>(),  // domain_hints
-        std::vector<std::string>(),  // labels
-        LoginState::kSignIn          // login_state
-    },
-    {
-        kAccountIdZach,              // id
-        "zach@email.com",            // email
-        "Zachary T",                 // name
-        "Zach",                      // given_name
-        GURL(),                      // picture
-        std::vector<std::string>(),  // login_hints
-        std::vector<std::string>(),  // domain_hints
-        std::vector<std::string>(),  // labels
-        LoginState::kSignUp          // login_state
-    }};
-
-static const std::vector<IdentityRequestAccount>
-    kMultipleAccountsWithHintsAndDomains{
-        {
-            kAccountIdNicolas,                          // id
-            kAccountEmailNicolas,                       // email
-            "Nicolas P",                                // name
-            "Nicolas",                                  // given_name
-            GURL(),                                     // picture
-            {kAccountIdNicolas, kAccountEmailNicolas},  // login_hints
-            {kDomainHint},                              // domain_hints
-            std::vector<std::string>(),                 // labels
-            LoginState::kSignUp                         // login_state
-        },
-        {
-            kAccountIdPeter,                        // id
-            kAccountEmailPeter,                     // email
-            "Peter K",                              // name
-            "Peter",                                // given_name
-            GURL(),                                 // picture
-            {kAccountIdPeter, kAccountEmailPeter},  // login_hints
-            std::vector<std::string>(),             // domain_hints
-            {"label"},                              // labels
-            LoginState::kSignIn                     // login_state
-        },
-        {
-            kAccountIdZach,                       // id
-            kAccountEmailZach,                    // email
-            "Zachary T",                          // name
-            "Zach",                               // given_name
-            GURL(),                               // picture
-            {kAccountIdZach, kAccountEmailZach},  // login_hints
-            {kDomainHint, kOtherDomainHint},      // domain_hints
-            std::vector<std::string>(),           // labels
-            LoginState::kSignUp                   // login_state
-        }};
+static std::vector<IdentityRequestAccountPtr> kMultipleAccounts;
+static std::vector<IdentityRequestAccountPtr>
+    kMultipleAccountsWithHintsAndDomains;
+static std::vector<IdentityRequestAccountPtr> kSingleAccount;
+static std::vector<IdentityRequestAccountPtr> kSingleAccountWithDomainHint;
+static std::vector<IdentityRequestAccountPtr> kSingleAccountWithHint;
+static std::vector<IdentityRequestAccountPtr> kTwoAccounts;
 
 static const std::set<std::string> kWellKnown{kProviderUrlFull};
 
@@ -321,7 +213,7 @@
   MockConfig config;
   MockClientIdConfiguration client_metadata;
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
 };
 
 // Action on accounts dialog taken by TestDialogController. Does not indicate a
@@ -392,50 +284,15 @@
         kDefaultIdentityProviderRequestOptions},
     blink::mojom::RpContext::kSignIn, blink::mojom::RpMode::kWidget};
 
-static const MockIdpInfo kDefaultIdentityProviderInfo{
-    {kWellKnown, {ParseStatus::kSuccess, net::HTTP_OK}},
-    {{ParseStatus::kSuccess, net::HTTP_OK},
-     kAccountsEndpoint,
-     kTokenEndpoint,
-     kClientMetadataEndpoint,
-     kMetricsEndpoint,
-     kIdpLoginUrl,
-     kIdpDisconnectUrl,
-     /*brand_background_color=*/std::nullopt,
-     /*brand_text_color=*/std::nullopt},
-    kDefaultClientMetadata,
-    {ParseStatus::kSuccess, net::HTTP_OK},
-    kSingleAccount,
-};
+static MockIdpInfo kDefaultIdentityProviderInfo;
+static MockIdpInfo kProviderTwoInfo;
 
-static const base::flat_map<std::string, MockIdpInfo> kSingleProviderInfo{
-    {kProviderUrlFull, kDefaultIdentityProviderInfo}};
+static base::flat_map<std::string, MockIdpInfo> kSingleProviderInfo;
 
 constexpr char kProviderTwoUrlFull[] = "https://idp2.example/fedcm.json";
-static const MockIdpInfo kProviderTwoInfo{
-    {{kProviderTwoUrlFull}},
-    {{ParseStatus::kSuccess, net::HTTP_OK},
-     "https://idp2.example/accounts",
-     "https://idp2.example/token",
-     "https://idp2.example/client_metadata",
-     "https://idp2.example/metrics",
-     "https://idp2.example/login_url",
-     "https://idp2.example/disconnect",
-     /*brand_background_color=*/std::nullopt,
-     /*brand_text_color=*/std::nullopt},
-    kDefaultClientMetadata,
-    {ParseStatus::kSuccess, net::HTTP_OK},
-    kMultipleAccounts};
 
-static const MockConfiguration kConfigurationValid{
-    kToken,
-    kSingleProviderInfo,
-    {ParseStatus::kSuccess, net::HTTP_OK},
-    /*delay_token_response=*/false,
-    AccountsDialogAction::kSelectFirstAccount,
-    IdpSigninStatusMismatchDialogAction::kNone,
-    ErrorDialogAction::kClose,
-    LoadingDialogAction::kNone};
+static MockConfiguration kConfigurationValid;
+static MockConfiguration kConfigurationMultiIdpValid;
 
 static const RequestExpectations kExpectationSuccess{
     RequestTokenStatus::kSuccess, FederatedAuthRequestResult::kSuccess,
@@ -450,17 +307,6 @@
     /*rp_context=*/blink::mojom::RpContext::kSignIn,
     /*rp_mode=*/blink::mojom::RpMode::kWidget};
 
-MockConfiguration kConfigurationMultiIdpValid{
-    kToken,
-    {{kProviderUrlFull, kDefaultIdentityProviderInfo},
-     {kProviderTwoUrlFull, kProviderTwoInfo}},
-    {ParseStatus::kSuccess, net::HTTP_OK},
-    false /* delay_token_response */,
-    AccountsDialogAction::kSelectFirstAccount,
-    IdpSigninStatusMismatchDialogAction::kNone,
-    ErrorDialogAction::kClose,
-    LoadingDialogAction::kNone};
-
 url::Origin OriginFromString(const std::string& url_string) {
   return url::Origin::Create(GURL(url_string));
 }
@@ -648,7 +494,7 @@
 
   // If non-empty, the accounts endpoint will return this accounts list instead
   // of the accounts list in the `config_`.
-  AccountList accounts_list_;
+  std::vector<IdentityRequestAccountPtr> accounts_list_;
 
  protected:
   MockConfiguration config_{kConfigurationValid};
@@ -720,10 +566,10 @@
   struct State {
     // State related to ShowAccountsDialog().
     // The list of all accounts passed to the UI.
-    AccountList all_accounts_for_display;
+    std::vector<IdentityRequestAccountPtr> all_accounts_for_display;
     std::optional<IdentityRequestAccount::SignInMode> sign_in_mode;
     blink::mojom::RpContext rp_context;
-    AccountList new_idp_accounts;
+    std::vector<IdentityRequestAccountPtr> new_accounts;
     // The last seen background/text color from IdP metadata.
     std::optional<SkColor> brand_background_color;
     std::optional<SkColor> brand_text_color;
@@ -758,10 +604,11 @@
 
   bool ShowAccountsDialog(
       const std::string& rp_for_display,
-      const std::vector<IdentityProviderData>& identity_provider_data,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       IdentityRequestAccount::SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<content::IdentityProviderData>& new_accounts_idp,
+      const std::vector<IdentityRequestAccountPtr>& new_accounts,
       IdentityRequestDialogController::AccountSelectionCallback on_selected,
       IdentityRequestDialogController::LoginToIdPCallback on_add_account,
       IdentityRequestDialogController::DismissCallback dismiss_callback,
@@ -773,40 +620,29 @@
     state_->all_accounts_for_display.clear();
 
     state_->sign_in_mode = sign_in_mode;
-    state_->rp_context = identity_provider_data[0].rp_context;
+    state_->rp_context = idp_list[0]->rp_context;
 
-    DCHECK(!new_accounts_idp || new_accounts_idp->accounts.size());
-    state_->new_idp_accounts.clear();
-    if (new_accounts_idp) {
-      state_->new_idp_accounts = new_accounts_idp->accounts;
-    }
+    state_->new_accounts = new_accounts;
 
-    for (const auto& idp_data : identity_provider_data) {
-      state_->all_accounts_for_display.insert(
-          state_->all_accounts_for_display.end(), idp_data.accounts.begin(),
-          idp_data.accounts.end());
-      if (idp_data.has_login_status_mismatch) {
-        state_->displayed_mismatch_idps.push_back(idp_data.idp_for_display);
+    state_->all_accounts_for_display = accounts;
+    for (const auto& idp_data : idp_list) {
+      if (idp_data->has_login_status_mismatch) {
+        state_->displayed_mismatch_idps.push_back(idp_data->idp_for_display);
       }
       state_->brand_background_color =
-          idp_data.idp_metadata.brand_background_color;
-      state_->brand_text_color = idp_data.idp_metadata.brand_text_color;
+          idp_data->idp_metadata.brand_background_color;
+      state_->brand_text_color = idp_data->idp_metadata.brand_text_color;
     }
 
     switch (accounts_dialog_action_) {
       case AccountsDialogAction::kSelectFirstAccount: {
-        for (const auto& idp_data : identity_provider_data) {
-          if (idp_data.accounts.empty()) {
-            continue;
-          }
-          base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
-              FROM_HERE,
-              base::BindOnce(
-                  std::move(on_selected), idp_data.idp_metadata.config_url,
-                  idp_data.accounts[0].id,
-                  idp_data.accounts[0].login_state == LoginState::kSignIn));
-          break;
-        }
+        base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
+            FROM_HERE,
+            base::BindOnce(
+                std::move(on_selected),
+                accounts[0]->identity_provider->idp_metadata.config_url,
+                accounts[0]->id,
+                accounts[0]->login_state == LoginState::kSignIn));
         break;
       }
       case AccountsDialogAction::kClose:
@@ -816,11 +652,9 @@
         break;
       case AccountsDialogAction::kAddAccount:
         base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
-            FROM_HERE,
-            base::BindOnce(
-                std::move(on_add_account),
-                identity_provider_data.data()->idp_metadata.config_url,
-                identity_provider_data.data()->idp_metadata.idp_login_url));
+            FROM_HERE, base::BindOnce(std::move(on_add_account),
+                                      idp_list[0]->idp_metadata.config_url,
+                                      idp_list[0]->idp_metadata.idp_login_url));
         // Set `accounts_dialog_action_` such that subsequent calls will select
         // the first account.
         accounts_dialog_action_ = AccountsDialogAction::kSelectFirstAccount;
@@ -1038,14 +872,188 @@
 
 class FederatedAuthRequestImplTest : public RenderViewHostImplTestHarness {
  protected:
-  FederatedAuthRequestImplTest(std::string_view rp_url = kRpUrl)
+  explicit FederatedAuthRequestImplTest(std::string_view rp_url = kRpUrl)
       : rp_url_(rp_url) {
     ukm_recorder_ = std::make_unique<ukm::TestAutoSetUkmRecorder>();
   }
   ~FederatedAuthRequestImplTest() override = default;
 
+  void InitConstants() {
+    kSingleAccount = {base::MakeRefCounted<IdentityRequestAccount>(
+        kAccountId,                  // id
+        kEmail,                      // email
+        "Ken R. Example",            // name
+        "Ken",                       // given_name
+        GURL(),                      // picture
+        std::vector<std::string>(),  // login_hints
+        std::vector<std::string>(),  // domain_hints
+        std::vector<std::string>()   // labels
+        )};
+    kDefaultIdentityProviderInfo = {
+        {kWellKnown, {ParseStatus::kSuccess, net::HTTP_OK}},
+        {{ParseStatus::kSuccess, net::HTTP_OK},
+         kAccountsEndpoint,
+         kTokenEndpoint,
+         kClientMetadataEndpoint,
+         kMetricsEndpoint,
+         kIdpLoginUrl,
+         kIdpDisconnectUrl,
+         /*brand_background_color=*/std::nullopt,
+         /*brand_text_color=*/std::nullopt},
+        kDefaultClientMetadata,
+        {ParseStatus::kSuccess, net::HTTP_OK},
+        kSingleAccount,
+    };
+    kSingleProviderInfo = {{kProviderUrlFull, kDefaultIdentityProviderInfo}};
+    kSingleAccountWithHint = {base::MakeRefCounted<IdentityRequestAccount>(
+        kAccountId,                  // id
+        kEmail,                      // email
+        "Ken R. Example",            // name
+        "Ken",                       // given_name
+        GURL(),                      // picture
+        kLoginHints,                 // login_hints
+        std::vector<std::string>(),  // domain_hints
+        std::vector<std::string>()   // labels
+        )};
+    kSingleAccountWithDomainHint = {
+        base::MakeRefCounted<IdentityRequestAccount>(
+            kAccountId,                  // id
+            kEmail,                      // email
+            "Ken R. Example",            // name
+            "Ken",                       // given_name
+            GURL(),                      // picture
+            std::vector<std::string>(),  // login_hints
+            kDomainHintVector,           // domain_hints
+            std::vector<std::string>()   // labels
+            )};
+    kTwoAccounts = {base::MakeRefCounted<IdentityRequestAccount>(
+                        kAccountIdNicolas,           // id
+                        kAccountEmailNicolas,        // email
+                        "Nicolas P",                 // name
+                        "Nicolas",                   // given_name
+                        GURL(),                      // picture
+                        std::vector<std::string>(),  // login_hints
+                        std::vector<std::string>(),  // domain_hints
+                        std::vector<std::string>(),  // labels
+                        LoginState::kSignUp          // login_state
+                        ),
+                    base::MakeRefCounted<IdentityRequestAccount>(
+                        kAccountIdZach,              // id
+                        "zach@email.com",            // email
+                        "Zachary T",                 // name
+                        "Zach",                      // given_name
+                        GURL(),                      // picture
+                        std::vector<std::string>(),  // login_hints
+                        std::vector<std::string>(),  // domain_hints
+                        std::vector<std::string>(),  // labels
+                        LoginState::kSignUp          // login_state
+                        )};
+    kMultipleAccounts = {base::MakeRefCounted<IdentityRequestAccount>(
+                             kAccountIdNicolas,           // id
+                             kAccountEmailNicolas,        // email
+                             "Nicolas P",                 // name
+                             "Nicolas",                   // given_name
+                             GURL(),                      // picture
+                             std::vector<std::string>(),  // login_hints
+                             std::vector<std::string>(),  // domain_hints
+                             std::vector<std::string>(),  // labels
+                             LoginState::kSignUp          // login_state
+                             ),
+                         base::MakeRefCounted<IdentityRequestAccount>(
+                             kAccountIdPeter,             // id
+                             kAccountEmailPeter,          // email
+                             "Peter K",                   // name
+                             "Peter",                     // given_name
+                             GURL(),                      // picture
+                             std::vector<std::string>(),  // login_hints
+                             std::vector<std::string>(),  // domain_hints
+                             std::vector<std::string>(),  // labels
+                             LoginState::kSignIn          // login_state
+                             ),
+                         base::MakeRefCounted<IdentityRequestAccount>(
+                             kAccountIdZach,              // id
+                             "zach@email.com",            // email
+                             "Zachary T",                 // name
+                             "Zach",                      // given_name
+                             GURL(),                      // picture
+                             std::vector<std::string>(),  // login_hints
+                             std::vector<std::string>(),  // domain_hints
+                             std::vector<std::string>(),  // labels
+                             LoginState::kSignUp          // login_state
+                             )};
+    kMultipleAccountsWithHintsAndDomains = {
+        base::MakeRefCounted<IdentityRequestAccount>(
+            kAccountIdNicolas,           // id
+            kAccountEmailNicolas,        // email
+            "Nicolas P",                 // name
+            "Nicolas",                   // given_name
+            GURL(),                      // picture
+            kNicolasHints,               // login_hints
+            kDomainHintVector,           // domain_hints
+            std::vector<std::string>(),  // labels
+            LoginState::kSignUp          // login_state
+            ),
+        base::MakeRefCounted<IdentityRequestAccount>(
+            kAccountIdPeter,             // id
+            kAccountEmailPeter,          // email
+            "Peter K",                   // name
+            "Peter",                     // given_name
+            GURL(),                      // picture
+            kPeterHints,                 // login_hints
+            std::vector<std::string>(),  // domain_hints
+            kLabelVector,                // labels
+            LoginState::kSignIn          // login_state
+            ),
+        base::MakeRefCounted<IdentityRequestAccount>(
+            kAccountIdZach,              // id
+            kAccountEmailZach,           // email
+            "Zachary T",                 // name
+            "Zach",                      // given_name
+            GURL(),                      // picture
+            kZachHints,                  // login_hints
+            kTwoDomainHints,             // domain_hints
+            std::vector<std::string>(),  // labels
+            LoginState::kSignUp          // login_state
+            )};
+    kProviderTwoInfo = {{{kProviderTwoUrlFull}},
+                        {{ParseStatus::kSuccess, net::HTTP_OK},
+                         "https://idp2.example/accounts",
+                         "https://idp2.example/token",
+                         "https://idp2.example/client_metadata",
+                         "https://idp2.example/metrics",
+                         "https://idp2.example/login_url",
+                         "https://idp2.example/disconnect",
+                         /*brand_background_color=*/std::nullopt,
+                         /*brand_text_color=*/std::nullopt},
+                        kDefaultClientMetadata,
+                        {ParseStatus::kSuccess, net::HTTP_OK},
+                        kMultipleAccounts};
+    kConfigurationValid = {kToken,
+                           kSingleProviderInfo,
+                           {ParseStatus::kSuccess, net::HTTP_OK},
+                           /*delay_token_response=*/false,
+                           AccountsDialogAction::kSelectFirstAccount,
+                           IdpSigninStatusMismatchDialogAction::kNone,
+                           ErrorDialogAction::kClose,
+                           LoadingDialogAction::kNone};
+    kConfigurationMultiIdpValid = {
+        kToken,
+        {{kProviderUrlFull, kDefaultIdentityProviderInfo},
+         {kProviderTwoUrlFull, kProviderTwoInfo}},
+        {ParseStatus::kSuccess, net::HTTP_OK},
+        false /* delay_token_response */,
+        AccountsDialogAction::kSelectFirstAccount,
+        IdpSigninStatusMismatchDialogAction::kNone,
+        ErrorDialogAction::kClose,
+        LoadingDialogAction::kNone};
+  }
+
   void SetUp() override {
     RenderViewHostImplTestHarness::SetUp();
+    // Initialize the accounts and account-dependent constants on SetUp() to
+    // ensure they are initialized correctly in every test.
+    InitConstants();
+
     test_api_permission_delegate_ =
         std::make_unique<TestApiPermissionDelegate>();
     test_permission_delegate_ = std::make_unique<TestPermissionDelegate>();
@@ -1237,13 +1245,12 @@
     request_remote_.set_disconnect_handler(base::OnceClosure());
   }
 
-  base::span<const content::IdentityRequestAccount> all_accounts_for_display()
-      const {
+  base::span<const IdentityRequestAccountPtr> all_accounts_for_display() const {
     return dialog_controller_state_.all_accounts_for_display;
   }
 
-  base::span<const content::IdentityRequestAccount> new_idp_accounts() const {
-    return dialog_controller_state_.new_idp_accounts;
+  base::span<const IdentityRequestAccountPtr> new_accounts() const {
+    return dialog_controller_state_.new_accounts;
   }
 
   std::vector<std::string> displayed_mismatch_idps() const {
@@ -1269,7 +1276,7 @@
   int CountNumLoginStateIsSignin() {
     int num_sign_in_login_state = 0;
     for (const auto& account : all_accounts_for_display()) {
-      if (account.login_state == LoginState::kSignIn) {
+      if (account->login_state == LoginState::kSignIn) {
         ++num_sign_in_login_state;
       }
     }
@@ -2083,7 +2090,7 @@
 TEST_F(FederatedAuthRequestImplTest, LoginStateShouldBeSignUpForFirstTimeUser) {
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
               kConfigurationValid);
-  EXPECT_EQ(LoginState::kSignUp, all_accounts_for_display()[0].login_state);
+  EXPECT_EQ(LoginState::kSignUp, all_accounts_for_display()[0]->login_state);
 }
 
 TEST_F(FederatedAuthRequestImplTest, LoginStateShouldBeSignInForReturningUser) {
@@ -2096,7 +2103,7 @@
 
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
               kConfigurationValid);
-  EXPECT_EQ(LoginState::kSignIn, all_accounts_for_display()[0].login_state);
+  EXPECT_EQ(LoginState::kSignIn, all_accounts_for_display()[0]->login_state);
 
   // CLIENT_METADATA only needs to be fetched for obtaining links to display in
   // the disclosure text. The disclosure text is not displayed for returning
@@ -2179,7 +2186,7 @@
   RunAuthTest(kDefaultRequestParameters, expectation, kConfigurationValid);
 
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignIn);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignIn);
   EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kAuto);
   EXPECT_TRUE(test_auto_reauthn_permission_delegate_->embargoed_origins_.count(
       OriginFromString(kRpUrl)));
@@ -2219,7 +2226,7 @@
   RunAuthTest(kDefaultRequestParameters, expectation, kConfigurationValid);
 
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignIn);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignIn);
   EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kAuto);
 
   ExpectAutoReauthnMetrics(FedCmMetrics::NumAccounts::kOne,
@@ -2270,7 +2277,7 @@
   RunAuthTest(kDefaultRequestParameters, expectation, configuration);
 
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdPeter);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdPeter);
   EXPECT_EQ(CountNumLoginStateIsSignin(), 1);
   EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kAuto);
 
@@ -2316,8 +2323,8 @@
               IsAutoReauthnEmbargoed(OriginFromString(kRpUrl)))
       .WillOnce(Return(false));
 
-  AccountList multiple_accounts = kMultipleAccounts;
-  multiple_accounts[0].login_state = LoginState::kSignIn;
+  std::vector<IdentityRequestAccountPtr> multiple_accounts = kMultipleAccounts;
+  multiple_accounts[0]->login_state = LoginState::kSignIn;
   MockConfiguration configuration = kConfigurationValid;
   configuration.idp_info[kProviderUrlFull].accounts = multiple_accounts;
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
@@ -2358,7 +2365,7 @@
               kConfigurationValid);
 
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignUp);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignUp);
   EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
 
   ExpectAutoReauthnMetrics(FedCmMetrics::NumAccounts::kZero,
@@ -2488,7 +2495,7 @@
 
   // Set IDP claims user is signed in.
   MockConfiguration configuration = kConfigurationValid;
-  configuration.idp_info[kProviderUrlFull].accounts[0].login_state =
+  configuration.idp_info[kProviderUrlFull].accounts[0]->login_state =
       LoginState::kSignIn;
 
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
@@ -2533,7 +2540,7 @@
 
   // Set IDP claims user is signed in.
   MockConfiguration configuration = kConfigurationValid;
-  configuration.idp_info[kProviderUrlFull].accounts[0].login_state =
+  configuration.idp_info[kProviderUrlFull].accounts[0]->login_state =
       LoginState::kSignIn;
   RequestExpectations expectation = kExpectationSuccess;
   expectation.is_auto_selected = true;
@@ -2559,7 +2566,7 @@
               kConfigurationValid);
 
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignUp);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignUp);
   EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
 }
 
@@ -2584,7 +2591,7 @@
               kConfigurationValid);
 
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignIn);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignIn);
   EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
 
   ExpectAutoReauthnMetrics(FedCmMetrics::NumAccounts::kOne,
@@ -2621,7 +2628,7 @@
   RunAuthTest(kDefaultRequestParameters, expectations, kConfigurationValid);
 
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignIn);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignIn);
   EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
 
   ExpectAutoReauthnMetrics(FedCmMetrics::NumAccounts::kOne,
@@ -2854,9 +2861,9 @@
       /*selected_idp_config_url=*/std::nullopt};
   MockConfiguration configuration = kConfigurationValid;
   configuration.mediation_requirement = MediationRequirement::kSilent;
-  AccountList multiple_accounts = kMultipleAccounts;
-  multiple_accounts[0].login_state = LoginState::kSignIn;
-  multiple_accounts[1].login_state = LoginState::kSignIn;
+  std::vector<IdentityRequestAccountPtr> multiple_accounts = kMultipleAccounts;
+  multiple_accounts[0]->login_state = LoginState::kSignIn;
+  multiple_accounts[1]->login_state = LoginState::kSignIn;
   configuration.idp_info[kProviderUrlFull].accounts = multiple_accounts;
 
   RunAuthTest(kDefaultRequestParameters, expectations, configuration);
@@ -2884,14 +2891,14 @@
       .WillRepeatedly(Return(std::nullopt));
 
   MockConfiguration configuration = kConfigurationValid;
-  configuration.idp_info[kProviderUrlFull].accounts[0].login_state =
+  configuration.idp_info[kProviderUrlFull].accounts[0]->login_state =
       LoginState::kSignIn;
   configuration.mediation_requirement = MediationRequirement::kRequired;
 
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
 
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignIn);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignIn);
   EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kExplicit);
 
   ExpectStatusMetrics(TokenStatus::kSuccessUsingTokenInHttpResponse,
@@ -2912,7 +2919,7 @@
 
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
               kConfigurationValid);
-  EXPECT_EQ(LoginState::kSignIn, all_accounts_for_display()[0].login_state);
+  EXPECT_EQ(LoginState::kSignIn, all_accounts_for_display()[0]->login_state);
 
   ukm_loop.Run();
 
@@ -2982,7 +2989,7 @@
   ukm_loop.Run();
 
   ASSERT_TRUE(did_show_accounts_dialog());
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignUp);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignUp);
 
   histogram_tester_.ExpectTotalCount(
       "Blink.FedCm.Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch",
@@ -3073,7 +3080,7 @@
 
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
               kConfigurationValid);
-  EXPECT_EQ(LoginState::kSignIn, all_accounts_for_display()[0].login_state);
+  EXPECT_EQ(LoginState::kSignIn, all_accounts_for_display()[0]->login_state);
 
   histogram_tester_.ExpectUniqueSample("Blink.FedCm.WebContentsVisible", 1, 1);
   histogram_tester_.ExpectUniqueSample("Blink.FedCm.WebContentsActive", 1, 1);
@@ -3101,7 +3108,7 @@
 
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess,
               kConfigurationValid);
-  EXPECT_EQ(LoginState::kSignIn, all_accounts_for_display()[0].login_state);
+  EXPECT_EQ(LoginState::kSignIn, all_accounts_for_display()[0]->login_state);
 
   histogram_tester_.ExpectUniqueSample("Blink.FedCm.WebContentsVisible", 0, 1);
   histogram_tester_.ExpectUniqueSample("Blink.FedCm.WebContentsActive", 1, 1);
@@ -3176,9 +3183,10 @@
 
   // Set IDP claims user is signed in.
   MockConfiguration configuration = kConfigurationValid;
-  AccountList all_accounts_for_display =
-      AccountList(kSingleAccount.begin(), kSingleAccount.end());
-  all_accounts_for_display[0].login_state = LoginState::kSignIn;
+  std::vector<IdentityRequestAccountPtr> all_accounts_for_display =
+      std::vector<IdentityRequestAccountPtr>(kSingleAccount.begin(),
+                                             kSingleAccount.end());
+  all_accounts_for_display[0]->login_state = LoginState::kSignIn;
   configuration.idp_info[kProviderUrlFull].accounts = all_accounts_for_display;
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
   EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));
@@ -3233,9 +3241,10 @@
 
   // Set IDP claims user is signed in.
   MockConfiguration configuration = kConfigurationValid;
-  AccountList all_accounts_for_display =
-      AccountList(kSingleAccount.begin(), kSingleAccount.end());
-  all_accounts_for_display[0].login_state = LoginState::kSignIn;
+  std::vector<IdentityRequestAccountPtr> all_accounts_for_display =
+      std::vector<IdentityRequestAccountPtr>(kSingleAccount.begin(),
+                                             kSingleAccount.end());
+  all_accounts_for_display[0]->login_state = LoginState::kSignIn;
   configuration.idp_info[kProviderUrlFull].accounts = all_accounts_for_display;
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
   EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA));
@@ -3390,10 +3399,11 @@
 
   bool ShowAccountsDialog(
       const std::string& rp_for_display,
-      const std::vector<IdentityProviderData>& identity_provider_data,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<content::IdentityProviderData>& new_accounts_idp,
+      const std::vector<IdentityRequestAccountPtr>& new_accounts,
       IdentityRequestDialogController::AccountSelectionCallback on_selected,
       IdentityRequestDialogController::LoginToIdPCallback on_add_account,
       IdentityRequestDialogController::DismissCallback dismiss_callback,
@@ -3405,10 +3415,9 @@
 
     // Call parent class method in order to store callback parameters.
     return TestDialogController::ShowAccountsDialog(
-        rp_for_display, std::move(identity_provider_data), sign_in_mode,
-        rp_mode, new_accounts_idp, std::move(on_selected),
-        std::move(on_add_account), std::move(dismiss_callback),
-        std::move(accounts_displayed_callback));
+        rp_for_display, idp_list, accounts, sign_in_mode, rp_mode, new_accounts,
+        std::move(on_selected), std::move(on_add_account),
+        std::move(dismiss_callback), std::move(accounts_displayed_callback));
   }
 
  private:
@@ -3516,7 +3525,8 @@
 TEST_F(FederatedAuthRequestImplTest, TokenEndpointPostDataEscaping) {
   const std::string kAccountIdWithSpace("account id");
   MockConfiguration configuration = kConfigurationValid;
-  configuration.idp_info[kProviderUrlFull].accounts[0].id = kAccountIdWithSpace;
+  configuration.idp_info[kProviderUrlFull].accounts[0]->id =
+      kAccountIdWithSpace;
 
   std::unique_ptr<IdpNetworkRequestManagerParamChecker> checker =
       std::make_unique<IdpNetworkRequestManagerParamChecker>();
@@ -3746,9 +3756,9 @@
 
   // Check the account order using the account ids.
   ASSERT_EQ(all_accounts_for_display().size(), 3u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdPeter);
-  EXPECT_EQ(all_accounts_for_display()[1].id, kAccountIdNicolas);
-  EXPECT_EQ(all_accounts_for_display()[2].id, kAccountIdZach);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdPeter);
+  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdNicolas);
+  EXPECT_EQ(all_accounts_for_display()[2]->id, kAccountIdZach);
 }
 
 // Test that first API call with a given IDP is not affected by the
@@ -3884,8 +3894,8 @@
 
       FetchStatus fetch_status{accounts_parse_status_, net::HTTP_OK};
       base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
-          FROM_HERE,
-          base::BindOnce(std::move(callback), fetch_status, AccountList()));
+          FROM_HERE, base::BindOnce(std::move(callback), fetch_status,
+                                    std::vector<IdentityRequestAccountPtr>()));
       return;
     }
 
@@ -4270,7 +4280,7 @@
   // selected account should be that one (second IDP also has returning accounts
   // and no reordering should happen).
   MockConfiguration config = kConfigurationMultiIdpValid;
-  config.idp_info[kProviderUrlFull].accounts[0].login_state =
+  config.idp_info[kProviderUrlFull].accounts[0]->login_state =
       LoginState::kSignIn;
   RunAuthTest(kDefaultMultiIdpRequestParameters, kExpectationSuccess, config);
   EXPECT_EQ(2u, NumFetched(FetchedEndpoint::ACCOUNTS));
@@ -4517,7 +4527,7 @@
   // The first IDP only has a single account, and the total of accounts is
   // now 4.
   EXPECT_EQ(all_accounts_for_display().size(), 4u);
-  EXPECT_EQ(new_idp_accounts().size(), 1u);
+  EXPECT_EQ(new_accounts().size(), 1u);
 }
 
 // Test that API can succeed with multiple IdPs, if all IDPs have login status
@@ -5199,7 +5209,7 @@
       .WillRepeatedly(Return(std::nullopt));
   // The third account is marked sign (as is the second), but since it has a
   // timestamp it should show first.
-  configuration.idp_info[kProviderUrlFull].accounts[2].login_state =
+  configuration.idp_info[kProviderUrlFull].accounts[2]->login_state =
       LoginState::kSignIn;
   EXPECT_CALL(
       *test_permission_delegate_,
@@ -5211,9 +5221,9 @@
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 3u);
   // Account order should be: accounts[2], accounts[1], accounts[0].
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdZach);
-  EXPECT_EQ(all_accounts_for_display()[1].id, kAccountIdPeter);
-  EXPECT_EQ(all_accounts_for_display()[2].id, kAccountIdNicolas);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdZach);
+  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdPeter);
+  EXPECT_EQ(all_accounts_for_display()[2]->id, kAccountIdNicolas);
 }
 
 TEST_F(FederatedAuthRequestImplTest, AccountLabelMultipleAccountsNoMatch) {
@@ -5257,7 +5267,7 @@
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdPeter);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdPeter);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.AccountLabel.NumMatchingAccounts",
@@ -5273,7 +5283,7 @@
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountId);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountId);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.LoginHint.NumMatchingAccounts",
@@ -5289,7 +5299,7 @@
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].email, kEmail);
+  EXPECT_EQ(all_accounts_for_display()[0]->email, kEmail);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.LoginHint.NumMatchingAccounts",
@@ -5326,8 +5336,9 @@
       kMultipleAccountsWithHintsAndDomains;
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
+
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdNicolas);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdNicolas);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.LoginHint.NumMatchingAccounts",
@@ -5344,7 +5355,7 @@
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdZach);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdZach);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.LoginHint.NumMatchingAccounts",
@@ -5389,7 +5400,7 @@
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountId);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountId);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.DomainHint.NumMatchingAccounts",
@@ -5407,7 +5418,7 @@
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountId);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountId);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.DomainHint.NumMatchingAccounts",
@@ -5488,7 +5499,7 @@
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdZach);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdZach);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.DomainHint.NumMatchingAccounts",
@@ -5509,8 +5520,8 @@
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 2u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdNicolas);
-  EXPECT_EQ(all_accounts_for_display()[1].id, kAccountIdZach);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdNicolas);
+  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdZach);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.DomainHint.NumMatchingAccounts",
@@ -5531,8 +5542,8 @@
 
   RunAuthTest(parameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 2u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdNicolas);
-  EXPECT_EQ(all_accounts_for_display()[1].id, kAccountIdZach);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdNicolas);
+  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdZach);
 
   histogram_tester_.ExpectUniqueSample(
       "Blink.FedCm.DomainHint.NumMatchingAccounts",
@@ -5563,45 +5574,45 @@
 
 TEST_F(FederatedAuthRequestImplTest, PictureFetch) {
   MockConfiguration configuration = kConfigurationValid;
-  configuration.idp_info[kProviderUrlFull].accounts[0].picture =
+  configuration.idp_info[kProviderUrlFull].accounts[0]->picture =
       GURL(kAccountPicture);
   // This ensures we don't fetch client metadata, to test a different codepath.
-  configuration.idp_info[kProviderUrlFull].accounts[0].login_state =
+  configuration.idp_info[kProviderUrlFull].accounts[0]->login_state =
       LoginState::kSignIn;
 
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountId);
-  EXPECT_FALSE(all_accounts_for_display()[0].decoded_picture.IsEmpty());
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountId);
+  EXPECT_FALSE(all_accounts_for_display()[0]->decoded_picture.IsEmpty());
   EXPECT_EQ(kAccountPictureSize,
-            all_accounts_for_display()[0].decoded_picture.Width());
+            all_accounts_for_display()[0]->decoded_picture.Width());
   EXPECT_EQ(kAccountPictureSize,
-            all_accounts_for_display()[0].decoded_picture.Height());
+            all_accounts_for_display()[0]->decoded_picture.Height());
 }
 
 TEST_F(FederatedAuthRequestImplTest, PictureFetchMultipleAccounts) {
   MockConfiguration configuration = kConfigurationValid;
   configuration.idp_info[kProviderUrlFull].accounts = kMultipleAccounts;
-  configuration.idp_info[kProviderUrlFull].accounts[0].picture =
+  configuration.idp_info[kProviderUrlFull].accounts[0]->picture =
       GURL(kAccountPicture);
-  configuration.idp_info[kProviderUrlFull].accounts[1].picture =
+  configuration.idp_info[kProviderUrlFull].accounts[1]->picture =
       GURL(kAccountPicture);
-  configuration.idp_info[kProviderUrlFull].accounts[2].picture =
+  configuration.idp_info[kProviderUrlFull].accounts[2]->picture =
       GURL(kAccountPicture404);
 
   RunAuthTest(kDefaultRequestParameters, kExpectationSuccess, configuration);
   ASSERT_EQ(all_accounts_for_display().size(), 3u);
-  EXPECT_FALSE(all_accounts_for_display()[0].decoded_picture.IsEmpty());
+  EXPECT_FALSE(all_accounts_for_display()[0]->decoded_picture.IsEmpty());
   EXPECT_EQ(kAccountPictureSize,
-            all_accounts_for_display()[0].decoded_picture.Width());
+            all_accounts_for_display()[0]->decoded_picture.Width());
   EXPECT_EQ(kAccountPictureSize,
-            all_accounts_for_display()[0].decoded_picture.Height());
-  EXPECT_FALSE(all_accounts_for_display()[1].decoded_picture.IsEmpty());
+            all_accounts_for_display()[0]->decoded_picture.Height());
+  EXPECT_FALSE(all_accounts_for_display()[1]->decoded_picture.IsEmpty());
   EXPECT_EQ(kAccountPictureSize,
-            all_accounts_for_display()[1].decoded_picture.Width());
+            all_accounts_for_display()[1]->decoded_picture.Width());
   EXPECT_EQ(kAccountPictureSize,
-            all_accounts_for_display()[1].decoded_picture.Height());
-  EXPECT_TRUE(all_accounts_for_display()[2].decoded_picture.IsEmpty());
+            all_accounts_for_display()[1]->decoded_picture.Height());
+  EXPECT_TRUE(all_accounts_for_display()[2]->decoded_picture.IsEmpty());
 }
 
 // Test that when FedCmRpContext flag is enabled and rp_context is specified,
@@ -6190,6 +6201,7 @@
  protected:
   void SetUp() override {
     RenderViewHostImplTestHarness::SetUp();
+    InitConstants();
     test_api_permission_delegate_ =
         std::make_unique<TestApiPermissionDelegate>();
     test_permission_delegate_ = std::make_unique<TestPermissionDelegate>();
@@ -7158,7 +7170,7 @@
   RunAuthDontWaitForCallback(parameters, kConfigurationValid);
 
   ASSERT_EQ(all_accounts_for_display().size(), 1u);
-  EXPECT_EQ(all_accounts_for_display()[0].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
             LoginState::kSignIn);
   EXPECT_EQ(CountNumLoginStateIsSignin(), 1);
   EXPECT_EQ(dialog_controller_state_.sign_in_mode, SignInMode::kAuto);
@@ -7191,14 +7203,14 @@
 
   ASSERT_EQ(all_accounts_for_display().size(), 3u);
   // Accounts are reordered to have sign-in users displayed first.
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignIn);
-  EXPECT_EQ(all_accounts_for_display()[0].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignIn);
+  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
             LoginState::kSignIn);
-  EXPECT_EQ(all_accounts_for_display()[1].login_state, LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[1].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[1]->login_state, LoginState::kSignUp);
+  EXPECT_EQ(all_accounts_for_display()[1]->browser_trusted_login_state,
             LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[2].login_state, LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[2].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[2]->login_state, LoginState::kSignUp);
+  EXPECT_EQ(all_accounts_for_display()[2]->browser_trusted_login_state,
             LoginState::kSignUp);
 }
 
@@ -7227,15 +7239,15 @@
   RunAuthDontWaitForCallback(parameters, configuration);
 
   ASSERT_EQ(all_accounts_for_display().size(), 3u);
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignIn);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignIn);
   // This should be kSignUp regardless of IdP's claim.
-  EXPECT_EQ(all_accounts_for_display()[0].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
             LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[1].login_state, LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[1].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[1]->login_state, LoginState::kSignUp);
+  EXPECT_EQ(all_accounts_for_display()[1]->browser_trusted_login_state,
             LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[2].login_state, LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[2].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[2]->login_state, LoginState::kSignUp);
+  EXPECT_EQ(all_accounts_for_display()[2]->browser_trusted_login_state,
             LoginState::kSignUp);
 }
 
@@ -7271,15 +7283,15 @@
   RunAuthDontWaitForCallback(parameters, configuration);
 
   ASSERT_EQ(all_accounts_for_display().size(), 3u);
-  EXPECT_EQ(all_accounts_for_display()[0].login_state, LoginState::kSignIn);
+  EXPECT_EQ(all_accounts_for_display()[0]->login_state, LoginState::kSignIn);
   // This should be kSignIn to match IdP's claim due to it has 3PC access.
-  EXPECT_EQ(all_accounts_for_display()[0].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[0]->browser_trusted_login_state,
             LoginState::kSignIn);
-  EXPECT_EQ(all_accounts_for_display()[1].login_state, LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[1].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[1]->login_state, LoginState::kSignUp);
+  EXPECT_EQ(all_accounts_for_display()[1]->browser_trusted_login_state,
             LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[2].login_state, LoginState::kSignUp);
-  EXPECT_EQ(all_accounts_for_display()[2].browser_trusted_login_state,
+  EXPECT_EQ(all_accounts_for_display()[2]->login_state, LoginState::kSignUp);
+  EXPECT_EQ(all_accounts_for_display()[2]->browser_trusted_login_state,
             LoginState::kSignUp);
 }
 
@@ -7419,10 +7431,11 @@
 
   bool ShowAccountsDialog(
       const std::string& rp_for_display,
-      const std::vector<IdentityProviderData>& identity_provider_data,
+      const std::vector<IdentityProviderDataPtr>& idp_list,
+      const std::vector<IdentityRequestAccountPtr>& accounts,
       IdentityRequestAccount::SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<content::IdentityProviderData>& new_accounts_idp,
+      const std::vector<IdentityRequestAccountPtr>& new_accounts,
       IdentityRequestDialogController::AccountSelectionCallback on_selected,
       IdentityRequestDialogController::LoginToIdPCallback on_add_account,
       IdentityRequestDialogController::DismissCallback dismiss_callback,
@@ -7515,18 +7528,18 @@
   RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
 
   ASSERT_EQ(all_accounts_for_display().size(), 3u);
-  ASSERT_EQ(new_idp_accounts().size(), 1u);
+  ASSERT_EQ(new_accounts().size(), 1u);
 
   // Accounts are reordered to have the most recently signed in account,
   // kAccountIdPeter, displayed first.
-  EXPECT_EQ(all_accounts_for_display()[0].id, kAccountIdPeter);
-  EXPECT_EQ(all_accounts_for_display()[1].id, kAccountIdNicolas);
-  EXPECT_EQ(all_accounts_for_display()[2].id, kAccountIdZach);
-  EXPECT_EQ(new_idp_accounts()[0].id, kAccountIdPeter);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kAccountIdPeter);
+  EXPECT_EQ(all_accounts_for_display()[1]->id, kAccountIdNicolas);
+  EXPECT_EQ(all_accounts_for_display()[2]->id, kAccountIdZach);
+  EXPECT_EQ(new_accounts()[0]->id, kAccountIdPeter);
 }
 
 // Tests that when use a different account is used and multiple accounts are
-// logged in at once, all the new accounts are part of the new_idp_accounts().
+// logged in at once, all the new accounts are part of the new_accounts().
 TEST_F(FederatedAuthRequestImplTest, UseOtherAccountMultipleNewAccounts) {
   base::test::ScopedFeatureList list;
   list.InitAndEnableFeature(features::kFedCmUseOtherAccount);
@@ -7555,15 +7568,15 @@
   RunAuthDontWaitForCallback(kDefaultRequestParameters, configuration);
 
   ASSERT_EQ(all_accounts_for_display().size(), 3u);
-  ASSERT_EQ(new_idp_accounts().size(), 2u);
+  ASSERT_EQ(new_accounts().size(), 2u);
 
   // Accounts are reordered to have the most recently signed in accounts
   // displayed first.
-  EXPECT_EQ(all_accounts_for_display()[0].id, kTwoAccounts[0].id);
-  EXPECT_EQ(all_accounts_for_display()[1].id, kTwoAccounts[1].id);
-  EXPECT_EQ(all_accounts_for_display()[2].id, kSingleAccount[0].id);
-  EXPECT_EQ(new_idp_accounts()[0].id, kTwoAccounts[0].id);
-  EXPECT_EQ(new_idp_accounts()[1].id, kTwoAccounts[1].id);
+  EXPECT_EQ(all_accounts_for_display()[0]->id, kTwoAccounts[0]->id);
+  EXPECT_EQ(all_accounts_for_display()[1]->id, kTwoAccounts[1]->id);
+  EXPECT_EQ(all_accounts_for_display()[2]->id, kSingleAccount[0]->id);
+  EXPECT_EQ(new_accounts()[0]->id, kTwoAccounts[0]->id);
+  EXPECT_EQ(new_accounts()[1]->id, kTwoAccounts[1]->id);
 }
 
 }  // namespace content
diff --git a/content/browser/webid/federated_auth_user_info_request.cc b/content/browser/webid/federated_auth_user_info_request.cc
index f7d23de..dcc1791 100644
--- a/content/browser/webid/federated_auth_user_info_request.cc
+++ b/content/browser/webid/federated_auth_user_info_request.cc
@@ -215,7 +215,7 @@
 
 void FederatedAuthUserInfoRequest::OnAccountsResponseReceived(
     IdpNetworkRequestManager::FetchStatus fetch_status,
-    IdpNetworkRequestManager::AccountList accounts) {
+    std::vector<IdentityRequestAccountPtr> accounts) {
   webid::UpdateIdpSigninStatusForAccountsEndpointResponse(
       *render_frame_host_, idp_config_url_, fetch_status,
       does_idp_have_failing_signin_status_, permission_delegate_);
@@ -236,7 +236,7 @@
     // We set the login state based on the IDP response if it sends
     // back an approved_clients list. If it does not, we need to set
     // it here based on browser state.
-    if (account.login_state) {
+    if (account->login_state) {
       continue;
     }
 
@@ -245,22 +245,22 @@
     // this account before.
     if (permission_delegate_->GetLastUsedTimestamp(
             parent_frame_origin_, embedding_origin_,
-            url::Origin::Create(idp_config_url_), account.id)) {
+            url::Origin::Create(idp_config_url_), account->id)) {
       login_state = LoginState::kSignIn;
     }
-    account.login_state = login_state;
+    account->login_state = login_state;
   }
 
   MaybeReturnAccounts(std::move(accounts));
 }
 
 void FederatedAuthUserInfoRequest::MaybeReturnAccounts(
-    const IdpNetworkRequestManager::AccountList& accounts) {
+    const std::vector<IdentityRequestAccountPtr>& accounts) {
   DCHECK(!accounts.empty());
 
   bool has_returning_accounts = false;
   for (const auto& account : accounts) {
-    if (IsReturningAccount(account)) {
+    if (IsReturningAccount(*account)) {
       has_returning_accounts = true;
       break;
     }
@@ -286,14 +286,14 @@
   std::vector<blink::mojom::IdentityUserInfoPtr> user_info;
   std::vector<blink::mojom::IdentityUserInfoPtr> not_returning_accounts;
   for (const auto& account : accounts) {
-    if (IsReturningAccount(account)) {
+    if (IsReturningAccount(*account)) {
       user_info.push_back(blink::mojom::IdentityUserInfo::New(
-          account.email, account.given_name, account.name,
-          account.picture.spec()));
+          account->email, account->given_name, account->name,
+          account->picture.spec()));
     } else {
       not_returning_accounts.push_back(blink::mojom::IdentityUserInfo::New(
-          account.email, account.given_name, account.name,
-          account.picture.spec()));
+          account->email, account->given_name, account->name,
+          account->picture.spec()));
     }
   }
   user_info.insert(user_info.end(),
diff --git a/content/browser/webid/federated_auth_user_info_request.h b/content/browser/webid/federated_auth_user_info_request.h
index 39887ea2..60f1ab44 100644
--- a/content/browser/webid/federated_auth_user_info_request.h
+++ b/content/browser/webid/federated_auth_user_info_request.h
@@ -63,10 +63,10 @@
 
   void OnAccountsResponseReceived(
       IdpNetworkRequestManager::FetchStatus fetch_status,
-      IdpNetworkRequestManager::AccountList accounts);
+      std::vector<IdentityRequestAccountPtr> accounts);
 
   void MaybeReturnAccounts(
-      const IdpNetworkRequestManager::AccountList& accounts);
+      const std::vector<IdentityRequestAccountPtr>& accounts);
 
   bool IsReturningAccount(const IdentityRequestAccount& account);
 
diff --git a/content/browser/webid/federated_auth_user_info_request_unittest.cc b/content/browser/webid/federated_auth_user_info_request_unittest.cc
index 9dbd59e..fe93ca6 100644
--- a/content/browser/webid/federated_auth_user_info_request_unittest.cc
+++ b/content/browser/webid/federated_auth_user_info_request_unittest.cc
@@ -168,14 +168,14 @@
                            AccountsRequestCallback callback) override {
     has_fetched_accounts_endpoint_ = true;
 
-    std::vector<IdentityRequestAccount> accounts;
+    std::vector<IdentityRequestAccountPtr> accounts;
     for (const AccountConfig& account_config : config_.accounts) {
-      accounts.emplace_back(
+      accounts.emplace_back(base::MakeRefCounted<IdentityRequestAccount>(
           account_config.id, GenerateEmailForUserId(account_config.id),
           kAccountName, kAccountGivenName, GURL(kAccountPicture),
           /*login_hints=*/std::vector<std::string>(),
           /*domain_hints=*/std::vector<std::string>(),
-          /*labels=*/std::vector<std::string>(), account_config.login_state);
+          /*labels=*/std::vector<std::string>(), account_config.login_state));
     }
 
     base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
diff --git a/content/browser/webid/idp_network_request_manager.cc b/content/browser/webid/idp_network_request_manager.cc
index cea745a0..1ab73e2 100644
--- a/content/browser/webid/idp_network_request_manager.cc
+++ b/content/browser/webid/idp_network_request_manager.cc
@@ -42,21 +42,19 @@
 namespace content {
 
 namespace {
-using LoginState = IdentityRequestAccount::LoginState;
 
-using AccountList = IdpNetworkRequestManager::AccountList;
+using AccountsResponseInvalidReason =
+    IdpNetworkRequestManager::AccountsResponseInvalidReason;
 using ClientMetadata = IdpNetworkRequestManager::ClientMetadata;
 using Endpoints = IdpNetworkRequestManager::Endpoints;
-using FetchStatus = content::IdpNetworkRequestManager::FetchStatus;
-using TokenResult = content::IdpNetworkRequestManager::TokenResult;
-using TokenError = content::IdentityCredentialTokenError;
-using ParseStatus = content::IdpNetworkRequestManager::ParseStatus;
-using AccountsResponseInvalidReason =
-    content::IdpNetworkRequestManager::AccountsResponseInvalidReason;
-using ErrorDialogType = content::IdpNetworkRequestManager::FedCmErrorDialogType;
-using TokenResponseType =
-    content::IdpNetworkRequestManager::FedCmTokenResponseType;
-using ErrorUrlType = content::IdpNetworkRequestManager::FedCmErrorUrlType;
+using ErrorDialogType = IdpNetworkRequestManager::FedCmErrorDialogType;
+using ErrorUrlType = IdpNetworkRequestManager::FedCmErrorUrlType;
+using FetchStatus = IdpNetworkRequestManager::FetchStatus;
+using LoginState = IdentityRequestAccount::LoginState;
+using ParseStatus = IdpNetworkRequestManager::ParseStatus;
+using TokenError = IdentityCredentialTokenError;
+using TokenResponseType = IdpNetworkRequestManager::FedCmTokenResponseType;
+using TokenResult = IdpNetworkRequestManager::TokenResult;
 
 // TODO(kenrb): These need to be defined in the explainer or draft spec and
 // referenced here.
@@ -210,9 +208,8 @@
   return *str;
 }
 
-std::optional<content::IdentityRequestAccount> ParseAccount(
-    const base::Value::Dict& account,
-    const std::string& client_id) {
+IdentityRequestAccountPtr ParseAccount(const base::Value::Dict& account,
+                                       const std::string& client_id) {
   auto* id = account.FindString(kAccountIdKey);
   auto* email = account.FindString(kAccountEmailKey);
   auto* name = account.FindString(kAccountNameKey);
@@ -249,8 +246,9 @@
   }
 
   // required fields
-  if (!(id && email && name))
-    return std::nullopt;
+  if (!(id && email && name)) {
+    return nullptr;
+  }
 
   auto trimmed_email =
       base::TrimWhitespace(base::UTF8ToUTF16(*email), base::TRIM_ALL);
@@ -258,7 +256,7 @@
       base::TrimWhitespace(base::UTF8ToUTF16(*name), base::TRIM_ALL);
   // TODO(crbug.com/40849405): validate email address.
   if (trimmed_email.empty() || trimmed_name.empty()) {
-    return std::nullopt;
+    return nullptr;
   }
 
   RecordApprovedClientsExistence(approved_clients != nullptr);
@@ -280,7 +278,7 @@
     RecordApprovedClientsSize(approved_clients->size());
   }
 
-  return content::IdentityRequestAccount(
+  return base::MakeRefCounted<IdentityRequestAccount>(
       *id, *email, *name, given_name ? *given_name : "",
       picture ? GURL(*picture) : GURL(), std::move(account_hints),
       std::move(domain_hints), std::move(labels), approved_value,
@@ -290,7 +288,7 @@
 // Parses accounts from given Value. Returns true if parse is successful and
 // adds parsed accounts to the |account_list|.
 bool ParseAccounts(const base::Value::List& accounts,
-                   AccountList& account_list,
+                   std::vector<IdentityRequestAccountPtr>& account_list,
                    const std::string& client_id,
                    AccountsResponseInvalidReason& parsing_error) {
   DCHECK(account_list.empty());
@@ -303,14 +301,15 @@
       return false;
     }
 
-    auto parsed_account = ParseAccount(*account_dict, client_id);
+    IdentityRequestAccountPtr parsed_account =
+        ParseAccount(*account_dict, client_id);
     if (parsed_account) {
       if (account_ids.count(parsed_account->id)) {
         parsing_error = AccountsResponseInvalidReason::kAccountsShareSameId;
         return false;
       }
-      account_list.push_back(parsed_account.value());
       account_ids.insert(parsed_account->id);
+      account_list.push_back(std::move(parsed_account));
     } else {
       parsing_error =
           AccountsResponseInvalidReason::kAccountMissesRequiredField;
@@ -327,8 +326,9 @@
     return std::nullopt;
 
   SkColor color;
-  if (!content::ParseCssColorString(*value, &color))
+  if (!ParseCssColorString(*value, &color)) {
     return std::nullopt;
+  }
 
   return SkColorSetA(color, 0xff);
 }
@@ -640,14 +640,14 @@
     IdpNetworkRequestManager::AccountsRequestCallback callback,
     FetchStatus fetch_status,
     data_decoder::DataDecoder::ValueOrError result) {
+  std::vector<IdentityRequestAccountPtr> account_list;
   if (fetch_status.parse_status != ParseStatus::kSuccess) {
     RecordAccountsResponseInvalidReason(
         AccountsResponseInvalidReason::kResponseIsNotJsonOrDict);
-    std::move(callback).Run(fetch_status, AccountList());
+    std::move(callback).Run(fetch_status, account_list);
     return;
   }
 
-  AccountList account_list;
   const base::Value::Dict& response = result->GetDict();
   const base::Value::List* accounts = response.FindList(kAccountsKey);
 
@@ -656,7 +656,7 @@
         AccountsResponseInvalidReason::kNoAccountsKey);
     std::move(callback).Run(
         {ParseStatus::kInvalidResponseError, fetch_status.response_code},
-        AccountList());
+        account_list);
     return;
   }
 
@@ -665,7 +665,7 @@
         AccountsResponseInvalidReason::kAccountListIsEmpty);
     std::move(callback).Run(
         {ParseStatus::kEmptyListError, fetch_status.response_code},
-        AccountList());
+        account_list);
     return;
   }
 
@@ -680,7 +680,7 @@
     RecordAccountsResponseInvalidReason(parsing_error);
     std::move(callback).Run(
         {ParseStatus::kInvalidResponseError, fetch_status.response_code},
-        AccountList());
+        std::vector<IdentityRequestAccountPtr>());
     return;
   }
 
diff --git a/content/browser/webid/idp_network_request_manager.h b/content/browser/webid/idp_network_request_manager.h
index 8f20b22..c4bcecdd 100644
--- a/content/browser/webid/idp_network_request_manager.h
+++ b/content/browser/webid/idp_network_request_manager.h
@@ -35,6 +35,8 @@
 
 namespace content {
 
+using IdentityProviderDataPtr = scoped_refptr<IdentityProviderData>;
+using IdentityRequestAccountPtr = scoped_refptr<IdentityRequestAccount>;
 class RenderFrameHostImpl;
 
 // Manages network requests and maintains relevant state for interaction with
@@ -215,9 +217,9 @@
     kMaxValue = kCrossSite
   };
 
-  using AccountList = std::vector<IdentityRequestAccount>;
   using AccountsRequestCallback =
-      base::OnceCallback<void(FetchStatus, AccountList)>;
+      base::OnceCallback<void(FetchStatus,
+                              std::vector<IdentityRequestAccountPtr>)>;
   using DownloadCallback =
       base::OnceCallback<void(std::unique_ptr<std::string> response_body,
                               int response_code,
diff --git a/content/browser/webid/idp_network_request_manager_unittest.cc b/content/browser/webid/idp_network_request_manager_unittest.cc
index bb46f9ca..ba92ab6 100644
--- a/content/browser/webid/idp_network_request_manager_unittest.cc
+++ b/content/browser/webid/idp_network_request_manager_unittest.cc
@@ -34,7 +34,6 @@
 #include "ui/gfx/geometry/size.h"
 #include "url/gurl.h"
 
-using AccountList = content::IdpNetworkRequestManager::AccountList;
 using IdpClientMetadata = content::IdpNetworkRequestManager::ClientMetadata;
 using TokenResult = content::IdpNetworkRequestManager::TokenResult;
 using Endpoints = content::IdpNetworkRequestManager::Endpoints;
@@ -192,7 +191,8 @@
     return {parsed_fetch_status, parsed_idp_metadata};
   }
 
-  std::tuple<FetchStatus, AccountList> SendAccountsRequestAndWaitForResponse(
+  std::tuple<FetchStatus, std::vector<IdentityRequestAccountPtr>>
+  SendAccountsRequestAndWaitForResponse(
       const std::string& test_accounts,
       const char* client_id = "",
       net::HttpStatusCode response_code = net::HTTP_OK,
@@ -202,9 +202,10 @@
 
     base::RunLoop run_loop;
     FetchStatus parsed_accounts_response;
-    AccountList parsed_accounts;
+    std::vector<IdentityRequestAccountPtr> parsed_accounts;
     auto callback = base::BindLambdaForTesting(
-        [&](FetchStatus response, AccountList accounts) {
+        [&](FetchStatus response,
+            std::vector<IdentityRequestAccountPtr> accounts) {
           parsed_accounts_response = response;
           parsed_accounts = accounts;
           run_loop.Quit();
@@ -308,7 +309,7 @@
   })";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_empty_account_json);
 
@@ -325,14 +326,14 @@
   const auto* test_single_account_json = kSingleAccountEndpointValidJson;
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_single_account_json);
 
   EXPECT_EQ(ParseStatus::kSuccess, accounts_response.parse_status);
   EXPECT_EQ(net::HTTP_OK, accounts_response.response_code);
   EXPECT_EQ(1UL, accounts.size());
-  EXPECT_EQ("1234", accounts[0].id);
+  EXPECT_EQ("1234", accounts[0]->id);
 }
 
 TEST_F(IdpNetworkRequestManagerTest, ParseAccountMultiple) {
@@ -355,15 +356,15 @@
   ]
   })";
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_accounts_json);
 
   EXPECT_EQ(ParseStatus::kSuccess, accounts_response.parse_status);
   EXPECT_EQ(net::HTTP_OK, accounts_response.response_code);
   EXPECT_EQ(2UL, accounts.size());
-  EXPECT_EQ("1234", accounts[0].id);
-  EXPECT_EQ("5678", accounts[1].id);
+  EXPECT_EQ("1234", accounts[0]->id);
+  EXPECT_EQ("5678", accounts[1]->id);
 }
 
 TEST_F(IdpNetworkRequestManagerTest, ParseAccountOptionalFields) {
@@ -379,13 +380,13 @@
   })";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_accounts_json);
 
   EXPECT_EQ(ParseStatus::kSuccess, accounts_response.parse_status);
   EXPECT_EQ(net::HTTP_OK, accounts_response.response_code);
-  EXPECT_EQ("1234", accounts[0].id);
+  EXPECT_EQ("1234", accounts[0]->id);
 }
 
 TEST_F(IdpNetworkRequestManagerTest, ParseAccountRequiredFields) {
@@ -394,7 +395,7 @@
     std::string test_account_missing_account_id_json =
         RemoveAllLinesWithKeyFromJson("id", kSingleAccountEndpointValidJson);
     FetchStatus accounts_response;
-    AccountList accounts;
+    std::vector<IdentityRequestAccountPtr> accounts;
     std::tie(accounts_response, accounts) =
         SendAccountsRequestAndWaitForResponse(
             test_account_missing_account_id_json);
@@ -412,7 +413,7 @@
     std::string test_account_missing_email_json =
         RemoveAllLinesWithKeyFromJson("email", kSingleAccountEndpointValidJson);
     FetchStatus accounts_response;
-    AccountList accounts;
+    std::vector<IdentityRequestAccountPtr> accounts;
     std::tie(accounts_response, accounts) =
         SendAccountsRequestAndWaitForResponse(test_account_missing_email_json);
 
@@ -429,7 +430,7 @@
     std::string test_account_missing_name_json =
         RemoveAllLinesWithKeyFromJson("name", kSingleAccountEndpointValidJson);
     FetchStatus accounts_response;
-    AccountList accounts;
+    std::vector<IdentityRequestAccountPtr> accounts;
     std::tie(accounts_response, accounts) =
         SendAccountsRequestAndWaitForResponse(test_account_missing_name_json);
 
@@ -457,7 +458,7 @@
     })";
 
     FetchStatus accounts_response;
-    AccountList accounts;
+    std::vector<IdentityRequestAccountPtr> accounts;
     std::tie(accounts_response, accounts) =
         SendAccountsRequestAndWaitForResponse(test_accounts_json);
 
@@ -482,7 +483,7 @@
     })";
 
     FetchStatus accounts_response;
-    AccountList accounts;
+    std::vector<IdentityRequestAccountPtr> accounts;
     std::tie(accounts_response, accounts) =
         SendAccountsRequestAndWaitForResponse(test_accounts_json);
 
@@ -514,7 +515,7 @@
   })";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(accounts_json);
 
@@ -555,15 +556,15 @@
   })";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_accounts_json);
 
   EXPECT_EQ(ParseStatus::kSuccess, accounts_response.parse_status);
   EXPECT_EQ(net::HTTP_OK, accounts_response.response_code);
-  EXPECT_TRUE(accounts[0].picture.is_valid());
-  EXPECT_EQ(GURL("https://idp.test/profile/1234"), accounts[0].picture);
-  EXPECT_FALSE(accounts[1].picture.is_valid());
+  EXPECT_TRUE(accounts[0]->picture.is_valid());
+  EXPECT_EQ(GURL("https://idp.test/profile/1234"), accounts[0]->picture);
+  EXPECT_FALSE(accounts[1]->picture.is_valid());
 }
 
 TEST_F(IdpNetworkRequestManagerTest, ParseAccountUnicode) {
@@ -587,12 +588,12 @@
     const auto& accounts_json = TestAccountWithKeyValue("name", test_value);
 
     FetchStatus accounts_response;
-    AccountList accounts;
+    std::vector<IdentityRequestAccountPtr> accounts;
     std::tie(accounts_response, accounts) =
         SendAccountsRequestAndWaitForResponse(accounts_json.c_str());
 
     EXPECT_EQ(1UL, accounts.size());
-    EXPECT_EQ(test_value, accounts[0].name);
+    EXPECT_EQ(test_value, accounts[0]->name);
   }
 }
 
@@ -600,7 +601,7 @@
   const auto* test_invalid_account_json = "{}";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_invalid_account_json);
 
@@ -616,7 +617,7 @@
   const auto* test_invalid_account_json = "malformed_json";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_invalid_account_json);
 
@@ -641,17 +642,17 @@
   })";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_accounts_json);
 
   EXPECT_EQ(ParseStatus::kSuccess, accounts_response.parse_status);
   EXPECT_EQ(net::HTTP_OK, accounts_response.response_code);
-  EXPECT_EQ("1234", accounts[0].id);
+  EXPECT_EQ("1234", accounts[0]->id);
   // The integer in the second position should be ignored.
-  ASSERT_EQ(2u, accounts[0].labels.size());
-  EXPECT_EQ("l1", accounts[0].labels[0]);
-  EXPECT_EQ("l2", accounts[0].labels[1]);
+  ASSERT_EQ(2u, accounts[0]->labels.size());
+  EXPECT_EQ("l1", accounts[0]->labels[0]);
+  EXPECT_EQ("l2", accounts[0]->labels[1]);
 }
 
 TEST_F(IdpNetworkRequestManagerTest, ComputeWellKnownUrl) {
@@ -1102,7 +1103,7 @@
   })";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_accounts_json);
 
@@ -1160,7 +1161,7 @@
   })";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_accounts_json, "xxx");
 
@@ -1168,15 +1169,15 @@
   EXPECT_EQ(ParseStatus::kSuccess, accounts_response.parse_status);
   EXPECT_EQ(net::HTTP_OK, accounts_response.response_code);
   ASSERT_EQ(5ul, accounts.size());
-  ASSERT_TRUE(accounts[0].login_state.has_value());
-  EXPECT_EQ(LoginState::kSignIn, *accounts[0].login_state);
-  ASSERT_TRUE(accounts[1].login_state.has_value());
-  EXPECT_EQ(LoginState::kSignUp, *accounts[1].login_state);
-  ASSERT_TRUE(accounts[2].login_state.has_value());
-  EXPECT_EQ(LoginState::kSignUp, *accounts[2].login_state);
-  EXPECT_FALSE(accounts[3].login_state.has_value());
-  ASSERT_TRUE(accounts[4].login_state.has_value());
-  EXPECT_EQ(LoginState::kSignIn, *accounts[4].login_state);
+  ASSERT_TRUE(accounts[0]->login_state.has_value());
+  EXPECT_EQ(LoginState::kSignIn, *accounts[0]->login_state);
+  ASSERT_TRUE(accounts[1]->login_state.has_value());
+  EXPECT_EQ(LoginState::kSignUp, *accounts[1]->login_state);
+  ASSERT_TRUE(accounts[2]->login_state.has_value());
+  EXPECT_EQ(LoginState::kSignUp, *accounts[2]->login_state);
+  EXPECT_FALSE(accounts[3]->login_state.has_value());
+  ASSERT_TRUE(accounts[4]->login_state.has_value());
+  EXPECT_EQ(LoginState::kSignIn, *accounts[4]->login_state);
 }
 
 // Tests the token request implementation.
@@ -1314,7 +1315,7 @@
   })";
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) =
       SendAccountsRequestAndWaitForResponse(test_accounts_json, "xxx");
 
@@ -1355,7 +1356,8 @@
 
   bool callback_called = false;
   auto callback = base::BindLambdaForTesting(
-      [&callback_called](FetchStatus response, AccountList accounts) {
+      [&callback_called](FetchStatus response,
+                         std::vector<IdentityRequestAccountPtr> accounts) {
         callback_called = true;
       });
 
@@ -1399,7 +1401,7 @@
 
 TEST_F(IdpNetworkRequestManagerTest, ErrorFetchingAccounts) {
   FetchStatus fetch_status;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(fetch_status, accounts) =
       SendAccountsRequestAndWaitForResponse(R"({
   "accounts" : []
@@ -1479,7 +1481,7 @@
   const auto* test_single_account_json = kSingleAccountEndpointValidJson;
 
   FetchStatus accounts_response;
-  AccountList accounts;
+  std::vector<IdentityRequestAccountPtr> accounts;
   std::tie(accounts_response, accounts) = SendAccountsRequestAndWaitForResponse(
       test_single_account_json, /*client_id=*/"", net::HTTP_OK, "text/html");
 
diff --git a/content/browser/webid/test/mock_identity_request_dialog_controller.h b/content/browser/webid/test/mock_identity_request_dialog_controller.h
index bb5d3d5..fb5255b 100644
--- a/content/browser/webid/test/mock_identity_request_dialog_controller.h
+++ b/content/browser/webid/test/mock_identity_request_dialog_controller.h
@@ -5,12 +5,16 @@
 #ifndef CONTENT_BROWSER_WEBID_TEST_MOCK_IDENTITY_REQUEST_DIALOG_CONTROLLER_H_
 #define CONTENT_BROWSER_WEBID_TEST_MOCK_IDENTITY_REQUEST_DIALOG_CONTROLLER_H_
 
+#include "base/memory/scoped_refptr.h"
 #include "content/public/browser/identity_request_dialog_controller.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "url/origin.h"
 
 namespace content {
 
+using IdentityProviderDataPtr = scoped_refptr<IdentityProviderData>;
+using IdentityRequestAccountPtr = scoped_refptr<IdentityRequestAccount>;
+
 class MockIdentityRequestDialogController
     : public IdentityRequestDialogController {
  public:
@@ -26,10 +30,11 @@
   MOCK_METHOD(bool,
               ShowAccountsDialog,
               (const std::string&,
-               const std::vector<content::IdentityProviderData>&,
+               const std::vector<IdentityProviderDataPtr>&,
+               const std::vector<IdentityRequestAccountPtr>&,
                IdentityRequestAccount::SignInMode,
-               blink::mojom::RpMode rp_mode,
-               const std::optional<content::IdentityProviderData>&,
+               blink::mojom::RpMode,
+               const std::vector<IdentityRequestAccountPtr>&,
                AccountSelectionCallback,
                LoginToIdPCallback,
                DismissCallback,
diff --git a/content/browser/webid/webid_browsertest.cc b/content/browser/webid/webid_browsertest.cc
index 213d333..ac7150c 100644
--- a/content/browser/webid/webid_browsertest.cc
+++ b/content/browser/webid/webid_browsertest.cc
@@ -1530,7 +1530,7 @@
 
   // Expects the account chooser to be opened. Selects the first account.
   EXPECT_CALL(*controller, ShowAccountsDialog)
-      .WillOnce(::testing::WithArg<5>([&config_url](auto on_selected) {
+      .WillOnce(::testing::WithArg<6>([&config_url](auto on_selected) {
         std::move(on_selected)
             .Run(config_url,
                  /* account_id=*/"not_real_account",
diff --git a/content/public/browser/identity_request_account.cc b/content/public/browser/identity_request_account.cc
index 699444d..a1b79b7 100644
--- a/content/public/browser/identity_request_account.cc
+++ b/content/public/browser/identity_request_account.cc
@@ -4,6 +4,8 @@
 
 #include "content/public/browser/identity_request_account.h"
 
+#include "content/public/browser/identity_request_dialog_controller.h"
+
 namespace content {
 
 IdentityRequestAccount::IdentityRequestAccount(
@@ -30,8 +32,6 @@
       browser_trusted_login_state{browser_trusted_login_state},
       last_used_timestamp{last_used_timestamp} {}
 
-IdentityRequestAccount::IdentityRequestAccount(const IdentityRequestAccount&) =
-    default;
 IdentityRequestAccount::~IdentityRequestAccount() = default;
 
 }  // namespace content
diff --git a/content/public/browser/identity_request_account.h b/content/public/browser/identity_request_account.h
index 2299f1d..1c8f1a727 100644
--- a/content/public/browser/identity_request_account.h
+++ b/content/public/browser/identity_request_account.h
@@ -9,6 +9,7 @@
 #include <string>
 #include <vector>
 
+#include "base/memory/ref_counted.h"
 #include "base/time/time.h"
 #include "content/common/content_export.h"
 #include "third_party/skia/include/core/SkColor.h"
@@ -17,9 +18,13 @@
 
 namespace content {
 
+class IdentityProviderData;
+
 // Represents a federated user account which is used when displaying the FedCM
 // account selector.
-struct CONTENT_EXPORT IdentityRequestAccount {
+class CONTENT_EXPORT IdentityRequestAccount
+    : public base::RefCounted<IdentityRequestAccount> {
+ public:
   enum class LoginState {
     // This is a returning user signing in with RP/IDP in this browser.
     kSignIn,
@@ -54,8 +59,10 @@
       std::optional<LoginState> login_state = std::nullopt,
       LoginState browser_trusted_login_state = LoginState::kSignUp,
       std::optional<base::Time> last_used_timestamp = std::nullopt);
-  IdentityRequestAccount(const IdentityRequestAccount&);
-  ~IdentityRequestAccount();
+
+  // The identity provider to which the account belongs to. This is not set in
+  // the constructor but instead set later.
+  scoped_refptr<IdentityProviderData> identity_provider = nullptr;
 
   std::string id;
   std::string email;
@@ -81,6 +88,11 @@
   // Whether this account is filtered out or not. An account may be filtered out
   // due to login hint, domain hint, or account label.
   bool is_filtered_out = false;
+
+ private:
+  friend class base::RefCounted<IdentityRequestAccount>;
+
+  ~IdentityRequestAccount();
 };
 
 }  // namespace content
diff --git a/content/public/browser/identity_request_dialog_controller.cc b/content/public/browser/identity_request_dialog_controller.cc
index 904a7a6e..24c07f3 100644
--- a/content/public/browser/identity_request_dialog_controller.cc
+++ b/content/public/browser/identity_request_dialog_controller.cc
@@ -27,22 +27,18 @@
 
 IdentityProviderData::IdentityProviderData(
     const std::string& idp_for_display,
-    const std::vector<IdentityRequestAccount>& accounts,
     const IdentityProviderMetadata& idp_metadata,
     const ClientMetadata& client_metadata,
     blink::mojom::RpContext rp_context,
     const std::vector<IdentityRequestDialogDisclosureField>& disclosure_fields,
     bool has_login_status_mismatch)
     : idp_for_display{idp_for_display},
-      accounts{accounts},
       idp_metadata{idp_metadata},
       client_metadata{client_metadata},
       rp_context(rp_context),
       disclosure_fields(disclosure_fields),
       has_login_status_mismatch(has_login_status_mismatch) {}
 
-IdentityProviderData::IdentityProviderData(const IdentityProviderData& other) =
-    default;
 IdentityProviderData::~IdentityProviderData() = default;
 
 int IdentityRequestDialogController::GetBrandIconIdealSize(
@@ -61,10 +57,12 @@
 
 bool IdentityRequestDialogController::ShowAccountsDialog(
     const std::string& rp_for_display,
-    const std::vector<IdentityProviderData>& identity_provider_data,
-    IdentityRequestAccount::SignInMode sign_in_mode,
+    const std::vector<scoped_refptr<content::IdentityProviderData>>& idp_list,
+    const std::vector<scoped_refptr<content::IdentityRequestAccount>>& accounts,
+    content::IdentityRequestAccount::SignInMode sign_in_mode,
     blink::mojom::RpMode rp_mode,
-    const std::optional<content::IdentityProviderData>& new_account_idp,
+    const std::vector<scoped_refptr<content::IdentityRequestAccount>>&
+        new_accounts,
     AccountSelectionCallback on_selected,
     LoginToIdPCallback on_add_account,
     DismissCallback dismiss_callback,
diff --git a/content/public/browser/identity_request_dialog_controller.h b/content/public/browser/identity_request_dialog_controller.h
index d4ac8c3..058f0e30 100644
--- a/content/public/browser/identity_request_dialog_controller.h
+++ b/content/public/browser/identity_request_dialog_controller.h
@@ -11,6 +11,7 @@
 
 #include "base/functional/callback.h"
 #include "base/functional/callback_forward.h"
+#include "base/memory/ref_counted.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/federated_identity_modal_dialog_view_delegate.h"
 #include "content/public/browser/identity_request_account.h"
@@ -65,20 +66,18 @@
   bool supports_add_account{false};
 };
 
-struct CONTENT_EXPORT IdentityProviderData {
-  IdentityProviderData(const std::string& idp_url_for_display,
-                       const std::vector<IdentityRequestAccount>& accounts,
+class CONTENT_EXPORT IdentityProviderData
+    : public base::RefCounted<IdentityProviderData> {
+ public:
+  IdentityProviderData(const std::string& idp_for_display,
                        const IdentityProviderMetadata& idp_metadata,
                        const ClientMetadata& client_metadata,
                        blink::mojom::RpContext rp_context,
                        const std::vector<IdentityRequestDialogDisclosureField>&
                            disclosure_fields,
                        bool has_login_status_mismatch);
-  IdentityProviderData(const IdentityProviderData& other);
-  ~IdentityProviderData();
 
   std::string idp_for_display;
-  std::vector<IdentityRequestAccount> accounts;
   IdentityProviderMetadata idp_metadata;
   ClientMetadata client_metadata;
   blink::mojom::RpContext rp_context;
@@ -88,6 +87,11 @@
   // Whether there was some login status API mismatch when fetching the IDP's
   // accounts.
   bool has_login_status_mismatch;
+
+ private:
+  friend class base::RefCounted<IdentityProviderData>;
+
+  ~IdentityProviderData();
 };
 
 // IdentityRequestDialogController is an interface, overridden and implemented
@@ -159,16 +163,19 @@
   // Shows and accounts selections for the given IDP. The `on_selected` callback
   // is called with the selected account id or empty string otherwise.
   // `sign_in_mode` represents whether this is an auto re-authn flow.
-  // `new_accounts_idp` are the accounts that were just logged in, which should
+  // `new_accounts` are the accounts that were just logged in, which should
   // be prioritized in the UI. Returns true if the method successfully showed
   // UI. When false, the caller should assume that the API invocation was
   // terminated and the cleanup methods invoked.
   virtual bool ShowAccountsDialog(
       const std::string& rp_for_display,
-      const std::vector<IdentityProviderData>& identity_provider_data,
-      IdentityRequestAccount::SignInMode sign_in_mode,
+      const std::vector<scoped_refptr<content::IdentityProviderData>>& idp_list,
+      const std::vector<scoped_refptr<content::IdentityRequestAccount>>&
+          accounts,
+      content::IdentityRequestAccount::SignInMode sign_in_mode,
       blink::mojom::RpMode rp_mode,
-      const std::optional<IdentityProviderData>& new_accounts_idp,
+      const std::vector<scoped_refptr<content::IdentityRequestAccount>>&
+          new_accounts,
       AccountSelectionCallback on_selected,
       LoginToIdPCallback on_add_account,
       DismissCallback dismiss_callback,
diff --git a/content/web_test/browser/web_test_fedcm_manager.cc b/content/web_test/browser/web_test_fedcm_manager.cc
index e18d043..bdfa2e8 100644
--- a/content/web_test/browser/web_test_fedcm_manager.cc
+++ b/content/web_test/browser/web_test_fedcm_manager.cc
@@ -77,25 +77,20 @@
     std::move(callback).Run(false);
     return;
   }
-  const std::vector<IdentityProviderData>& idp_data =
-      auth_request->GetSortedIdpData();
-  if (idp_data.empty()) {
+  const std::vector<IdentityRequestAccountPtr>& accounts =
+      auth_request->GetAccounts();
+  if (accounts.empty()) {
     std::move(callback).Run(false);
     return;
   }
-  uint32_t current = 0;
-  for (const auto& data : idp_data) {
-    for (const IdentityRequestAccount& account : data.accounts) {
-      if (current == account_index) {
-        auth_request->AcceptAccountsDialogForDevtools(
-            data.idp_metadata.config_url, account);
-        std::move(callback).Run(true);
-        return;
-      }
-      ++current;
-    }
+  if (account_index >= accounts.size()) {
+    std::move(callback).Run(false);
+    return;
   }
-  std::move(callback).Run(false);
+  const IdentityRequestAccount& account = *accounts[account_index];
+  auth_request->AcceptAccountsDialogForDevtools(
+      account.identity_provider->idp_metadata.config_url, account);
+  std::move(callback).Run(true);
 }
 
 void WebTestFedCmManager::DismissFedCmDialog(
@@ -151,7 +146,7 @@
             return;
           }
           std::move(callback).Run(
-              auth_request->UseAnotherAccountForDevtools(data[0]));
+              auth_request->UseAnotherAccountForDevtools(*data[0]));
           return;
         }
         default:
diff --git a/device/fido/virtual_fido_device.cc b/device/fido/virtual_fido_device.cc
index 34f742e..a6962a0 100644
--- a/device/fido/virtual_fido_device.cc
+++ b/device/fido/virtual_fido_device.cc
@@ -451,9 +451,8 @@
     base::span<const uint8_t> credential_id,
     device::PublicKeyCredentialRpEntity rp,
     device::PublicKeyCredentialUserEntity user) {
-  return InjectResidentKey(std::move(credential_id), std::move(rp),
-                           std::move(user), /*signature_counter=*/0,
-                           PrivateKey::FreshP256Key());
+  return InjectResidentKey(credential_id, std::move(rp), std::move(user),
+                           /*signature_counter=*/0, PrivateKey::FreshP256Key());
 }
 
 bool VirtualFidoDevice::State::InjectResidentKey(
diff --git a/docs/chrome_browser_design_principles.md b/docs/chrome_browser_design_principles.md
index ecad4c0..af0a4053 100644
--- a/docs/chrome_browser_design_principles.md
+++ b/docs/chrome_browser_design_principles.md
@@ -245,6 +245,46 @@
 * Threaded code should have DCHECKs asserting correct sequence.
     * Provides documentation and correctness checks.
     * See base/sequence_checker.h.
+* Avoid tight coupling of unrelated features.
+    * This results in O(N^2) complexity, since every pair of features ends up
+      implicitly coupled.
+    * The proper solution is to work with UX to use consistent design language,
+      which in turn results in O(N) complexity.
+```cpp
+// Good, complexity is O(N) and no tight coupling using a well-understood and
+// common design pattern: modality. Similar logic will be needed in other modal
+// UIs. The logic in this class does not change regardless of how many other new
+// modal features are created.
+class Sparkles {
+  // Shows sparkles over the entire tab. Should not be shown over other Chrome
+  // contents (e.g. print preview)
+  void Show() {
+    if (tab_->CanShowModalUI()) {
+      MakeSparkles();
+      // Prevents other modals from showing until the member is reset.
+      modal_ui_ = tab_->ShowModalUI();
+    }
+  }
+
+  std::unique_ptr<ScopedTabModalUI> modal_ui_;
+  raw_ptr<TabInterface> tab_;
+};
+
+// Bad. Introduces tight coupling between unrelated features. Similar logic is
+// needed in PrintPreview and DevTools. Complexity will scale with O(N^2). When
+// a new modal feature is created, every modal feature will need to be updated.
+class Sparkles {
+  void Show() {
+    if (PrintPreview::Showing()) {
+      return;
+    }
+    if (DevTools::Showing()) {
+      return;
+    }
+    MakeSparkles();
+  }
+};
+```
 * Most features should be gated by base::Feature, API keys and/or gn build
   configuration, not C preprocessor conditionals e.g. `#if
   BUILDFLAG(FEATURE_FOO)`.
diff --git a/docs/website b/docs/website
index f377d19..59974df 160000
--- a/docs/website
+++ b/docs/website
@@ -1 +1 @@
-Subproject commit f377d194c7d27d9f7627080a1f3a31b112febe8e
+Subproject commit 59974df09115902c44c20a65b3e47c038384d643
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index c2e349a7..12b2efa0 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1678,8 +1678,8 @@
   FILEMANAGERPRIVATE_GETFRAMECOLOR = 1616,
   DEVELOPERPRIVATE_ADDUSERSPECIFIEDSITES = 1617,
   DEVELOPERPRIVATE_REMOVEUSERSPECIFIEDSITES = 1618,
-  AUTOTESTPRIVATE_STARTARC = 1619,
-  AUTOTESTPRIVATE_STOPARC = 1620,
+  DELETED_AUTOTESTPRIVATE_STARTARC = 1619,
+  DELETED_AUTOTESTPRIVATE_STOPARC = 1620,
   PASSWORDSPRIVATE_MUTEINSECURECREDENTIAL = 1621,
   WEB_AUTHENTICATION_PROXY_COMPLETE_GET_REQUEST = 1622,
   PASSWORDSPRIVATE_UNMUTEINSECURECREDENTIAL = 1623,
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc
index 7c13a06..c67d600 100644
--- a/extensions/renderer/dispatcher.cc
+++ b/extensions/renderer/dispatcher.cc
@@ -15,6 +15,7 @@
 #include "base/command_line.h"
 #include "base/containers/contains.h"
 #include "base/debug/alias.h"
+#include "base/debug/crash_logging.h"
 #include "base/debug/dump_without_crashing.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
@@ -36,6 +37,7 @@
 #include "content/public/renderer/render_frame.h"
 #include "content/public/renderer/render_thread.h"
 #include "content/public/renderer/v8_value_converter.h"
+#include "extensions/common/api/incognito.h"
 #include "extensions/common/api/messaging/message.h"
 #include "extensions/common/constants.h"
 #include "extensions/common/cors_util.h"
@@ -54,6 +56,7 @@
 #include "extensions/common/features/feature_session_type.h"
 #include "extensions/common/manifest_constants.h"
 #include "extensions/common/manifest_handlers/background_info.h"
+#include "extensions/common/manifest_handlers/incognito_info.h"
 #include "extensions/common/manifest_handlers/options_page_info.h"
 #include "extensions/common/mojom/context_type.mojom.h"
 #include "extensions/common/mojom/host_id.mojom.h"
@@ -240,8 +243,85 @@
   return extension;
 }
 
+using IncognitoManifestKeys = api::incognito::ManifestKeys;
+
+base::debug::CrashKeyString* GetExtensionIdCrashKey() {
+  static auto* crash_key = base::debug::AllocateCrashKeyString(
+      "ext_token_id", base::debug::CrashKeySize::Size32);
+  return crash_key;
+}
+
+base::debug::CrashKeyString* GetIncognitoModeCrashKey() {
+  static auto* crash_key = base::debug::AllocateCrashKeyString(
+      "ext_token_incog_mode", base::debug::CrashKeySize::Size32);
+  return crash_key;
+}
+
+base::debug::CrashKeyString* GetIncognitoProcessCrashKey() {
+  static auto* crash_key = base::debug::AllocateCrashKeyString(
+      "ext_token_incog_process", base::debug::CrashKeySize::Size32);
+  return crash_key;
+}
+
+const ExtensionId& GetExtensionIdValue(const Extension* extension) {
+  return extension->id();
+}
+
+const char* GetIncognitoModeValue(const Extension* extension) {
+  IncognitoInfo* info = static_cast<IncognitoInfo*>(
+      extension->GetManifestData(IncognitoManifestKeys::kIncognito));
+  if (!info) {
+    return "no_incognito_info";
+  }
+  return api::incognito::ToString(info->mode);
+}
+
+const char* GetIncognitoProcessValue(
+    const ExtensionsRendererClient* renderer_client) {
+  if (!renderer_client) {
+    return "no_renderer_client";
+  }
+  return renderer_client->IsIncognitoProcess() ? "yes" : "no";
+}
+
 }  // namespace
 
+namespace debug {
+
+// Helper for adding a set of missing activation token related crash keys.
+//
+// It is created when being notified that an extension worker will evaluate (is
+// in the process of starting) and we might detect that there isn't an
+// activation token recorded for the extension worker.
+//
+// All keys are logged every time this class is instantiated.
+class ScopedActivationTokenMissingCrashKeys {
+ public:
+  explicit ScopedActivationTokenMissingCrashKeys(
+      const Extension* extension,
+      const ExtensionsRendererClient* renderer_client)
+      : extension_id_crash_key_(GetExtensionIdCrashKey(),
+                                GetExtensionIdValue(extension)),
+        incognito_mode_crash_key_(GetIncognitoModeCrashKey(),
+                                  GetIncognitoModeValue(extension)),
+        incognito_process_crash_key_(
+            GetIncognitoProcessCrashKey(),
+            GetIncognitoProcessValue(renderer_client)) {}
+  ~ScopedActivationTokenMissingCrashKeys() = default;
+
+ private:
+  // ExtensionId of the extension.
+  base::debug::ScopedCrashKeyString extension_id_crash_key_;
+
+  // What the api::incognito::IncognitoMode is for the extension.
+  base::debug::ScopedCrashKeyString incognito_mode_crash_key_;
+
+  // Whether the renderer process for the extension was launched incognito.
+  base::debug::ScopedCrashKeyString incognito_process_crash_key_;
+};
+
+}  // namespace debug
+
 Dispatcher::PendingServiceWorker::PendingServiceWorker(
     blink::WebServiceWorkerContextProxy* context_proxy)
     : task_runner(base::SingleThreadTaskRunner::GetCurrentDefault()),
@@ -577,7 +657,12 @@
   std::unique_ptr<IPCMessageSender> ipc_sender =
       IPCMessageSender::CreateWorkerThreadIPCMessageSender(
           worker_dispatcher, context_proxy, service_worker_version_id);
-  CHECK(worker_activation_token.has_value());
+  {
+    // TODO(crbug.com/357889496): Remove these crash keys once bug is resolved.
+    debug::ScopedActivationTokenMissingCrashKeys activation_token_missing_keys(
+        extension, ExtensionsRendererClient::Get());
+    CHECK(worker_activation_token.has_value());
+  }
   worker_dispatcher->AddWorkerData(
       context_proxy, service_worker_version_id, worker_activation_token,
       service_worker_token, context,
diff --git a/fuchsia_web/shell/cast_streaming_shell.cc b/fuchsia_web/shell/cast_streaming_shell.cc
index 12eb1b2..101d3b83 100644
--- a/fuchsia_web/shell/cast_streaming_shell.cc
+++ b/fuchsia_web/shell/cast_streaming_shell.cc
@@ -47,16 +47,6 @@
 // JavaScripts.
 constexpr int kAddBeforeLoadJavaScriptID = 0;
 
-void PrintUsage() {
-  std::cerr << "Usage: "
-            << base::CommandLine::ForCurrentProcess()->GetProgram().BaseName()
-            << " [--" << kRemoteDebuggingPortSwitch
-            << "=<port>] [-- [--{extra_flag1}] [--{extra_flag2}]]\n"
-            << "Setting " << kRemoteDebuggingPortSwitch << "=0"
-            << " will automatically choose an available port.\n"
-            << "Extra flags will be passed to WebEngine to be processed.\n";
-}
-
 media::VideoDecoderConfig GetDefaultVideoConfig() {
   constexpr gfx::Size kVideoSize = {1280, 720};
   constexpr gfx::Rect kVideoRect(kVideoSize);
@@ -70,7 +60,7 @@
 
 // Set up content directory and context params.
 fuchsia::web::CreateContextParams GetCreateContextParams(
-    uint16_t remote_debugging_port) {
+    std::optional<uint16_t> remote_debugging_port) {
   // Configure the fuchsia-dir://cast-streaming/ directory.
   fuchsia::web::CreateContextParams create_context_params;
   ApplyCastStreamingContextParams(&create_context_params);
@@ -83,7 +73,9 @@
       fuchsia::web::ContextFeatureFlags::VULKAN;
   create_context_params.set_features(features);
 
-  create_context_params.set_remote_debugging_port(remote_debugging_port);
+  if (remote_debugging_port) {
+    create_context_params.set_remote_debugging_port(*remote_debugging_port);
+  }
 
   return create_context_params;
 }
@@ -118,10 +110,6 @@
 
   std::optional<uint16_t> remote_debugging_port =
       GetRemoteDebuggingPort(*command_line);
-  if (!remote_debugging_port) {
-    PrintUsage();
-    return 1;
-  }
 
   // Instantiate Web Instance Host.
   WebInstanceHostWithServicesFromThisComponent web_instance_host(
@@ -133,7 +121,7 @@
       base::CommandLine(command_line->GetArgs());
   child_command_line.AppendSwitch(switches::kEnableCastStreamingReceiver);
   zx_status_t result = web_instance_host.CreateInstanceForContextWithCopiedArgs(
-      GetCreateContextParams(remote_debugging_port.value()),
+      GetCreateContextParams(remote_debugging_port),
       std::move(services_request), child_command_line);
   if (result != ZX_OK) {
     ZX_LOG(ERROR, result) << "CreateInstanceForContextWithCopiedArgs failed";
@@ -156,7 +144,9 @@
 
   // Create the browser `frame`.
   fuchsia::web::CreateFrameParams frame_params;
-  frame_params.set_enable_remote_debugging(true);
+  if (remote_debugging_port) {
+    frame_params.set_enable_remote_debugging(true);
+  }
 
   fuchsia::web::FramePtr frame;
   context->CreateFrameWithParams(std::move(frame_params), frame.NewRequest());
diff --git a/fuchsia_web/shell/remote_debugging_port.cc b/fuchsia_web/shell/remote_debugging_port.cc
index 729902ef..16b8cb15 100644
--- a/fuchsia_web/shell/remote_debugging_port.cc
+++ b/fuchsia_web/shell/remote_debugging_port.cc
@@ -13,17 +13,17 @@
 std::optional<uint16_t> GetRemoteDebuggingPort(
     const base::CommandLine& command_line) {
   if (!command_line.HasSwitch(kRemoteDebuggingPortSwitch)) {
-    return 0;
-  } else {
-    std::string port_str =
-        command_line.GetSwitchValueNative(kRemoteDebuggingPortSwitch);
-    int port_parsed;
-    if (!base::StringToInt(port_str, &port_parsed) || port_parsed < 0 ||
-        port_parsed > 65535) {
-      LOG(ERROR) << "Invalid value for --remote-debugging-port (must be in the "
-                    "range 0-65535).";
-      return std::nullopt;
-    }
+    return std::nullopt;
+  }
+  std::string port_str =
+      command_line.GetSwitchValueNative(kRemoteDebuggingPortSwitch);
+  int port_parsed;
+  if (base::StringToInt(port_str, &port_parsed) && port_parsed >= 0 &&
+      port_parsed <= 65535) {
     return static_cast<uint16_t>(port_parsed);
   }
+  LOG(ERROR) << "Invalid value for --remote-debugging-port [" << port_str
+             << "], must be an integer in the "
+                "range of 0-65535.";
+  return std::nullopt;
 }
diff --git a/fuchsia_web/shell/remote_debugging_port.h b/fuchsia_web/shell/remote_debugging_port.h
index a8865f3..41a93b2 100644
--- a/fuchsia_web/shell/remote_debugging_port.h
+++ b/fuchsia_web/shell/remote_debugging_port.h
@@ -15,10 +15,8 @@
 
 }  // namespace base
 
-// Return default value of 0 if |command_line| does not have remote debugging
-// port switch. If |command_line| contains the appropriate switch, returns the
-// remote debugging port specified in the |command_line| or nullopt on parsing
-// failure.
+// Returns the debugging port parsed from the |command_line|; if no flag is
+// provided or the value is invalid, returns nullopt.
 std::optional<uint16_t> GetRemoteDebuggingPort(
     const base::CommandLine& command_line);
 
diff --git a/fuchsia_web/shell/web_engine_shell.cc b/fuchsia_web/shell/web_engine_shell.cc
index 5d9c9a8..3a724c4 100644
--- a/fuchsia_web/shell/web_engine_shell.cc
+++ b/fuchsia_web/shell/web_engine_shell.cc
@@ -114,10 +114,6 @@
 
   std::optional<uint16_t> remote_debugging_port =
       GetRemoteDebuggingPort(*command_line);
-  if (!remote_debugging_port) {
-    PrintUsage();
-    return 1;
-  }
 
   const bool is_headless = command_line->HasSwitch(kHeadlessSwitch);
   const bool enable_protected_media_identifier_access =
@@ -183,7 +179,9 @@
   }
 
   create_context_params.set_features(features);
-  create_context_params.set_remote_debugging_port(*remote_debugging_port);
+  if (remote_debugging_port) {
+    create_context_params.set_remote_debugging_port(*remote_debugging_port);
+  }
 
   // DRM services require cdm_data_directory to be populated, so create a
   // directory under /data and use that as the cdm_data_directory.
@@ -253,7 +251,9 @@
 
   // Create the browser |frame| which will contain the webpage.
   fuchsia::web::CreateFrameParams frame_params;
-  frame_params.set_enable_remote_debugging(true);
+  if (remote_debugging_port) {
+    frame_params.set_enable_remote_debugging(true);
+  }
 
   fuchsia::web::FramePtr frame;
   context->CreateFrameWithParams(std::move(frame_params), frame.NewRequest());
@@ -267,18 +267,6 @@
   settings.set_autoplay_policy(fuchsia::web::AutoplayPolicy::ALLOW);
   frame->SetContentAreaSettings(std::move(settings));
 
-  // Log the debugging port.
-  context->GetRemoteDebuggingPort(
-      [](fuchsia::web::Context_GetRemoteDebuggingPort_Result result) {
-        if (result.is_err()) {
-          LOG(ERROR) << "Remote debugging service was not opened.";
-          return;
-        }
-        // Telemetry expects this exact format of log line output to retrieve
-        // the remote debugging port.
-        LOG(INFO) << "Remote debugging port: " << result.response().port;
-      });
-
   // Navigate |frame| to |url|.
   fuchsia::web::LoadUrlParams load_params;
   load_params.set_type(fuchsia::web::LoadUrlReason::TYPED);
diff --git a/fuchsia_web/webengine/renderer/web_engine_audio_renderer.cc b/fuchsia_web/webengine/renderer/web_engine_audio_renderer.cc
index 8245251..214c590 100644
--- a/fuchsia_web/webengine/renderer/web_engine_audio_renderer.cc
+++ b/fuchsia_web/webengine/renderer/web_engine_audio_renderer.cc
@@ -341,8 +341,9 @@
   NOTIMPLEMENTED();
 }
 
-void WebEngineAudioRenderer::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
+void WebEngineAudioRenderer::
+    SetWasPlayedWithUserActivationAndHighMediaEngagement(
+        bool was_played_with_user_activation_and_high_media_engagement) {
   // WebEngine does not use this signal. This is currently only used by the Live
   // Caption feature.
   NOTIMPLEMENTED_LOG_ONCE();
diff --git a/fuchsia_web/webengine/renderer/web_engine_audio_renderer.h b/fuchsia_web/webengine/renderer/web_engine_audio_renderer.h
index d62476f..877d5ae 100644
--- a/fuchsia_web/webengine/renderer/web_engine_audio_renderer.h
+++ b/fuchsia_web/webengine/renderer/web_engine_audio_renderer.h
@@ -52,8 +52,8 @@
   void SetVolume(float volume) override;
   void SetLatencyHint(std::optional<base::TimeDelta> latency_hint) override;
   void SetPreservesPitch(bool preserves_pitch) override;
-  void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) override;
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) override;
 
   // TimeSource implementation.
   void StartTicking() override;
diff --git a/infra/archive_config/linux-archive-rel.json b/infra/archive_config/linux-archive-rel.json
index 47081d97..0003e48 100644
--- a/infra/archive_config/linux-archive-rel.json
+++ b/infra/archive_config/linux-archive-rel.json
@@ -149,6 +149,14 @@
             "gcs_bucket": "chromium-browser-snapshots",
             "gcs_path": "Linux_x64/{%position%}",
             "archive_type": "ARCHIVE_TYPE_FILES"
+        },
+        {
+            "files": [
+                "enterprise_companion.zip"
+            ],
+            "gcs_bucket": "chromium-browser-snapshots",
+            "gcs_path": "Linux_x64/{%position%}",
+            "archive_type": "ARCHIVE_TYPE_FILES"
         }
     ]
 }
diff --git a/infra/archive_config/mac-archive-rel.json b/infra/archive_config/mac-archive-rel.json
index a537a65..c37457c 100644
--- a/infra/archive_config/mac-archive-rel.json
+++ b/infra/archive_config/mac-archive-rel.json
@@ -68,6 +68,14 @@
             "gcs_bucket": "chromium-browser-snapshots",
             "gcs_path": "Mac/{%position%}",
             "archive_type": "ARCHIVE_TYPE_FILES"
+        },
+        {
+            "files": [
+                "enterprise_companion.zip"
+            ],
+            "gcs_bucket": "chromium-browser-snapshots",
+            "gcs_path": "Mac/{%position%}",
+            "archive_type": "ARCHIVE_TYPE_FILES"
         }
     ]
 }
diff --git a/infra/archive_config/mac-arm64-archive-rel.json b/infra/archive_config/mac-arm64-archive-rel.json
index cca6e16..83da14f 100644
--- a/infra/archive_config/mac-arm64-archive-rel.json
+++ b/infra/archive_config/mac-arm64-archive-rel.json
@@ -68,6 +68,14 @@
             "gcs_bucket": "chromium-browser-snapshots",
             "gcs_path": "Mac_Arm/{%position%}",
             "archive_type": "ARCHIVE_TYPE_FILES"
+        },
+        {
+            "files": [
+                "enterprise_companion.zip"
+            ],
+            "gcs_bucket": "chromium-browser-snapshots",
+            "gcs_path": "Mac_Arm/{%position%}",
+            "archive_type": "ARCHIVE_TYPE_FILES"
         }
     ]
 }
diff --git a/infra/archive_config/win-archive-rel.json b/infra/archive_config/win-archive-rel.json
index 119cb99..f975191 100644
--- a/infra/archive_config/win-archive-rel.json
+++ b/infra/archive_config/win-archive-rel.json
@@ -175,6 +175,14 @@
             "gcs_bucket": "chromium-browser-snapshots",
             "gcs_path": "Win_x64/{%position%}/updater-syms.zip",
             "archive_type":"ARCHIVE_TYPE_ZIP"
+        },
+        {
+            "files": [
+                "enterprise_companion.zip"
+            ],
+            "gcs_bucket": "chromium-browser-snapshots",
+            "gcs_path": "Win_x64/{%position%}",
+            "archive_type": "ARCHIVE_TYPE_FILES"
         }
     ]
 }
diff --git a/infra/archive_config/win32-archive-rel.json b/infra/archive_config/win32-archive-rel.json
index 2af8ac40..d8e081b2 100644
--- a/infra/archive_config/win32-archive-rel.json
+++ b/infra/archive_config/win32-archive-rel.json
@@ -183,6 +183,14 @@
             "gcs_bucket": "chromium-browser-snapshots",
             "gcs_path": "Win/{%position%}/updater-syms.zip",
             "archive_type":"ARCHIVE_TYPE_ZIP"
+        },
+        {
+            "files": [
+                "enterprise_companion.zip"
+            ],
+            "gcs_bucket": "chromium-browser-snapshots",
+            "gcs_path": "Win/{%position%}",
+            "archive_type": "ARCHIVE_TYPE_FILES"
         }
     ]
 }
diff --git a/infra/config/generated/builders/ci/ios18-sdk-simulator/properties.json b/infra/config/generated/builders/ci/ios18-sdk-simulator/properties.json
index ba50ae3..e3bfa57 100644
--- a/infra/config/generated/builders/ci/ios18-sdk-simulator/properties.json
+++ b/infra/config/generated/builders/ci/ios18-sdk-simulator/properties.json
@@ -72,5 +72,5 @@
   },
   "builder_group": "chromium.fyi",
   "recipe": "chromium",
-  "xcode_build_version": "16a5230g"
+  "xcode_build_version": "16a242"
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/try/ios18-sdk-simulator/properties.json b/infra/config/generated/builders/try/ios18-sdk-simulator/properties.json
index 9961394c6..ebca9afc 100644
--- a/infra/config/generated/builders/try/ios18-sdk-simulator/properties.json
+++ b/infra/config/generated/builders/try/ios18-sdk-simulator/properties.json
@@ -65,5 +65,5 @@
   },
   "builder_group": "tryserver.chromium.mac",
   "recipe": "chromium_trybot",
-  "xcode_build_version": "16a5230g"
+  "xcode_build_version": "16a242"
 }
\ 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 316b91f7..47c46f9 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -45141,8 +45141,8 @@
       priority: 35
       execution_timeout_secs: 36000
       caches {
-        name: "xcode_ios_16a5230g"
-        path: "xcode_ios_16a5230g.app"
+        name: "xcode_ios_16a242"
+        path: "xcode_ios_16a242.app"
       }
       build_numbers: YES
       service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
@@ -47811,6 +47811,7 @@
         '    ]'
         '  },'
         '  "builder_group": "chromium.memory",'
+        '  "codeql_version": "latest",'
         '  "recipe": "chrome_codeql_database_builder"'
         '}'
       execution_timeout_secs: 64800
@@ -47923,6 +47924,7 @@
         '    ]'
         '  },'
         '  "builder_group": "chromium.memory",'
+        '  "codeql_version": "latest",'
         '  "recipe": "chrome_codeql_query_runner"'
         '}'
       execution_timeout_secs: 64800
@@ -89565,8 +89567,8 @@
         seconds: 120
       }
       caches {
-        name: "xcode_ios_16a5230g"
-        path: "xcode_ios_16a5230g.app"
+        name: "xcode_ios_16a242"
+        path: "xcode_ios_16a242.app"
       }
       build_numbers: YES
       service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
diff --git a/infra/config/generated/testing/gn_isolate_map.pyl b/infra/config/generated/testing/gn_isolate_map.pyl
index 8a0a4236..847e4b6e 100644
--- a/infra/config/generated/testing/gn_isolate_map.pyl
+++ b/infra/config/generated/testing/gn_isolate_map.pyl
@@ -608,13 +608,6 @@
     "label": "//content/test:content_unittests",
     "type": "windowed_test_launcher",
   },
-  "cq_medium_tast_tests": {
-    "label": "//chromeos:cq_medium_tast_tests",
-    "type": "generated_script",
-    "args": [
-      "--logs-dir=${ISOLATED_OUTDIR}",
-    ],
-  },
   "crashpad_tests": {
     "label": "//third_party/crashpad/crashpad:crashpad_tests",
     "type": "console_test_launcher",
diff --git a/infra/config/generated/testing/mixins.pyl b/infra/config/generated/testing/mixins.pyl
index 11c352d2..925671bb 100644
--- a/infra/config/generated/testing/mixins.pyl
+++ b/infra/config/generated/testing/mixins.pyl
@@ -1161,15 +1161,15 @@
       'failed_only',
     ],
   },
-  'shards-10': {
-    'shards': 10,
-  },
   'shards-20': {
     'shards': 20,
   },
   'shards-30': {
     'shards': 30,
   },
+  'shards-50': {
+    'shards': 50,
+  },
   'shiba': {
     'swarming': {
       'dimensions': {
@@ -1485,12 +1485,12 @@
   'xcode_16_beta': {
     'args': [
       '--xcode-build-version',
-      '16a5230g',
+      '16a242',
     ],
     'swarming': {
       'named_caches': [
         {
-          'name': 'xcode_ios_16a5230g',
+          'name': 'xcode_ios_16a242',
           'path': 'Xcode.app',
         },
       ],
diff --git a/infra/config/generated/testing/test_suites.pyl b/infra/config/generated/testing/test_suites.pyl
index d91b8d3..8acdecfb 100644
--- a/infra/config/generated/testing/test_suites.pyl
+++ b/infra/config/generated/testing/test_suites.pyl
@@ -610,15 +610,6 @@
       },
     },
 
-    'chromeos_chrome_cq_medium_tast_tests': {
-      'cq_medium_tast_tests': {
-        'tast_expr': 'STUB_STRING_TO_RUN_TAST_TESTS',
-        'test_level_retries': 2,
-        'timeout_sec': 3600,
-        'shards': 5,
-      },
-    },
-
     'chromeos_chrome_criticalstaging_tast_tests': {
       'chrome_criticalstaging_tast_tests': {
         'tast_expr': 'STUB_STRING_TO_RUN_TAST_TESTS',
@@ -6791,10 +6782,10 @@
       },
     },
 
-    'chromeos_jacuzzi_preuprev_tests': {
-      'chromeos_chrome_cq_medium_tast_tests': {
+    'chromeos_ctp_preuprev_tests_slow_boards': {
+      'chromeos_chrome_all_tast_tests': {
         'mixins': [
-          'shards-10',
+          'shards-50',
         ],
         'variants': [
           'CROS_RELEASE_LKGM',
diff --git a/infra/config/lib/xcode.star b/infra/config/lib/xcode.star
index c91816a..38cbe45 100644
--- a/infra/config/lib/xcode.star
+++ b/infra/config/lib/xcode.star
@@ -29,7 +29,7 @@
     # A newer Xcode 15 version used on beta bots.
     x15betabots = xcode_enum("15f31d"),
     # Xcode 16 beta version used on beta bots.
-    x16betabots = xcode_enum("16a5230g"),
+    x16betabots = xcode_enum("16a242"),
     # Temporary Xcode16.1 beta 1 version.
     x16_1betabots = xcode_enum("16b5001e"),
     # in use by ios-webkit-tot
diff --git a/infra/config/subprojects/chromium/ci/chromium.memory.star b/infra/config/subprojects/chromium/ci/chromium.memory.star
index ced1b551..0198cca8 100644
--- a/infra/config/subprojects/chromium/ci/chromium.memory.star
+++ b/infra/config/subprojects/chromium/ci/chromium.memory.star
@@ -797,6 +797,9 @@
     contact_team_email = "chrome-memory-safety-team@google.com",
     execution_timeout = 18 * time.hour,
     notifies = ["codeql-infra"],
+    properties = {
+        "codeql_version": "latest",
+    },
 )
 
 ci.builder(
@@ -817,4 +820,7 @@
     contact_team_email = "chrome-memory-safety-team@google.com",
     execution_timeout = 18 * time.hour,
     notifies = ["codeql-infra"],
+    properties = {
+        "codeql_version": "latest",
+    },
 )
diff --git a/infra/config/targets/basic_suites.star b/infra/config/targets/basic_suites.star
index 589fb2d..7714adf 100644
--- a/infra/config/targets/basic_suites.star
+++ b/infra/config/targets/basic_suites.star
@@ -564,23 +564,6 @@
     },
 )
 
-targets.legacy_basic_suite(
-    name = "chromeos_chrome_cq_medium_tast_tests",
-    tests = {
-        "cq_medium_tast_tests": targets.legacy_test_config(
-            # `tast_expr` must be a non-empty string to run the tast tests. But the value of
-            # would be overridden by `tast_arrt_expr` defined in chromeos/BUILD.gn, so that we
-            # put the stub string here.
-            tast_expr = "STUB_STRING_TO_RUN_TAST_TESTS",
-            test_level_retries = 2,
-            # Timeout including DUT privisioning.
-            timeout_sec = 3600,
-            # Number of shards. Might be overriden for slower boards.
-            shards = 5,
-        ),
-    },
-)
-
 # GTests to run on Chrome OS devices, but not Chrome OS VMs. Any differences
 # between this and chromeos_system_friendly_gtests below should only be due
 # to resource constraints (ie: not enough devices).
diff --git a/infra/config/targets/binaries.star b/infra/config/targets/binaries.star
index 3084f90..a118b82 100644
--- a/infra/config/targets/binaries.star
+++ b/infra/config/targets/binaries.star
@@ -340,14 +340,6 @@
     ],
 )
 
-targets.binaries.generated_script(
-    name = "cq_medium_tast_tests",
-    label = "//chromeos:cq_medium_tast_tests",
-    args = [
-        "--logs-dir=${ISOLATED_OUTDIR}",
-    ],
-)
-
 targets.binaries.console_test_launcher(
     name = "chrome_elf_unittests",
     label = "//chrome/chrome_elf:chrome_elf_unittests",
diff --git a/infra/config/targets/matrix_compound_suites.star b/infra/config/targets/matrix_compound_suites.star
index 27ae5b10..c1f0471 100644
--- a/infra/config/targets/matrix_compound_suites.star
+++ b/infra/config/targets/matrix_compound_suites.star
@@ -614,12 +614,12 @@
 )
 
 targets.legacy_matrix_compound_suite(
-    name = "chromeos_jacuzzi_preuprev_tests",
+    name = "chromeos_ctp_preuprev_tests_slow_boards",
     basic_suites = {
-        "chromeos_chrome_cq_medium_tast_tests": targets.legacy_matrix_config(
+        "chromeos_chrome_all_tast_tests": targets.legacy_matrix_config(
             mixins = [
                 # jacuzzi is slow. So that we use more number of shards.
-                "shards-10",
+                "shards-50",
             ],
             variants = [
                 "CROS_RELEASE_LKGM",
diff --git a/infra/config/targets/mixins.star b/infra/config/targets/mixins.star
index 03f1400..e751960 100644
--- a/infra/config/targets/mixins.star
+++ b/infra/config/targets/mixins.star
@@ -351,11 +351,6 @@
 )
 
 targets.mixin(
-    name = "shards-10",
-    shards = 10,
-)
-
-targets.mixin(
     name = "shards-20",
     shards = 20,
 )
@@ -366,6 +361,11 @@
 )
 
 targets.mixin(
+    name = "shards-50",
+    shards = 50,
+)
+
+targets.mixin(
     name = "chromeos-generic-vm",
     args = [
         "--magic-vm-cache=magic_cros_vm_cache",
@@ -2012,12 +2012,12 @@
     name = "xcode_16_beta",
     args = [
         "--xcode-build-version",
-        "16a5230g",
+        "16a242",
     ],
     swarming = targets.swarming(
         named_caches = [
             swarming.cache(
-                name = "xcode_ios_16a5230g",
+                name = "xcode_ios_16a242",
                 path = "Xcode.app",
             ),
         ],
diff --git a/infra/config/targets/tests.star b/infra/config/targets/tests.star
index b7e1c20..24e234e 100644
--- a/infra/config/targets/tests.star
+++ b/infra/config/targets/tests.star
@@ -453,10 +453,6 @@
 )
 
 targets.tests.gtest_test(
-    name = "cq_medium_tast_tests",
-)
-
-targets.tests.gtest_test(
     name = "chrome_elf_unittests",
 )
 
diff --git a/internal b/internal
index 619a026..a8d0d66 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit 619a026e7cb0711040338bb724d00e8420611336
+Subproject commit a8d0d660e4e573f811962bfaeb3437067efd8d24
diff --git a/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model.mm b/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model.mm
index a78fb47..11a5c18 100644
--- a/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model.mm
+++ b/ios/chrome/browser/ui/content_suggestions/magic_stack/magic_stack_ranking_model.mm
@@ -371,6 +371,12 @@
   [self.delegate magicStackRankingModel:self didInsertItem:card atIndex:0];
 }
 
+- (void)removePriceTrackingPromo {
+  [self.delegate magicStackRankingModel:self
+                          didRemoveItem:_priceTrackingPromoMediator
+                                            .priceTrackingPromoItemToShow];
+}
+
 // Starts a fetch of the Segmentation module ranking.
 - (void)fetchMagicStackModuleRankingFromSegmentationPlatform {
   if (!base::FeatureList::IsEnabled(segmentation_platform::features::
diff --git a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/BUILD.gn b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/BUILD.gn
index 66000470..2e602824 100644
--- a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/BUILD.gn
+++ b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/BUILD.gn
@@ -13,8 +13,10 @@
     "price_tracking_promo_view.mm",
   ]
   deps = [
+    ":price_tracking_promo_constants",
     "//base:base",
     "//ios/chrome/app/strings:ios_strings_grit",
+    "//ios/chrome/browser/push_notification/model:push_notification_service",
     "//ios/chrome/browser/shared/ui/symbols",
     "//ios/chrome/browser/shared/ui/util:util",
     "//ios/chrome/browser/ui/content_suggestions:constants",
@@ -25,6 +27,14 @@
   ]
 }
 
+source_set("price_tracking_promo_constants") {
+  sources = [
+    "price_tracking_promo_constants.h",
+    "price_tracking_promo_constants.mm",
+  ]
+  deps = []
+}
+
 source_set("unit_tests") {
   testonly = true
   sources = [
@@ -38,3 +48,20 @@
     "//testing/gtest",
   ]
 }
+
+source_set("eg2_tests") {
+  configs += [ "//build/config/ios:xctest_config" ]
+  testonly = true
+  sources = [ "price_tracking_promo_view_egtest.mm" ]
+  deps = [
+    ":price_tracking_promo_constants",
+    "//base/test:test_support",
+    "//components/commerce/core:feature_list",
+    "//components/segmentation_platform/public:public",
+    "//ios/chrome/app/strings:ios_strings_grit",
+    "//ios/chrome/browser/ui/content_suggestions:eg_test_support+eg2",
+    "//ios/chrome/test/earl_grey:eg_test_support+eg2",
+    "//ios/testing/earl_grey:eg_test_support+eg2",
+  ]
+  frameworks = [ "UIKit.framework" ]
+}
diff --git a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_constants.h b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_constants.h
new file mode 100644
index 0000000..68b717f
--- /dev/null
+++ b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_constants.h
@@ -0,0 +1,13 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_PRICE_TRACKING_PROMO_PRICE_TRACKING_PROMO_CONSTANTS_H_
+#define IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_PRICE_TRACKING_PROMO_PRICE_TRACKING_PROMO_CONSTANTS_H_
+
+#import <Foundation/Foundation.h>
+
+// Accessibility ID for Price Tracking Promo UI on Magic Stack.
+extern NSString* const kPriceTrackingPromoViewID;
+
+#endif  // IOS_CHROME_BROWSER_UI_CONTENT_SUGGESTIONS_PRICE_TRACKING_PROMO_PRICE_TRACKING_PROMO_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_constants.mm b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_constants.mm
new file mode 100644
index 0000000..95c774b
--- /dev/null
+++ b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_constants.mm
@@ -0,0 +1,7 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_constants.h"
+
+constexpr NSString* const kPriceTrackingPromoViewID = @"price_tracking_promo";
diff --git a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_mediator.h b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_mediator.h
index 3d937be..2bd3c8e 100644
--- a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_mediator.h
+++ b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_mediator.h
@@ -22,6 +22,9 @@
 // New subscription for user observed (originating from a different platform).
 - (void)newSubscriptionAvailable;
 
+// Price Tracking Promo is removed from the magic stack.
+- (void)removePriceTrackingPromo;
+
 @end
 
 @interface PriceTrackingPromoMediator : NSObject <PriceTrackingPromoCommands>
diff --git a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_mediator.mm b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_mediator.mm
index f3a596d..e24ef28 100644
--- a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_mediator.mm
+++ b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_mediator.mm
@@ -5,6 +5,7 @@
 #import "ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_mediator.h"
 
 #import "base/memory/raw_ptr.h"
+#import "ios/chrome/browser/push_notification/model/push_notification_util.h"
 #import "ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_item.h"
 
 @implementation PriceTrackingPromoMediator {
@@ -23,6 +24,7 @@
     // stack card to be build out with static assets. This will
     // be removed when TODO(crbug.com/361106168) is implemented.
     _priceTrackingPromoItem = [[PriceTrackingPromoItem alloc] init];
+    _priceTrackingPromoItem.commandHandler = self;
   }
   return self;
 }
@@ -54,7 +56,10 @@
 #pragma mark - PriceTrackingPromoCommands
 
 - (void)allowPriceTrackingNotifications {
-  // TODO(crbug.com/361106328) implement opt in flow A
+  [PushNotificationUtil requestPushNotificationPermission:^(
+                            BOOL granted, BOOL promptShown, NSError* error) {
+    [self.delegate removePriceTrackingPromo];
+  }];
   // TODO(crbug.com/361107178) implement opt in flow B
   // TODO(crbug.com/361107641) implement opt in flow C
 }
diff --git a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_view.mm b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_view.mm
index 5c754e1..6fc4e99 100644
--- a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_view.mm
+++ b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_view.mm
@@ -6,6 +6,8 @@
 
 #import "ios/chrome/browser/shared/ui/symbols/symbols.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
+#import "ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_commands.h"
+#import "ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_constants.h"
 #import "ios/chrome/common/ui/colors/semantic_color_names.h"
 #import "ios/chrome/common/ui/util/constraints_ui_util.h"
 #import "ios/chrome/common/ui/util/ui_util.h"
@@ -41,13 +43,14 @@
 @implementation PriceTrackingPromoModuleView {
   UILabel* _titleLabel;
   UILabel* _descriptionLabel;
-  UILabel* _allowLabel;
+  UIButton* _allowButton;
   UIImageView* _fallbackProductImageView;
   // To create a background circle around the fallback product image.
   UIView* _fallbackProductImageBackgroundCircle;
   UIStackView* _contentStack;
   UIStackView* _textStack;
   UIView* _separator;
+  UITapGestureRecognizer* _tapRecognizer;
 }
 
 - (instancetype)initWithFrame:(CGRect)frame {
@@ -71,6 +74,7 @@
     return;
   }
   self.translatesAutoresizingMaskIntoConstraints = NO;
+  self.accessibilityIdentifier = kPriceTrackingPromoViewID;
   _titleLabel = [[UILabel alloc] init];
   _titleLabel.translatesAutoresizingMaskIntoConstraints = NO;
   _titleLabel.textColor = [UIColor colorNamed:kTextPrimaryColor];
@@ -120,19 +124,27 @@
                               _fallbackProductImageBackgroundCircle,
                               kProductImageFallbackInset);
 
-  _allowLabel = [[UILabel alloc] init];
-  _allowLabel.translatesAutoresizingMaskIntoConstraints = NO;
-  _allowLabel.textColor = [UIColor colorNamed:kBlueColor];
-  _allowLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
-  _allowLabel.adjustsFontForContentSizeCategory = YES;
-  _allowLabel.text = l10n_util::GetNSString(
-      IDS_IOS_CONTENT_SUGGESTIONS_PRICE_TRACKING_PROMO_ALLOW);
+  _allowButton = [[UIButton alloc] init];
+  _allowButton.translatesAutoresizingMaskIntoConstraints = NO;
+  [_allowButton
+      setTitle:l10n_util::GetNSString(
+                   IDS_IOS_CONTENT_SUGGESTIONS_PRICE_TRACKING_PROMO_ALLOW)
+      forState:UIControlStateNormal];
+  [_allowButton setTitleColor:[UIColor colorNamed:kBlueColor]
+                     forState:UIControlStateNormal];
+  _allowButton.titleLabel.font =
+      [UIFont preferredFontForTextStyle:UIFontTextStyleFootnote];
+  _tapRecognizer = [[UITapGestureRecognizer alloc]
+      initWithTarget:self
+              action:@selector(allowPriceTrackingTapped:)];
+
+  [_allowButton addGestureRecognizer:_tapRecognizer];
 
   _separator = [[UIView alloc] init];
   _separator.backgroundColor = [UIColor colorNamed:kSeparatorColor];
 
   _textStack = [[UIStackView alloc] initWithArrangedSubviews:@[
-    _titleLabel, _descriptionLabel, _separator, _allowLabel
+    _titleLabel, _descriptionLabel, _separator, _allowButton
   ]];
   _textStack.axis = UILayoutConstraintAxisVertical;
   _textStack.translatesAutoresizingMaskIntoConstraints = NO;
@@ -157,6 +169,10 @@
   AddSameConstraints(_contentStack, self);
 }
 
+- (void)allowPriceTrackingTapped:(UIGestureRecognizer*)sender {
+  [self.commandHandler allowPriceTrackingNotifications];
+}
+
 #pragma mark - Testing category methods
 
 - (NSString*)titleLabelTextForTesting {
@@ -168,7 +184,7 @@
 }
 
 - (NSString*)allowLabelTextForTesting {
-  return self->_allowLabel.text;
+  return self->_allowButton.currentTitle;
 }
 
 @end
diff --git a/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_view_egtest.mm b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_view_egtest.mm
new file mode 100644
index 0000000..cbca0383
--- /dev/null
+++ b/ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_view_egtest.mm
@@ -0,0 +1,82 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "base/strings/stringprintf.h"
+#import "base/test/ios/wait_util.h"
+#import "components/commerce/core/commerce_feature_list.h"
+#import "components/segmentation_platform/public/features.h"
+#import "ios/chrome/browser/ui/content_suggestions/price_tracking_promo/price_tracking_promo_constants.h"
+#import "ios/chrome/grit/ios_strings.h"
+#import "ios/chrome/test/earl_grey/chrome_earl_grey.h"
+#import "ios/chrome/test/earl_grey/chrome_matchers.h"
+#import "ios/chrome/test/earl_grey/chrome_test_case.h"
+#import "ios/testing/earl_grey/app_launch_manager.h"
+#import "ios/testing/earl_grey/earl_grey_test.h"
+#import "ios/testing/earl_grey/system_alert_handler.h"
+
+namespace {
+
+// Checks Price Tracking Promo module disappears.
+void WaitForPriceTrackingPromoToDisappear() {
+  GREYCondition* module_shown = [GREYCondition
+      conditionWithName:@"Price Tracking Promo Module Disappears"
+                  block:^BOOL {
+                    NSError* error;
+                    [[EarlGrey
+                        selectElementWithMatcher:grey_accessibilityID(
+                                                     kPriceTrackingPromoViewID)]
+                        assertWithMatcher:grey_notVisible()
+                                    error:&error];
+                    return error == nil;
+                  }];
+
+  GREYAssertTrue(
+      [module_shown waitWithTimeout:base::test::ios::kWaitForUIElementTimeout
+                                        .InSecondsF()],
+      @"Price Tracking Promo Module was visible.");
+}
+
+}  // namespace
+
+// Test case for the Price Tracking Promo view in the Magic Stack module.
+@interface PriceTrackingPromoViewTestCase : ChromeTestCase
+@end
+
+@implementation PriceTrackingPromoViewTestCase
+
+- (AppLaunchConfiguration)appConfigurationForTestCase {
+  AppLaunchConfiguration config;
+  config.relaunch_policy = ForceRelaunchByCleanShutdown;
+  config.additional_args.push_back(
+      "--test-ios-module-ranker=price_tracking_promo");
+  std::string enableFeatures = base::StringPrintf(
+      "--enable-features=%s,%s:%s/%s", commerce::kPriceTrackingPromo.name,
+      segmentation_platform::features::kSegmentationPlatformEphemeralCardRanker
+          .name,
+      segmentation_platform::features::kEphemeralCardRankerForceShowCardParam,
+      segmentation_platform::features::kPriceTrackingPromoForceOverride);
+  config.additional_args.push_back(enableFeatures);
+  return config;
+}
+
+// Tests the first opt in flow of the price tracking promo card in the magic
+// stack whereby the user has not opted into notifications in the app at all.
+- (void)testFirstOptInFlow {
+  [[EarlGrey selectElementWithMatcher:
+                 chrome_test_util::ButtonWithAccessibilityLabelId(
+                     IDS_IOS_CONTENT_SUGGESTIONS_PRICE_TRACKING_PROMO_ALLOW)]
+      performAction:grey_tap()];
+
+  if ([EarlGrey WaitForAlertVisibility:YES withTimeout:1]) {
+    NSError* error;
+    NSString* alertString = [EarlGrey SystemAlertTextWithError:&error];
+    NSString* expectedString = @"Would Like to Send You Notifications";
+    XCTAssertTrue([alertString containsString:expectedString]);
+    XCTAssertTrue([EarlGrey AcceptSystemDialogWithError:nil]);
+    XCTAssertTrue([EarlGrey WaitForAlertVisibility:NO withTimeout:1]);
+  }
+  WaitForPriceTrackingPromoToDisappear();
+}
+
+@end
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn
index b70800e..74ba6e7 100644
--- a/ios/chrome/test/earl_grey2/BUILD.gn
+++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -220,6 +220,7 @@
     "//ios/chrome/browser/start_surface/ui_bundled:eg2_tests",
     "//ios/chrome/browser/tabs/ui_bundled:eg2_tests",
     "//ios/chrome/browser/text_fragments/ui_bundled:eg2_tests",
+    "//ios/chrome/browser/ui/content_suggestions/price_tracking_promo:eg2_tests",
     "//ios/chrome/browser/ui/content_suggestions/safety_check:eg2_tests",
     "//ios/chrome/browser/ui/content_suggestions/set_up_list:eg2_tests",
     "//ios/chrome/browser/ui/fullscreen:eg2_tests",
diff --git a/ios_internal b/ios_internal
index ec602e2..0b65641 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit ec602e23d833ae149c27f173248ef9c6255442bc
+Subproject commit 0b6564166940fa48dc3a219f6d4eda6e3188f8e3
diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc
index a44fbc63..675291d3 100644
--- a/media/audio/win/audio_output_win_unittest.cc
+++ b/media/audio/win/audio_output_win_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include <windows.h>
 
 #include <mmsystem.h>
diff --git a/media/base/audio_renderer.h b/media/base/audio_renderer.h
index 49f212ee..56f0bc4 100644
--- a/media/base/audio_renderer.h
+++ b/media/base/audio_renderer.h
@@ -73,9 +73,9 @@
   virtual void SetPreservesPitch(bool preserves_pitch) = 0;
 
   // Sets a flag indicating whether the audio stream was played with user
-  // activation.
-  virtual void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) = 0;
+  // activation and high media engagement.
+  virtual void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) = 0;
 };
 
 }  // namespace media
diff --git a/media/base/media_log_events.h b/media/base/media_log_events.h
index 2b2e03743..a72b64a1 100644
--- a/media/base/media_log_events.h
+++ b/media/base/media_log_events.h
@@ -6,8 +6,10 @@
 #define MEDIA_BASE_MEDIA_LOG_EVENTS_H_
 
 #include <string>
+
 #include "media/base/media_export.h"
 #include "media/base/media_log_type_enforcement.h"
+#include "media/base/media_track.h"
 #include "ui/gfx/geometry/size.h"
 
 namespace media {
@@ -81,6 +83,10 @@
   // These logs only apply to HTMLVideoElement. Other media elements will not
   // log these events.
   kVideoOcclusionState,
+
+  // Triggered whenever WMPI handles a track change.
+  kAudioTrackChange,
+  kVideoTrackChange,
 };
 
 // Sometimes URLs can have encoded data that can be exteremly large.
@@ -124,6 +130,13 @@
     SerializableBufferingState<SerializableBufferingStateType::kPipeline>,
     "pipeline_buffering_state");
 
+MEDIA_LOG_EVENT_NAMED_DATA(kAudioTrackChange,
+                           std::vector<MediaTrack::Id>,
+                           "audio_tracks_enabled");
+MEDIA_LOG_EVENT_NAMED_DATA(kVideoTrackChange,
+                           std::optional<MediaTrack::Id>,
+                           "video_track_selected");
+
 }  // namespace media
 
 #endif  // MEDIA_BASE_MEDIA_LOG_EVENTS_H_
diff --git a/media/base/media_serializers.h b/media/base/media_serializers.h
index 985e449..1fba5ad 100644
--- a/media/base/media_serializers.h
+++ b/media/base/media_serializers.h
@@ -16,6 +16,7 @@
 #include "media/base/cdm_config.h"
 #include "media/base/decoder.h"
 #include "media/base/media_serializers_base.h"
+#include "media/base/media_track.h"
 #include "media/base/renderer.h"
 #include "media/base/status.h"
 #include "media/base/video_decoder_config.h"
@@ -559,6 +560,13 @@
   }
 };
 
+template <>
+struct MediaSerializer<MediaTrack::Id> {
+  static inline base::Value Serialize(MediaTrack::Id id) {
+    return base::Value(id.value());
+  }
+};
+
 #undef FIELD_SERIALIZE
 
 }  // namespace media::internal
diff --git a/media/base/mock_filters.h b/media/base/mock_filters.h
index 1c595f58..eba3500e 100644
--- a/media/base/mock_filters.h
+++ b/media/base/mock_filters.h
@@ -125,7 +125,8 @@
   MOCK_METHOD1(SetVolume, void(float));
   MOCK_METHOD1(SetLatencyHint, void(std::optional<base::TimeDelta>));
   MOCK_METHOD1(SetPreservesPitch, void(bool));
-  MOCK_METHOD1(SetWasPlayedWithUserActivation, void(bool));
+  MOCK_METHOD1(SetWasPlayedWithUserActivationAndHighMediaEngagement,
+               void(bool));
 
   // TODO(sandersd): These should probably have setters too.
   MOCK_CONST_METHOD0(GetMediaTime, base::TimeDelta());
@@ -500,7 +501,8 @@
   MOCK_METHOD1(SetLatencyHint,
                void(std::optional<base::TimeDelta> latency_hint));
   MOCK_METHOD1(SetPreservesPitch, void(bool));
-  MOCK_METHOD1(SetWasPlayedWithUserActivation, void(bool));
+  MOCK_METHOD1(SetWasPlayedWithUserActivationAndHighMediaEngagement,
+               void(bool));
 };
 
 class MockRenderer : public Renderer {
@@ -524,7 +526,8 @@
                     PipelineStatusCallback& init_cb));
   MOCK_METHOD1(SetLatencyHint, void(std::optional<base::TimeDelta>));
   MOCK_METHOD1(SetPreservesPitch, void(bool));
-  MOCK_METHOD1(SetWasPlayedWithUserActivation, void(bool));
+  MOCK_METHOD1(SetWasPlayedWithUserActivationAndHighMediaEngagement,
+               void(bool));
   void Flush(base::OnceClosure flush_cb) override { OnFlush(flush_cb); }
   MOCK_METHOD1(OnFlush, void(base::OnceClosure& flush_cb));
   MOCK_METHOD1(StartPlayingFrom, void(base::TimeDelta timestamp));
diff --git a/media/base/pipeline.h b/media/base/pipeline.h
index 68896c9..81bcb8d 100644
--- a/media/base/pipeline.h
+++ b/media/base/pipeline.h
@@ -233,8 +233,8 @@
 
   // Sets a flag indicating whether the audio stream was played with user
   // activation.
-  virtual void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) = 0;
+  virtual void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) = 0;
 
   // Returns the current media playback time, which progresses from 0 until
   // GetMediaDuration().
diff --git a/media/base/pipeline_impl.cc b/media/base/pipeline_impl.cc
index b8de748..8a36e6d 100644
--- a/media/base/pipeline_impl.cc
+++ b/media/base/pipeline_impl.cc
@@ -92,7 +92,8 @@
   void SetVolume(float volume);
   void SetLatencyHint(std::optional<base::TimeDelta> latency_hint);
   void SetPreservesPitch(bool preserves_pitch);
-  void SetWasPlayedWithUserActivation(bool was_played_with_user_activation);
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement);
   base::TimeDelta GetMediaTime() const;
   Ranges<base::TimeDelta> GetBufferedTimeRanges() const;
   bool DidLoadingProgress();
@@ -236,7 +237,7 @@
   // By default, apply pitch adjustments.
   bool preserves_pitch_ = true;
 
-  bool was_played_with_user_activation_ = false;
+  bool was_played_with_user_activation_and_high_media_engagement_ = false;
 
   // Lock used to serialize |shared_state_|.
   // TODO(crbug.com/41419817): Add GUARDED_BY annotations.
@@ -544,14 +545,17 @@
     shared_state_.renderer->SetPreservesPitch(preserves_pitch_);
 }
 
-void PipelineImpl::RendererWrapper::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
+void PipelineImpl::RendererWrapper::
+    SetWasPlayedWithUserActivationAndHighMediaEngagement(
+        bool was_played_with_user_activation_and_high_media_engagement) {
   DCHECK(media_task_runner_->RunsTasksInCurrentSequence());
 
-  was_played_with_user_activation_ = was_played_with_user_activation;
+  was_played_with_user_activation_and_high_media_engagement_ =
+      was_played_with_user_activation_and_high_media_engagement;
   if (shared_state_.renderer) {
-    shared_state_.renderer->SetWasPlayedWithUserActivation(
-        was_played_with_user_activation_);
+    shared_state_.renderer
+        ->SetWasPlayedWithUserActivationAndHighMediaEngagement(
+            was_played_with_user_activation_and_high_media_engagement_);
   }
 }
 
@@ -1190,8 +1194,8 @@
   // power by avoiding initialization of audio output until necessary.
   shared_state_.renderer->SetVolume(volume_);
 
-  shared_state_.renderer->SetWasPlayedWithUserActivation(
-      was_played_with_user_activation_);
+  shared_state_.renderer->SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      was_played_with_user_activation_and_high_media_engagement_);
 
   // Initialize Renderer and report timeout UMA.
   std::string uma_name = "Media.InitializeRendererTimeout";
@@ -1527,15 +1531,17 @@
                                 preserves_pitch));
 }
 
-void PipelineImpl::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
+void PipelineImpl::SetWasPlayedWithUserActivationAndHighMediaEngagement(
+    bool was_played_with_user_activation_and_high_media_engagement) {
   DCHECK(thread_checker_.CalledOnValidThread());
 
   media_task_runner_->PostTask(
       FROM_HERE,
-      base::BindOnce(&RendererWrapper::SetWasPlayedWithUserActivation,
-                     base::Unretained(renderer_wrapper_.get()),
-                     was_played_with_user_activation));
+      base::BindOnce(
+          &RendererWrapper::
+              SetWasPlayedWithUserActivationAndHighMediaEngagement,
+          base::Unretained(renderer_wrapper_.get()),
+          was_played_with_user_activation_and_high_media_engagement));
 }
 
 base::TimeDelta PipelineImpl::GetMediaTime() const {
diff --git a/media/base/pipeline_impl.h b/media/base/pipeline_impl.h
index 27769b0a7..3493ca14 100644
--- a/media/base/pipeline_impl.h
+++ b/media/base/pipeline_impl.h
@@ -111,8 +111,8 @@
   void SetVolume(float volume) override;
   void SetLatencyHint(std::optional<base::TimeDelta> latency_hint) override;
   void SetPreservesPitch(bool preserves_pitch) override;
-  void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) override;
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) override;
   base::TimeDelta GetMediaTime() const override;
   Ranges<base::TimeDelta> GetBufferedTimeRanges() const override;
   base::TimeDelta GetMediaDuration() const override;
diff --git a/media/base/pipeline_impl_unittest.cc b/media/base/pipeline_impl_unittest.cc
index 1fa3b962..3555095c 100644
--- a/media/base/pipeline_impl_unittest.cc
+++ b/media/base/pipeline_impl_unittest.cc
@@ -185,7 +185,8 @@
   void SetRendererPostStartExpectations() {
     EXPECT_CALL(*renderer_, SetPlaybackRate(0.0));
     EXPECT_CALL(*renderer_, SetVolume(1.0f));
-    EXPECT_CALL(*renderer_, SetWasPlayedWithUserActivation(false));
+    EXPECT_CALL(*renderer_,
+                SetWasPlayedWithUserActivationAndHighMediaEngagement(false));
     EXPECT_CALL(*renderer_, StartPlayingFrom(start_time_))
         .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH,
                                     BUFFERING_CHANGE_REASON_UNKNOWN));
@@ -312,7 +313,8 @@
         .WillOnce(RunOnceCallback<1>(PIPELINE_OK));
     EXPECT_CALL(*renderer_, SetPlaybackRate(_));
     EXPECT_CALL(*renderer_, SetVolume(_));
-    EXPECT_CALL(*renderer_, SetWasPlayedWithUserActivation(false));
+    EXPECT_CALL(*renderer_,
+                SetWasPlayedWithUserActivationAndHighMediaEngagement(false));
     EXPECT_CALL(*renderer_, StartPlayingFrom(seek_time))
         .WillOnce(SetBufferingState(&renderer_client_, BUFFERING_HAVE_ENOUGH,
                                     BUFFERING_CHANGE_REASON_UNKNOWN));
@@ -648,7 +650,8 @@
   // The audio renderer should receive two calls to SetVolume().
   float expected = 0.5f;
   EXPECT_CALL(*renderer_, SetVolume(expected)).Times(2);
-  EXPECT_CALL(*renderer_, SetWasPlayedWithUserActivation(false));
+  EXPECT_CALL(*renderer_,
+              SetWasPlayedWithUserActivationAndHighMediaEngagement(false));
   EXPECT_CALL(callbacks_, OnStart(HasStatusCode(PIPELINE_OK)));
   EXPECT_CALL(callbacks_, OnMetadata(_))
       .WillOnce(RunOnceClosure(base::BindOnce(&PipelineImpl::SetVolume,
@@ -1053,7 +1056,8 @@
     CreateVideoStream();
     SetDemuxerExpectations(base::Seconds(3000));
     EXPECT_CALL(*renderer_, SetVolume(1.0f));
-    EXPECT_CALL(*renderer_, SetWasPlayedWithUserActivation(false));
+    EXPECT_CALL(*renderer_,
+                SetWasPlayedWithUserActivationAndHighMediaEngagement(false));
 
     if (state == kInitRenderer) {
       if (stop_or_error == kStop) {
diff --git a/media/base/renderer.cc b/media/base/renderer.cc
index 3a2d6a30..a8ad087 100644
--- a/media/base/renderer.cc
+++ b/media/base/renderer.cc
@@ -63,8 +63,8 @@
   // Not supported by most renderers.
 }
 
-void Renderer::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
+void Renderer::SetWasPlayedWithUserActivationAndHighMediaEngagement(
+    bool was_played_with_user_activation_and_high_media_engagement) {
   // Not supported by most renderers.
 }
 
diff --git a/media/base/renderer.h b/media/base/renderer.h
index c90c760..bfc0efd5 100644
--- a/media/base/renderer.h
+++ b/media/base/renderer.h
@@ -83,8 +83,8 @@
 
   // Sets a flag indicating whether the audio stream was played with user
   // activation.
-  virtual void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation);
+  virtual void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement);
 
   // The following functions must be called after Initialize().
 
diff --git a/media/cast/common/encoded_frame.h b/media/cast/common/encoded_frame.h
index 5690ba3..ef55d94 100644
--- a/media/cast/common/encoded_frame.h
+++ b/media/cast/common/encoded_frame.h
@@ -13,7 +13,7 @@
 #include "media/cast/cast_config.h"
 #include "media/cast/common/frame_id.h"
 #include "media/cast/common/rtp_time.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 namespace media {
 namespace cast {
diff --git a/media/cast/common/frame_id.h b/media/cast/common/frame_id.h
index a9ab2fa..c47cd330 100644
--- a/media/cast/common/frame_id.h
+++ b/media/cast/common/frame_id.h
@@ -5,7 +5,7 @@
 #ifndef MEDIA_CAST_COMMON_FRAME_ID_H_
 #define MEDIA_CAST_COMMON_FRAME_ID_H_
 
-#include "third_party/openscreen/src/cast/streaming/frame_id.h"
+#include "third_party/openscreen/src/cast/streaming/public/frame_id.h"
 
 namespace media::cast {
 
diff --git a/media/cast/common/openscreen_conversion_helpers.h b/media/cast/common/openscreen_conversion_helpers.h
index b153d40e..b4142d5 100644
--- a/media/cast/common/openscreen_conversion_helpers.h
+++ b/media/cast/common/openscreen_conversion_helpers.h
@@ -8,10 +8,10 @@
 #include "media/cast/common/sender_encoded_frame.h"
 #include "net/base/ip_address.h"
 #include "third_party/openscreen/src/cast/streaming/capture_configs.h"
-#include "third_party/openscreen/src/cast/streaming/constants.h"
-#include "third_party/openscreen/src/cast/streaming/offer_messages.h"
+#include "third_party/openscreen/src/cast/streaming/public/constants.h"
+#include "third_party/openscreen/src/cast/streaming/public/offer_messages.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 #include "third_party/openscreen/src/cast/streaming/rtp_time.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
 #include "third_party/openscreen/src/cast/streaming/sender_message.h"
 #include "third_party/openscreen/src/platform/api/time.h"
 #include "ui/gfx/geometry/size.h"
diff --git a/media/cast/common/openscreen_conversion_helpers_unittest.cc b/media/cast/common/openscreen_conversion_helpers_unittest.cc
index 36e830c..78bccf6 100644
--- a/media/cast/common/openscreen_conversion_helpers_unittest.cc
+++ b/media/cast/common/openscreen_conversion_helpers_unittest.cc
@@ -7,9 +7,9 @@
 #include "media/cast/cast_config.h"
 #include "media/cast/common/sender_encoded_frame.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 #include "third_party/openscreen/src/cast/streaming/rtp_time.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
 #include "third_party/openscreen/src/platform/api/time.h"
 
 namespace media::cast {
diff --git a/media/cast/encoding/audio_encoder.cc b/media/cast/encoding/audio_encoder.cc
index b9efb97..52229e5a 100644
--- a/media/cast/encoding/audio_encoder.cc
+++ b/media/cast/encoding/audio_encoder.cc
@@ -32,7 +32,7 @@
 #include "media/cast/common/rtp_time.h"
 #include "media/cast/common/sender_encoded_frame.h"
 #include "media/cast/constants.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 #include "third_party/opus/src/include/opus.h"
 
 #if BUILDFLAG(IS_APPLE)
diff --git a/media/cast/encoding/audio_encoder_unittest.cc b/media/cast/encoding/audio_encoder_unittest.cc
index 2a6dc1e..f88b712bc 100644
--- a/media/cast/encoding/audio_encoder_unittest.cc
+++ b/media/cast/encoding/audio_encoder_unittest.cc
@@ -28,7 +28,7 @@
 #include "media/cast/common/sender_encoded_frame.h"
 #include "media/cast/test/utility/audio_utility.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 namespace media {
 namespace cast {
diff --git a/media/cast/encoding/av1_encoder.cc b/media/cast/encoding/av1_encoder.cc
index 6f9969cc..eeeece3d 100644
--- a/media/cast/encoding/av1_encoder.cc
+++ b/media/cast/encoding/av1_encoder.cc
@@ -18,7 +18,7 @@
 #include "media/cast/constants.h"
 #include "media/cast/encoding/encoding_util.h"
 #include "third_party/libaom/source/libaom/aom/aomcx.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 namespace media {
 namespace cast {
diff --git a/media/cast/encoding/fake_software_video_encoder.cc b/media/cast/encoding/fake_software_video_encoder.cc
index 9e68bac..f09e9b59 100644
--- a/media/cast/encoding/fake_software_video_encoder.cc
+++ b/media/cast/encoding/fake_software_video_encoder.cc
@@ -14,7 +14,7 @@
 #include "media/cast/common/rtp_time.h"
 #include "media/cast/common/sender_encoded_frame.h"
 #include "media/cast/constants.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 using Dependency = openscreen::cast::EncodedFrame::Dependency;
 
diff --git a/media/cast/encoding/video_encoder_unittest.cc b/media/cast/encoding/video_encoder_unittest.cc
index d86110e..54a430b 100644
--- a/media/cast/encoding/video_encoder_unittest.cc
+++ b/media/cast/encoding/video_encoder_unittest.cc
@@ -32,7 +32,7 @@
 #include "media/cast/test/utility/default_config.h"
 #include "media/cast/test/utility/video_utility.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 namespace media {
 namespace cast {
diff --git a/media/cast/encoding/vpx_encoder.cc b/media/cast/encoding/vpx_encoder.cc
index 2e47f8f..e54b3a58 100644
--- a/media/cast/encoding/vpx_encoder.cc
+++ b/media/cast/encoding/vpx_encoder.cc
@@ -20,7 +20,7 @@
 #include "media/cast/constants.h"
 #include "media/cast/encoding/encoding_util.h"
 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 using Dependency = openscreen::cast::EncodedFrame::Dependency;
 
diff --git a/media/cast/encoding/vpx_quantizer_parser_unittest.cc b/media/cast/encoding/vpx_quantizer_parser_unittest.cc
index b516b72c..e471287 100644
--- a/media/cast/encoding/vpx_quantizer_parser_unittest.cc
+++ b/media/cast/encoding/vpx_quantizer_parser_unittest.cc
@@ -24,7 +24,7 @@
 #include "media/cast/test/utility/default_config.h"
 #include "media/cast/test/utility/video_utility.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 namespace media {
 namespace cast {
diff --git a/media/cast/openscreen/remoting_message_factories.h b/media/cast/openscreen/remoting_message_factories.h
index df56c38..3abf92cb 100644
--- a/media/cast/openscreen/remoting_message_factories.h
+++ b/media/cast/openscreen/remoting_message_factories.h
@@ -10,7 +10,7 @@
 #include "base/time/time.h"
 #include "media/base/buffering_state.h"
 #include "media/base/pipeline_status.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 namespace gfx {
 class Size;
diff --git a/media/cast/openscreen/rpc_call_message_handler.h b/media/cast/openscreen/rpc_call_message_handler.h
index dd8ad8ca..aef96fa 100644
--- a/media/cast/openscreen/rpc_call_message_handler.h
+++ b/media/cast/openscreen/rpc_call_message_handler.h
@@ -10,7 +10,7 @@
 #include "base/time/time.h"
 #include "media/base/audio_decoder_config.h"
 #include "media/base/video_decoder_config.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 namespace openscreen::cast {
 class RpcMessage;
diff --git a/media/cast/sender/audio_sender.cc b/media/cast/sender/audio_sender.cc
index e0be9e53..240e1a5 100644
--- a/media/cast/sender/audio_sender.cc
+++ b/media/cast/sender/audio_sender.cc
@@ -15,7 +15,7 @@
 #include "media/cast/common/sender_encoded_frame.h"
 #include "media/cast/encoding/audio_encoder.h"
 #include "media/cast/sender/frame_sender.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 
 namespace media::cast {
 namespace {
diff --git a/media/cast/sender/audio_sender_unittest.cc b/media/cast/sender/audio_sender_unittest.cc
index 53ca637..8428d5dc 100644
--- a/media/cast/sender/audio_sender_unittest.cc
+++ b/media/cast/sender/audio_sender_unittest.cc
@@ -28,8 +28,8 @@
 #include "media/cast/test/mock_openscreen_environment.h"
 #include "media/cast/test/utility/audio_utility.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/environment.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/environment.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 #include "third_party/openscreen/src/cast/streaming/sender_packet_router.h"
 #include "third_party/openscreen/src/platform/api/time.h"
 #include "third_party/openscreen/src/platform/base/ip_address.h"
diff --git a/media/cast/sender/openscreen_frame_sender.cc b/media/cast/sender/openscreen_frame_sender.cc
index 1bb66e65..7d26815 100644
--- a/media/cast/sender/openscreen_frame_sender.cc
+++ b/media/cast/sender/openscreen_frame_sender.cc
@@ -24,7 +24,7 @@
 #include "media/cast/common/openscreen_conversion_helpers.h"
 #include "media/cast/common/sender_encoded_frame.h"
 #include "media/cast/constants.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
 
 namespace media::cast {
 namespace {
diff --git a/media/cast/sender/openscreen_frame_sender.h b/media/cast/sender/openscreen_frame_sender.h
index 1a50047e..9debd31 100644
--- a/media/cast/sender/openscreen_frame_sender.h
+++ b/media/cast/sender/openscreen_frame_sender.h
@@ -19,7 +19,7 @@
 #include "media/cast/cast_environment.h"
 #include "media/cast/sender/frame_sender.h"
 #include "media/cast/sender/video_bitrate_suggester.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 
 namespace media::cast {
 
diff --git a/media/cast/sender/openscreen_frame_sender_unittest.cc b/media/cast/sender/openscreen_frame_sender_unittest.cc
index d9eedc5..98b2768ef 100644
--- a/media/cast/sender/openscreen_frame_sender_unittest.cc
+++ b/media/cast/sender/openscreen_frame_sender_unittest.cc
@@ -19,8 +19,8 @@
 #include "media/cast/common/openscreen_conversion_helpers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/environment.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/environment.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 #include "third_party/openscreen/src/cast/streaming/sender_packet_router.h"
 #include "third_party/openscreen/src/platform/api/time.h"
 #include "third_party/openscreen/src/platform/base/trivial_clock_traits.h"
diff --git a/media/cast/sender/video_sender.cc b/media/cast/sender/video_sender.cc
index 66488b9..4636363f6 100644
--- a/media/cast/sender/video_sender.cc
+++ b/media/cast/sender/video_sender.cc
@@ -5,6 +5,7 @@
 #include "media/cast/sender/video_sender.h"
 
 #include <stdint.h>
+
 #include <algorithm>
 #include <cmath>
 #include <cstring>
@@ -22,8 +23,8 @@
 #include "media/cast/encoding/video_encoder.h"
 #include "media/cast/sender/openscreen_frame_sender.h"
 #include "media/cast/sender/performance_metrics_overlay.h"
-#include "third_party/openscreen/src/cast/streaming/encoded_frame.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/encoded_frame.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 
 namespace media::cast {
 
diff --git a/media/cast/sender/video_sender_unittest.cc b/media/cast/sender/video_sender_unittest.cc
index 3d4830e..edc600b 100644
--- a/media/cast/sender/video_sender_unittest.cc
+++ b/media/cast/sender/video_sender_unittest.cc
@@ -35,9 +35,9 @@
 #include "media/video/fake_video_encode_accelerator.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/capture_recommendations.h"
-#include "third_party/openscreen/src/cast/streaming/environment.h"
-#include "third_party/openscreen/src/cast/streaming/sender.h"
+#include "third_party/openscreen/src/cast/streaming/public/capture_recommendations.h"
+#include "third_party/openscreen/src/cast/streaming/public/environment.h"
+#include "third_party/openscreen/src/cast/streaming/public/sender.h"
 #include "third_party/openscreen/src/cast/streaming/sender_packet_router.h"
 #include "third_party/openscreen/src/platform/api/time.h"
 
diff --git a/media/cast/test/mock_openscreen_environment.h b/media/cast/test/mock_openscreen_environment.h
index d87537760..0dbe593 100644
--- a/media/cast/test/mock_openscreen_environment.h
+++ b/media/cast/test/mock_openscreen_environment.h
@@ -6,7 +6,7 @@
 #define MEDIA_CAST_TEST_MOCK_OPENSCREEN_ENVIRONMENT_H_
 
 #include "testing/gmock/include/gmock/gmock.h"
-#include "third_party/openscreen/src/cast/streaming/environment.h"
+#include "third_party/openscreen/src/cast/streaming/public/environment.h"
 
 namespace media::cast {
 
diff --git a/media/cdm/cenc_utils_fuzzertest.cc b/media/cdm/cenc_utils_fuzzertest.cc
index 759dcc5..d03fae3 100644
--- a/media/cdm/cenc_utils_fuzzertest.cc
+++ b/media/cdm/cenc_utils_fuzzertest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include <stddef.h>
 #include <stdint.h>
 #include <vector>
diff --git a/media/cdm/cenc_utils_unittest.cc b/media/cdm/cenc_utils_unittest.cc
index d8c90fa..f50f083 100644
--- a/media/cdm/cenc_utils_unittest.cc
+++ b/media/cdm/cenc_utils_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/cdm/cenc_utils.h"
 
 #include <stddef.h>
diff --git a/media/filters/ffmpeg_aac_bitstream_converter.cc b/media/filters/ffmpeg_aac_bitstream_converter.cc
index ad9a8c82..e26b6cd 100644
--- a/media/filters/ffmpeg_aac_bitstream_converter.cc
+++ b/media/filters/ffmpeg_aac_bitstream_converter.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/filters/ffmpeg_aac_bitstream_converter.h"
 
 #include "base/logging.h"
diff --git a/media/filters/ffmpeg_aac_bitstream_converter_unittest.cc b/media/filters/ffmpeg_aac_bitstream_converter_unittest.cc
index 093a5779..1897eb09 100644
--- a/media/filters/ffmpeg_aac_bitstream_converter_unittest.cc
+++ b/media/filters/ffmpeg_aac_bitstream_converter_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include <stddef.h>
 #include <stdint.h>
 
diff --git a/media/filters/ffmpeg_h265_to_annex_b_bitstream_converter.cc b/media/filters/ffmpeg_h265_to_annex_b_bitstream_converter.cc
index cfbbb89..8de8c46 100644
--- a/media/filters/ffmpeg_h265_to_annex_b_bitstream_converter.cc
+++ b/media/filters/ffmpeg_h265_to_annex_b_bitstream_converter.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/filters/ffmpeg_h265_to_annex_b_bitstream_converter.h"
 
 #include <stdint.h>
diff --git a/media/filters/h264_to_annex_b_bitstream_converter.cc b/media/filters/h264_to_annex_b_bitstream_converter.cc
index 01069114..74f552055 100644
--- a/media/filters/h264_to_annex_b_bitstream_converter.cc
+++ b/media/filters/h264_to_annex_b_bitstream_converter.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/filters/h264_to_annex_b_bitstream_converter.h"
 
 #include <stddef.h>
diff --git a/media/filters/h265_to_annex_b_bitstream_converter.cc b/media/filters/h265_to_annex_b_bitstream_converter.cc
index 6bd4c8e..640b481c 100644
--- a/media/filters/h265_to_annex_b_bitstream_converter.cc
+++ b/media/filters/h265_to_annex_b_bitstream_converter.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/filters/h265_to_annex_b_bitstream_converter.h"
 
 #include <stddef.h>
diff --git a/media/filters/hls_data_source_provider.cc b/media/filters/hls_data_source_provider.cc
index 11f4fb8..ad2b7fc68 100644
--- a/media/filters/hls_data_source_provider.cc
+++ b/media/filters/hls_data_source_provider.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/filters/hls_data_source_provider.h"
 #include "base/trace_event/trace_event.h"
 
diff --git a/media/filters/hls_manifest_demuxer_engine.cc b/media/filters/hls_manifest_demuxer_engine.cc
index c8e0589..b933a3e 100644
--- a/media/filters/hls_manifest_demuxer_engine.cc
+++ b/media/filters/hls_manifest_demuxer_engine.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/filters/hls_manifest_demuxer_engine.h"
 
 #include <optional>
diff --git a/media/filters/hls_rendition_impl.cc b/media/filters/hls_rendition_impl.cc
index 45dea50a..02b897d 100644
--- a/media/filters/hls_rendition_impl.cc
+++ b/media/filters/hls_rendition_impl.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/filters/hls_rendition_impl.h"
 
 #include "base/task/bind_post_task.h"
diff --git a/media/filters/pipeline_controller.cc b/media/filters/pipeline_controller.cc
index b92038b..74dd2e0 100644
--- a/media/filters/pipeline_controller.cc
+++ b/media/filters/pipeline_controller.cc
@@ -399,9 +399,10 @@
   pipeline_->SetPreservesPitch(preserves_pitch);
 }
 
-void PipelineController::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
-  pipeline_->SetWasPlayedWithUserActivation(was_played_with_user_activation);
+void PipelineController::SetWasPlayedWithUserActivationAndHighMediaEngagement(
+    bool was_played_with_user_activation_and_high_media_engagement) {
+  pipeline_->SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      was_played_with_user_activation_and_high_media_engagement);
 }
 
 base::TimeDelta PipelineController::GetMediaTime() const {
diff --git a/media/filters/pipeline_controller.h b/media/filters/pipeline_controller.h
index 35e03a79..6243bba 100644
--- a/media/filters/pipeline_controller.h
+++ b/media/filters/pipeline_controller.h
@@ -139,7 +139,8 @@
   void SetVolume(float volume);
   void SetLatencyHint(std::optional<base::TimeDelta> latency_hint);
   void SetPreservesPitch(bool preserves_pitch);
-  void SetWasPlayedWithUserActivation(bool was_played_with_user_activation);
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement);
   base::TimeDelta GetMediaTime() const;
   Ranges<base::TimeDelta> GetBufferedTimeRanges() const;
   base::TimeDelta GetMediaDuration() const;
diff --git a/media/formats/mp2t/descriptors.cc b/media/formats/mp2t/descriptors.cc
index 6c2eb9c..94c967fb 100644
--- a/media/formats/mp2t/descriptors.cc
+++ b/media/formats/mp2t/descriptors.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/descriptors.h"
 
 #include <vector>
diff --git a/media/formats/mp2t/es_adapter_video_unittest.cc b/media/formats/mp2t/es_adapter_video_unittest.cc
index 1882780..a7d3be73 100644
--- a/media/formats/mp2t/es_adapter_video_unittest.cc
+++ b/media/formats/mp2t/es_adapter_video_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/es_adapter_video.h"
 
 #include <stddef.h>
diff --git a/media/formats/mp2t/es_parser.cc b/media/formats/mp2t/es_parser.cc
index b66f551..1bf00d39 100644
--- a/media/formats/mp2t/es_parser.cc
+++ b/media/formats/mp2t/es_parser.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/es_parser.h"
 
 #include "base/logging.h"
diff --git a/media/formats/mp2t/es_parser_adts.cc b/media/formats/mp2t/es_parser_adts.cc
index dea858d..e16cd9e 100644
--- a/media/formats/mp2t/es_parser_adts.cc
+++ b/media/formats/mp2t/es_parser_adts.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/es_parser_adts.h"
 
 #include <stddef.h>
diff --git a/media/formats/mp2t/es_parser_h264.cc b/media/formats/mp2t/es_parser_h264.cc
index 1064355..b75fc95 100644
--- a/media/formats/mp2t/es_parser_h264.cc
+++ b/media/formats/mp2t/es_parser_h264.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/es_parser_h264.h"
 
 #include <limits>
diff --git a/media/formats/mp2t/es_parser_mpeg1audio.cc b/media/formats/mp2t/es_parser_mpeg1audio.cc
index 597e7ca..6cd645fd 100644
--- a/media/formats/mp2t/es_parser_mpeg1audio.cc
+++ b/media/formats/mp2t/es_parser_mpeg1audio.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/es_parser_mpeg1audio.h"
 
 #include <vector>
diff --git a/media/formats/mp2t/es_parser_test_base.cc b/media/formats/mp2t/es_parser_test_base.cc
index acc95d3..414275e 100644
--- a/media/formats/mp2t/es_parser_test_base.cc
+++ b/media/formats/mp2t/es_parser_test_base.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/es_parser_test_base.h"
 
 #include "base/check_op.h"
diff --git a/media/formats/mp2t/mp2t_stream_parser.cc b/media/formats/mp2t/mp2t_stream_parser.cc
index ab1ad25..e89c0a3c 100644
--- a/media/formats/mp2t/mp2t_stream_parser.cc
+++ b/media/formats/mp2t/mp2t_stream_parser.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/mp2t_stream_parser.h"
 
 #include <memory>
diff --git a/media/formats/mp2t/mp2t_stream_parser_unittest.cc b/media/formats/mp2t/mp2t_stream_parser_unittest.cc
index abfa59c..0d0411b 100644
--- a/media/formats/mp2t/mp2t_stream_parser_unittest.cc
+++ b/media/formats/mp2t/mp2t_stream_parser_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/mp2t_stream_parser.h"
 
 #include <openssl/aes.h>
diff --git a/media/formats/mp2t/timestamp_unroller_unittest.cc b/media/formats/mp2t/timestamp_unroller_unittest.cc
index 98f3b1b5..cc2f999 100644
--- a/media/formats/mp2t/timestamp_unroller_unittest.cc
+++ b/media/formats/mp2t/timestamp_unroller_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/timestamp_unroller.h"
 
 #include <stddef.h>
diff --git a/media/formats/mp2t/ts_packet.cc b/media/formats/mp2t/ts_packet.cc
index 79a5202a..5a28e4d 100644
--- a/media/formats/mp2t/ts_packet.cc
+++ b/media/formats/mp2t/ts_packet.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/ts_packet.h"
 
 #include <memory>
diff --git a/media/formats/mp2t/ts_section_pes.cc b/media/formats/mp2t/ts_section_pes.cc
index bb3b8c399..e97a710a 100644
--- a/media/formats/mp2t/ts_section_pes.cc
+++ b/media/formats/mp2t/ts_section_pes.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/ts_section_pes.h"
 
 #include <memory>
diff --git a/media/formats/mp2t/ts_section_psi.cc b/media/formats/mp2t/ts_section_psi.cc
index b951568d..ed2b03b 100644
--- a/media/formats/mp2t/ts_section_psi.cc
+++ b/media/formats/mp2t/ts_section_psi.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp2t/ts_section_psi.h"
 
 #include <algorithm>
diff --git a/media/formats/mp4/aac.cc b/media/formats/mp4/aac.cc
index ae3c469..eae8efdff 100644
--- a/media/formats/mp4/aac.cc
+++ b/media/formats/mp4/aac.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/aac.h"
 
 #include <stddef.h>
diff --git a/media/formats/mp4/aac_unittest.cc b/media/formats/mp4/aac_unittest.cc
index d35680b0..c73dd4f 100644
--- a/media/formats/mp4/aac_unittest.cc
+++ b/media/formats/mp4/aac_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include <stdint.h>
 
 #include <string>
diff --git a/media/formats/mp4/ac3.cc b/media/formats/mp4/ac3.cc
index dd900cd..e884cec 100644
--- a/media/formats/mp4/ac3.cc
+++ b/media/formats/mp4/ac3.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/ac3.h"
 
 #include <algorithm>
diff --git a/media/formats/mp4/avc.cc b/media/formats/mp4/avc.cc
index 47f105b..0990467 100644
--- a/media/formats/mp4/avc.cc
+++ b/media/formats/mp4/avc.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/avc.h"
 
 #include <memory>
diff --git a/media/formats/mp4/avc_unittest.cc b/media/formats/mp4/avc_unittest.cc
index 4828cd0..f05d3991 100644
--- a/media/formats/mp4/avc_unittest.cc
+++ b/media/formats/mp4/avc_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/avc.h"
 
 #include <stddef.h>
diff --git a/media/formats/mp4/box_reader_unittest.cc b/media/formats/mp4/box_reader_unittest.cc
index 50d7f64..0676d98 100644
--- a/media/formats/mp4/box_reader_unittest.cc
+++ b/media/formats/mp4/box_reader_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/box_reader.h"
 
 #include <stdint.h>
diff --git a/media/formats/mp4/eac3.cc b/media/formats/mp4/eac3.cc
index 6b808282..6998491 100644
--- a/media/formats/mp4/eac3.cc
+++ b/media/formats/mp4/eac3.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/eac3.h"
 
 #include <algorithm>
diff --git a/media/formats/mp4/es_descriptor_unittest.cc b/media/formats/mp4/es_descriptor_unittest.cc
index 94bac2a..04e9eae 100644
--- a/media/formats/mp4/es_descriptor_unittest.cc
+++ b/media/formats/mp4/es_descriptor_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/es_descriptor.h"
 
 #include <stdint.h>
diff --git a/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter_fuzztest.cc b/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter_fuzztest.cc
index 28daaab..5e7d0c44 100644
--- a/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter_fuzztest.cc
+++ b/media/formats/mp4/h264_annex_b_to_avc_bitstream_converter_fuzztest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include <stdint.h>
 
 #include <memory>
diff --git a/media/formats/mp4/hevc.cc b/media/formats/mp4/hevc.cc
index 024aff9..db812462 100644
--- a/media/formats/mp4/hevc.cc
+++ b/media/formats/mp4/hevc.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/hevc.h"
 
 #include <algorithm>
diff --git a/media/formats/mp4/hevc_unittest.cc b/media/formats/mp4/hevc_unittest.cc
index d9cdf73..7920699 100644
--- a/media/formats/mp4/hevc_unittest.cc
+++ b/media/formats/mp4/hevc_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/hevc.h"
 
 #include "media/formats/mp4/nalu_test_helper.h"
diff --git a/media/formats/mp4/mp4_stream_parser_unittest.cc b/media/formats/mp4/mp4_stream_parser_unittest.cc
index a5953048..11924074 100644
--- a/media/formats/mp4/mp4_stream_parser_unittest.cc
+++ b/media/formats/mp4/mp4_stream_parser_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/mp4_stream_parser.h"
 
 #include <stddef.h>
diff --git a/media/formats/mp4/sample_to_group_iterator_unittest.cc b/media/formats/mp4/sample_to_group_iterator_unittest.cc
index 3f94267..fa99954 100644
--- a/media/formats/mp4/sample_to_group_iterator_unittest.cc
+++ b/media/formats/mp4/sample_to_group_iterator_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/sample_to_group_iterator.h"
 
 #include <stddef.h>
diff --git a/media/formats/mp4/track_run_iterator_unittest.cc b/media/formats/mp4/track_run_iterator_unittest.cc
index 22874d2..6cd2646 100644
--- a/media/formats/mp4/track_run_iterator_unittest.cc
+++ b/media/formats/mp4/track_run_iterator_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mp4/track_run_iterator.h"
 
 #include <stddef.h>
diff --git a/media/formats/mpeg/adts_stream_parser.cc b/media/formats/mpeg/adts_stream_parser.cc
index 5e0b48bd..a406375 100644
--- a/media/formats/mpeg/adts_stream_parser.cc
+++ b/media/formats/mpeg/adts_stream_parser.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/formats/mpeg/adts_stream_parser.h"
 
 #include <stddef.h>
diff --git a/media/gpu/android/ndk_audio_encoder.cc b/media/gpu/android/ndk_audio_encoder.cc
index 6084e78..26478c1a 100644
--- a/media/gpu/android/ndk_audio_encoder.cc
+++ b/media/gpu/android/ndk_audio_encoder.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/gpu/android/ndk_audio_encoder.h"
 
 #include <aaudio/AAudio.h>
diff --git a/media/gpu/h265_builder.cc b/media/gpu/h265_builder.cc
index a3b4864d4..44e716f9 100644
--- a/media/gpu/h265_builder.cc
+++ b/media/gpu/h265_builder.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/gpu/h265_builder.h"
 #include "media/filters/h26x_annex_b_bitstream_builder.h"
 
diff --git a/media/gpu/h265_decoder.cc b/media/gpu/h265_decoder.cc
index 71266331..8f72aa9 100644
--- a/media/gpu/h265_decoder.cc
+++ b/media/gpu/h265_decoder.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/gpu/h265_decoder.h"
 
 #include <algorithm>
diff --git a/media/gpu/h265_decoder_fuzzer.cc b/media/gpu/h265_decoder_fuzzer.cc
index 36f3866..0e60dab 100644
--- a/media/gpu/h265_decoder_fuzzer.cc
+++ b/media/gpu/h265_decoder_fuzzer.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/gpu/h265_decoder.h"
 
 #include <stddef.h>
diff --git a/media/gpu/mac/video_toolbox_h265_accelerator.cc b/media/gpu/mac/video_toolbox_h265_accelerator.cc
index 7efe77b..b8c3a9d 100644
--- a/media/gpu/mac/video_toolbox_h265_accelerator.cc
+++ b/media/gpu/mac/video_toolbox_h265_accelerator.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/gpu/mac/video_toolbox_h265_accelerator.h"
 
 #include <array>
diff --git a/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.cc b/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.cc
index 0b8c62308..0bfc9ee1 100644
--- a/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.cc
+++ b/media/gpu/vaapi/h265_vaapi_video_decoder_delegate.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/gpu/vaapi/h265_vaapi_video_decoder_delegate.h"
 
 #include "build/chromeos_buildflags.h"
diff --git a/media/gpu/vaapi/test/h265_decoder.cc b/media/gpu/vaapi/test/h265_decoder.cc
index a7d6356..d1dc262d 100644
--- a/media/gpu/vaapi/test/h265_decoder.cc
+++ b/media/gpu/vaapi/test/h265_decoder.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/gpu/vaapi/test/h265_decoder.h"
 
 #include <algorithm>
diff --git a/media/gpu/vaapi/test/h265_vaapi_wrapper.cc b/media/gpu/vaapi/test/h265_vaapi_wrapper.cc
index 8c30e20..198c90a 100644
--- a/media/gpu/vaapi/test/h265_vaapi_wrapper.cc
+++ b/media/gpu/vaapi/test/h265_vaapi_wrapper.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/gpu/vaapi/test/h265_vaapi_wrapper.h"
 
 #include "build/chromeos_buildflags.h"
diff --git a/media/gpu/windows/d3d11_h265_accelerator.cc b/media/gpu/windows/d3d11_h265_accelerator.cc
index c9a7c3c..a5892d2 100644
--- a/media/gpu/windows/d3d11_h265_accelerator.cc
+++ b/media/gpu/windows/d3d11_h265_accelerator.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/gpu/windows/d3d11_h265_accelerator.h"
 
 #include <algorithm>
diff --git a/media/muxers/mp4_muxer_delegate.cc b/media/muxers/mp4_muxer_delegate.cc
index ecd7437..299f329 100644
--- a/media/muxers/mp4_muxer_delegate.cc
+++ b/media/muxers/mp4_muxer_delegate.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/muxers/mp4_muxer_delegate.h"
 
 #include "base/logging.h"
diff --git a/media/muxers/mp4_muxer_delegate_unittest.cc b/media/muxers/mp4_muxer_delegate_unittest.cc
index acc1553c..89a51ed 100644
--- a/media/muxers/mp4_muxer_delegate_unittest.cc
+++ b/media/muxers/mp4_muxer_delegate_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/muxers/mp4_muxer_delegate.h"
 
 #include <algorithm>
diff --git a/media/parsers/h264_bit_reader.cc b/media/parsers/h264_bit_reader.cc
index 81a5178..fd77d320 100644
--- a/media/parsers/h264_bit_reader.cc
+++ b/media/parsers/h264_bit_reader.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/parsers/h264_bit_reader.h"
 #include "base/check.h"
 
diff --git a/media/parsers/h265_nalu_parser.cc b/media/parsers/h265_nalu_parser.cc
index b6f1dd6..14b50d8 100644
--- a/media/parsers/h265_nalu_parser.cc
+++ b/media/parsers/h265_nalu_parser.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/parsers/h265_nalu_parser.h"
 
 #include <stddef.h>
diff --git a/media/parsers/h265_parser.cc b/media/parsers/h265_parser.cc
index b6211fa..2471638 100644
--- a/media/parsers/h265_parser.cc
+++ b/media/parsers/h265_parser.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/parsers/h265_parser.h"
 
 #include <stddef.h>
diff --git a/media/parsers/h265_parser_unittest.cc b/media/parsers/h265_parser_unittest.cc
index 06d35226..d80bb66 100644
--- a/media/parsers/h265_parser_unittest.cc
+++ b/media/parsers/h265_parser_unittest.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include <memory>
 #include <string>
 
diff --git a/media/remoting/courier_renderer.h b/media/remoting/courier_renderer.h
index 5dbf5d7..98ebe75b 100644
--- a/media/remoting/courier_renderer.h
+++ b/media/remoting/courier_renderer.h
@@ -26,8 +26,8 @@
 #include "media/remoting/metrics.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/system/data_pipe.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 #include "third_party/openscreen/src/cast/streaming/remoting.pb.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
 #include "third_party/openscreen/src/util/weak_ptr.h"
 
 namespace media {
diff --git a/media/remoting/courier_renderer_unittest.cc b/media/remoting/courier_renderer_unittest.cc
index 7110d9b..b309560 100644
--- a/media/remoting/courier_renderer_unittest.cc
+++ b/media/remoting/courier_renderer_unittest.cc
@@ -25,7 +25,7 @@
 #include "media/remoting/renderer_controller.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 using openscreen::cast::RpcMessenger;
 using testing::_;
diff --git a/media/remoting/demuxer_stream_adapter.h b/media/remoting/demuxer_stream_adapter.h
index fb994e9..9affe85 100644
--- a/media/remoting/demuxer_stream_adapter.h
+++ b/media/remoting/demuxer_stream_adapter.h
@@ -25,7 +25,7 @@
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/system/data_pipe.h"
 #include "mojo/public/cpp/system/simple_watcher.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 #include "third_party/openscreen/src/util/weak_ptr.h"
 
 namespace base {
diff --git a/media/remoting/end2end_test_renderer.h b/media/remoting/end2end_test_renderer.h
index cf73d49..8b3046dc 100644
--- a/media/remoting/end2end_test_renderer.h
+++ b/media/remoting/end2end_test_renderer.h
@@ -14,7 +14,7 @@
 #include "media/base/demuxer_stream.h"
 #include "media/base/renderer.h"
 #include "media/remoting/stream_provider.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 namespace media {
 
diff --git a/media/remoting/receiver.h b/media/remoting/receiver.h
index 900c1c3..c42b4e3 100644
--- a/media/remoting/receiver.h
+++ b/media/remoting/receiver.h
@@ -19,8 +19,8 @@
 #include "media/base/renderer.h"
 #include "media/base/renderer_client.h"
 #include "media/cast/openscreen/rpc_call_message_handler.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 #include "third_party/openscreen/src/cast/streaming/remoting.pb.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
 
 namespace openscreen {
 namespace cast {
diff --git a/media/remoting/receiver_controller.h b/media/remoting/receiver_controller.h
index f847467..81d8e3e 100644
--- a/media/remoting/receiver_controller.h
+++ b/media/remoting/receiver_controller.h
@@ -13,7 +13,7 @@
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 namespace media {
 namespace remoting {
diff --git a/media/remoting/remoting_renderer_factory.h b/media/remoting/remoting_renderer_factory.h
index 142e470b0..1cb64960 100644
--- a/media/remoting/remoting_renderer_factory.h
+++ b/media/remoting/remoting_renderer_factory.h
@@ -10,7 +10,7 @@
 #include "media/base/renderer_factory.h"
 #include "media/mojo/mojom/remoting.mojom.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 namespace media {
 namespace remoting {
diff --git a/media/remoting/renderer_controller.h b/media/remoting/renderer_controller.h
index dd365cb..9e816f8 100644
--- a/media/remoting/renderer_controller.h
+++ b/media/remoting/renderer_controller.h
@@ -25,7 +25,7 @@
 #include "mojo/public/cpp/bindings/remote.h"
 
 #if BUILDFLAG(ENABLE_MEDIA_REMOTING_RPC)
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"  // nogncheck
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"  // nogncheck
 #include "third_party/openscreen/src/util/weak_ptr.h"  // nogncheck
 #endif
 
diff --git a/media/remoting/stream_provider.cc b/media/remoting/stream_provider.cc
index 778b690..2f8aa45 100644
--- a/media/remoting/stream_provider.cc
+++ b/media/remoting/stream_provider.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "media/remoting/stream_provider.h"
+
 #include <vector>
 
 #include "base/containers/circular_deque.h"
@@ -21,7 +22,7 @@
 #include "media/cast/openscreen/remoting_proto_utils.h"
 #include "media/mojo/common/mojo_decoder_buffer_converter.h"
 #include "media/remoting/receiver_controller.h"
-#include "third_party/openscreen/src/cast/streaming/rpc_messenger.h"
+#include "third_party/openscreen/src/cast/streaming/public/rpc_messenger.h"
 
 using openscreen::cast::RpcMessenger;
 
diff --git a/media/renderers/audio_renderer_impl.cc b/media/renderers/audio_renderer_impl.cc
index f989ff3..ee72a61 100644
--- a/media/renderers/audio_renderer_impl.cc
+++ b/media/renderers/audio_renderer_impl.cc
@@ -865,10 +865,11 @@
     algorithm_->SetPreservesPitch(preserves_pitch);
 }
 
-void AudioRendererImpl::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
+void AudioRendererImpl::SetWasPlayedWithUserActivationAndHighMediaEngagement(
+    bool was_played_with_user_activation_and_high_media_engagement) {
   base::AutoLock auto_lock(lock_);
-  was_played_with_user_activation_ = was_played_with_user_activation;
+  was_played_with_user_activation_and_high_media_engagement_ =
+      was_played_with_user_activation_and_high_media_engagement;
 }
 
 void AudioRendererImpl::OnSuspend() {
@@ -1067,7 +1068,8 @@
     // Do not transcribe muted streams initiated by autoplay if the stream was
     // never unmuted.
     if (transcribe_audio_callback_ &&
-        (was_played_with_user_activation_ || was_unmuted_)) {
+        (was_played_with_user_activation_and_high_media_engagement_ ||
+         was_unmuted_)) {
       transcribe_audio_callback_.Run(buffer);
     }
 #endif
diff --git a/media/renderers/audio_renderer_impl.h b/media/renderers/audio_renderer_impl.h
index 8c3e96aea..a09c576 100644
--- a/media/renderers/audio_renderer_impl.h
+++ b/media/renderers/audio_renderer_impl.h
@@ -108,8 +108,8 @@
   void SetVolume(float volume) override;
   void SetLatencyHint(std::optional<base::TimeDelta> latency_hint) override;
   void SetPreservesPitch(bool preserves_pitch) override;
-  void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) override;
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) override;
 
   // base::PowerSuspendObserver implementation.
   void OnSuspend() override;
@@ -338,7 +338,7 @@
   // make pitch adjustments at playbacks other than 1.0.
   bool preserves_pitch_ = true;
 
-  bool was_played_with_user_activation_ = false;
+  bool was_played_with_user_activation_and_high_media_engagement_ = false;
 
   // Simple state tracking variable.
   State state_;
diff --git a/media/renderers/audio_renderer_impl_unittest.cc b/media/renderers/audio_renderer_impl_unittest.cc
index efaf1cfe..77230b2 100644
--- a/media/renderers/audio_renderer_impl_unittest.cc
+++ b/media/renderers/audio_renderer_impl_unittest.cc
@@ -1915,7 +1915,7 @@
 TEST_F(AudioRendererImplTest,
        TranscribeAudioCallback_Muted_WithUserActivation) {
   EnableSpeechRecognition();
-  renderer_->SetWasPlayedWithUserActivation(true);
+  renderer_->SetWasPlayedWithUserActivationAndHighMediaEngagement(true);
 
   EXPECT_CALL(*this, SetOnReadyCallback(_));
   Initialize();
diff --git a/media/renderers/decrypting_renderer.cc b/media/renderers/decrypting_renderer.cc
index 1fe5a28..5ca8ec1c 100644
--- a/media/renderers/decrypting_renderer.cc
+++ b/media/renderers/decrypting_renderer.cc
@@ -116,9 +116,10 @@
   renderer_->SetPreservesPitch(preserves_pitch);
 }
 
-void DecryptingRenderer::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
-  renderer_->SetWasPlayedWithUserActivation(was_played_with_user_activation);
+void DecryptingRenderer::SetWasPlayedWithUserActivationAndHighMediaEngagement(
+    bool was_played_with_user_activation_and_high_media_engagement) {
+  renderer_->SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      was_played_with_user_activation_and_high_media_engagement);
 }
 
 void DecryptingRenderer::Flush(base::OnceClosure flush_cb) {
diff --git a/media/renderers/decrypting_renderer.h b/media/renderers/decrypting_renderer.h
index 44112cd3..47d96b49 100644
--- a/media/renderers/decrypting_renderer.h
+++ b/media/renderers/decrypting_renderer.h
@@ -53,8 +53,8 @@
   void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
   void SetLatencyHint(std::optional<base::TimeDelta> latency_hint) override;
   void SetPreservesPitch(bool preserves_pitch) override;
-  void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) override;
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) override;
 
   void Flush(base::OnceClosure flush_cb) override;
   void StartPlayingFrom(base::TimeDelta time) override;
diff --git a/media/renderers/renderer_impl.cc b/media/renderers/renderer_impl.cc
index 8ecbf0f..2f4d1309 100644
--- a/media/renderers/renderer_impl.cc
+++ b/media/renderers/renderer_impl.cc
@@ -203,14 +203,14 @@
     audio_renderer_->SetPreservesPitch(preserves_pitch);
 }
 
-void RendererImpl::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
+void RendererImpl::SetWasPlayedWithUserActivationAndHighMediaEngagement(
+    bool was_played_with_user_activation_and_high_media_engagement) {
   DVLOG(1) << __func__;
   DCHECK(task_runner_->RunsTasksInCurrentSequence());
 
   if (audio_renderer_)
-    audio_renderer_->SetWasPlayedWithUserActivation(
-        was_played_with_user_activation);
+    audio_renderer_->SetWasPlayedWithUserActivationAndHighMediaEngagement(
+        was_played_with_user_activation_and_high_media_engagement);
 }
 
 void RendererImpl::Flush(base::OnceClosure flush_cb) {
diff --git a/media/renderers/renderer_impl.h b/media/renderers/renderer_impl.h
index 253995a..431dc1f 100644
--- a/media/renderers/renderer_impl.h
+++ b/media/renderers/renderer_impl.h
@@ -59,8 +59,8 @@
   void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) final;
   void SetLatencyHint(std::optional<base::TimeDelta> latency_hint) final;
   void SetPreservesPitch(bool preserves_pitch) final;
-  void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) final;
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) final;
   void Flush(base::OnceClosure flush_cb) final;
   void StartPlayingFrom(base::TimeDelta time) final;
   void SetPlaybackRate(double playback_rate) final;
diff --git a/media/renderers/win/media_foundation_audio_stream.cc b/media/renderers/win/media_foundation_audio_stream.cc
index 06ed8aa3..0426c98 100644
--- a/media/renderers/win/media_foundation_audio_stream.cc
+++ b/media/renderers/win/media_foundation_audio_stream.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/renderers/win/media_foundation_audio_stream.h"
 
 #include <mferror.h>
diff --git a/media/video/openh264_video_encoder.cc b/media/video/openh264_video_encoder.cc
index a92ddad..7b032065 100644
--- a/media/video/openh264_video_encoder.cc
+++ b/media/video/openh264_video_encoder.cc
@@ -2,11 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifdef UNSAFE_BUFFERS_BUILD
-// TODO(crbug.com/40285824): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "media/video/openh264_video_encoder.h"
 
 #include <algorithm>
diff --git a/net/BUILD.gn b/net/BUILD.gn
index e4a2a4b..63fa07e1 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1174,6 +1174,8 @@
       "device_bound_sessions/session.h",
       "device_bound_sessions/session_binding_utils.cc",
       "device_bound_sessions/session_binding_utils.h",
+      "device_bound_sessions/session_challenge_param.cc",
+      "device_bound_sessions/session_challenge_param.h",
       "device_bound_sessions/session_inclusion_rules.cc",
       "device_bound_sessions/session_inclusion_rules.h",
       "device_bound_sessions/session_json_utils.cc",
@@ -3318,6 +3320,7 @@
       "device_bound_sessions/registration_fetcher_param_unittest.cc",
       "device_bound_sessions/registration_fetcher_unittest.cc",
       "device_bound_sessions/session_binding_utils_unittest.cc",
+      "device_bound_sessions/session_challenge_param_unittest.cc",
       "device_bound_sessions/session_inclusion_rules_unittest.cc",
       "device_bound_sessions/session_service_impl_unittest.cc",
       "device_bound_sessions/session_service_unittest.cc",
diff --git a/net/base/proxy_string_util.cc b/net/base/proxy_string_util.cc
index 5c8d6c6..08f0a6b 100644
--- a/net/base/proxy_string_util.cc
+++ b/net/base/proxy_string_util.cc
@@ -70,7 +70,7 @@
   // And everything to the right of the space is the
   // <host>[":" <port>].
   std::string_view host_and_port = pac_result_element.substr(space);
-  return std::make_tuple(std::move(scheme), std::move(host_and_port));
+  return std::make_tuple(scheme, host_and_port);
 }
 
 }  // namespace
diff --git a/net/device_bound_sessions/session.h b/net/device_bound_sessions/session.h
index f4b3d61..7c442e2e 100644
--- a/net/device_bound_sessions/session.h
+++ b/net/device_bound_sessions/session.h
@@ -8,6 +8,7 @@
 #include <memory>
 #include <optional>
 #include <string>
+#include <string_view>
 
 #include "base/types/strong_alias.h"
 #include "components/unexportable_keys/service_error.h"
@@ -47,10 +48,18 @@
 
   const GURL& refresh_url() const { return refresh_url_; }
 
+  const std::optional<std::string>& cached_challenge() const {
+    return cached_challenge_;
+  }
+
   bool should_defer_when_expired() const { return should_defer_when_expired_; }
 
   bool IsEqualForTesting(const Session& other) const;
 
+  void set_cached_challenge(std::string challenge) {
+    cached_challenge_ = std::move(challenge);
+  }
+
  private:
   Session(Id id, url::Origin origin, GURL refresh);
   Session(Id id,
diff --git a/net/device_bound_sessions/session_challenge_param.cc b/net/device_bound_sessions/session_challenge_param.cc
new file mode 100644
index 0000000..4e42c19
--- /dev/null
+++ b/net/device_bound_sessions/session_challenge_param.cc
@@ -0,0 +1,104 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/device_bound_sessions/session_challenge_param.h"
+
+#include <optional>
+
+#include "base/ranges/algorithm.h"
+#include "net/http/http_response_headers.h"
+#include "net/http/structured_headers.h"
+
+namespace {
+// Sec-Session-Challenge header defined in
+// https://github.com/WICG/dbsc/blob/main/README.md#high-level-overview
+constexpr char kSessionChallengeHeaderName[] = "Sec-Session-Challenge";
+constexpr char kSessionIdKey[] = "id";
+}  // namespace
+
+namespace net::device_bound_sessions {
+
+SessionChallengeParam::SessionChallengeParam(SessionChallengeParam&& other) =
+    default;
+
+SessionChallengeParam& SessionChallengeParam::operator=(
+    SessionChallengeParam&& other) noexcept = default;
+
+SessionChallengeParam::~SessionChallengeParam() = default;
+
+SessionChallengeParam::SessionChallengeParam(
+    std::optional<std::string> session_id,
+    std::string challenge)
+    : session_id_(std::move(session_id)), challenge_(std::move(challenge)) {}
+
+// static
+std::optional<SessionChallengeParam> SessionChallengeParam::ParseItem(
+    const structured_headers::ParameterizedMember& session_challenge) {
+  if (session_challenge.member_is_inner_list ||
+      session_challenge.member.empty()) {
+    return std::nullopt;
+  }
+
+  const structured_headers::Item& item = session_challenge.member[0].item;
+  if (!item.is_string()) {
+    return std::nullopt;
+  }
+
+  std::string challenge(item.GetString());
+  if (challenge.empty()) {
+    return std::nullopt;
+  }
+
+  std::optional<std::string> session_id;
+  if (auto it = base::ranges::find(
+          session_challenge.params, kSessionIdKey,
+          &std::pair<std::string, structured_headers::Item>::first);
+      it != session_challenge.params.end()) {
+    const auto& param = it->second;
+    if (!param.is_string()) {
+      return std::nullopt;
+    }
+
+    auto id = param.GetString();
+    if (!id.empty()) {
+      session_id = std::move(id);
+    }
+  }
+
+  return SessionChallengeParam(std::move(session_id), std::move(challenge));
+}
+
+// static
+std::vector<SessionChallengeParam> SessionChallengeParam::CreateIfValid(
+    const GURL& request_url,
+    const net::HttpResponseHeaders* headers) {
+  std::vector<SessionChallengeParam> params;
+  if (!request_url.is_valid()) {
+    return params;
+  }
+
+  std::string header_value;
+  if (!headers || !headers->GetNormalizedHeader(kSessionChallengeHeaderName,
+                                                &header_value)) {
+    return params;
+  }
+
+  std::optional<structured_headers::List> list =
+      structured_headers::ParseList(header_value);
+
+  if (!list) {
+    return params;
+  }
+
+  for (const auto& session_challenge : *list) {
+    std::optional<SessionChallengeParam> param = ParseItem(session_challenge);
+    if (param) {
+      params.push_back(std::move(*param));
+    }
+  }
+
+  return params;
+}
+
+}  // namespace net::device_bound_sessions
diff --git a/net/device_bound_sessions/session_challenge_param.h b/net/device_bound_sessions/session_challenge_param.h
new file mode 100644
index 0000000..a6e4a545
--- /dev/null
+++ b/net/device_bound_sessions/session_challenge_param.h
@@ -0,0 +1,65 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_DEVICE_BOUND_SESSIONS_SESSION_CHALLENGE_PARAM_H_
+#define NET_DEVICE_BOUND_SESSIONS_SESSION_CHALLENGE_PARAM_H_
+
+#include <optional>
+#include <string>
+#include <vector>
+
+#include "net/base/net_export.h"
+#include "net/http/structured_headers.h"
+#include "url/gurl.h"
+
+namespace net {
+class HttpResponseHeaders;
+}
+
+namespace net::device_bound_sessions {
+
+// Class to parse Sec-Session-Challenge header.
+// See explainer for details:
+// https://github.com/WICG/dbsc/blob/main/README.md.
+// It is a RFC 8941 list of challenges for the associated DBSC sessions.
+// Example:
+// Sec-Session-Challenge: "challenge";id="session_id".
+// Sec-Session-Challenge: "challenge";id="session_id", "challenge1";id="id1".
+// The session id may be unknown during the session registration, hence it can
+// be omitted:
+// Sec-Session-Challenge: "challenge".
+// It is possible to have multiple Sec-Session-Challenge headers in
+// one response. If multiple challenges are given for one specific session,
+// the last one will take effect.
+class NET_EXPORT SessionChallengeParam {
+ public:
+  SessionChallengeParam(SessionChallengeParam&& other);
+  SessionChallengeParam& operator=(SessionChallengeParam&& other) noexcept;
+
+  // Disabled to make accidental copies compile errors.
+  SessionChallengeParam(const SessionChallengeParam& other) = delete;
+  SessionChallengeParam& operator=(const SessionChallengeParam&) = delete;
+  ~SessionChallengeParam();
+
+  // Returns a vector of valid instances from the headers.
+  static std::vector<SessionChallengeParam> CreateIfValid(
+      const GURL& request_url,
+      const HttpResponseHeaders* headers);
+
+  const std::optional<std::string>& session_id() const { return session_id_; }
+  const std::string& challenge() const { return challenge_; }
+
+ private:
+  SessionChallengeParam(std::optional<std::string> session_id,
+                        std::string challenge);
+
+  static std::optional<SessionChallengeParam> ParseItem(
+      const structured_headers::ParameterizedMember& session_challenge);
+
+  std::optional<std::string> session_id_;
+  std::string challenge_;
+};
+}  // namespace net::device_bound_sessions
+
+#endif  // NET_DEVICE_BOUND_SESSIONS_SESSION_CHALLENGE_PARAM_H_
diff --git a/net/device_bound_sessions/session_challenge_param_unittest.cc b/net/device_bound_sessions/session_challenge_param_unittest.cc
new file mode 100644
index 0000000..d0b2137
--- /dev/null
+++ b/net/device_bound_sessions/session_challenge_param_unittest.cc
@@ -0,0 +1,403 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/device_bound_sessions/session_challenge_param.h"
+
+#include "base/memory/scoped_refptr.h"
+#include "base/strings/stringprintf.h"
+#include "net/http/http_response_headers.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net::device_bound_sessions {
+
+namespace {
+
+constexpr char kSessionChallengeHeaderForTest[] = "Sec-Session-Challenge";
+constexpr char kSessionIdKey[] = "id";
+constexpr char kSampleSessionId[] = "session_id";
+constexpr char kSampleChallenge[] = "challenge";
+constexpr char kTestUrl[] = "https://www.example.com/refresh";
+
+std::string CreateHeaderStringForTest(std::optional<std::string> session_id,
+                                      std::string challenge) {
+  if (session_id.has_value()) {
+    return base::StringPrintf("\"%s\";%s=\"%s\"", challenge.c_str(),
+                              kSessionIdKey, (*session_id).c_str());
+  } else {
+    return base::StringPrintf("\"%s\"", challenge.c_str());
+  }
+}
+
+TEST(SessionChallengeParamTest, ValidBareChallenge) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string(
+      CreateHeaderStringForTest(std::nullopt, kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_EQ(params.size(), 1U);
+  EXPECT_FALSE(params[0].session_id());
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+}
+
+TEST(SessionChallengeParamTest, ValidSessionAndChallenge) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string(
+      CreateHeaderStringForTest(kSampleSessionId, kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_EQ(params.size(), 1U);
+  EXPECT_EQ(params[0].session_id(), kSampleSessionId);
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+}
+
+TEST(SessionChallengeParamTest, InvalidURL) {
+  const GURL url("invalid.url");
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string(
+      CreateHeaderStringForTest(kSampleSessionId, kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, NoHeader) {
+  const GURL url(kTestUrl);
+  scoped_refptr<net::HttpResponseHeaders> headers =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, EmptyHeader) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  builder.AddHeader(kSessionChallengeHeaderForTest, "");
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, EmptySessionId) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string(CreateHeaderStringForTest("", kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_EQ(params.size(), 1U);
+  EXPECT_FALSE(params[0].session_id());
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+}
+
+TEST(SessionChallengeParamTest, EmptyChallenge) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string(CreateHeaderStringForTest(kSampleSessionId, ""));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, NoQuotes) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string = base::StringPrintf(
+      "%s;%s=\"%s\"", kSampleChallenge, kSessionIdKey, kSampleSessionId);
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, InvalidNonsenseCharacters) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string =
+      base::StringPrintf("\"%s\"; %s=\"%s\";;=;OTHER", kSampleChallenge,
+                         kSessionIdKey, kSampleSessionId);
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, ExtraSymbol) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string =
+      base::StringPrintf("\"%s\"; %s=\"%s\";cache", kSampleChallenge,
+                         kSessionIdKey, kSampleSessionId);
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_EQ(params.size(), 1U);
+  EXPECT_EQ(params[0].session_id(), kSampleSessionId);
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+}
+
+TEST(SessionChallengeParamTest, ExtraParameters) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string =
+      base::StringPrintf("\"%s\"; %s=\"%s\";cache;key=value;k=v",
+                         kSampleChallenge, kSessionIdKey, kSampleSessionId);
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_EQ(params.size(), 1U);
+  EXPECT_EQ(params[0].session_id(), kSampleSessionId);
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+}
+
+TEST(SessionChallengeParamTest, InnerListParameter) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  builder.AddHeader(kSessionChallengeHeaderForTest,
+                    "(\"challenge\";id=\"id\"), (\"challenge1\" \"id1\")");
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, SessionChallengeAsByteSequence) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string = base::StringPrintf(
+      "\"%s\"; %s=%s", kSampleChallenge, kSessionIdKey, ":Y29kZWQ=:");
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, BareChallengeAsByteSequence) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  builder.AddHeader(kSessionChallengeHeaderForTest, ":Y29kZWQ=:");
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, ValidTwoSessionChallenges) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string1(
+      CreateHeaderStringForTest(kSampleSessionId, kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string1);
+
+  std::string session_id2("session_id2");
+  std::string challenge2("nonce2");
+  std::string header_string2(
+      CreateHeaderStringForTest(session_id2, challenge2));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string2);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+
+  ASSERT_EQ(params.size(), 2U);
+  EXPECT_EQ(params[0].session_id(), kSampleSessionId);
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+
+  EXPECT_EQ(params[1].session_id(), session_id2);
+  EXPECT_EQ(params[1].challenge(), challenge2);
+}
+
+TEST(SessionChallengeParamTest, ValidTwoBareChallenges) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string1(
+      CreateHeaderStringForTest(std::nullopt, kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string1);
+
+  std::string challenge2("nonce2");
+  std::string header_string2(
+      CreateHeaderStringForTest(std::nullopt, challenge2));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string2);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+
+  ASSERT_EQ(params.size(), 2U);
+  EXPECT_FALSE(params[0].session_id());
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+
+  EXPECT_FALSE(params[1].session_id());
+  EXPECT_EQ(params[1].challenge(), challenge2);
+}
+
+TEST(SessionChallengeParamTest, ValidMixedChallenges) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string challenge("new");
+  std::string header_string1(
+      CreateHeaderStringForTest(std::nullopt, challenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string1);
+  std::string header_string2(
+      CreateHeaderStringForTest(kSampleSessionId, kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string2);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+
+  ASSERT_EQ(params.size(), 2U);
+  EXPECT_FALSE(params[0].session_id());
+  EXPECT_EQ(params[0].challenge(), challenge);
+
+  EXPECT_EQ(params[1].session_id(), kSampleSessionId);
+  EXPECT_EQ(params[1].challenge(), kSampleChallenge);
+}
+
+TEST(SessionChallengeParamTest, MixedHeaderParameterFirst) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string1(
+      CreateHeaderStringForTest(kSampleSessionId, kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string1);
+  std::string challenge("new");
+  std::string header_string2(
+      CreateHeaderStringForTest(std::nullopt, challenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string2);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+
+  ASSERT_EQ(params.size(), 2U);
+  EXPECT_EQ(params[0].session_id(), kSampleSessionId);
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+
+  EXPECT_FALSE(params[1].session_id());
+  EXPECT_EQ(params[1].challenge(), challenge);
+}
+
+TEST(SessionChallengeParamTest, TwoChallengesInOneHeader) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string1(
+      CreateHeaderStringForTest(kSampleSessionId, kSampleChallenge));
+
+  std::string session_id2("session_id2");
+  std::string challenge2("nonce2");
+  std::string header_string2(
+      CreateHeaderStringForTest(session_id2, challenge2));
+  std::string combined_header = base::StringPrintf(
+      "%s,%s", header_string1.c_str(), header_string2.c_str());
+  builder.AddHeader(kSessionChallengeHeaderForTest, combined_header);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+
+  ASSERT_EQ(params.size(), 2U);
+  EXPECT_EQ(params[0].session_id(), kSampleSessionId);
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+
+  EXPECT_EQ(params[1].session_id(), session_id2);
+  EXPECT_EQ(params[1].challenge(), challenge2);
+}
+
+TEST(SessionChallengeParamTest, ValidInvalid) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string(
+      CreateHeaderStringForTest(kSampleSessionId, kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  builder.AddHeader(kSessionChallengeHeaderForTest, ";;OTHER");
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, EmptyHeaderValidHeader) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  builder.AddHeader(kSessionChallengeHeaderForTest, "");
+  std::string header_string(
+      CreateHeaderStringForTest(kSampleSessionId, kSampleChallenge));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+
+  ASSERT_TRUE(params.empty());
+}
+
+TEST(SessionChallengeParamTest, ThreeChallengesInTwoHeaders) {
+  const GURL url(kTestUrl);
+  net::HttpResponseHeaders::Builder builder =
+      net::HttpResponseHeaders::Builder({1, 1}, "200 OK");
+  std::string header_string1(
+      CreateHeaderStringForTest(kSampleSessionId, kSampleChallenge));
+
+  std::string session_id2("session_id2");
+  std::string challenge2("nonce2");
+  std::string header_string2(
+      CreateHeaderStringForTest(session_id2, challenge2));
+  std::string combined_header = base::StringPrintf(
+      "%s,%s", header_string1.c_str(), header_string2.c_str());
+  builder.AddHeader(kSessionChallengeHeaderForTest, combined_header);
+
+  std::string session_id3("session_id3");
+  std::string challenge3("nonce3");
+  std::string header_string3(
+      CreateHeaderStringForTest(session_id3, challenge3));
+  builder.AddHeader(kSessionChallengeHeaderForTest, header_string3);
+  scoped_refptr<net::HttpResponseHeaders> headers = builder.Build();
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(url, headers.get());
+
+  ASSERT_EQ(params.size(), 3U);
+  EXPECT_EQ(params[0].session_id(), kSampleSessionId);
+  EXPECT_EQ(params[0].challenge(), kSampleChallenge);
+
+  EXPECT_EQ(params[1].session_id(), session_id2);
+  EXPECT_EQ(params[1].challenge(), challenge2);
+
+  EXPECT_EQ(params[2].session_id(), session_id3);
+  EXPECT_EQ(params[2].challenge(), challenge3);
+}
+
+}  // namespace
+}  // namespace net::device_bound_sessions
diff --git a/net/device_bound_sessions/session_service.h b/net/device_bound_sessions/session_service.h
index 1cf4cdb..41eeeb3 100644
--- a/net/device_bound_sessions/session_service.h
+++ b/net/device_bound_sessions/session_service.h
@@ -10,6 +10,7 @@
 #include "net/base/net_export.h"
 #include "net/device_bound_sessions/registration_fetcher_param.h"
 #include "net/device_bound_sessions/session.h"
+#include "net/device_bound_sessions/session_challenge_param.h"
 
 namespace net {
 class IsolationInfo;
@@ -68,6 +69,12 @@
       RefreshCompleteCallback restart_callback,
       RefreshCompleteCallback continue_callback) = 0;
 
+  // Set the challenge for a bound session after getting a
+  // Sec-Session-Challenge header.
+  virtual void SetChallengeForBoundSession(
+      const GURL& request_url,
+      const SessionChallengeParam& param) = 0;
+
  protected:
   SessionService() = default;
 };
diff --git a/net/device_bound_sessions/session_service_impl.cc b/net/device_bound_sessions/session_service_impl.cc
index ab98187..c68db827 100644
--- a/net/device_bound_sessions/session_service_impl.cc
+++ b/net/device_bound_sessions/session_service_impl.cc
@@ -73,4 +73,34 @@
   std::move(continue_callback).Run();
 }
 
+void SessionServiceImpl::SetChallengeForBoundSession(
+    const GURL& request_url,
+    const SessionChallengeParam& param) {
+  if (!param.session_id()) {
+    return;
+  }
+
+  SchemefulSite site(request_url);
+  auto range = unpartitioned_sessions_.equal_range(site);
+  for (auto it = range.first; it != range.second; ++it) {
+    if (it->second->id().value() == param.session_id()) {
+      it->second->set_cached_challenge(param.challenge());
+      return;
+    }
+  }
+}
+
+const Session* SessionServiceImpl::GetSessionForTesting(
+    const SchemefulSite& site,
+    const std::string& session_id) const {
+  auto range = unpartitioned_sessions_.equal_range(site);
+  for (auto it = range.first; it != range.second; ++it) {
+    if (it->second->id().value() == session_id) {
+      return it->second.get();
+    }
+  }
+
+  return nullptr;
+}
+
 }  // namespace net::device_bound_sessions
diff --git a/net/device_bound_sessions/session_service_impl.h b/net/device_bound_sessions/session_service_impl.h
index 161f8acc..07a9eca3 100644
--- a/net/device_bound_sessions/session_service_impl.h
+++ b/net/device_bound_sessions/session_service_impl.h
@@ -45,6 +45,12 @@
       RefreshCompleteCallback restart_callback,
       RefreshCompleteCallback continue_callback) override;
 
+  void SetChallengeForBoundSession(const GURL& request_url,
+                                   const SessionChallengeParam& param) override;
+
+  const Session* GetSessionForTesting(const SchemefulSite& site,
+                                      const std::string& session_id) const;
+
  private:
   // The key is the site (eTLD+1) of the session's origin.
   using SessionsMap = std::multimap<SchemefulSite, std::unique_ptr<Session>>;
diff --git a/net/device_bound_sessions/session_service_impl_unittest.cc b/net/device_bound_sessions/session_service_impl_unittest.cc
index c2a89117..50284ec 100644
--- a/net/device_bound_sessions/session_service_impl_unittest.cc
+++ b/net/device_bound_sessions/session_service_impl_unittest.cc
@@ -20,9 +20,16 @@
 class SessionServiceImplTest : public TestWithTaskEnvironment {
  protected:
   SessionServiceImplTest()
-      : context_(CreateTestURLRequestContextBuilder()->Build()) {}
+      : context_(CreateTestURLRequestContextBuilder()->Build()),
+        service_(*UnexportableKeyServiceFactory::GetInstance()->GetShared(),
+                 context_.get()) {}
+
+  SessionServiceImpl& service() { return service_; }
 
   std::unique_ptr<URLRequestContext> context_;
+
+ private:
+  SessionServiceImpl service_;
 };
 
 class FakeDelegate : public URLRequest::Delegate {
@@ -71,30 +78,24 @@
 
 // Not implemented so test just makes sure it can run
 TEST_F(SessionServiceImplTest, TestDefer) {
-  SessionServiceImpl service(
-      *UnexportableKeyServiceFactory::GetInstance()->GetShared(),
-      context_.get());
   SessionService::RefreshCompleteCallback cb1 = base::DoNothing();
   SessionService::RefreshCompleteCallback cb2 = base::DoNothing();
   std::unique_ptr<URLRequest> request = context_->CreateRequest(
       kTestUrl, IDLE, new FakeDelegate(), kDummyAnnotation);
-  service.DeferRequestForRefresh(request.get(), Session::Id("test"),
-                                 std::move(cb1), std::move(cb2));
+  service().DeferRequestForRefresh(request.get(), Session::Id("test"),
+                                   std::move(cb1), std::move(cb2));
 }
 
 TEST_F(SessionServiceImplTest, RegisterSuccess) {
   // Set the session id to be used for in TestFetcher()
   g_session_id = "SessionId";
   ScopedTestFetcher scopedTestFetcher;
-  SessionServiceImpl service(
-      *UnexportableKeyServiceFactory::GetInstance()->GetShared(),
-      context_.get());
 
   auto fetch_param = RegistrationFetcherParam::CreateInstanceForTesting(
       kTestUrl, {crypto::SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256},
       "challenge");
-  service.RegisterBoundSession(std::move(fetch_param),
-                               IsolationInfo::CreateTransient());
+  service().RegisterBoundSession(std::move(fetch_param),
+                                 IsolationInfo::CreateTransient());
 
   std::unique_ptr<URLRequest> request = context_->CreateRequest(
       kTestUrl, IDLE, new FakeDelegate(), kDummyAnnotation);
@@ -103,7 +104,7 @@
   request->set_site_for_cookies(SiteForCookies::FromUrl(kTestUrl));
 
   std::optional<Session::Id> maybe_id =
-      service.GetAnySessionRequiringDeferral(request.get());
+      service().GetAnySessionRequiringDeferral(request.get());
   ASSERT_TRUE(maybe_id);
   EXPECT_EQ(**maybe_id, g_session_id);
 }
@@ -112,47 +113,78 @@
   // Set the session id to be used for in TestFetcher()
   g_session_id = "";
   ScopedTestFetcher scopedTestFetcher;
-  SessionServiceImpl service(
-      *UnexportableKeyServiceFactory::GetInstance()->GetShared(),
-      context_.get());
 
   auto fetch_param = RegistrationFetcherParam::CreateInstanceForTesting(
       kTestUrl, {crypto::SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256},
       "challenge");
-  service.RegisterBoundSession(std::move(fetch_param),
-                               IsolationInfo::CreateTransient());
+  service().RegisterBoundSession(std::move(fetch_param),
+                                 IsolationInfo::CreateTransient());
 
   std::unique_ptr<URLRequest> request = context_->CreateRequest(
       kTestUrl, IDLE, new FakeDelegate(), kDummyAnnotation);
   request->set_site_for_cookies(SiteForCookies::FromUrl(kTestUrl));
 
   std::optional<Session::Id> maybe_id =
-      service.GetAnySessionRequiringDeferral(request.get());
+      service().GetAnySessionRequiringDeferral(request.get());
   // g_session_id is empty, so should not be valid
   EXPECT_FALSE(maybe_id);
 }
 
 TEST_F(SessionServiceImplTest, RegisterNullFetcher) {
   ScopedNullFetcher scopedNullFetcher;
-  SessionServiceImpl service(
-      *UnexportableKeyServiceFactory::GetInstance()->GetShared(),
-      context_.get());
 
   auto fetch_param = RegistrationFetcherParam::CreateInstanceForTesting(
       kTestUrl, {crypto::SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256},
       "challenge");
-  service.RegisterBoundSession(std::move(fetch_param),
-                               IsolationInfo::CreateTransient());
+  service().RegisterBoundSession(std::move(fetch_param),
+                                 IsolationInfo::CreateTransient());
 
   std::unique_ptr<URLRequest> request = context_->CreateRequest(
       kTestUrl, IDLE, new FakeDelegate(), kDummyAnnotation);
   request->set_site_for_cookies(SiteForCookies::FromUrl(kTestUrl));
 
   std::optional<Session::Id> maybe_id =
-      service.GetAnySessionRequiringDeferral(request.get());
+      service().GetAnySessionRequiringDeferral(request.get());
   // NullFetcher, so should not be valid
   EXPECT_FALSE(maybe_id);
 }
 
+TEST_F(SessionServiceImplTest, SetChallengeForBoundSession) {
+  // Set the session id to be used for in TestFetcher()
+  g_session_id = "SessionId";
+  ScopedTestFetcher scopedTestFetcher;
+
+  auto fetch_param = RegistrationFetcherParam::CreateInstanceForTesting(
+      kTestUrl, {crypto::SignatureVerifier::SignatureAlgorithm::ECDSA_SHA256},
+      "challenge");
+  service().RegisterBoundSession(std::move(fetch_param),
+                                 IsolationInfo::CreateTransient());
+
+  scoped_refptr<net::HttpResponseHeaders> headers =
+      HttpResponseHeaders::Builder({1, 1}, "200 OK").Build();
+  headers->AddHeader("Sec-Session-Challenge",
+                     "\"challenge\";id=\"SessionId\", "
+                     "\"challenge1\";id=\"NonExisted\"");
+  headers->AddHeader("Sec-Session-Challenge", "\"challenge2\"");
+
+  std::vector<SessionChallengeParam> params =
+      SessionChallengeParam::CreateIfValid(kTestUrl, headers.get());
+
+  EXPECT_EQ(params.size(), 3U);
+
+  for (const auto& param : params) {
+    service().SetChallengeForBoundSession(kTestUrl, param);
+  }
+
+  const Session* session =
+      service().GetSessionForTesting(SchemefulSite(kTestUrl), g_session_id);
+  ASSERT_TRUE(session);
+  EXPECT_EQ(session->cached_challenge(), "challenge");
+
+  session =
+      service().GetSessionForTesting(SchemefulSite(kTestUrl), "NonExisted");
+  ASSERT_FALSE(session);
+}
+
 }  // namespace
 }  // namespace net::device_bound_sessions
diff --git a/net/device_bound_sessions/test_util.h b/net/device_bound_sessions/test_util.h
index aec6848..d836dd5 100644
--- a/net/device_bound_sessions/test_util.h
+++ b/net/device_bound_sessions/test_util.h
@@ -10,8 +10,10 @@
 
 #include "base/containers/span.h"
 #include "net/device_bound_sessions/registration_fetcher_param.h"
+#include "net/device_bound_sessions/session_challenge_param.h"
 #include "net/device_bound_sessions/session_service.h"
 #include "testing/gmock/include/gmock/gmock.h"
+#include "url/gurl.h"
 
 namespace net::device_bound_sessions {
 
@@ -36,6 +38,11 @@
                RefreshCompleteCallback restart_callback,
                RefreshCompleteCallback continue_callback),
               (override));
+  MOCK_METHOD(void,
+              SetChallengeForBoundSession,
+              (const GURL& request_url,
+               const SessionChallengeParam& challenge_param),
+              (override));
 };
 
 // Return a hard-coded RS256 public key's SPKI bytes and JWK string for testing.
diff --git a/net/http/http_stream_factory_job_controller_unittest.cc b/net/http/http_stream_factory_job_controller_unittest.cc
index e944813..a1ae7a61 100644
--- a/net/http/http_stream_factory_job_controller_unittest.cc
+++ b/net/http/http_stream_factory_job_controller_unittest.cc
@@ -65,6 +65,7 @@
 #include "net/quic/quic_chromium_connection_helper.h"
 #include "net/quic/quic_http_stream.h"
 #include "net/quic/quic_server_info.h"
+#include "net/quic/quic_session_alias_key.h"
 #include "net/quic/quic_session_pool.h"
 #include "net/quic/quic_session_pool_peer.h"
 #include "net/quic/quic_test_packet_maker.h"
@@ -679,7 +680,8 @@
     factory_ = session_->http_stream_factory();
   }
 
-  void CreateMockQUICProxySession(url::SchemeHostPort server) {
+  std::unique_ptr<MockQuicChromiumClientSession> CreateMockQUICProxySession(
+      url::SchemeHostPort server) {
     const IPEndPoint kIpEndPoint = IPEndPoint(IPAddress::IPv4AllZeros(), 0);
     quic::test::MockRandom random{0};
     quic::MockClock clock;
@@ -709,37 +711,35 @@
         ProxyChain::ForIpProtection({}, 0), SessionUsage::kProxy, SocketTag(),
         NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
         /*require_dns_https_alpn=*/false);
-    mock_proxy_sessions_.emplace_back(
-        std::make_unique<MockQuicChromiumClientSession>(
-            connection, std::move(socket), session_->quic_session_pool(),
-            &crypto_client_stream_factory_, &clock, &transport_security_state,
-            &ssl_config_service,
-            base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
-            session_key,
-            /*require_confirmation=*/false,
-            /*migrate_session_early_v2=*/false,
-            /*migrate_session_on_network_change_v2=*/false,
-            kDefaultNetworkForTests,
-            quic::QuicTime::Delta::FromMilliseconds(
-                kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
-            /*migrate_idle_session=*/false, /*allow_port_migration_=*/false,
-            kDefaultIdleSessionMigrationPeriod,
-            /*multi_port_probing_interval=*/0, kMaxTimeOnNonDefaultNetwork,
-            kMaxMigrationsToNonDefaultNetworkOnWriteError,
-            kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
-            kQuicYieldAfterPacketsRead,
-            quic::QuicTime::Delta::FromMilliseconds(
-                kQuicYieldAfterDurationMilliseconds),
-            /*cert_verify_flags=*/0, quic_config,
-            std::make_unique<TestQuicCryptoClientConfigHandle>(&crypto_config),
-            "CONNECTION_UNKNOWN", base::TimeTicks::Now(),
-            base::TimeTicks::Now(), base::DefaultTickClock::GetInstance(),
-            base::SingleThreadTaskRunner::GetCurrentDefault().get(),
-            /*socket_performance_watcher=*/nullptr,
-            ConnectionEndpointMetadata(),
-            /*report_ecn=*/true,
-            /*enable_origin_frame=*/true,
-            NetLogWithSource::Make(NetLogSourceType::NONE)));
+    auto new_session = std::make_unique<MockQuicChromiumClientSession>(
+        connection, std::move(socket), session_->quic_session_pool(),
+        &crypto_client_stream_factory_, &clock, &transport_security_state,
+        &ssl_config_service,
+        base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
+        QuicSessionAliasKey(server, session_key),
+        /*require_confirmation=*/false,
+        /*migrate_session_early_v2=*/false,
+        /*migrate_session_on_network_change_v2=*/false, kDefaultNetworkForTests,
+        quic::QuicTime::Delta::FromMilliseconds(
+            kDefaultRetransmittableOnWireTimeout.InMilliseconds()),
+        /*migrate_idle_session=*/false, /*allow_port_migration_=*/false,
+        kDefaultIdleSessionMigrationPeriod,
+        /*multi_port_probing_interval=*/0, kMaxTimeOnNonDefaultNetwork,
+        kMaxMigrationsToNonDefaultNetworkOnWriteError,
+        kMaxMigrationsToNonDefaultNetworkOnPathDegrading,
+        kQuicYieldAfterPacketsRead,
+        quic::QuicTime::Delta::FromMilliseconds(
+            kQuicYieldAfterDurationMilliseconds),
+        /*cert_verify_flags=*/0, quic_config,
+        std::make_unique<TestQuicCryptoClientConfigHandle>(&crypto_config),
+        "CONNECTION_UNKNOWN", base::TimeTicks::Now(), base::TimeTicks::Now(),
+        base::DefaultTickClock::GetInstance(),
+        base::SingleThreadTaskRunner::GetCurrentDefault().get(),
+        /*socket_performance_watcher=*/nullptr, ConnectionEndpointMetadata(),
+        /*report_ecn=*/true,
+        /*enable_origin_frame=*/true,
+        NetLogWithSource::Make(NetLogSourceType::NONE));
+    mock_proxy_sessions_.emplace_back(new_session.get());
 
     quic::test::NoopQpackStreamSenderDelegate
         noop_qpack_stream_sender_delegate_;
@@ -748,6 +748,8 @@
         ->qpack_decoder()
         ->set_qpack_stream_sender_delegate(&noop_qpack_stream_sender_delegate_);
     mock_proxy_sessions_.back()->StartReading();
+
+    return new_session;
   }
 
   std::unique_ptr<HttpStreamRequest> CreateJobController(
@@ -767,8 +769,7 @@
   }
 
  protected:
-  std::vector<std::unique_ptr<MockQuicChromiumClientSession>>
-      mock_proxy_sessions_;
+  std::vector<raw_ptr<MockQuicChromiumClientSession>> mock_proxy_sessions_;
 
  private:
   // Use real Jobs so that Job::Resume() is not mocked out. When main job is
@@ -2112,13 +2113,11 @@
                std::move(test_proxy_delegate),
                /*using_quic=*/true);
     if (mock_error.phase == ErrorPhase::kProxySession) {
-      CreateMockQUICProxySession(proxy_server);
-      CreateMockQUICProxySession(proxy_server2);
+      session_->quic_session_pool()->ActivateSessionForTesting(
+          CreateMockQUICProxySession(proxy_server));
+      session_->quic_session_pool()->ActivateSessionForTesting(
+          CreateMockQUICProxySession(proxy_server2));
       ASSERT_EQ(mock_proxy_sessions_.size(), 2u);
-      session_->quic_session_pool()->ActivateSessionForTesting(
-          proxy_server, mock_proxy_sessions_[0].get());
-      session_->quic_session_pool()->ActivateSessionForTesting(
-          proxy_server2, mock_proxy_sessions_[1].get());
     }
 
     // Start two requests. The first request should consume data from
@@ -2151,12 +2150,12 @@
       // Quic connection does not create socket. So only check the sessions,
       // and close them. So that the next loop iteration won't reuse them.
       QuicSessionPool* quic_session_pool = session_->quic_session_pool();
-      // Mock session is owned by the test case. So after test is done,
-      // remove them from the session pool to avoid dangling pointer.
+      // Mock sessions must be removed from the vector before the session pool
+      // destroys them to avoid dangling pointers.
       while (!mock_proxy_sessions_.empty()) {
-        quic_session_pool->DeactivateSessionForTesting(
-            mock_proxy_sessions_.back().get());
+        MockQuicChromiumClientSession* session = mock_proxy_sessions_.back();
         mock_proxy_sessions_.pop_back();
+        quic_session_pool->DeactivateSessionForTesting(session);
       }
       EXPECT_EQ(1, quic_session_pool->CountActiveSessions());
       quic_session_pool->CloseAllSessions(OK, quic::QUIC_NO_ERROR);
diff --git a/net/http/http_stream_factory_unittest.cc b/net/http/http_stream_factory_unittest.cc
index 7cf35faf..c9c76f2 100644
--- a/net/http/http_stream_factory_unittest.cc
+++ b/net/http/http_stream_factory_unittest.cc
@@ -1608,12 +1608,20 @@
                           /*allowed_bad_certs=*/{},
                           /*enable_ip_based_pooling=*/true,
                           /*enable_alternative_services=*/true);
+  requester.MaybeWaitForSwitchesToHttpStreamPool();
   EXPECT_FALSE(requester.stream_done());
 
-  // Confirm a stream has been created by asserting that a new session
-  // has been created.  (The stream is only created at the SPDY level on
-  // first write, which happens after the request has returned a stream).
-  ASSERT_EQ(1, GetSpdySessionCount(session.get()));
+  if (base::FeatureList::IsEnabled(features::kHappyEyeballsV3)) {
+    // When the HappyEyeballsV3 is enabled, SpdySessions never created
+    // synchronously even when the mocked connects complete synchronously.
+    // There is no new session at this point.
+    ASSERT_EQ(0, GetSpdySessionCount(session.get()));
+  } else {
+    // Confirm a stream has been created by asserting that a new session
+    // has been created.  (The stream is only created at the SPDY level on
+    // first write, which happens after the request has returned a stream).
+    ASSERT_EQ(1, GetSpdySessionCount(session.get()));
+  }
 
   // Test to confirm that a SetPriority received after the stream is created
   // but before the request returns it does not crash.
@@ -2654,6 +2662,11 @@
         proxy_resolution_service_(
             ConfiguredProxyResolutionService::CreateDirect()),
         ssl_config_service_(std::make_unique<SSLConfigServiceDefaults>()) {
+    // Explicitly disable HappyEyeballsV3 because it doesn't support
+    // bidirectional streams.
+    // TODO(crbug.com/346835898): Support bidirectional streams in
+    // HappyEyeballsV3.
+    feature_list_.InitAndDisableFeature(features::kHappyEyeballsV3);
     FLAGS_quic_enable_http3_grease_randomness = false;
     quic_context_.AdvanceTime(quic::QuicTime::Delta::FromMilliseconds(20));
     quic::QuicEnableVersion(version_);
@@ -2730,6 +2743,7 @@
   MockHostResolver* host_resolver() { return &host_resolver_; }
 
  private:
+  base::test::ScopedFeatureList feature_list_;
   quic::test::QuicFlagSaver saver_;
   const quic::ParsedQuicVersion version_;
   MockQuicContext quic_context_;
diff --git a/net/quic/bidirectional_stream_quic_impl_unittest.cc b/net/quic/bidirectional_stream_quic_impl_unittest.cc
index 37579f2..5625758 100644
--- a/net/quic/bidirectional_stream_quic_impl_unittest.cc
+++ b/net/quic/bidirectional_stream_quic_impl_unittest.cc
@@ -49,6 +49,7 @@
 #include "net/quic/quic_crypto_client_config_handle.h"
 #include "net/quic/quic_http_utils.h"
 #include "net/quic/quic_server_info.h"
+#include "net/quic/quic_session_alias_key.h"
 #include "net/quic/quic_session_key.h"
 #include "net/quic/quic_session_pool.h"
 #include "net/quic/quic_test_packet_maker.h"
@@ -538,11 +539,13 @@
         /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
         &transport_security_state_, &ssl_config_service_,
         base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
-        QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
-                       PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
-                       SessionUsage::kDestination, SocketTag(),
-                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
-                       /*require_dns_https_alpn=*/false),
+        QuicSessionAliasKey(
+            url::SchemeHostPort(),
+            QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
+                           PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
+                           SessionUsage::kDestination, SocketTag(),
+                           NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
+                           /*require_dns_https_alpn=*/false)),
         /*require_confirmation=*/false,
         /*migrate_session_early_v2=*/false,
         /*migrate_session_on_network_change_v2=*/false,
diff --git a/net/quic/quic_chromium_client_session.cc b/net/quic/quic_chromium_client_session.cc
index 3366fe3..d86c8fa0 100644
--- a/net/quic/quic_chromium_client_session.cc
+++ b/net/quic/quic_chromium_client_session.cc
@@ -921,7 +921,7 @@
     TransportSecurityState* transport_security_state,
     SSLConfigService* ssl_config_service,
     std::unique_ptr<QuicServerInfo> server_info,
-    const QuicSessionKey& session_key,
+    QuicSessionAliasKey session_alias_key,
     bool require_confirmation,
     bool migrate_session_early_v2,
     bool migrate_sessions_on_network_change_v2,
@@ -953,7 +953,8 @@
                                       /*visitor=*/nullptr,
                                       config,
                                       connection->supported_versions()),
-      session_key_(session_key),
+      session_alias_key_(std::move(session_alias_key)),
+      session_key_(session_alias_key_.session_key()),
       require_confirmation_(require_confirmation),
       migrate_session_early_v2_(migrate_session_early_v2),
       migrate_session_on_network_change_v2_(
@@ -998,7 +999,7 @@
       std::move(socket), clock, this, yield_after_packets, yield_after_duration,
       report_ecn, net_log_));
   crypto_stream_ = crypto_client_stream_factory->CreateQuicCryptoClientStream(
-      session_key.server_id(), this,
+      session_key_.server_id(), this,
       std::make_unique<ProofVerifyContextChromium>(cert_verify_flags, net_log_),
       crypto_config_->GetConfig());
   set_debug_visitor(http3_logger_.get());
@@ -1007,7 +1008,7 @@
   migrate_back_to_default_timer_.SetTaskRunner(task_runner_.get());
   net_log_.BeginEvent(NetLogEventType::QUIC_SESSION, [&] {
     return NetLogQuicClientSessionParams(
-        net_log, &session_key, connection_id(),
+        net_log, &session_key_, connection_id(),
         connection->client_connection_id(), supported_versions(),
         cert_verify_flags, require_confirmation_, ech_config_list_);
   });
diff --git a/net/quic/quic_chromium_client_session.h b/net/quic/quic_chromium_client_session.h
index de45999..cfe5d9a 100644
--- a/net/quic/quic_chromium_client_session.h
+++ b/net/quic/quic_chromium_client_session.h
@@ -42,6 +42,7 @@
 #include "net/quic/quic_connection_logger.h"
 #include "net/quic/quic_crypto_client_config_handle.h"
 #include "net/quic/quic_http3_logger.h"
+#include "net/quic/quic_session_alias_key.h"
 #include "net/quic/quic_session_key.h"
 #include "net/socket/socket_performance_watcher.h"
 #include "net/spdy/http2_priority_dependencies.h"
@@ -604,7 +605,7 @@
       TransportSecurityState* transport_security_state,
       SSLConfigService* ssl_config_service,
       std::unique_ptr<QuicServerInfo> server_info,
-      const QuicSessionKey& session_key,
+      QuicSessionAliasKey session_alias_key,
       bool require_confirmation,
       bool migrate_sesion_early_v2,
       bool migrate_session_on_network_change_v2,
@@ -829,6 +830,10 @@
 
   const QuicSessionKey& quic_session_key() const { return session_key_; }
 
+  const QuicSessionAliasKey& session_alias_key() const {
+    return session_alias_key_;
+  }
+
   // Attempts to migrate session when |writer| encounters a write error.
   // If |writer| is no longer actively used, abort migration.
   void MigrateSessionOnWriteError(int error_code,
@@ -1067,6 +1072,7 @@
       StreamRequest* stream_request);
 #endif  // BUILDFLAG(ENABLE_WEBSOCKETS)
 
+  const QuicSessionAliasKey session_alias_key_;
   QuicSessionKey session_key_;
   bool require_confirmation_;
   bool migrate_session_early_v2_;
diff --git a/net/quic/quic_chromium_client_session_test.cc b/net/quic/quic_chromium_client_session_test.cc
index ab1cdd2..f509d65 100644
--- a/net/quic/quic_chromium_client_session_test.cc
+++ b/net/quic/quic_chromium_client_session_test.cc
@@ -46,6 +46,7 @@
 #include "net/quic/quic_crypto_client_stream_factory.h"
 #include "net/quic/quic_http_utils.h"
 #include "net/quic/quic_server_info.h"
+#include "net/quic/quic_session_alias_key.h"
 #include "net/quic/quic_session_key.h"
 #include "net/quic/quic_test_packet_maker.h"
 #include "net/quic/test_quic_crypto_client_config_handle.h"
@@ -178,7 +179,8 @@
         connection, std::move(socket),
         /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
         transport_security_state_.get(), &ssl_config_service_,
-        base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)), session_key_,
+        base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
+        QuicSessionAliasKey(url::SchemeHostPort(), session_key_),
         /*require_confirmation=*/false, migrate_session_early_v2_,
         /*migrate_session_on_network_change_v2=*/false, default_network_,
         quic::QuicTime::Delta::FromMilliseconds(
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index ed98cfe..19c0c7d 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -60,6 +60,7 @@
 #include "net/quic/quic_crypto_client_config_handle.h"
 #include "net/quic/quic_http_utils.h"
 #include "net/quic/quic_server_info.h"
+#include "net/quic/quic_session_alias_key.h"
 #include "net/quic/quic_session_key.h"
 #include "net/quic/quic_session_pool.h"
 #include "net/quic/quic_test_packet_maker.h"
@@ -417,11 +418,13 @@
         /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
         &transport_security_state_, &ssl_config_service_,
         base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
-        QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
-                       PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
-                       SessionUsage::kDestination, SocketTag(),
-                       NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
-                       /*require_dns_https_alpn=*/false),
+        QuicSessionAliasKey(
+            url::SchemeHostPort(),
+            QuicSessionKey(kDefaultServerHostName, kDefaultServerPort,
+                           PRIVACY_MODE_DISABLED, ProxyChain::Direct(),
+                           SessionUsage::kDestination, SocketTag(),
+                           NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
+                           /*require_dns_https_alpn=*/false)),
         /*require_confirmation=*/false,
         /*migrate_session_early_v2=*/false,
         /*migrate_session_on_network_change_v2=*/false,
diff --git a/net/quic/quic_proxy_client_socket_test_base.cc b/net/quic/quic_proxy_client_socket_test_base.cc
index d32f6f14..4a0a48b 100644
--- a/net/quic/quic_proxy_client_socket_test_base.cc
+++ b/net/quic/quic_proxy_client_socket_test_base.cc
@@ -31,6 +31,8 @@
 #include "net/quic/quic_chromium_packet_writer.h"
 #include "net/quic/quic_crypto_client_config_handle.h"
 #include "net/quic/quic_http_utils.h"
+#include "net/quic/quic_session_alias_key.h"
+#include "net/quic/quic_session_key.h"
 #include "net/quic/test_quic_crypto_client_config_handle.h"
 #include "net/quic/test_task_runner.h"
 #include "net/socket/socket_tag.h"
@@ -169,10 +171,12 @@
       /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
       &transport_security_state_, &ssl_config_service_,
       base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
-      QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
-                     proxy_chain_, SessionUsage::kDestination, SocketTag(),
-                     NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
-                     /*require_dns_https_alpn=*/false),
+      QuicSessionAliasKey(
+          url::SchemeHostPort(),
+          QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
+                         proxy_chain_, SessionUsage::kDestination, SocketTag(),
+                         NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
+                         /*require_dns_https_alpn=*/false)),
       /*require_confirmation=*/false,
       /*migrate_session_early_v2=*/false,
       /*migrate_session_on_network_change_v2=*/false,
diff --git a/net/quic/quic_session_pool.cc b/net/quic/quic_session_pool.cc
index 372da201..412b2cf 100644
--- a/net/quic/quic_session_pool.cc
+++ b/net/quic/quic_session_pool.cc
@@ -195,6 +195,17 @@
   }
 }
 
+// Checks if `destination` matches the alias key of `session`. If
+// `match_received_origins` is true, also checks if `destination` matches any of
+// its received origins. Returns true on any match.
+bool DestinationInAliasOrReceivedOrigins(QuicChromiumClientSession* session,
+                                         const url::SchemeHostPort& destination,
+                                         bool match_received_origins) {
+  return destination == session->session_alias_key().destination() ||
+         (match_received_origins &&
+          session->received_origins().contains(destination));
+}
+
 // An implementation of quic::QuicCryptoClientConfig::ServerIdFilter that wraps
 // an |origin_filter|.
 class ServerIdOriginFilter
@@ -545,10 +556,7 @@
   UMA_HISTOGRAM_COUNTS_1000("Net.NumQuicSessionsAtShutdown",
                             all_sessions_.size());
   CloseAllSessions(ERR_ABORTED, quic::QUIC_CONNECTION_CANCELLED);
-  while (!all_sessions_.empty()) {
-    delete all_sessions_.begin()->first;
-    all_sessions_.erase(all_sessions_.begin());
-  }
+  all_sessions_.clear();
   active_jobs_.clear();
 
   DCHECK(dns_aliases_by_session_key_.empty());
@@ -586,15 +594,9 @@
     QuicChromiumClientSession* session = key_value.second;
     // Check received origins and "remote" (alternative service and origin have
     // different hostnames) alt-svc for this active session.
-    if (!skip_dns_with_origin_frame_ ||
-        !session->received_origins().contains(destination)) {
-      const auto& it = all_sessions_.find(session);
-      CHECK(it != all_sessions_.end());
-      if (destination != it->second.destination()) {
-        continue;
-      }
-    }
-    if (session->CanPool(session_key.host(), session_key)) {
+    if (DestinationInAliasOrReceivedOrigins(session, destination,
+                                            skip_dns_with_origin_frame_) &&
+        session->CanPool(session_key.host(), session_key)) {
       return session;
     }
   }
@@ -736,7 +738,8 @@
     active_sessions_.erase(session_key);
     ProcessGoingAwaySession(session, session_key.server_id(), true);
   }
-  ProcessGoingAwaySession(session, all_sessions_[session].server_id(), false);
+  ProcessGoingAwaySession(session, session->session_alias_key().server_id(),
+                          false);
   if (!aliases.empty()) {
     DCHECK(base::Contains(session_peer_ip_, session));
     const IPEndPoint peer_address = session_peer_ip_[session];
@@ -752,8 +755,9 @@
 void QuicSessionPool::OnSessionClosed(QuicChromiumClientSession* session) {
   DCHECK_EQ(0u, session->GetNumActiveStreams());
   OnSessionGoingAway(session);
-  delete session;
-  all_sessions_.erase(session);
+  auto it = all_sessions_.find(session);
+  CHECK(it != all_sessions_.end());
+  all_sessions_.erase(it);
 }
 
 void QuicSessionPool::OnBlackholeAfterHandshakeConfirmed(
@@ -793,9 +797,10 @@
   }
   while (!all_sessions_.empty()) {
     size_t initial_size = all_sessions_.size();
-    all_sessions_.begin()->first->CloseSessionOnError(
-        error, quic_error,
-        quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
+    (*all_sessions_.begin())
+        ->CloseSessionOnError(
+            error, quic_error,
+            quic::ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
     DCHECK_NE(initial_size, all_sessions_.size());
   }
   DCHECK(all_sessions_.empty());
@@ -1097,9 +1102,9 @@
   // Broadcast network connected to all sessions.
   // If migration is not turned on, session will not migrate but collect data.
   auto it = all_sessions_.begin();
-  // Sessions may be deleted while iterating through the map.
+  // Sessions may be deleted while iterating through the set.
   while (it != all_sessions_.end()) {
-    QuicChromiumClientSession* session = it->first;
+    QuicChromiumClientSession* session = it->get();
     ++it;
     session->OnNetworkConnected(network);
   }
@@ -1119,9 +1124,9 @@
   // Broadcast network disconnected to all sessions.
   // If migration is not turned on, session will not migrate but collect data.
   auto it = all_sessions_.begin();
-  // Sessions may be deleted while iterating through the map.
+  // Sessions may be deleted while iterating through the set.
   while (it != all_sessions_.end()) {
-    QuicChromiumClientSession* session = it->first;
+    QuicChromiumClientSession* session = it->get();
     ++it;
     session->OnNetworkDisconnectedV2(/*disconnected_network*/ network);
   }
@@ -1160,9 +1165,9 @@
   }
 
   auto it = all_sessions_.begin();
-  // Sessions may be deleted while iterating through the map.
+  // Sessions may be deleted while iterating through the set.
   while (it != all_sessions_.end()) {
-    QuicChromiumClientSession* session = it->first;
+    QuicChromiumClientSession* session = it->get();
     ++it;
     session->OnNetworkMadeDefault(network);
   }
@@ -1257,17 +1262,19 @@
 }
 
 void QuicSessionPool::ActivateSessionForTesting(
-    const url::SchemeHostPort& destination,
-    QuicChromiumClientSession* session) {
-  all_sessions_.emplace(
-      session, QuicSessionAliasKey(destination, session->quic_session_key()));
-  ActivateSession(all_sessions_[session], session, std::set<std::string>());
+    std::unique_ptr<QuicChromiumClientSession> new_session) {
+  QuicChromiumClientSession* session = new_session.get();
+  all_sessions_.insert(std::move(new_session));
+  ActivateSession(session->session_alias_key(), session,
+                  std::set<std::string>());
 }
 
 void QuicSessionPool::DeactivateSessionForTesting(
     QuicChromiumClientSession* session) {
   OnSessionGoingAway(session);
-  all_sessions_.erase(session);
+  auto it = all_sessions_.find(session);
+  CHECK(it != all_sessions_.end());
+  all_sessions_.erase(it);
 }
 
 void QuicSessionPool::SetTimeDelayForWaitingJobForTesting(
@@ -1691,10 +1698,10 @@
     require_confirmation = true;
   }
 
-  *session = new QuicChromiumClientSession(
+  auto new_session = std::make_unique<QuicChromiumClientSession>(
       connection, std::move(socket), this, quic_crypto_client_stream_factory_,
       clock_, transport_security_state_, ssl_config_service_,
-      std::move(server_info), key.session_key(), require_confirmation,
+      std::move(server_info), std::move(key), require_confirmation,
       params_.migrate_sessions_early_v2,
       params_.migrate_sessions_on_network_change_v2, default_network_,
       retransmittable_on_wire_timeout_, params_.migrate_idle_sessions,
@@ -1709,8 +1716,9 @@
       dns_resolution_end_time, tick_clock_, task_runner_.get(),
       std::move(socket_performance_watcher), metadata, params_.report_ecn,
       params_.enable_origin_frame, net_log);
+  *session = new_session.get();
 
-  all_sessions_[*session] = std::move(key);  // owning pointer
+  all_sessions_.insert(std::move(new_session));
   writer->set_delegate(*session);
   (*session)->AddConnectivityObserver(&connectivity_monitor_);
 
diff --git a/net/quic/quic_session_pool.h b/net/quic/quic_session_pool.h
index f983625..60d10f4 100644
--- a/net/quic/quic_session_pool.h
+++ b/net/quic/quic_session_pool.h
@@ -15,6 +15,7 @@
 #include <vector>
 
 #include "base/containers/lru_cache.h"
+#include "base/containers/unique_ptr_adapters.h"
 #include "base/gtest_prod_util.h"
 #include "base/memory/memory_pressure_monitor.h"
 #include "base/memory/raw_ptr.h"
@@ -512,8 +513,8 @@
   int CountActiveSessions() { return active_sessions_.size(); }
 
   // Inject a QUIC session for testing various edge cases.
-  void ActivateSessionForTesting(const url::SchemeHostPort& destination,
-                                 QuicChromiumClientSession* session);
+  void ActivateSessionForTesting(
+      std::unique_ptr<QuicChromiumClientSession> new_session);
 
   void DeactivateSessionForTesting(QuicChromiumClientSession* session);
 
@@ -539,8 +540,8 @@
   friend class test::QuicSessionPoolPeer;
 
   using SessionMap = std::map<QuicSessionKey, QuicChromiumClientSession*>;
-  using SessionIdMap =
-      std::map<QuicChromiumClientSession*, QuicSessionAliasKey>;
+  using SessionIdSet = std::set<std::unique_ptr<QuicChromiumClientSession>,
+                                base::UniquePtrComparator>;
   using AliasSet = std::set<QuicSessionAliasKey>;
   using SessionAliasMap = std::map<QuicChromiumClientSession*, AliasSet>;
   using SessionSet =
@@ -762,7 +763,7 @@
   std::unique_ptr<quic::QuicAlarmFactory> alarm_factory_;
 
   // Contains owning pointers to all sessions that currently exist.
-  SessionIdMap all_sessions_;
+  SessionIdSet all_sessions_;
   // Contains non-owning pointers to currently active session
   // (not going away session, once they're implemented).
   SessionMap active_sessions_;
diff --git a/net/quic/quic_session_pool_peer.cc b/net/quic/quic_session_pool_peer.cc
index bfc8b06..a5fd295 100644
--- a/net/quic/quic_session_pool_peer.cc
+++ b/net/quic/quic_session_pool_peer.cc
@@ -7,6 +7,7 @@
 #include <string>
 #include <vector>
 
+#include "base/containers/contains.h"
 #include "base/task/sequenced_task_runner.h"
 #include "net/base/network_anonymization_key.h"
 #include "net/base/privacy_mode.h"
@@ -81,8 +82,9 @@
   QuicSessionAliasKey key(std::move(destination), session_key);
   DCHECK(factory->HasActiveJob(session_key));
   DCHECK_EQ(factory->all_sessions_.size(), 1u);
-  DCHECK(key == factory->all_sessions_.begin()->second);
-  return factory->all_sessions_.begin()->first;
+  QuicChromiumClientSession* session = factory->all_sessions_.begin()->get();
+  DCHECK(key == session->session_alias_key());
+  return session;
 }
 
 QuicChromiumClientSession* QuicSessionPoolPeer::GetActiveSession(
@@ -103,12 +105,7 @@
 
 bool QuicSessionPoolPeer::IsLiveSession(QuicSessionPool* factory,
                                         QuicChromiumClientSession* session) {
-  for (const auto& it : factory->all_sessions_) {
-    if (it.first == session) {
-      return true;
-    }
-  }
-  return false;
+  return base::Contains(factory->all_sessions_, session);
 }
 
 void QuicSessionPoolPeer::SetTaskRunner(
diff --git a/net/url_request/url_request_http_job.cc b/net/url_request/url_request_http_job.cc
index 6f83984a..6255fe2 100644
--- a/net/url_request/url_request_http_job.cc
+++ b/net/url_request/url_request_http_job.cc
@@ -111,6 +111,7 @@
 
 #if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
 #include "net/device_bound_sessions/registration_fetcher_param.h"
+#include "net/device_bound_sessions/session_challenge_param.h"
 #include "net/device_bound_sessions/session_service.h"
 #endif  // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
 
@@ -1163,14 +1164,26 @@
 
 #if BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
 void URLRequestHttpJob::ProcessDeviceBoundSessionsHeader() {
+  device_bound_sessions::SessionService* service =
+      request_->context()->device_bound_session_service();
+  if (!service) {
+    return;
+  }
+
+  const auto& request_url = request_->url();
+  auto* headers = GetResponseHeaders();
   std::vector<device_bound_sessions::RegistrationFetcherParam> params =
       device_bound_sessions::RegistrationFetcherParam::CreateIfValid(
-          request_->url(), GetResponseHeaders());
-  if (auto* service = request_->context()->device_bound_session_service()) {
-    for (auto& param : params) {
-      service->RegisterBoundSession(std::move(param),
-                                    request_->isolation_info());
-    }
+          request_url, headers);
+  for (auto& param : params) {
+    service->RegisterBoundSession(std::move(param), request_->isolation_info());
+  }
+
+  std::vector<device_bound_sessions::SessionChallengeParam> challenge_params =
+      device_bound_sessions::SessionChallengeParam::CreateIfValid(request_url,
+                                                                  headers);
+  for (auto& param : challenge_params) {
+    service->SetChallengeForBoundSession(request_url, std::move(param));
   }
 }
 #endif  // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
diff --git a/net/url_request/url_request_http_job_unittest.cc b/net/url_request/url_request_http_job_unittest.cc
index 26aff4ac..aa067a91 100644
--- a/net/url_request/url_request_http_job_unittest.cc
+++ b/net/url_request/url_request_http_job_unittest.cc
@@ -1306,6 +1306,33 @@
   EXPECT_THAT(delegate_.request_status(), IsOk());
 }
 
+TEST_F(URLRequestHttpJobWithMockSocketsDeviceBoundSessionServiceTest,
+       ShouldProcessDeviceBoundSessionChallengeHeader) {
+  const MockWrite writes[] = {
+      MockWrite("GET / HTTP/1.1\r\n"
+                "Host: www.example.com\r\n"
+                "Connection: keep-alive\r\n"
+                "User-Agent: \r\n"
+                "Accept-Encoding: gzip, deflate\r\n"
+                "Accept-Language: en-us,fr\r\n\r\n")};
+
+  const MockRead reads[] = {
+      MockRead(
+          "HTTP/1.1 200 OK\r\n"
+          "Accept-Ranges: bytes\r\n"
+          "Sec-Session-Challenge: \"session_identifier\";challenge=\"test\"\r\n"
+          "Content-Length: 12\r\n\r\n"),
+      MockRead("Test Content")};
+
+  StaticSocketDataProvider socket_data(reads, writes);
+  socket_factory_.AddSocketDataProvider(&socket_data);
+
+  request_->Start();
+  EXPECT_CALL(GetMockService(), SetChallengeForBoundSession).Times(1);
+  delegate_.RunUntilComplete();
+  EXPECT_THAT(delegate_.request_status(), IsOk());
+}
+
 #endif  // BUILDFLAG(ENABLE_DEVICE_BOUND_SESSIONS)
 
 namespace {
diff --git a/net/websockets/websocket_basic_stream_adapters_test.cc b/net/websockets/websocket_basic_stream_adapters_test.cc
index c5d91f6..b0a431e0 100644
--- a/net/websockets/websocket_basic_stream_adapters_test.cc
+++ b/net/websockets/websocket_basic_stream_adapters_test.cc
@@ -55,6 +55,7 @@
 #include "net/quic/quic_context.h"
 #include "net/quic/quic_http_utils.h"
 #include "net/quic/quic_server_info.h"
+#include "net/quic/quic_session_alias_key.h"
 #include "net/quic/quic_session_key.h"
 #include "net/quic/quic_test_packet_maker.h"
 #include "net/quic/test_quic_crypto_client_config_handle.h"
@@ -1279,11 +1280,13 @@
         /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
         &transport_security_state_, &ssl_config_service_,
         /*server_info=*/nullptr,
-        QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
-                       ProxyChain::Direct(), SessionUsage::kDestination,
-                       SocketTag(), NetworkAnonymizationKey(),
-                       SecureDnsPolicy::kAllow,
-                       /*require_dns_https_alpn=*/false),
+        QuicSessionAliasKey(
+            url::SchemeHostPort(),
+            QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
+                           ProxyChain::Direct(), SessionUsage::kDestination,
+                           SocketTag(), NetworkAnonymizationKey(),
+                           SecureDnsPolicy::kAllow,
+                           /*require_dns_https_alpn=*/false)),
         /*require_confirmation=*/false,
         /*migrate_session_early_v2=*/false,
         /*migrate_session_on_network_change_v2=*/false,
diff --git a/net/websockets/websocket_handshake_stream_create_helper_test.cc b/net/websockets/websocket_handshake_stream_create_helper_test.cc
index a045036..2c36b0a 100644
--- a/net/websockets/websocket_handshake_stream_create_helper_test.cc
+++ b/net/websockets/websocket_handshake_stream_create_helper_test.cc
@@ -52,6 +52,7 @@
 #include "net/quic/quic_context.h"
 #include "net/quic/quic_http_utils.h"
 #include "net/quic/quic_server_info.h"
+#include "net/quic/quic_session_alias_key.h"
 #include "net/quic/quic_session_key.h"
 #include "net/quic/quic_test_packet_maker.h"
 #include "net/quic/test_quic_crypto_client_config_handle.h"
@@ -490,11 +491,13 @@
             /*stream_factory=*/nullptr, &crypto_client_stream_factory, &clock_,
             &transport_security_state, &ssl_config_service,
             /*server_info=*/nullptr,
-            QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
-                           ProxyChain::Direct(), SessionUsage::kDestination,
-                           SocketTag(), NetworkAnonymizationKey(),
-                           SecureDnsPolicy::kAllow,
-                           /*require_dns_https_alpn=*/false),
+            QuicSessionAliasKey(
+                url::SchemeHostPort(),
+                QuicSessionKey("mail.example.org", 80, PRIVACY_MODE_DISABLED,
+                               ProxyChain::Direct(), SessionUsage::kDestination,
+                               SocketTag(), NetworkAnonymizationKey(),
+                               SecureDnsPolicy::kAllow,
+                               /*require_dns_https_alpn=*/false)),
             /*require_confirmation=*/false,
             /*migrate_session_early_v2=*/false,
             /*migrate_session_on_network_change_v2=*/false,
diff --git a/remoting/host/setup/start_host_as_root.cc b/remoting/host/setup/start_host_as_root.cc
index 891abbe..75a9f4b2 100644
--- a/remoting/host/setup/start_host_as_root.cc
+++ b/remoting/host/setup/start_host_as_root.cc
@@ -82,13 +82,13 @@
     if (!parts) {
       user_name = std::move(arg_value);
     } else {
-      user_name = std::move(parts->first);
+      user_name = std::string(parts->first);
     }
   } else if (command_line.HasSwitch("cloud-user")) {
     auto parts = base::SplitStringOnce(
         command_line.GetSwitchValueASCII("cloud-user"), '@');
     if (parts) {
-      user_name = std::move(parts->first);
+      user_name = std::string(parts->first);
     } else {
       fprintf(stderr, "The --cloud-user flag requires an email address.\n");
     }
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc
index de856945..a17425d4 100644
--- a/services/network/cors/cors_url_loader_factory.cc
+++ b/services/network/cors/cors_url_loader_factory.cc
@@ -392,8 +392,12 @@
   }
 
   if (!disable_web_security_) {
-    mojo::PendingRemote<mojom::DevToolsObserver> devtools_observer =
-        GetDevToolsObserver(resource_request);
+    mojo::PendingRemote<mojom::DevToolsObserver> devtools_observer;
+    const bool always_clone = !base::FeatureList::IsEnabled(
+        network::features::kCloneDevToolsConnectionOnlyIfRequested);
+    if (always_clone || resource_request.devtools_request_id.has_value()) {
+      devtools_observer = GetDevToolsObserver(resource_request);
+    }
 
     scoped_refptr<SharedDictionaryStorage> shared_dictionary_storage =
         shared_dictionary_storage_;
diff --git a/services/network/cors/cors_url_loader_private_network_access_unittest.cc b/services/network/cors/cors_url_loader_private_network_access_unittest.cc
index 273aa8d..86687918 100644
--- a/services/network/cors/cors_url_loader_private_network_access_unittest.cc
+++ b/services/network/cors/cors_url_loader_private_network_access_unittest.cc
@@ -884,6 +884,7 @@
                   .Build())
           .WithDevToolsObserver(devtools_observer.Bind())
           .Build();
+  request.devtools_request_id = "devtools";
 
   base::HistogramTester histogram_tester;
 
@@ -962,6 +963,7 @@
                   .Build())
           .WithDevToolsObserver(devtools_observer.Bind())
           .Build();
+  request.devtools_request_id = "devtools";
 
   base::HistogramTester histogram_tester;
 
@@ -1115,6 +1117,7 @@
                   .WithIPAddressSpace(mojom::IPAddressSpace::kPublic)
                   .Build())
           .Build();
+  request.devtools_request_id = "devtools";
 
   base::HistogramTester histogram_tester;
 
@@ -1424,6 +1427,7 @@
                   .Build())
           .WithDevToolsObserver(devtools_observer.Bind())
           .Build();
+  request.devtools_request_id = "devtools";
 
   base::HistogramTester histogram_tester;
 
@@ -1902,6 +1906,7 @@
                   .Build())
           .WithDevToolsObserver(devtools_observer.Bind())
           .Build();
+  request.devtools_request_id = "devtools";
 
   base::HistogramTester histogram_tester;
 
@@ -1983,6 +1988,7 @@
                   .Build())
           .WithDevToolsObserver(devtools_observer.Bind())
           .Build();
+  request.devtools_request_id = "devtools";
 
   base::HistogramTester histogram_tester;
 
@@ -2065,6 +2071,7 @@
                   .Build())
           .WithDevToolsObserver(devtools_observer.Bind())
           .Build();
+  request.devtools_request_id = "devtools";
 
   base::HistogramTester histogram_tester;
 
diff --git a/services/network/cors/cors_url_loader_test_util.cc b/services/network/cors/cors_url_loader_test_util.cc
index 9b0361fc..82b73ad 100644
--- a/services/network/cors/cors_url_loader_test_util.cc
+++ b/services/network/cors/cors_url_loader_test_util.cc
@@ -203,6 +203,7 @@
   if (request.mode == mojom::RequestMode::kNavigate)
     request.navigation_redirect_chain.push_back(url);
   request.request_initiator = url::Origin::Create(origin);
+  request.devtools_request_id = "devtools";
   if (devtools_observer_for_next_request_) {
     request.trusted_params = ResourceRequest::TrustedParams();
     request.trusted_params->devtools_observer =
diff --git a/services/network/public/cpp/crash_keys.cc b/services/network/public/cpp/crash_keys.cc
index fb15f59..bbcac981 100644
--- a/services/network/public/cpp/crash_keys.cc
+++ b/services/network/public/cpp/crash_keys.cc
@@ -19,7 +19,7 @@
 }  // namespace
 
 void SetDeserializationCrashKeyString(std::string_view str) {
-  base::debug::SetCrashKeyString(GetCrashKey(), std::move(str));
+  base::debug::SetCrashKeyString(GetCrashKey(), str);
 }
 
 void ClearDeserializationCrashKeyString() {
diff --git a/services/network/public/cpp/features.cc b/services/network/public/cpp/features.cc
index f68c2aff..6839890 100644
--- a/services/network/public/cpp/features.cc
+++ b/services/network/public/cpp/features.cc
@@ -475,4 +475,10 @@
              "TreatNullIPAsPublicAddressSpace",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+// When enabled, the CORS URL loader will clone the DevTools connection for a
+// resource request only if the request includes a DevTools request id.
+BASE_FEATURE(kCloneDevToolsConnectionOnlyIfRequested,
+             "CloneDevToolsConnectionOnlyIfRequested",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
 }  // namespace network::features
diff --git a/services/network/public/cpp/features.h b/services/network/public/cpp/features.h
index 10ebf18..b384725 100644
--- a/services/network/public/cpp/features.h
+++ b/services/network/public/cpp/features.h
@@ -186,6 +186,9 @@
 COMPONENT_EXPORT(NETWORK_CPP)
 BASE_DECLARE_FEATURE(kTreatNullIPAsPublicAddressSpace);
 
+COMPONENT_EXPORT(NETWORK_CPP)
+BASE_DECLARE_FEATURE(kCloneDevToolsConnectionOnlyIfRequested);
+
 }  // namespace network::features
 
 #endif  // SERVICES_NETWORK_PUBLIC_CPP_FEATURES_H_
diff --git a/services/webnn/dml/context_impl_dml_test.cc b/services/webnn/dml/context_impl_dml_test.cc
index fd83ad3..d4afd14 100644
--- a/services/webnn/dml/context_impl_dml_test.cc
+++ b/services/webnn/dml/context_impl_dml_test.cc
@@ -100,7 +100,7 @@
 
   // The GraphImplDml should be built successfully.
   base::test::TestFuture<mojom::CreateGraphResultPtr> create_graph_future;
-  graph_builder_remote->CreateGraph(builder.CloneGraphInfo(),
+  graph_builder_remote->CreateGraph(builder.TakeGraphInfo(),
                                     create_graph_future.GetCallback());
   mojom::CreateGraphResultPtr create_graph_result = create_graph_future.Take();
   EXPECT_TRUE(create_graph_result->is_graph_remote());
diff --git a/services/webnn/webnn_graph_impl_backend_test.cc b/services/webnn/webnn_graph_impl_backend_test.cc
index 3492332f..cf40c26b 100644
--- a/services/webnn/webnn_graph_impl_backend_test.cc
+++ b/services/webnn/webnn_graph_impl_backend_test.cc
@@ -523,7 +523,7 @@
     }
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyIsEqual(std::move(named_outputs["output"]), output);
@@ -712,7 +712,7 @@
     named_inputs.insert({"input", VectorToBigBuffer(input.values)});
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyIsEqual(std::move(named_outputs["output"]), output);
@@ -977,7 +977,7 @@
     named_inputs.insert({"rhs", VectorToBigBuffer(rhs.values)});
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
 #if BUILDFLAG(IS_MAC)
@@ -1016,7 +1016,7 @@
     named_inputs.insert({"rhs", VectorToBigBuffer(rhs.values)});
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyIsEqual(std::move(named_outputs["output"]), output);
@@ -1091,7 +1091,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   // [[1  2]
@@ -1179,7 +1179,7 @@
     named_inputs.insert({"input", VectorToBigBuffer(input.values)});
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs, expectation);
 
     if (expectation == BuildAndComputeExpectation::kSuccess) {
@@ -1277,7 +1277,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(
@@ -1312,7 +1312,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
@@ -1346,7 +1346,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
@@ -1378,7 +1378,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
@@ -1410,7 +1410,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(
@@ -1471,7 +1471,7 @@
     }
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyIsEqual(std::move(named_outputs["output"]), output);
@@ -1605,7 +1605,7 @@
     }
 
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs, expectation);
 
     if (expectation == BuildAndComputeExpectation::kSuccess) {
@@ -1945,7 +1945,7 @@
     }
 
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs, expectation);
 
     if (expectation == BuildAndComputeExpectation::kSuccess) {
@@ -2061,7 +2061,7 @@
   named_inputs.insert({"input_b", VectorToBigBuffer(input_b_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
@@ -2088,7 +2088,7 @@
   named_inputs.insert({"input_a", VectorToBigBuffer(input_a_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
@@ -2141,7 +2141,7 @@
 
   // The GraphImpl should be built successfully.
   base::test::TestFuture<mojom::CreateGraphResultPtr> create_graph_future;
-  webnn_graph_builder_remote->CreateGraph(builder.CloneGraphInfo(),
+  webnn_graph_builder_remote->CreateGraph(builder.TakeGraphInfo(),
                                           create_graph_future.GetCallback());
   mojom::CreateGraphResultPtr create_graph_result = create_graph_future.Take();
   EXPECT_FALSE(create_graph_result->is_error());
@@ -2254,7 +2254,7 @@
     }
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyIsEqual(std::move(named_outputs["output"]), output);
@@ -2325,7 +2325,7 @@
     }
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs, expectation);
 
     if (expectation == BuildAndComputeExpectation::kSuccess) {
@@ -2368,7 +2368,7 @@
     }
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyIsEqual(std::move(named_outputs["output"]), output);
@@ -2548,7 +2548,7 @@
     }
 
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs, expectation);
 
     if (expectation == BuildAndComputeExpectation::kSuccess) {
@@ -2707,7 +2707,7 @@
                       std::move(attributes));
 
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-    BuildAndCompute(builder.CloneGraphInfo(), /*named_inputs=*/{},
+    BuildAndCompute(builder.TakeGraphInfo(), /*named_inputs=*/{},
                     named_outputs);
 
     ASSERT_EQ(named_outputs.size(), 2u);
@@ -2788,7 +2788,7 @@
       {"cellState", VectorToBigBuffer(initial_cell_state_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   ASSERT_EQ(named_outputs.size(), 2u);
@@ -2858,7 +2858,7 @@
     named_inputs.insert({"input_b", VectorToBigBuffer(input_b.values)});
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyFloatDataIsEqual(
@@ -3021,7 +3021,7 @@
   named_inputs.insert({"input_b", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
@@ -3070,7 +3070,7 @@
   named_inputs.insert({"input_b", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
@@ -3115,7 +3115,7 @@
   named_inputs.insert({"input_b", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
@@ -3152,7 +3152,7 @@
   std::vector<float> input_data = {1, 1, 1, 1};
   named_inputs.insert({"input_a", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
             std::vector<float>({2, 2, 2, 2}));
@@ -3176,7 +3176,7 @@
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
             std::vector<float>({0, 0, 1}));
@@ -3206,7 +3206,7 @@
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
             std::vector<float>({3, 3, 3, 3}));
@@ -3248,7 +3248,7 @@
 
   base::flat_map<std::string, mojo_base::BigBuffer> named_inputs;
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
             std::vector<float>({9, 9, 9, 9}));
@@ -3305,7 +3305,7 @@
   named_inputs.insert({"input_a", VectorToBigBuffer(input_data)});
   named_inputs.insert({"input_b", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
             std::vector<float>({2, 2, 2, 2}));
@@ -3354,7 +3354,7 @@
   named_inputs.insert({"input_a", VectorToBigBuffer(input_data)});
   named_inputs.insert({"input_b", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
             std::vector<float>({2, 2, 2, 2}));
@@ -3404,7 +3404,7 @@
   named_inputs.insert({"input_a", VectorToBigBuffer(input_data)});
   named_inputs.insert({"input_b", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
   EXPECT_EQ(BigBufferToVector<float>(std::move(named_outputs["output"])),
             std::vector<float>({2, 2, 2, 2}));
@@ -3456,7 +3456,7 @@
   named_inputs.insert({"input_b", VectorToBigBuffer(input_data2)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   // [[[[1.25 2.   3.  ]
@@ -3520,7 +3520,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   // [[[[ 0  0  0]
@@ -3556,7 +3556,7 @@
     named_inputs.insert({"input", VectorToBigBuffer(input.values)});
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyFloatDataIsEqual(
@@ -3622,7 +3622,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   // [[[[ -1  13]]
@@ -3676,7 +3676,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
   // [[[[ 0  13]]
   //   [[ 0  17]]
@@ -3741,7 +3741,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
 
   // [[ -1  -5  -9  -2  -6 -10  -3  -7 -11  -4  -8 -12]
@@ -3788,7 +3788,7 @@
   named_inputs.insert({"input", VectorToBigBuffer(input_data)});
   base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-  BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+  BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                   named_outputs);
   // [[ 0  0  0  0]
   //  [ 0  0  1  2]
@@ -3860,7 +3860,7 @@
                       13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24})});
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     std::vector<float> expected_output_data{0,  0,  0, 0,  0,  0,  0, 0,  0,
@@ -3928,7 +3928,7 @@
                       13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24})});
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyFloatDataIsEqual(
@@ -3993,7 +3993,7 @@
                       13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24})});
     base::flat_map<std::string, mojo_base::BigBuffer> named_outputs;
 
-    BuildAndCompute(builder.CloneGraphInfo(), std::move(named_inputs),
+    BuildAndCompute(builder.TakeGraphInfo(), std::move(named_inputs),
                     named_outputs);
 
     VerifyFloatDataIsEqual(
diff --git a/services/webnn/webnn_test_utils.h b/services/webnn/webnn_test_utils.h
index 491a7d1..90290998 100644
--- a/services/webnn/webnn_test_utils.h
+++ b/services/webnn/webnn_test_utils.h
@@ -526,16 +526,10 @@
 
   const mojom::GraphInfo& GetGraphInfo() const { return *graph_info_; }
 
-  // Get a clone of internal graph info. This is used by
-  // `WebNNContextDMLImplTest` because mojom::WebNNContext::CreateGraph()` needs
-  // to take the ownership of graph info.
-  //
-  // Notice cloning of graph info could be expensive and should only be used in
-  // tests.
+  // Prefer `TakeGraphInfo()` when possible. Cloning can be expensive and should
+  // only be used in tests.
   mojom::GraphInfoPtr CloneGraphInfo() const;
 
-  // TODO(crbug.com/354724062): Consider deprecating `CloneGraphInfo()` in favor
-  // of this method.
   mojom::GraphInfoPtr TakeGraphInfo();
 
  private:
diff --git a/testing/buildbot/chromeos.preuprev.json b/testing/buildbot/chromeos.preuprev.json
index cee77721..22a1253 100644
--- a/testing/buildbot/chromeos.preuprev.json
+++ b/testing/buildbot/chromeos.preuprev.json
@@ -112,6 +112,21 @@
         "variant_id": "RELEASE_LKGM"
       },
       {
+        "autotest_name": "tast.chrome-from-gcs",
+        "cros_board": "jacuzzi",
+        "name": "chrome_all_tast_tests RELEASE_LKGM",
+        "run_cft": true,
+        "shard_level_retries_on_ctp": 1,
+        "shards": 50,
+        "tast_expr": "STUB_STRING_TO_RUN_TAST_TESTS",
+        "test": "chrome_all_tast_tests",
+        "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/",
+        "test_level_retries": 1,
+        "timeout_sec": 14400,
+        "use_lkgm": true,
+        "variant_id": "RELEASE_LKGM"
+      },
+      {
         "autotest_name": "chromium",
         "cros_board": "jacuzzi",
         "name": "chromeos_integration_tests RELEASE_LKGM",
@@ -121,21 +136,6 @@
         "test_id_prefix": "ninja://chrome/test:chromeos_integration_tests/",
         "use_lkgm": true,
         "variant_id": "RELEASE_LKGM"
-      },
-      {
-        "autotest_name": "tast.chrome-from-gcs",
-        "cros_board": "jacuzzi",
-        "name": "cq_medium_tast_tests RELEASE_LKGM",
-        "run_cft": true,
-        "shard_level_retries_on_ctp": 1,
-        "shards": 10,
-        "tast_expr": "STUB_STRING_TO_RUN_TAST_TESTS",
-        "test": "cq_medium_tast_tests",
-        "test_id_prefix": "ninja://chromeos:cq_medium_tast_tests/",
-        "test_level_retries": 2,
-        "timeout_sec": 3600,
-        "use_lkgm": true,
-        "variant_id": "RELEASE_LKGM"
       }
     ]
   },
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 225c4c38..1f69f63 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -29437,7 +29437,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29466,7 +29466,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29485,7 +29485,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29514,7 +29514,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29533,7 +29533,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29562,7 +29562,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29581,7 +29581,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29610,7 +29610,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29629,7 +29629,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29658,7 +29658,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29677,7 +29677,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29706,7 +29706,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29725,7 +29725,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29754,7 +29754,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29773,7 +29773,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29802,7 +29802,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29821,7 +29821,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29850,7 +29850,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29869,7 +29869,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29898,7 +29898,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29917,7 +29917,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29946,7 +29946,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -29965,7 +29965,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -29994,7 +29994,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30013,7 +30013,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30042,7 +30042,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30061,7 +30061,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30090,7 +30090,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30109,7 +30109,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30138,7 +30138,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30157,7 +30157,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30186,7 +30186,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30205,7 +30205,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30234,7 +30234,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30253,7 +30253,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30282,7 +30282,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30304,7 +30304,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30333,7 +30333,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30356,7 +30356,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30385,7 +30385,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30408,7 +30408,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30437,7 +30437,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30460,7 +30460,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30489,7 +30489,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30514,7 +30514,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30543,7 +30543,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30568,7 +30568,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30597,7 +30597,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30622,7 +30622,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30651,7 +30651,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30676,7 +30676,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30705,7 +30705,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30730,7 +30730,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30759,7 +30759,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30784,7 +30784,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30813,7 +30813,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30838,7 +30838,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30867,7 +30867,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30890,7 +30890,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30919,7 +30919,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30942,7 +30942,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -30971,7 +30971,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -30994,7 +30994,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31023,7 +31023,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31046,7 +31046,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31075,7 +31075,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31098,7 +31098,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31127,7 +31127,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31149,7 +31149,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31178,7 +31178,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31200,7 +31200,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31229,7 +31229,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31251,7 +31251,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31280,7 +31280,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31304,7 +31304,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31333,7 +31333,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31358,7 +31358,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31387,7 +31387,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31412,7 +31412,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31441,7 +31441,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31466,7 +31466,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31495,7 +31495,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31515,7 +31515,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31544,7 +31544,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31563,7 +31563,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31592,7 +31592,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31611,7 +31611,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31640,7 +31640,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31659,7 +31659,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31688,7 +31688,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31710,7 +31710,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31739,7 +31739,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31762,7 +31762,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31791,7 +31791,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31814,7 +31814,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31843,7 +31843,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31866,7 +31866,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31895,7 +31895,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31915,7 +31915,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31944,7 +31944,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -31964,7 +31964,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -31993,7 +31993,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32012,7 +32012,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32041,7 +32041,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32061,7 +32061,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32090,7 +32090,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32109,7 +32109,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32138,7 +32138,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32157,7 +32157,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32186,7 +32186,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32205,7 +32205,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32234,7 +32234,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32253,7 +32253,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32282,7 +32282,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32301,7 +32301,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32330,7 +32330,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32352,7 +32352,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32381,7 +32381,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32403,7 +32403,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32432,7 +32432,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32454,7 +32454,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32483,7 +32483,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32502,7 +32502,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32531,7 +32531,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32550,7 +32550,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32579,7 +32579,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32598,7 +32598,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32627,7 +32627,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32646,7 +32646,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32675,7 +32675,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32694,7 +32694,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32723,7 +32723,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32742,7 +32742,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32771,7 +32771,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32790,7 +32790,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32819,7 +32819,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32838,7 +32838,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32867,7 +32867,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32886,7 +32886,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32915,7 +32915,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32934,7 +32934,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -32963,7 +32963,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -32982,7 +32982,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33011,7 +33011,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33030,7 +33030,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33059,7 +33059,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33078,7 +33078,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33107,7 +33107,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33126,7 +33126,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33155,7 +33155,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33174,7 +33174,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33203,7 +33203,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33222,7 +33222,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33251,7 +33251,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33270,7 +33270,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33299,7 +33299,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33318,7 +33318,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33347,7 +33347,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33366,7 +33366,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33395,7 +33395,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33414,7 +33414,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33443,7 +33443,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33462,7 +33462,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33491,7 +33491,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33510,7 +33510,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33539,7 +33539,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33558,7 +33558,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33587,7 +33587,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33606,7 +33606,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33635,7 +33635,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33661,7 +33661,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33690,7 +33690,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33709,7 +33709,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33738,7 +33738,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33757,7 +33757,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33786,7 +33786,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33805,7 +33805,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33834,7 +33834,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33853,7 +33853,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33882,7 +33882,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33901,7 +33901,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33930,7 +33930,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33949,7 +33949,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -33978,7 +33978,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -33997,7 +33997,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34026,7 +34026,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34045,7 +34045,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34074,7 +34074,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34093,7 +34093,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34122,7 +34122,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34141,7 +34141,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34170,7 +34170,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34189,7 +34189,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34218,7 +34218,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34237,7 +34237,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34266,7 +34266,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34285,7 +34285,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34314,7 +34314,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34333,7 +34333,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34362,7 +34362,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34381,7 +34381,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34410,7 +34410,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34429,7 +34429,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34458,7 +34458,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34477,7 +34477,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34506,7 +34506,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34525,7 +34525,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34554,7 +34554,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34573,7 +34573,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34602,7 +34602,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34621,7 +34621,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34650,7 +34650,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34669,7 +34669,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34698,7 +34698,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34717,7 +34717,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34746,7 +34746,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34765,7 +34765,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34794,7 +34794,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34816,7 +34816,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34845,7 +34845,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34868,7 +34868,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34897,7 +34897,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34920,7 +34920,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -34949,7 +34949,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -34974,7 +34974,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35003,7 +35003,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35028,7 +35028,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35057,7 +35057,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35082,7 +35082,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35111,7 +35111,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35136,7 +35136,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35165,7 +35165,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35190,7 +35190,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35219,7 +35219,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35244,7 +35244,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35273,7 +35273,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35296,7 +35296,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35325,7 +35325,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35348,7 +35348,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35377,7 +35377,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35400,7 +35400,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35429,7 +35429,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35452,7 +35452,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35481,7 +35481,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35503,7 +35503,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35532,7 +35532,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35554,7 +35554,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35583,7 +35583,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35607,7 +35607,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35636,7 +35636,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35661,7 +35661,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35690,7 +35690,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35715,7 +35715,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35744,7 +35744,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35764,7 +35764,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35793,7 +35793,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35812,7 +35812,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35841,7 +35841,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35860,7 +35860,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35889,7 +35889,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35908,7 +35908,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35937,7 +35937,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -35959,7 +35959,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -35988,7 +35988,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36011,7 +36011,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36040,7 +36040,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36063,7 +36063,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36092,7 +36092,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36112,7 +36112,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36141,7 +36141,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36160,7 +36160,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36189,7 +36189,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36209,7 +36209,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36238,7 +36238,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36258,7 +36258,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36287,7 +36287,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36306,7 +36306,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36335,7 +36335,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36355,7 +36355,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36384,7 +36384,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36404,7 +36404,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36433,7 +36433,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36452,7 +36452,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36481,7 +36481,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36500,7 +36500,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36529,7 +36529,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36548,7 +36548,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36577,7 +36577,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36596,7 +36596,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36625,7 +36625,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36644,7 +36644,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36673,7 +36673,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36692,7 +36692,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36721,7 +36721,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36740,7 +36740,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36769,7 +36769,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36791,7 +36791,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36820,7 +36820,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36842,7 +36842,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36871,7 +36871,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36893,7 +36893,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36922,7 +36922,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36941,7 +36941,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -36970,7 +36970,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -36989,7 +36989,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37018,7 +37018,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37037,7 +37037,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37066,7 +37066,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37085,7 +37085,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37114,7 +37114,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37133,7 +37133,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37162,7 +37162,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37181,7 +37181,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37210,7 +37210,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37229,7 +37229,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37258,7 +37258,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37277,7 +37277,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37306,7 +37306,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37325,7 +37325,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37354,7 +37354,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37373,7 +37373,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37402,7 +37402,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37421,7 +37421,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37450,7 +37450,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37469,7 +37469,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37498,7 +37498,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37517,7 +37517,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37546,7 +37546,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37565,7 +37565,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37594,7 +37594,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37613,7 +37613,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37642,7 +37642,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37661,7 +37661,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37690,7 +37690,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37709,7 +37709,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37738,7 +37738,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37757,7 +37757,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37786,7 +37786,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37805,7 +37805,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37834,7 +37834,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37853,7 +37853,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37882,7 +37882,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37901,7 +37901,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37930,7 +37930,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37949,7 +37949,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -37978,7 +37978,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -37997,7 +37997,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -38026,7 +38026,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -38045,7 +38045,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -38074,7 +38074,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -38093,7 +38093,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -38122,7 +38122,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -38141,7 +38141,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -38170,7 +38170,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -38189,7 +38189,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -38218,7 +38218,7 @@
               "path": "Runtime-ios-17.5"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
@@ -38237,7 +38237,7 @@
           "--out-dir",
           "${ISOLATED_OUTDIR}",
           "--xcode-build-version",
-          "16a5230g",
+          "16a242",
           "--xctest"
         ],
         "merge": {
@@ -38266,7 +38266,7 @@
               "path": "Runtime-ios-18.0"
             },
             {
-              "name": "xcode_ios_16a5230g",
+              "name": "xcode_ios_16a242",
               "path": "Xcode.app"
             }
           ],
diff --git a/testing/buildbot/mixins.pyl b/testing/buildbot/mixins.pyl
index 11c352d2..925671bb 100644
--- a/testing/buildbot/mixins.pyl
+++ b/testing/buildbot/mixins.pyl
@@ -1161,15 +1161,15 @@
       'failed_only',
     ],
   },
-  'shards-10': {
-    'shards': 10,
-  },
   'shards-20': {
     'shards': 20,
   },
   'shards-30': {
     'shards': 30,
   },
+  'shards-50': {
+    'shards': 50,
+  },
   'shiba': {
     'swarming': {
       'dimensions': {
@@ -1485,12 +1485,12 @@
   'xcode_16_beta': {
     'args': [
       '--xcode-build-version',
-      '16a5230g',
+      '16a242',
     ],
     'swarming': {
       'named_caches': [
         {
-          'name': 'xcode_ios_16a5230g',
+          'name': 'xcode_ios_16a242',
           'path': 'Xcode.app',
         },
       ],
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index cfafce2..db81b73 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -382,7 +382,7 @@
           'skylab-cft',
         ],
         'test_suites': {
-          'skylab_tests': 'chromeos_jacuzzi_preuprev_tests',
+          'skylab_tests': 'chromeos_ctp_preuprev_tests_slow_boards',
         },
         'os_type': 'chromeos',
         'cros_board': 'jacuzzi',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 31945fb..ca97543 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -4017,6 +4017,24 @@
             ]
         }
     ],
+    "CastCertificateRevocation": [
+        {
+            "platforms": [
+                "chromeos",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "CastCertificateRevocation"
+                    ]
+                }
+            ]
+        }
+    ],
     "CastMirroringPlayoutDelayChromeOS": [
         {
             "platforms": [
@@ -5554,6 +5572,25 @@
             ]
         }
     ],
+    "CloneDevToolsConnectionOnlyIfRequested": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "CloneDevToolsConnectionOnlyIfRequested"
+                    ]
+                }
+            ]
+        }
+    ],
     "CoalesceSelectionchangeEvent": [
         {
             "platforms": [
@@ -13653,6 +13690,13 @@
                         "Mahi",
                         "MediaAppPdfMahi"
                     ]
+                },
+                {
+                    "name": "Disabled",
+                    "disable_features": [
+                        "Mahi",
+                        "MediaAppPdfMahi"
+                    ]
                 }
             ]
         }
@@ -17225,6 +17269,27 @@
             ]
         }
     ],
+    "PolicyBlocklistProceedUntilResponse": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "ios",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "PolicyBlocklistProceedUntilResponse"
+                    ]
+                }
+            ]
+        }
+    ],
     "PostGetMyMemoryStateToBackground": [
         {
             "platforms": [
diff --git a/third_party/angle b/third_party/angle
index 53476d6..941b3df 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit 53476d6ff2740267db0c0573644378621c4e7d78
+Subproject commit 941b3df3df32a06a4b8a01c41c5522e2ea859d04
diff --git a/third_party/blink/common/DEPS b/third_party/blink/common/DEPS
index 0c8365b8..dd89d84e 100644
--- a/third_party/blink/common/DEPS
+++ b/third_party/blink/common/DEPS
@@ -10,6 +10,7 @@
     "+build",
     "+crypto/sha2.h",
     "+cc/mojom/browser_controls_params.mojom.h",
+    "+gpu/command_buffer/common/shared_image_usage.h",
     "+net",
     "+media",
     "+mojo",
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc
index 65d975b0..726d699 100644
--- a/third_party/blink/common/features.cc
+++ b/third_party/blink/common/features.cc
@@ -743,9 +743,11 @@
     &kDelayLowPriorityRequestsAccordingToNetworkState,
     "MaxNumOfThrottleableRequestsInTightMode", 5};
 
-const base::FeatureParam<base::TimeDelta> kHttpRttThreshold{
-    &kDelayLowPriorityRequestsAccordingToNetworkState, "HttpRttThreshold",
-    base::Milliseconds(450)};
+BASE_FEATURE_PARAM(base::TimeDelta,
+                   kHttpRttThreshold,
+                   &kDelayLowPriorityRequestsAccordingToNetworkState,
+                   "HttpRttThreshold",
+                   base::Milliseconds(450));
 
 const base::FeatureParam<double> kCostReductionOfMultiplexedRequests{
     &kDelayLowPriorityRequestsAccordingToNetworkState,
diff --git a/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc b/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc
index fd66a20..994b519 100644
--- a/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc
+++ b/third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc
@@ -4,6 +4,7 @@
 
 #include "third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h"
 
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/bindings/self_owned_receiver.h"
 
@@ -54,6 +55,14 @@
   return callback;
 }
 
+bool StructTraits<blink::mojom::SharedImageUsageSet::DataView,
+                  gpu::SharedImageUsageSet>::
+    Read(blink::mojom::SharedImageUsageSet::DataView data,
+         gpu::SharedImageUsageSet* out) {
+  *out = gpu::SharedImageUsageSet(data.usage());
+  return true;
+}
+
 bool StructTraits<blink::mojom::AcceleratedStaticBitmapImage::DataView,
                   blink::AcceleratedImageInfo>::
     Read(blink::mojom::AcceleratedStaticBitmapImage::DataView data,
@@ -63,7 +72,9 @@
     return false;
   }
 
-  out->usage = data.usage();
+  if (!data.ReadUsage(&out->usage)) {
+    return false;
+  }
   out->is_origin_top_left = data.is_origin_top_left();
   out->supports_display_compositing = data.supports_display_compositing();
   out->is_overlay_candidate = data.is_overlay_candidate();
diff --git a/third_party/blink/public/common/DEPS b/third_party/blink/public/common/DEPS
index c1e2c22..0d2241e 100644
--- a/third_party/blink/public/common/DEPS
+++ b/third_party/blink/public/common/DEPS
@@ -13,6 +13,7 @@
     "+components/viz/common/surfaces/local_surface_id.h",
     "+components/viz/common/view_transition_element_resource_id.h",
     "+gpu/command_buffer/common/mailbox_holder.h",
+    "+gpu/command_buffer/common/shared_image_usage.h",
     "+net",
     "+media",
     "+mojo",
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h
index 129d2d27..94abb57 100644
--- a/third_party/blink/public/common/features.h
+++ b/third_party/blink/public/common/features.h
@@ -415,8 +415,8 @@
 // The HTTP RTT threshold: decide whether the
 // `kDelayLowPriorityRequestsAccordingToNetworkState` feature can take effect
 // practically according to the network connection state.
-BLINK_COMMON_EXPORT
-extern const base::FeatureParam<base::TimeDelta> kHttpRttThreshold;
+BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE_PARAM(base::TimeDelta,
+                                               kHttpRttThreshold);
 // The cost reduction for the multiplexed requests when
 // `kDelayLowPriorityRequestsAccordingToNetworkState` is enabled.
 BLINK_COMMON_EXPORT
diff --git a/third_party/blink/public/common/messaging/accelerated_image_info.h b/third_party/blink/public/common/messaging/accelerated_image_info.h
index 0164136d..6c185231 100644
--- a/third_party/blink/public/common/messaging/accelerated_image_info.h
+++ b/third_party/blink/public/common/messaging/accelerated_image_info.h
@@ -7,6 +7,7 @@
 
 #include "base/functional/callback.h"
 #include "gpu/command_buffer/common/mailbox_holder.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "third_party/blink/public/common/common_export.h"
 #include "third_party/skia/include/core/SkImage.h"
@@ -19,7 +20,7 @@
 // for details.
 struct BLINK_COMMON_EXPORT AcceleratedImageInfo {
   gpu::MailboxHolder mailbox_holder;
-  uint32_t usage;
+  gpu::SharedImageUsageSet usage;
   SkImageInfo image_info;
   bool is_origin_top_left;
   bool supports_display_compositing;
diff --git a/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h b/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h
index 7cc2b68..f9a97ed 100644
--- a/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h
+++ b/third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h
@@ -13,6 +13,18 @@
 
 template <>
 struct BLINK_COMMON_EXPORT
+    StructTraits<blink::mojom::SharedImageUsageSet::DataView,
+                 gpu::SharedImageUsageSet> {
+  static uint32_t usage(const gpu::SharedImageUsageSet& input) {
+    return uint32_t(input);
+  }
+
+  static bool Read(blink::mojom::SharedImageUsageSet::DataView data,
+                   gpu::SharedImageUsageSet* out);
+};
+
+template <>
+struct BLINK_COMMON_EXPORT
     StructTraits<blink::mojom::AcceleratedStaticBitmapImage::DataView,
                  blink::AcceleratedImageInfo> {
   static const gpu::MailboxHolder& mailbox_holder(
@@ -20,7 +32,8 @@
     return input.mailbox_holder;
   }
 
-  static uint32_t usage(const blink::AcceleratedImageInfo& input) {
+  static gpu::SharedImageUsageSet usage(
+      const blink::AcceleratedImageInfo& input) {
     return input.usage;
   }
 
diff --git a/third_party/blink/public/mojom/messaging/static_bitmap_image.mojom b/third_party/blink/public/mojom/messaging/static_bitmap_image.mojom
index 7a3f66e..76c3a6a 100644
--- a/third_party/blink/public/mojom/messaging/static_bitmap_image.mojom
+++ b/third_party/blink/public/mojom/messaging/static_bitmap_image.mojom
@@ -8,6 +8,7 @@
 import "gpu/ipc/common/mailbox_holder.mojom";
 import "gpu/ipc/common/sync_token.mojom";
 import "skia/public/mojom/image_info.mojom";
+import "mojo/public/mojom/base/values.mojom";
 
 // This interface is used to manage the lifetime of the
 // AcceleratedStaticBitmapImage transferred in the TranferableMessage.
@@ -24,6 +25,11 @@
   Release(gpu.mojom.SyncToken token);
 };
 
+// Isolate unsafe conversion to/from uint32.
+struct SharedImageUsageSet {
+  uint32 usage;
+};
+
 // Holds all information, necessary to recreate the accelerated image.
 struct AcceleratedStaticBitmapImage {
   // Mailbox holder contains SharedImage reference:
@@ -32,7 +38,7 @@
   // Shared image usage: a bitmask identifying which API(s)
   // the SharedImage may be used with.
   // See gpu/command_buffer/common/shared_image_usage.h
-  uint32 usage;
+  SharedImageUsageSet usage;
   // Common image metadata.
   skia.mojom.ImageInfo image_info;
   // Indicates the orientation of the image.
diff --git a/third_party/blink/public/platform/web_media_player.h b/third_party/blink/public/platform/web_media_player.h
index d0cc347..5a08291 100644
--- a/third_party/blink/public/platform/web_media_player.h
+++ b/third_party/blink/public/platform/web_media_player.h
@@ -159,9 +159,9 @@
   virtual void SetPreservesPitch(bool preserves_pitch) = 0;
 
   // Sets a flag indicating whether the audio stream was played with user
-  // activation.
-  virtual void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) = 0;
+  // activation and high media engagement.
+  virtual void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) = 0;
 
   // Sets a flag indicating whether media playback should be paused when the
   // the iframe is hidden.
@@ -334,8 +334,8 @@
 
   virtual void EnabledAudioTracksChanged(
       const WebVector<TrackId>& enabled_track_ids) {}
-  // |selected_track_id| is null if no track is selected.
-  virtual void SelectedVideoTrackChanged(TrackId* selected_track_id) {}
+  virtual void SelectedVideoTrackChanged(
+      std::optional<TrackId> selected_track_id) {}
 
   // Callback called whenever the media element may have received or last native
   // controls. It might be called twice with the same value: the caller has to
diff --git a/third_party/blink/public/web/modules/mediastream/web_media_player_ms.h b/third_party/blink/public/web/modules/mediastream/web_media_player_ms.h
index 87a66d6..3c2d0e2 100644
--- a/third_party/blink/public/web/modules/mediastream/web_media_player_ms.h
+++ b/third_party/blink/public/web/modules/mediastream/web_media_player_ms.h
@@ -116,8 +116,8 @@
   void SetVolume(double volume) override;
   void SetLatencyHint(double seconds) override;
   void SetPreservesPitch(bool preserves_pitch) override;
-  void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) override;
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) override;
   void OnRequestPictureInPicture() override;
   bool SetSinkId(const WebString& sink_id,
                  WebSetSinkIdCompleteCallback completion_callback) override;
diff --git a/third_party/blink/renderer/bindings/generated_in_core.gni b/third_party/blink/renderer/bindings/generated_in_core.gni
index 0ea52d1..139ae45 100644
--- a/third_party/blink/renderer/bindings/generated_in_core.gni
+++ b/third_party/blink/renderer/bindings/generated_in_core.gni
@@ -404,6 +404,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_shared_worker_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_show_context_menu_item.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_show_context_menu_item.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_show_popover_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_show_popover_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_static_range_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_static_range_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_stream_pipe_options.cc",
@@ -432,6 +434,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_timeline_range_offset.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_toggle_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_toggle_event_init.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_toggle_popover_options.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_toggle_popover_options.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_touch_event_init.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_touch_event_init.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_touch_init.cc",
@@ -1796,6 +1800,8 @@
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_boolean_scrollintoviewoptions.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_boolean_string_unrestricteddouble.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_boolean_string_unrestricteddouble.h",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_boolean_togglepopoveroptions.cc",
+  "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_boolean_togglepopoveroptions.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_bytestringbytestringrecord_bytestringsequencesequence.cc",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_bytestringbytestringrecord_bytestringsequencesequence.h",
   "$root_gen_dir/third_party/blink/renderer/bindings/core/v8/v8_union_childnodepart_documentpartroot.cc",
diff --git a/third_party/blink/renderer/bindings/idl_in_core.gni b/third_party/blink/renderer/bindings/idl_in_core.gni
index 9283397..d3e0ac29 100644
--- a/third_party/blink/renderer/bindings/idl_in_core.gni
+++ b/third_party/blink/renderer/bindings/idl_in_core.gni
@@ -463,6 +463,7 @@
   "//third_party/blink/renderer/core/html/media/html_media_element.idl",
   "//third_party/blink/renderer/core/html/media/html_video_element.idl",
   "//third_party/blink/renderer/core/html/media/media_error.idl",
+  "//third_party/blink/renderer/core/html/popover_options.idl",
   "//third_party/blink/renderer/core/html/time_ranges.idl",
   "//third_party/blink/renderer/core/html/track/audio_track.idl",
   "//third_party/blink/renderer/core/html/track/audio_track_list.idl",
diff --git a/third_party/blink/renderer/core/css/cssom/css_hsl.h b/third_party/blink/renderer/core/css/cssom/css_hsl.h
index 0d1d16c47..af18e36 100644
--- a/third_party/blink/renderer/core/css/cssom/css_hsl.h
+++ b/third_party/blink/renderer/core/css/cssom/css_hsl.h
@@ -33,7 +33,7 @@
          CSSNumericValue*);
 
   // Getters and setters from the IDL
-  Member<CSSNumericValue> h() const { return h_; }
+  CSSNumericValue* h() const { return h_.Get(); }
   V8CSSNumberish* s() const;
   V8CSSNumberish* l() const;
   V8CSSNumberish* alpha() const;
diff --git a/third_party/blink/renderer/core/css/cssom/css_hwb.h b/third_party/blink/renderer/core/css/cssom/css_hwb.h
index 33733505..aa85a2f 100644
--- a/third_party/blink/renderer/core/css/cssom/css_hwb.h
+++ b/third_party/blink/renderer/core/css/cssom/css_hwb.h
@@ -33,7 +33,7 @@
          CSSNumericValue*);
 
   // Getters and setters from the IDL
-  Member<CSSNumericValue> h() const { return h_; }
+  CSSNumericValue* h() const { return h_.Get(); }
   V8CSSNumberish* w() const;
   V8CSSNumberish* b() const;
   V8CSSNumberish* alpha() const;
diff --git a/third_party/blink/renderer/core/fullscreen/document_fullscreen.h b/third_party/blink/renderer/core/fullscreen/document_fullscreen.h
index b437118..40697fb 100644
--- a/third_party/blink/renderer/core/fullscreen/document_fullscreen.h
+++ b/third_party/blink/renderer/core/fullscreen/document_fullscreen.h
@@ -43,6 +43,9 @@
  public:
   static bool fullscreenEnabled(Document&);
   static Element* fullscreenElement(Document&);
+  static bool fullscreen(Document& document) {
+    return !!fullscreenElement(document);
+  }
   static ScriptPromise<IDLUndefined> exitFullscreen(ScriptState*,
                                                     Document&,
                                                     ExceptionState&);
diff --git a/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl b/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl
index 92c729b..6ec7cee 100644
--- a/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl
+++ b/third_party/blink/renderer/core/fullscreen/document_fullscreen.idl
@@ -25,7 +25,7 @@
     ImplementedAs=DocumentFullscreen
 ] partial interface Document {
     [LegacyLenientSetter] readonly attribute boolean fullscreenEnabled;
-    [LegacyLenientSetter, Unscopable, ImplementedAs=fullscreenElement] readonly attribute boolean fullscreen;
+    [LegacyLenientSetter, Unscopable] readonly attribute boolean fullscreen;
 
     [CallWith=ScriptState, RaisesException] Promise<undefined> exitFullscreen();
 
@@ -33,7 +33,7 @@
     attribute EventHandler onfullscreenerror;
 
     // Mozilla version
-    [MeasureAs=PrefixedDocumentIsFullscreen, ImplementedAs=fullscreenElement] readonly attribute boolean webkitIsFullScreen;
+    [MeasureAs=PrefixedDocumentIsFullscreen, ImplementedAs=fullscreen] readonly attribute boolean webkitIsFullScreen;
     [MeasureAs=PrefixedDocumentCurrentFullScreenElement, ImplementedAs=fullscreenElement] readonly attribute Element webkitCurrentFullScreenElement;
     [MeasureAs=PrefixedDocumentCancelFullScreen, ImplementedAs=webkitExitFullscreen] void webkitCancelFullScreen();
 
diff --git a/third_party/blink/renderer/core/html/DEPS b/third_party/blink/renderer/core/html/DEPS
index b5041b10..2c096b32 100644
--- a/third_party/blink/renderer/core/html/DEPS
+++ b/third_party/blink/renderer/core/html/DEPS
@@ -1,10 +1,14 @@
 specific_include_rules = {
     "canvas_image_source.cc": [
         "+gpu/command_buffer/client/shared_image_interface.h",
+        "+gpu/command_buffer/common/shared_image_usage.h",
     ],
     "canvas_rendering_context.cc": [
         "+services/metrics/public/cpp/ukm_builders.h",
     ],
+    "canvas_rendering_context_host.cc": [
+        "+gpu/command_buffer/common/shared_image_usage.h",
+    ],
     "client_hints_util.cc": [
         "+services/network/public/cpp/client_hints.h",
         "+url/gurl.h",
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_image_source.cc b/third_party/blink/renderer/core/html/canvas/canvas_image_source.cc
index 63530bf5..0c3c7d92 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_image_source.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_image_source.cc
@@ -5,6 +5,7 @@
 #include "third_party/blink/renderer/core/html/canvas/canvas_image_source.h"
 
 #include "gpu/command_buffer/client/shared_image_interface.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
 #include "third_party/blink/renderer/platform/graphics/skia/skia_utils.h"
 
@@ -19,7 +20,7 @@
   const cc::PaintFlags::FilterQuality filter_quality =
       cc::PaintFlags::FilterQuality::kLow;
   if (context_provider) {
-    const uint32_t usage_flags =
+    const gpu::SharedImageUsageSet usage_flags =
         context_provider->ContextProvider()
             ->SharedImageInterface()
             ->UsageForMailbox(source_image->GetMailboxHolder().mailbox);
diff --git a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
index 8d6933e..37670a9 100644
--- a/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
+++ b/third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc
@@ -8,6 +8,7 @@
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "gpu/config/gpu_feature_info.h"
 #include "third_party/blink/public/common/features.h"
 #include "third_party/blink/public/common/privacy_budget/identifiability_study_settings.h"
@@ -137,7 +138,7 @@
   std::unique_ptr<CanvasResourceProvider> provider;
   if (SharedGpuContext::IsGpuCompositingEnabled()) {
     provider = CanvasResourceProvider::CreateWebGPUImageProvider(
-        resource_info, /*shared_image_usage_flags=*/0, this);
+        resource_info, gpu::SharedImageUsageSet(), this);
   }
   ReplaceResourceProvider(std::move(provider));
   if (ResourceProvider() && ResourceProvider()->IsValid()) {
@@ -187,7 +188,8 @@
       // If PassThrough failed, try a SharedImage with usage display enabled,
       // and if WebGLImageChromium is enabled, add concurrent read write and
       // usage scanout (overlay).
-      uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
+      gpu::SharedImageUsageSet shared_image_usage_flags =
+          gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
       if (SharedGpuContext::MaySupportImageChromium() &&
           (RuntimeEnabledFeatures::WebGLImageChromiumEnabled() ||
            base::FeatureList::IsEnabled(
@@ -205,7 +207,8 @@
     // If there is no LowLatency mode, and GPU is enabled, will try a GPU
     // SharedImage that should support Usage Display and probably Usage Scanout
     // if WebGLImageChromium is enabled.
-    uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
+    gpu::SharedImageUsageSet shared_image_usage_flags =
+        gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
     if (SharedGpuContext::MaySupportImageChromium() &&
         RuntimeEnabledFeatures::WebGLImageChromiumEnabled()) {
       shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
@@ -264,7 +267,8 @@
     // with a set of flags trying to add Usage Display and Usage Scanout and
     // Concurrent Read and Write if possible.
     if (!provider) {
-      uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
+      gpu::SharedImageUsageSet shared_image_usage_flags =
+          gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
       if (SharedGpuContext::MaySupportImageChromium() &&
           (RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled() ||
            base::FeatureList::IsEnabled(
@@ -282,7 +286,8 @@
     // First try to be optimized for displaying on screen. In the case we are
     // hardware compositing, we also try to enable the usage of the image as
     // scanout buffer (overlay)
-    uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
+    gpu::SharedImageUsageSet shared_image_usage_flags =
+        gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
     if (SharedGpuContext::MaySupportImageChromium() &&
         RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) {
       shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
@@ -293,7 +298,7 @@
         shared_image_usage_flags, this);
   } else if (SharedGpuContext::MaySupportImageChromium() &&
              RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) {
-    const uint32_t shared_image_usage_flags =
+    const gpu::SharedImageUsageSet shared_image_usage_flags =
         gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
     provider = CanvasResourceProvider::CreateSharedImageProvider(
         resource_info, FilterQuality(), kShouldInitialize,
diff --git a/third_party/blink/renderer/core/html/forms/html_input_element.cc b/third_party/blink/renderer/core/html/forms/html_input_element.cc
index 6f411c0..77373ee 100644
--- a/third_party/blink/renderer/core/html/forms/html_input_element.cc
+++ b/third_party/blink/renderer/core/html/forms/html_input_element.cc
@@ -856,9 +856,7 @@
         autocomplete_ = kOn;
     }
   } else if (name == html_names::kTypeAttr) {
-    if ((!RuntimeEnabledFeatures::
-             SkipUpdateTypeForHTMLInputElementCreatedByParserEnabled() ||
-         params.reason != AttributeModificationReason::kByParser) &&
+    if (params.reason != AttributeModificationReason::kByParser &&
         params.old_value != value) {
       UpdateType(value);
     }
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc
index e268c66a..61e4961 100644
--- a/third_party/blink/renderer/core/html/html_element.cc
+++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -35,6 +35,9 @@
 #include "third_party/blink/public/mojom/forms/form_control_type.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/js_event_handler_for_content_attribute.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_show_popover_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_toggle_popover_options.h"
+#include "third_party/blink/renderer/bindings/core/v8/v8_union_boolean_togglepopoveroptions.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_union_stringlegacynulltoemptystring_trustedscript.h"
 #include "third_party/blink/renderer/core/accessibility/ax_object_cache.h"
 #include "third_party/blink/renderer/core/css/css_color.h"
@@ -1386,41 +1389,64 @@
 }  // namespace
 
 bool HTMLElement::togglePopover(ExceptionState& exception_state) {
-  if (popoverOpen()) {
-    hidePopover(exception_state);
-  } else {
-    ShowPopoverInternal(/*invoker*/ nullptr, &exception_state);
-  }
-
-  if (GetPopoverData()) {
-    return GetPopoverData()->visibilityState() ==
-           PopoverVisibilityState::kShowing;
-  }
-  return false;
+  return togglePopover(nullptr, exception_state);
 }
 
-bool HTMLElement::togglePopover(bool force, ExceptionState& exception_state) {
-  if (!force && popoverOpen()) {
-    hidePopover(exception_state);
-  } else if (force && !popoverOpen()) {
-    ShowPopoverInternal(/*invoker*/ nullptr, &exception_state);
+// The `force` parameter to `togglePopover()` is specified here:
+// https://html.spec.whatwg.org/multipage/popover.html#dom-togglepopover
+// and is roughly:
+//  - If `force` is provided, and true, then ensure the popover is *shown*.
+//    So if the popover is already showing, do nothing.
+//  - If `force` is provided, and false, then ensure the popover is *hidden*.
+//    So if the popover is already hidden, do nothing.
+//  - If `force` is not provided, just toggle the popover's current state.
+bool HTMLElement::togglePopover(
+    V8UnionBooleanOrTogglePopoverOptions* options_or_force,
+    ExceptionState& exception_state) {
+  bool popover_was_open = popoverOpen();
+  bool force = !popover_was_open;
+  Element* invoker;
+  if (options_or_force && options_or_force->IsBoolean()) {
+    force = options_or_force->GetAsBoolean();
+    invoker = nullptr;
   } else {
-    // Throw an exception if this element is disconnected or doesn't have a
-    // popover attribute.
+    TogglePopoverOptions* options =
+        (options_or_force &&
+         RuntimeEnabledFeatures::PopoverAnchorRelationshipsEnabled())
+            ? options_or_force->GetAsTogglePopoverOptions()
+            : nullptr;
+    if (options && options->hasForce()) {
+      force = options->force();
+    }
+    invoker = (options && options->hasInvoker()) ? options->invoker() : nullptr;
+  }
+  if (!force && popover_was_open) {
+    hidePopover(exception_state);
+  } else if (force && !popover_was_open) {
+    ShowPopoverInternal(invoker, &exception_state);
+  } else {
+    // We had `force`, and the state already lined up. Just make sure to still
+    // throw exceptions in other cases, e.g. disconnected element or no popover
+    // attribute.
     IsPopoverReady(PopoverTriggerAction::kToggle, &exception_state,
                    /*include_event_handler_text=*/false,
                    /*document=*/nullptr);
   }
-
-  if (GetPopoverData()) {
-    return GetPopoverData()->visibilityState() ==
-           PopoverVisibilityState::kShowing;
-  }
-  return false;
+  return GetPopoverData() && GetPopoverData()->visibilityState() ==
+                                 PopoverVisibilityState::kShowing;
 }
 
 void HTMLElement::showPopover(ExceptionState& exception_state) {
-  ShowPopoverInternal(/*invoker*/ nullptr, &exception_state);
+  return showPopover(nullptr, exception_state);
+}
+void HTMLElement::showPopover(ShowPopoverOptions* options,
+                              ExceptionState& exception_state) {
+  if (!RuntimeEnabledFeatures::PopoverAnchorRelationshipsEnabled()) {
+    options = nullptr;
+  }
+  Element* invoker =
+      options && options->hasInvoker() ? options->invoker() : nullptr;
+  ShowPopoverInternal(invoker, &exception_state);
 }
 
 void HTMLElement::ShowPopoverInternal(Element* invoker,
diff --git a/third_party/blink/renderer/core/html/html_element.h b/third_party/blink/renderer/core/html/html_element.h
index acee812..e5c2110 100644
--- a/third_party/blink/renderer/core/html/html_element.h
+++ b/third_party/blink/renderer/core/html/html_element.h
@@ -48,6 +48,8 @@
 class KeyboardEvent;
 class TextControlElement;
 class V8UnionStringLegacyNullToEmptyStringOrTrustedScript;
+class V8UnionBooleanOrTogglePopoverOptions;
+class ShowPopoverOptions;
 
 enum TranslateAttributeMode {
   kTranslateAttributeYes,
@@ -260,8 +262,11 @@
                       bool include_event_handler_text,
                       Document* expected_document) const;
   bool togglePopover(ExceptionState& exception_state);
-  bool togglePopover(bool force, ExceptionState& exception_state);
+  bool togglePopover(V8UnionBooleanOrTogglePopoverOptions* options_or_force,
+                     ExceptionState& exception_state);
   void showPopover(ExceptionState& exception_state);
+  void showPopover(ShowPopoverOptions* options,
+                   ExceptionState& exception_state);
   void hidePopover(ExceptionState& exception_state);
   // |exception_state| can be nullptr when exceptions can't be thrown, such as
   // when the browser hides a popover during light dismiss or shows a popover in
diff --git a/third_party/blink/renderer/core/html/html_element.idl b/third_party/blink/renderer/core/html/html_element.idl
index d18fe30..5b153334 100644
--- a/third_party/blink/renderer/core/html/html_element.idl
+++ b/third_party/blink/renderer/core/html/html_element.idl
@@ -66,9 +66,10 @@
     [ImplementedAs=offsetHeightForBinding] readonly attribute long offsetHeight;
 
     // The Popover API
-    [MeasureAs=ElementTogglePopover,RaisesException] boolean togglePopover(optional boolean force);
-    [MeasureAs=ElementShowPopover,RaisesException] void showPopover();
+    [MeasureAs=ElementTogglePopover,RaisesException] boolean togglePopover(optional (TogglePopoverOptions or boolean) options);
+    [MeasureAs=ElementShowPopover,RaisesException] void showPopover(optional ShowPopoverOptions options);
     [MeasureAs=ElementHidePopover,RaisesException] void hidePopover();
+
     // See crbug.com/1418144. We need to change ReflectOnly based on a runtime flag, which isn't possible.
     // See also crbug.com/1416284. When HTMLPopoverHint is removed as a flag, we should be able to go back to using [Reflect].
     // [CEReactions,Reflect,ReflectOnly=("auto","hint","manual"),ReflectEmpty="auto",ReflectInvalid="manual"] attribute DOMString? popover;
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc
index 7178c0b..bd7a7b8a 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -2858,8 +2858,9 @@
   DVLOG(3) << "playInternal(" << *this << ")";
 
   if (web_media_player_) {
-    web_media_player_->SetWasPlayedWithUserActivation(
-        LocalFrame::HasTransientUserActivation(GetDocument().GetFrame()));
+    web_media_player_->SetWasPlayedWithUserActivationAndHighMediaEngagement(
+        LocalFrame::HasTransientUserActivation(GetDocument().GetFrame()) &&
+        AutoplayPolicy::DocumentHasHighMediaEngagement(GetDocument()));
   }
 
   // Playback aborts any lazy loading.
@@ -3247,9 +3248,11 @@
   if (media_source_attachment_)
     media_source_attachment_->OnTrackChanged(media_source_tracer_, track);
 
-  WebMediaPlayer::TrackId id = track->id();
-  web_media_player_->SelectedVideoTrackChanged(track->selected() ? &id
-                                                                 : nullptr);
+  if (track->selected()) {
+    web_media_player_->SelectedVideoTrackChanged(track->id());
+  } else {
+    web_media_player_->SelectedVideoTrackChanged(std::nullopt);
+  }
 }
 
 void HTMLMediaElement::AddMediaTrack(const media::MediaTrack& track) {
diff --git a/third_party/blink/renderer/core/html/media/html_media_element_test.cc b/third_party/blink/renderer/core/html/media/html_media_element_test.cc
index d47ae1a4..4b29235 100644
--- a/third_party/blink/renderer/core/html/media/html_media_element_test.cc
+++ b/third_party/blink/renderer/core/html/media/html_media_element_test.cc
@@ -95,9 +95,10 @@
   MOCK_CONST_METHOD0(GetNetworkState, NetworkState());
   MOCK_CONST_METHOD0(WouldTaintOrigin, bool());
   MOCK_METHOD1(SetLatencyHint, void(double));
-  MOCK_METHOD1(SetWasPlayedWithUserActivation, void(bool));
+  MOCK_METHOD1(SetWasPlayedWithUserActivationAndHighMediaEngagement,
+               void(bool));
   MOCK_METHOD1(EnabledAudioTracksChanged, void(const WebVector<TrackId>&));
-  MOCK_METHOD1(SelectedVideoTrackChanged, void(TrackId*));
+  MOCK_METHOD1(SelectedVideoTrackChanged, void(std::optional<TrackId>));
   MOCK_METHOD4(
       Load,
       WebMediaPlayer::LoadTiming(LoadType load_type,
@@ -1664,7 +1665,8 @@
   SetReadyState(HTMLMediaElement::kHaveEnoughData);
   test::RunPendingTasks();
 
-  EXPECT_CALL(*MockMediaPlayer(), SetWasPlayedWithUserActivation(false));
+  EXPECT_CALL(*MockMediaPlayer(),
+              SetWasPlayedWithUserActivationAndHighMediaEngagement(false));
   Media()->Play();
 }
 
@@ -1679,7 +1681,25 @@
       Media()->GetDocument().GetFrame(),
       mojom::UserActivationNotificationType::kTest);
 
-  EXPECT_CALL(*MockMediaPlayer(), SetWasPlayedWithUserActivation(true));
+  EXPECT_CALL(*MockMediaPlayer(),
+              SetWasPlayedWithUserActivationAndHighMediaEngagement(false));
+  Media()->Play();
+}
+
+TEST_P(HTMLMediaElementTest, PlayedWithUserActivationAndHighMediaEngagement) {
+  Media()->SetSrc(SrcSchemeToURL(TestURLScheme::kHttp));
+  test::RunPendingTasks();
+
+  SetReadyState(HTMLMediaElement::kHaveEnoughData);
+  SimulateHighMediaEngagement();
+  test::RunPendingTasks();
+
+  LocalFrame::NotifyUserActivation(
+      Media()->GetDocument().GetFrame(),
+      mojom::UserActivationNotificationType::kTest);
+
+  EXPECT_CALL(*MockMediaPlayer(),
+              SetWasPlayedWithUserActivationAndHighMediaEngagement(true));
   Media()->Play();
 }
 
@@ -1688,7 +1708,9 @@
       Media()->GetDocument().GetFrame(),
       mojom::UserActivationNotificationType::kTest);
 
-  EXPECT_CALL(*MockMediaPlayer(), SetWasPlayedWithUserActivation(_)).Times(0);
+  EXPECT_CALL(*MockMediaPlayer(),
+              SetWasPlayedWithUserActivationAndHighMediaEngagement(_))
+      .Times(0);
   Media()->Play();
 }
 
@@ -1699,7 +1721,8 @@
   SetReadyState(HTMLMediaElement::kHaveEnoughData);
   test::RunPendingTasks();
 
-  EXPECT_CALL(*MockMediaPlayer(), SetWasPlayedWithUserActivation(false));
+  EXPECT_CALL(*MockMediaPlayer(),
+              SetWasPlayedWithUserActivationAndHighMediaEngagement(false));
   Media()->Play();
 
   ResetWebMediaPlayer();
@@ -1720,7 +1743,8 @@
   SetReadyState(HTMLMediaElement::kHaveEnoughData);
   test::RunPendingTasks();
 
-  EXPECT_CALL(*MockMediaPlayer(), SetWasPlayedWithUserActivation(false));
+  EXPECT_CALL(*MockMediaPlayer(),
+              SetWasPlayedWithUserActivationAndHighMediaEngagement(false));
   EXPECT_CALL(*MockMediaPlayer(), OnFrozen());
   Media()->Play();
 
diff --git a/third_party/blink/renderer/core/html/popover_options.idl b/third_party/blink/renderer/core/html/popover_options.idl
new file mode 100644
index 0000000..2235056
--- /dev/null
+++ b/third_party/blink/renderer/core/html/popover_options.idl
@@ -0,0 +1,12 @@
+// Copyright 2024 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+dictionary TogglePopoverOptions {
+  boolean force;
+  HTMLElement invoker;
+};
+
+dictionary ShowPopoverOptions {
+  HTMLElement invoker;
+};
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.cc
index d438de5d9..99f11b4 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.cc
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.cc
@@ -53,34 +53,22 @@
   if (Remaining() < characters.size()) {
     return false;
   }
-  if (Is8Bit()) {
-    auto [to_match, rest] = buf<LChar>().split_at(characters.size());
+  return Invoke([&characters](auto& buf) {
+    auto [to_match, rest] = buf.split_at(characters.size());
     if (to_match != characters) {
       return false;
     }
-    buf<LChar>() = rest;
-  } else {
-    auto [to_match, rest] = buf<UChar>().split_at(characters.size());
-    if (to_match != characters) {
-      return false;
-    }
-    buf<UChar>() = rest;
-  }
-  return true;
+    buf = rest;
+    return true;
+  });
 }
 
 String VTTScanner::ExtractString(size_t length) {
-  String s;
-  if (Is8Bit()) {
-    auto [string_data, rest] = buf<LChar>().split_at(length);
-    s = String(string_data);
-    buf<LChar>() = rest;
-  } else {
-    auto [string_data, rest] = buf<UChar>().split_at(length);
-    s = String(string_data);
-    buf<UChar>() = rest;
-  }
-  return s;
+  return Invoke([length](auto& buf) {
+    auto [string_data, rest] = buf.split_at(length);
+    buf = rest;
+    return String(string_data);
+  });
 }
 
 String VTTScanner::RestOfInputAsString() {
@@ -94,19 +82,13 @@
     return 0;
   }
   bool valid_number;
-  if (Is8Bit()) {
-    auto [number_data, rest] = buf<LChar>().split_at(num_digits);
-    number = CharactersToUInt(number_data.data(), num_digits,
-                              WTF::NumberParsingOptions(), &valid_number);
+  number = Invoke([num_digits, &valid_number](auto& buf) {
+    auto [number_data, rest] = buf.split_at(num_digits);
     // Consume the digits.
-    buf<LChar>() = rest;
-  } else {
-    auto [number_data, rest] = buf<UChar>().split_at(num_digits);
-    number = CharactersToUInt(number_data.data(), num_digits,
-                              WTF::NumberParsingOptions(), &valid_number);
-    // Consume the digits.
-    buf<UChar>() = rest;
-  }
+    buf = rest;
+    return CharactersToUInt(number_data.data(), num_digits,
+                            WTF::NumberParsingOptions(), &valid_number);
+  });
 
   // Since we know that scanDigits only scanned valid (ASCII) digits (and
   // hence that's what got passed to charactersToUInt()), the remaining
@@ -138,13 +120,11 @@
   }
 
   bool valid_number;
-  if (Is8Bit()) {
-    number = CharactersToDouble(buf<LChar>(start_state).data(),
-                                length_of_double, &valid_number);
-  } else {
-    number = CharactersToDouble(buf<UChar>(start_state).data(),
-                                length_of_double, &valid_number);
-  }
+  number = Invoke(
+      [length_of_double, &valid_number](auto& buf) {
+        return CharactersToDouble(buf.data(), length_of_double, &valid_number);
+      },
+      start_state);
 
   if (number == std::numeric_limits<double>::infinity())
     return false;
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.h b/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.h
index 9569b1d6..78fc6657 100644
--- a/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.h
+++ b/third_party/blink/renderer/core/html/track/vtt/vtt_scanner.h
@@ -52,6 +52,32 @@
 class CORE_EXPORT VTTScanner {
   STACK_ALLOCATED();
 
+ private:
+  using LCharSpan = base::span<const LChar>;
+  using UCharSpan = base::span<const UChar>;
+  using State = std::variant<LCharSpan, UCharSpan>;
+
+  template <typename Functor>
+  decltype(auto) Invoke(Functor functor, State& state) {
+    return std::holds_alternative<LCharSpan>(state_)
+               ? functor(std::get<LCharSpan>(state))
+               : functor(std::get<UCharSpan>(state));
+  }
+  template <typename Functor>
+  decltype(auto) Invoke(Functor functor, const State& state) const {
+    return std::holds_alternative<LCharSpan>(state_)
+               ? functor(std::get<LCharSpan>(state))
+               : functor(std::get<UCharSpan>(state));
+  }
+  template <typename Functor>
+  decltype(auto) Invoke(Functor functor) {
+    return Invoke(functor, state_);
+  }
+  template <typename Functor>
+  decltype(auto) Invoke(Functor functor) const {
+    return Invoke(functor, state_);
+  }
+
  public:
   explicit VTTScanner(const String& line);
   VTTScanner(const VTTScanner&) = delete;
@@ -59,11 +85,11 @@
 
   // Return the number of remaining characters.
   size_t Remaining() const {
-    return Is8Bit() ? buf<LChar>().size() : buf<UChar>().size();
+    return Invoke([](const auto& buf) { return buf.size(); });
   }
   // Check if the input pointer points at the end of the input.
   bool IsAtEnd() const {
-    return Is8Bit() ? buf<LChar>().empty() : buf<UChar>().empty();
+    return Invoke([](const auto& buf) { return buf.empty(); });
   }
   // Match the character |c| against the character at the input pointer
   // (~lookahead).
@@ -77,11 +103,11 @@
   // |characterPredicate| returns true. The start of the run will be the
   // current input pointer.
   template <bool predicate(UChar)>
-  size_t CountWhile();
+  size_t CountWhile() const;
 
   // Like CountWhile, but using a negated predicate.
   template <bool predicate(UChar)>
-  size_t CountUntil();
+  size_t CountUntil() const;
 
   // Skip (advance the input pointer) as long as the specified
   // |characterPredicate| returns true, and the input pointer is not passed
@@ -124,29 +150,6 @@
   bool ScanPercentage(double& percentage);
 
  protected:
-  using State = std::variant<base::span<const LChar>, base::span<const UChar>>;
-
-  template <typename CharType>
-  static base::span<const CharType>& buf(State& state) {
-    return std::get<base::span<const CharType>>(state);
-  }
-  template <typename CharType>
-  static const base::span<const CharType>& buf(const State& state) {
-    return std::get<base::span<const CharType>>(state);
-  }
-
-  template <typename CharType>
-  base::span<const CharType>& buf() {
-    return buf<CharType>(state_);
-  }
-  template <typename CharType>
-  const base::span<const CharType>& buf() const {
-    return buf<CharType>(state_);
-  }
-  bool Is8Bit() const {
-    return std::holds_alternative<base::span<const LChar>>(state_);
-  }
-
   explicit VTTScanner(State state) : state_(std::move(state)) {}
 
   UChar CurrentChar() const;
@@ -157,29 +160,19 @@
 };
 
 template <bool predicate(UChar)>
-inline size_t VTTScanner::CountWhile() {
-  size_t skipped = 0;
-  if (Is8Bit()) {
-    auto it = base::ranges::find_if_not(buf<LChar>(), predicate);
-    skipped = std::distance(buf<LChar>().begin(), it);
-  } else {
-    auto it = base::ranges::find_if_not(buf<UChar>(), predicate);
-    skipped = std::distance(buf<UChar>().begin(), it);
-  }
-  return skipped;
+inline size_t VTTScanner::CountWhile() const {
+  return Invoke([](const auto& buf) {
+    auto it = base::ranges::find_if_not(buf, predicate);
+    return std::distance(buf.begin(), it);
+  });
 }
 
 template <bool predicate(UChar)>
-inline size_t VTTScanner::CountUntil() {
-  size_t skipped = 0;
-  if (Is8Bit()) {
-    auto it = base::ranges::find_if(buf<LChar>(), predicate);
-    skipped = std::distance(buf<LChar>().begin(), it);
-  } else {
-    auto it = base::ranges::find_if(buf<UChar>(), predicate);
-    skipped = std::distance(buf<UChar>().begin(), it);
-  }
-  return skipped;
+inline size_t VTTScanner::CountUntil() const {
+  return Invoke([](const auto& buf) {
+    auto it = base::ranges::find_if(buf, predicate);
+    return std::distance(buf.begin(), it);
+  });
 }
 
 template <bool predicate(UChar)>
@@ -195,37 +188,29 @@
 template <bool predicate(UChar)>
 inline VTTScanner VTTScanner::SubrangeWhile() {
   const size_t count = CountWhile<predicate>();
-  State collected;
-  if (Is8Bit()) {
-    std::tie(collected, buf<LChar>()) = buf<LChar>().split_at(count);
-  } else {
-    std::tie(collected, buf<UChar>()) = buf<UChar>().split_at(count);
-  }
-  return VTTScanner(collected);
+  return VTTScanner(Invoke([count](auto& buf) {
+    State collected;
+    std::tie(collected, buf) = buf.split_at(count);
+    return collected;
+  }));
 }
 
 template <bool predicate(UChar)>
 inline VTTScanner VTTScanner::SubrangeUntil() {
   const size_t count = CountUntil<predicate>();
-  State collected;
-  if (Is8Bit()) {
-    std::tie(collected, buf<LChar>()) = buf<LChar>().split_at(count);
-  } else {
-    std::tie(collected, buf<UChar>()) = buf<UChar>().split_at(count);
-  }
-  return VTTScanner(collected);
+  return VTTScanner(Invoke([count](auto& buf) {
+    State collected;
+    std::tie(collected, buf) = buf.split_at(count);
+    return collected;
+  }));
 }
 
 inline UChar VTTScanner::CurrentChar() const {
-  return Is8Bit() ? buf<LChar>().front() : buf<UChar>().front();
+  return Invoke([](const auto& buf) { return buf.front(); });
 }
 
 inline void VTTScanner::Advance(size_t amount) {
-  if (Is8Bit()) {
-    buf<LChar>() = buf<LChar>().subspan(amount);
-  } else {
-    buf<UChar>() = buf<UChar>().subspan(amount);
-  }
+  Invoke([amount](auto& buf) { buf = buf.subspan(amount); });
 }
 
 inline void VTTScanner::AdvanceIfNonZero(size_t amount) {
diff --git a/third_party/blink/renderer/core/imagebitmap/DEPS b/third_party/blink/renderer/core/imagebitmap/DEPS
index fd3e874..67a8fe5 100644
--- a/third_party/blink/renderer/core/imagebitmap/DEPS
+++ b/third_party/blink/renderer/core/imagebitmap/DEPS
@@ -1,3 +1,4 @@
 include_rules = [
     "+gpu/command_buffer/client",
+    "+gpu/command_buffer/common/shared_image_usage.h",
 ]
\ No newline at end of file
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
index 2a1f900..9ab2add6 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap.cc
@@ -18,6 +18,7 @@
 #include "base/task/sequenced_task_runner.h"
 #include "base/task/single_thread_task_runner.h"
 #include "gpu/command_buffer/client/shared_image_interface.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "gpu/config/gpu_feature_info.h"
 #include "skia/ext/legacy_display_globals.h"
 #include "third_party/blink/public/common/features.h"
@@ -193,7 +194,7 @@
   constexpr auto kShouldInitialize =
       CanvasResourceProvider::ShouldInitialize::kNo;
   if (context_provider) {
-    const uint32_t usage_flags =
+    const gpu::SharedImageUsageSet usage_flags =
         context_provider->ContextProvider()
             ->SharedImageInterface()
             ->UsageForMailbox(source_image->GetMailboxHolder().mailbox);
diff --git a/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc b/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc
index 0723bc0c..72c967de 100644
--- a/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc
+++ b/third_party/blink/renderer/core/imagebitmap/image_bitmap_test.cc
@@ -261,7 +261,7 @@
   auto resource_provider = CanvasResourceProvider::CreateSharedImageProvider(
       SkImageInfo::MakeN32Premul(100, 100), cc::PaintFlags::FilterQuality::kLow,
       CanvasResourceProvider::ShouldInitialize::kNo, context_provider_wrapper,
-      RasterMode::kGPU, /*shared_image_usage_flags=*/0u);
+      RasterMode::kGPU, gpu::SharedImageUsageSet());
 
   scoped_refptr<StaticBitmapImage> bitmap =
       resource_provider->Snapshot(FlushReason::kTesting);
diff --git a/third_party/blink/renderer/core/layout/absolute_utils.cc b/third_party/blink/renderer/core/layout/absolute_utils.cc
index 5435fce..d88ce3f 100644
--- a/third_party/blink/renderer/core/layout/absolute_utils.cc
+++ b/third_party/blink/renderer/core/layout/absolute_utils.cc
@@ -51,7 +51,8 @@
     WritingDirectionMode container_writing_direction,
     WritingDirectionMode self_writing_direction,
     bool is_justify_axis,
-    std::optional<InsetBias>* out_safe_inset_bias) {
+    std::optional<InsetBias>* out_safe_inset_bias,
+    std::optional<InsetBias>* out_default_inset_bias) {
   // `alignment` is in the writing-direction of the containing-block, vs. the
   // inset-bias which is relative to the writing-direction of the candidate.
   const LogicalToLogical bias(
@@ -62,6 +63,11 @@
     *out_safe_inset_bias =
         is_justify_axis ? bias.InlineStart() : bias.BlockStart();
   }
+  if (alignment.Overflow() == OverflowAlignment::kDefault &&
+      alignment.GetPosition() != ItemPosition::kNormal) {
+    *out_default_inset_bias =
+        is_justify_axis ? bias.InlineStart() : bias.BlockStart();
+  }
 
   switch (alignment.GetPosition()) {
     case ItemPosition::kStart:
@@ -69,8 +75,8 @@
     case ItemPosition::kBaseline:
     case ItemPosition::kStretch:
     case ItemPosition::kNormal:
-    case ItemPosition::kAnchorCenter:
       return is_justify_axis ? bias.InlineStart() : bias.BlockStart();
+    case ItemPosition::kAnchorCenter:
     case ItemPosition::kCenter:
       return InsetBias::kEqual;
     case ItemPosition::kEnd:
@@ -114,18 +120,6 @@
   }
 }
 
-// Adjusts the insets so they will be equidistant from the center offset.
-// |<-----*----->      |
-void ResizeIMCBForCenterOffset(const LayoutUnit available_size,
-                               const LayoutUnit offset,
-                               LayoutUnit* inset_start,
-                               LayoutUnit* inset_end) {
-  const LayoutUnit half_imcb_size =
-      std::min(offset - *inset_start, available_size - *inset_end - offset);
-  *inset_start = offset - half_imcb_size;
-  *inset_end = available_size - offset - half_imcb_size;
-}
-
 // Computes the inset modified containing block in one axis, accounting for
 // insets and the static-position.
 void ComputeUnclampedIMCBInOneAxis(
@@ -136,10 +130,12 @@
     InsetBias static_position_inset_bias,
     InsetBias alignment_inset_bias,
     const std::optional<InsetBias>& safe_inset_bias,
+    const std::optional<InsetBias>& default_inset_bias,
     LayoutUnit* imcb_start_out,
     LayoutUnit* imcb_end_out,
     InsetBias* imcb_inset_bias_out,
-    std::optional<InsetBias>* safe_inset_bias_out) {
+    std::optional<InsetBias>* safe_inset_bias_out,
+    std::optional<InsetBias>* default_inset_bias_out) {
   DCHECK_NE(available_size, kIndefiniteSize);
   if (!inset_start && !inset_end) {
     // If both our insets are auto, the available-space is defined by the
@@ -156,10 +152,10 @@
         // The available-space for the center static-position "grows" towards
         // both edges (equally), and stops when it hits the first one.
         // |<-----*----->      |
-        *imcb_start_out = LayoutUnit();
-        *imcb_end_out = LayoutUnit();
-        ResizeIMCBForCenterOffset(available_size, static_position_offset,
-                                  imcb_start_out, imcb_end_out);
+        const LayoutUnit half_size = std::min(
+            static_position_offset, available_size - static_position_offset);
+        *imcb_start_out = static_position_offset - half_size;
+        *imcb_end_out = available_size - static_position_offset - half_size;
         break;
       }
       case InsetBias::kEnd:
@@ -185,6 +181,7 @@
       // edge of the containing block if we have normal alignment).
       *imcb_inset_bias_out = alignment_inset_bias;
       *safe_inset_bias_out = safe_inset_bias;
+      *default_inset_bias_out = default_inset_bias;
     }
   }
 }
@@ -207,34 +204,42 @@
                             self_writing_direction.GetWritingMode());
 
   std::optional<InsetBias> inline_safe_inset_bias;
+  std::optional<InsetBias> inline_default_inset_bias;
   const auto inline_alignment_inset_bias = GetAlignmentInsetBias(
       alignment.inline_alignment, container_writing_direction,
       self_writing_direction,
-      /* is_justify_axis */ is_parallel, &inline_safe_inset_bias);
+      /* is_justify_axis */ is_parallel, &inline_safe_inset_bias,
+      &inline_default_inset_bias);
   std::optional<InsetBias> block_safe_inset_bias;
-  const auto block_alignment_inset_bias = GetAlignmentInsetBias(
-      alignment.block_alignment, container_writing_direction,
-      self_writing_direction,
-      /* is_justify_axis */ !is_parallel, &block_safe_inset_bias);
+  std::optional<InsetBias> block_default_inset_bias;
+  const auto block_alignment_inset_bias =
+      GetAlignmentInsetBias(alignment.block_alignment,
+                            container_writing_direction, self_writing_direction,
+                            /* is_justify_axis */ !is_parallel,
+                            &block_safe_inset_bias, &block_default_inset_bias);
 
   ComputeUnclampedIMCBInOneAxis(
       available_size.inline_size, insets.inline_start, insets.inline_end,
       static_position.offset.inline_offset,
       GetStaticPositionInsetBias(static_position.inline_edge),
-      inline_alignment_inset_bias, inline_safe_inset_bias, &imcb.inline_start,
-      &imcb.inline_end, &imcb.inline_inset_bias, &imcb.inline_safe_inset_bias);
+      inline_alignment_inset_bias, inline_safe_inset_bias,
+      inline_default_inset_bias, &imcb.inline_start, &imcb.inline_end,
+      &imcb.inline_inset_bias, &imcb.inline_safe_inset_bias,
+      &imcb.inline_default_inset_bias);
   ComputeUnclampedIMCBInOneAxis(
       available_size.block_size, insets.block_start, insets.block_end,
       static_position.offset.block_offset,
       GetStaticPositionInsetBias(static_position.block_edge),
-      block_alignment_inset_bias, block_safe_inset_bias, &imcb.block_start,
-      &imcb.block_end, &imcb.block_inset_bias, &imcb.block_safe_inset_bias);
+      block_alignment_inset_bias, block_safe_inset_bias,
+      block_default_inset_bias, &imcb.block_start, &imcb.block_end,
+      &imcb.block_inset_bias, &imcb.block_safe_inset_bias,
+      &imcb.block_default_inset_bias);
   return imcb;
 }
 
 // Absolutize margin values to pixels and resolve any auto margins.
 // https://drafts.csswg.org/css-position-3/#abspos-margins
-void ComputeMargins(LogicalSize margin_percentage_resolution_size,
+bool ComputeMargins(LogicalSize margin_percentage_resolution_size,
                     const LayoutUnit imcb_size,
                     const Length& margin_start_length,
                     const Length& margin_end_length,
@@ -255,9 +260,12 @@
         margin_end_length, margin_percentage_resolution_size.inline_size);
   }
 
+  const bool apply_auto_margins =
+      !has_auto_inset && (!margin_start || !margin_end);
+
   // Solving the equation:
   // |margin_start| + |size| + |margin_end| = |imcb_size|
-  if (!has_auto_inset) {
+  if (apply_auto_margins) {
     // "If left, right, and width are not auto:"
     // Compute margins.
     const LayoutUnit free_space = imcb_size - size -
@@ -286,29 +294,57 @@
     }
   }
 
-  // Set any unknown margins.
+  // Set any unknown margins, auto margins with any auto inset resolve to zero.
   *margin_start_out = margin_start.value_or(LayoutUnit());
   *margin_end_out = margin_end.value_or(LayoutUnit());
+
+  return apply_auto_margins;
 }
 
 // Align the margin box within the inset-modified containing block as defined by
 // its self-alignment properties.
 // https://drafts.csswg.org/css-position-3/#abspos-layout
 void ComputeInsets(const LayoutUnit available_size,
-                   LayoutUnit imcb_start,
-                   LayoutUnit imcb_end,
+                   const LayoutUnit container_start,
+                   const LayoutUnit container_end,
+                   const LayoutUnit original_imcb_start,
+                   const LayoutUnit original_imcb_end,
                    const InsetBias imcb_inset_bias,
                    const std::optional<InsetBias>& safe_inset_bias,
+                   const std::optional<InsetBias>& default_inset_bias,
                    const LayoutUnit margin_start,
                    const LayoutUnit margin_end,
                    const LayoutUnit size,
+                   const std::optional<LayoutUnit>& anchor_center_offset,
                    LayoutUnit* inset_start_out,
                    LayoutUnit* inset_end_out) {
   DCHECK_NE(available_size, kIndefiniteSize);
+
+  LayoutUnit imcb_start = original_imcb_start;
+  LayoutUnit imcb_end = original_imcb_end;
+
+  // First if we have a valid anchor-center position, adjust the offsets so
+  // that it is centered on that point.
+  //
+  // At this stage it doesn't matter what the resulting free-space is, just
+  // that if we have safe alignment, we bias towards the safe inset.
+  if (anchor_center_offset) {
+    const LayoutUnit half_size =
+        (safe_inset_bias.value_or(InsetBias::kStart) == InsetBias::kStart)
+            ? *anchor_center_offset - imcb_start
+            : available_size - *anchor_center_offset - imcb_end;
+    imcb_start = *anchor_center_offset - half_size;
+    imcb_end = available_size - *anchor_center_offset - half_size;
+  }
+
+  // Determine the free-space. If we have safe alignment specified, e.g.
+  // "justify-self: safe start", clamp the free-space to zero and bias towards
+  // the safe edge (may be end if RTL for example).
   LayoutUnit free_space =
-      available_size - imcb_start - imcb_end - margin_start - margin_end - size;
+      available_size - imcb_start - imcb_end - margin_start - size - margin_end;
   InsetBias bias = imcb_inset_bias;
-  if (safe_inset_bias && free_space < LayoutUnit()) {
+  bool apply_safe_bias = safe_inset_bias && free_space < LayoutUnit();
+  if (apply_safe_bias) {
     free_space = LayoutUnit();
     bias = *safe_inset_bias;
   }
@@ -318,6 +354,40 @@
   // `available_size`
   ResizeIMCBInOneAxis(bias, free_space, &imcb_start, &imcb_end);
 
+  // Finally consider the default alignment overflow behavior if applicable.
+  // This only applies when both insets are specified, and we have non-normal
+  // alignment.
+  //
+  // This will take the element, and shift it to be within the bounds of the
+  // containing-block. It will prioritize the edge specified by
+  // `default_inset_bias`.
+  if (default_inset_bias && !apply_safe_bias) {
+    // If the insets shifted the IMCB outside the containing-block, we consider
+    // that to be the safe edge.
+    auto adjust_start = [&]() {
+      const LayoutUnit safe_start =
+          std::min(original_imcb_start, -container_start);
+      if (imcb_start < safe_start) {
+        imcb_end += (imcb_start - safe_start);
+        imcb_start = safe_start;
+      }
+    };
+    auto adjust_end = [&]() {
+      const LayoutUnit safe_end = std::min(original_imcb_end, -container_end);
+      if (imcb_end < safe_end) {
+        imcb_start += (imcb_end - safe_end);
+        imcb_end = safe_end;
+      }
+    };
+    if (*default_inset_bias == InsetBias::kStart) {
+      adjust_end();
+      adjust_start();
+    } else {
+      adjust_start();
+      adjust_end();
+    }
+  }
+
   *inset_start_out = imcb_start + margin_start;
   *inset_end_out = imcb_end + margin_end;
 }
@@ -430,6 +500,7 @@
 
 LogicalAlignment ComputeAlignment(
     const ComputedStyle& style,
+    bool is_containing_block_scrollable,
     WritingDirectionMode container_writing_direction,
     WritingDirectionMode self_writing_direction) {
   StyleSelfAlignmentData align_normal_behavior(ItemPosition::kNormal,
@@ -440,7 +511,8 @@
       container_writing_direction, self_writing_direction);
   if (!position_area.IsNone()) {
     std::tie(align_normal_behavior, justify_normal_behavior) =
-        position_area.AlignJustifySelfFromPhysical(container_writing_direction);
+        position_area.AlignJustifySelfFromPhysical(
+            container_writing_direction, is_containing_block_scrollable);
   }
   const bool is_parallel =
       IsParallelWritingMode(container_writing_direction.GetWritingMode(),
@@ -505,27 +577,11 @@
     const LogicalAlignment& alignment,
     const LogicalOofInsets& insets,
     const LogicalStaticPosition& static_position,
-    const LogicalAnchorCenterPosition& anchor_center_position,
     WritingDirectionMode container_writing_direction,
     WritingDirectionMode self_writing_direction) {
   InsetModifiedContainingBlock imcb = ComputeUnclampedIMCB(
       available_size, alignment, insets, static_position, node.Style(),
       container_writing_direction, self_writing_direction);
-  // `anchor-center` coerces the IMCB to be based on the anchor center position.
-  if (anchor_center_position.inline_offset) {
-    ResizeIMCBForCenterOffset(available_size.inline_size,
-                              *anchor_center_position.inline_offset,
-                              &imcb.inline_start, &imcb.inline_end);
-    imcb.inline_inset_bias = InsetBias::kEqual;
-    imcb.inline_safe_inset_bias = std::nullopt;
-  }
-  if (anchor_center_position.block_offset) {
-    ResizeIMCBForCenterOffset(available_size.block_size,
-                              *anchor_center_position.block_offset,
-                              &imcb.block_start, &imcb.block_end);
-    imcb.block_inset_bias = InsetBias::kEqual;
-    imcb.block_safe_inset_bias = std::nullopt;
-  }
   // Clamp any negative size to 0.
   if (imcb.InlineSize() < LayoutUnit()) {
     ResizeIMCBInOneAxis(imcb.inline_inset_bias, imcb.InlineSize(),
@@ -569,9 +625,11 @@
     const ComputedStyle& style,
     const ConstraintSpace& space,
     const InsetModifiedContainingBlock& imcb,
+    const LogicalAnchorCenterPosition& anchor_center_position,
     const LogicalAlignment& alignment,
     const BoxStrut& border_padding,
     const std::optional<LogicalSize>& replaced_size,
+    const BoxStrut& container_insets,
     WritingDirectionMode container_writing_direction,
     LogicalOofDimensions* dimensions) {
   DCHECK(dimensions);
@@ -600,10 +658,11 @@
 
     // Compute our block-size if we haven't already.
     if (dimensions->size.block_size == kIndefiniteSize) {
-      ComputeOofBlockDimensions(node, style, space, imcb, alignment,
-                                border_padding,
-                                /* replaced_size */ std::nullopt,
-                                container_writing_direction, dimensions);
+      ComputeOofBlockDimensions(
+          node, style, space, imcb, anchor_center_position, alignment,
+          border_padding,
+          /* replaced_size */ std::nullopt, container_insets,
+          container_writing_direction, dimensions);
     }
 
     // Create a new space, setting the fixed block-size.
@@ -690,17 +749,27 @@
   const bool is_block_direction = !IsParallelWritingMode(
       container_writing_direction.GetWritingMode(), style.GetWritingMode());
 
-  ComputeMargins(
+  const bool applied_auto_margins = ComputeMargins(
       space.MarginPaddingPercentageResolutionSize(), imcb.InlineSize(),
       style.MarginInlineStart(), style.MarginInlineEnd(), inline_size,
       imcb.has_auto_inline_inset, is_margin_start_dominant, is_block_direction,
       &dimensions->margins.inline_start, &dimensions->margins.inline_end);
 
-  ComputeInsets(space.AvailableSize().inline_size, imcb.inline_start,
-                imcb.inline_end, imcb.inline_inset_bias,
-                imcb.inline_safe_inset_bias, dimensions->margins.inline_start,
-                dimensions->margins.inline_end, inline_size,
-                &dimensions->inset.inline_start, &dimensions->inset.inline_end);
+  if (applied_auto_margins) {
+    dimensions->inset.inline_start =
+        imcb.inline_start + dimensions->margins.inline_start;
+    dimensions->inset.inline_end =
+        imcb.inline_end + dimensions->margins.inline_end;
+  } else {
+    ComputeInsets(
+        space.AvailableSize().inline_size, container_insets.inline_start,
+        container_insets.inline_end, imcb.inline_start, imcb.inline_end,
+        imcb.inline_inset_bias, imcb.inline_safe_inset_bias,
+        imcb.inline_default_inset_bias, dimensions->margins.inline_start,
+        dimensions->margins.inline_end, inline_size,
+        anchor_center_position.inline_offset, &dimensions->inset.inline_start,
+        &dimensions->inset.inline_end);
+  }
 
   return depends_on_min_max_sizes;
 }
@@ -710,9 +779,11 @@
     const ComputedStyle& style,
     const ConstraintSpace& space,
     const InsetModifiedContainingBlock& imcb,
+    const LogicalAnchorCenterPosition& anchor_center_position,
     const LogicalAlignment& alignment,
     const BoxStrut& border_padding,
     const std::optional<LogicalSize>& replaced_size,
+    const BoxStrut& container_insets,
     WritingDirectionMode container_writing_direction,
     LogicalOofDimensions* dimensions) {
   DCHECK(dimensions);
@@ -786,18 +857,27 @@
   const bool is_block_direction = IsParallelWritingMode(
       container_writing_direction.GetWritingMode(), style.GetWritingMode());
 
-  ComputeMargins(
+  const bool applied_auto_margins = ComputeMargins(
       space.MarginPaddingPercentageResolutionSize(), imcb.BlockSize(),
       style.MarginBlockStart(), style.MarginBlockEnd(), block_size,
       imcb.has_auto_block_inset, is_margin_start_dominant, is_block_direction,
       &dimensions->margins.block_start, &dimensions->margins.block_end);
 
-  ComputeInsets(space.AvailableSize().block_size, imcb.block_start,
-                imcb.block_end, imcb.block_inset_bias,
-                imcb.block_safe_inset_bias, dimensions->margins.block_start,
-                dimensions->margins.block_end, block_size,
-                &dimensions->inset.block_start, &dimensions->inset.block_end);
-
+  if (applied_auto_margins) {
+    dimensions->inset.block_start =
+        imcb.block_start + dimensions->margins.block_start;
+    dimensions->inset.block_end =
+        imcb.block_end + dimensions->margins.block_end;
+  } else {
+    ComputeInsets(space.AvailableSize().block_size,
+                  container_insets.block_start, container_insets.block_end,
+                  imcb.block_start, imcb.block_end, imcb.block_inset_bias,
+                  imcb.block_safe_inset_bias, imcb.block_default_inset_bias,
+                  dimensions->margins.block_start,
+                  dimensions->margins.block_end, block_size,
+                  anchor_center_position.block_offset,
+                  &dimensions->inset.block_start, &dimensions->inset.block_end);
+  }
   return result;
 }
 
diff --git a/third_party/blink/renderer/core/layout/absolute_utils.h b/third_party/blink/renderer/core/layout/absolute_utils.h
index ce5cfae..e7d62e9a 100644
--- a/third_party/blink/renderer/core/layout/absolute_utils.h
+++ b/third_party/blink/renderer/core/layout/absolute_utils.h
@@ -59,6 +59,7 @@
 
 LogicalAlignment ComputeAlignment(
     const ComputedStyle& style,
+    bool is_containing_block_scrollable,
     WritingDirectionMode container_writing_direction,
     WritingDirectionMode self_writing_direction);
 
@@ -109,6 +110,12 @@
   std::optional<InsetBias> inline_safe_inset_bias;
   std::optional<InsetBias> block_safe_inset_bias;
 
+  // If non-normal alignment is specified (e.g. "align-self: center") we'll
+  // adjust the position so that it doesn't overflow the containing block.
+  // This field indicates the "start" edge of the containing block.
+  std::optional<InsetBias> inline_default_inset_bias;
+  std::optional<InsetBias> block_default_inset_bias;
+
   LayoutUnit InlineEndOffset() const {
     return available_size.inline_size - inline_end;
   }
@@ -133,7 +140,6 @@
     const LogicalAlignment&,
     const LogicalOofInsets&,
     const LogicalStaticPosition&,
-    const LogicalAnchorCenterPosition&,
     WritingDirectionMode container_writing_direction,
     WritingDirectionMode self_writing_direction);
 
@@ -168,9 +174,11 @@
     const ComputedStyle& style,
     const ConstraintSpace&,
     const InsetModifiedContainingBlock&,
+    const LogicalAnchorCenterPosition&,
     const LogicalAlignment&,
     const BoxStrut& border_padding,
     const std::optional<LogicalSize>& replaced_size,
+    const BoxStrut& container_insets,
     WritingDirectionMode container_writing_direction,
     LogicalOofDimensions* dimensions);
 
@@ -181,9 +189,11 @@
     const ComputedStyle& style,
     const ConstraintSpace&,
     const InsetModifiedContainingBlock&,
+    const LogicalAnchorCenterPosition&,
     const LogicalAlignment&,
     const BoxStrut& border_padding,
     const std::optional<LogicalSize>& replaced_size,
+    const BoxStrut& container_insets,
     WritingDirectionMode container_writing_direction,
     LogicalOofDimensions* dimensions);
 
diff --git a/third_party/blink/renderer/core/layout/absolute_utils_test.cc b/third_party/blink/renderer/core/layout/absolute_utils_test.cc
index f2929bb..91522ca2 100644
--- a/third_party/blink/renderer/core/layout/absolute_utils_test.cc
+++ b/third_party/blink/renderer/core/layout/absolute_utils_test.cc
@@ -129,11 +129,12 @@
     const InsetModifiedContainingBlock imcb =
         ComputeInsetModifiedContainingBlock(
             node, space.AvailableSize(), LogicalAlignment(), insets,
-            static_position, LogicalAnchorCenterPosition(),
-            container_writing_direction, node.Style().GetWritingDirection());
-    ComputeOofInlineDimensions(node, node.Style(), space, imcb,
-                               LogicalAlignment(), border_padding, std::nullopt,
-                               container_writing_direction, dimensions);
+            static_position, container_writing_direction,
+            node.Style().GetWritingDirection());
+    ComputeOofInlineDimensions(
+        node, node.Style(), space, imcb, LogicalAnchorCenterPosition(),
+        LogicalAlignment(), border_padding, std::nullopt, BoxStrut(),
+        container_writing_direction, dimensions);
     GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kAfterPerformLayout);
     GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kLayoutClean);
   }
@@ -171,10 +172,11 @@
     const InsetModifiedContainingBlock imcb =
         ComputeInsetModifiedContainingBlock(
             node, space.AvailableSize(), LogicalAlignment(), insets,
-            static_position, LogicalAnchorCenterPosition(),
-            container_writing_direction, node.Style().GetWritingDirection());
+            static_position, container_writing_direction,
+            node.Style().GetWritingDirection());
     ComputeOofBlockDimensions(node, node.Style(), space, imcb,
-                              LogicalAlignment(), border_padding, std::nullopt,
+                              LogicalAnchorCenterPosition(), LogicalAlignment(),
+                              border_padding, std::nullopt, BoxStrut(),
                               container_writing_direction, dimensions);
     GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kAfterPerformLayout);
     GetDocument().Lifecycle().AdvanceTo(DocumentLifecycle::kLayoutClean);
diff --git a/third_party/blink/renderer/core/layout/block_layout_algorithm.cc b/third_party/blink/renderer/core/layout/block_layout_algorithm.cc
index 1adeb50..5da190c 100644
--- a/third_party/blink/renderer/core/layout/block_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/block_layout_algorithm.cc
@@ -2681,12 +2681,12 @@
       // Trim the space to respect the `text-box-trim` property here. Objects
       // that pushes following boxes down (e.g., Ruby annotations) are also
       // trimmed.
+      logical_block_offset -= *trim_block_end_by;
+
       if (clearance_after_line) {
         // `<br>` with clearance is an exception. It still pushes down, after
         // all other objects are trimmed. See `AddAnyClearanceAfterLine()`.
         logical_block_offset += *clearance_after_line;
-      } else {
-        logical_block_offset -= *trim_block_end_by;
       }
     } else {
       // We add the greater of AnnotationOverflow and ClearanceAfterLine here.
diff --git a/third_party/blink/renderer/core/layout/inline/inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/inline/inline_layout_algorithm.cc
index c5b3068..f60f915 100644
--- a/third_party/blink/renderer/core/layout/inline/inline_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/inline/inline_layout_algorithm.cc
@@ -1010,7 +1010,9 @@
   DCHECK(item_result.item);
   const InlineItem& item = *item_result.item;
   const LayoutObject* layout_object = item.GetLayoutObject();
-  LayoutUnit content_size = container_builder_.LineHeight();
+  const LayoutUnit content_size =
+      container_builder_.LineHeight() -
+      container_builder_.TrimBlockEndBy().value_or(LayoutUnit());
 
   // layout_object may be null in certain cases, e.g. if it's a kBidiControl.
   if (layout_object && layout_object->IsBR()) {
diff --git a/third_party/blink/renderer/core/layout/inline/line_box_fragment_builder.h b/third_party/blink/renderer/core/layout/inline/line_box_fragment_builder.h
index 2a61b0b..660800f 100644
--- a/third_party/blink/renderer/core/layout/inline/line_box_fragment_builder.h
+++ b/third_party/blink/renderer/core/layout/inline/line_box_fragment_builder.h
@@ -70,6 +70,9 @@
     line_box_bfc_block_offset_ = offset;
   }
 
+  const std::optional<LayoutUnit>& TrimBlockEndBy() const {
+    return trim_block_end_by_;
+  }
   void SetTrimBlockEndBy(LayoutUnit trim_block_end_by) {
     trim_block_end_by_ = trim_block_end_by;
   }
diff --git a/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc
index b198832..2d4e306c 100644
--- a/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc
+++ b/third_party/blink/renderer/core/layout/out_of_flow_layout_part.cc
@@ -483,6 +483,10 @@
       GetConstraintSpace().GetWritingDirection();
   default_containing_block_info_for_fixed_.writing_direction =
       GetConstraintSpace().GetWritingDirection();
+  default_containing_block_info_for_absolute_.is_scroll_container =
+      container_builder_->Node().IsScrollContainer();
+  default_containing_block_info_for_fixed_.is_scroll_container =
+      container_builder_->Node().IsScrollContainer();
   if (container_builder_->HasBlockSize()) {
     default_containing_block_info_for_absolute_.rect.size =
         ShrinkLogicalSize(container_builder_->Size(), border_scrollbar);
@@ -790,7 +794,7 @@
       container_offset += fragmentainer_descendant.containing_block.Offset();
 
       ContainingBlockInfo containing_block_info{
-          writing_direction,
+          writing_direction, containing_block_fragment->IsScrollContainer(),
           LogicalRect(container_offset, content_size),
           fragmentainer_descendant.containing_block.RelativeOffset(),
           fragmentainer_descendant.containing_block.Offset()};
@@ -1068,6 +1072,7 @@
         block_info.key.Get(),
         ContainingBlockInfo{
             inline_writing_direction,
+            /* is_scroll_container */ false,
             LogicalRect(container_offset, inline_cb_size),
             total_relative_offset,
             containing_block_offset - block_info.value->relative_offset});
@@ -2118,14 +2123,10 @@
       ToPhysicalSize(container_rect.size,
                      node_info.default_writing_direction.GetWritingMode());
 
-  // "used" position-area offsets. Don't use the position-area offsets directly
-  // as they may be clamped to produce non-negative space. Instead take the
-  // difference between the base, and adjusted container-info.
-  const BoxStrut position_area_offsets = ([&]() -> BoxStrut {
-    if (!candidate_style.PositionAreaOffsets()) {
-      return BoxStrut();
-    }
-
+  // The container insets. Don't use the position-area offsets directly as they
+  // may be clamped to produce non-negative space. Instead take the difference
+  // between the base, and adjusted container-info.
+  const BoxStrut container_insets = ([&]() -> BoxStrut {
     const LogicalRect& base_rect = node_info.base_container_info.rect;
     const BoxStrut insets(
         container_rect.offset.inline_offset - base_rect.offset.inline_offset,
@@ -2158,19 +2159,14 @@
     return builder.ToConstraintSpace();
   })();
 
-  const LogicalAlignment alignment =
-      ComputeAlignment(candidate_style, container_writing_direction,
-                       candidate_writing_direction);
+  const LogicalAlignment alignment = ComputeAlignment(
+      candidate_style, container_info.is_scroll_container,
+      container_writing_direction, candidate_writing_direction);
 
   const LogicalOofInsets insets =
       ComputeOutOfFlowInsets(candidate_style, space.AvailableSize(), alignment,
                              candidate_writing_direction);
 
-  const LogicalAnchorCenterPosition anchor_center_position =
-      ComputeAnchorCenterPosition(candidate_style, alignment,
-                                  candidate_writing_direction,
-                                  space.AvailableSize());
-
   // Adjust the |static_position| (which is currently relative to the default
   // container's border-box) to be relative to the padding-box.
   // Since |container_rect.offset| is relative to its fragmentainer in this
@@ -2188,8 +2184,7 @@
 
   const InsetModifiedContainingBlock imcb = ComputeInsetModifiedContainingBlock(
       node_info.node, space.AvailableSize(), alignment, insets, static_position,
-      anchor_center_position, container_writing_direction,
-      candidate_writing_direction);
+      container_writing_direction, candidate_writing_direction);
 
   {
     auto& document = node_info.node.GetDocument();
@@ -2257,11 +2252,17 @@
                             border_padding, ReplacedSizeMode::kNormal);
   }
 
+  const LogicalAnchorCenterPosition anchor_center_position =
+      ComputeAnchorCenterPosition(candidate_style, alignment,
+                                  candidate_writing_direction,
+                                  space.AvailableSize());
+
   OffsetInfo offset_info;
   LogicalOofDimensions& node_dimensions = offset_info.node_dimensions;
   offset_info.inline_size_depends_on_min_max_sizes = ComputeOofInlineDimensions(
-      node_info.node, candidate_style, space, imcb, alignment, border_padding,
-      replaced_size, container_writing_direction, &node_dimensions);
+      node_info.node, candidate_style, space, imcb, anchor_center_position,
+      alignment, border_padding, replaced_size, container_insets,
+      container_writing_direction, &node_dimensions);
 
   PhysicalToLogicalGetter has_non_auto_inset(
       candidate_writing_direction, candidate_style,
@@ -2283,10 +2284,9 @@
             node_dimensions.MarginBoxInlineEnd(),
             imcb_for_position_fallback->inline_start,
             imcb_for_position_fallback->InlineEndOffset(),
-            position_area_offsets.inline_start,
-            position_area_offsets.inline_end, has_non_auto_inset.InlineStart(),
-            has_non_auto_inset.InlineEnd(), &inline_scroll_min,
-            &inline_scroll_max)) {
+            container_insets.inline_start, container_insets.inline_end,
+            has_non_auto_inset.InlineStart(), has_non_auto_inset.InlineEnd(),
+            &inline_scroll_min, &inline_scroll_max)) {
       return std::nullopt;
     }
   }
@@ -2295,8 +2295,9 @@
   // our min/max sizes, only run if needed.
   if (node_dimensions.size.block_size == kIndefiniteSize) {
     offset_info.initial_layout_result = ComputeOofBlockDimensions(
-        node_info.node, candidate_style, space, imcb, alignment, border_padding,
-        replaced_size, container_writing_direction, &node_dimensions);
+        node_info.node, candidate_style, space, imcb, anchor_center_position,
+        alignment, border_padding, replaced_size, container_insets,
+        container_writing_direction, &node_dimensions);
   }
 
   // Calculate the block scroll offset range where the block dimension fits.
@@ -2308,7 +2309,7 @@
             node_dimensions.MarginBoxBlockEnd(),
             imcb_for_position_fallback->block_start,
             imcb_for_position_fallback->BlockEndOffset(),
-            position_area_offsets.block_start, position_area_offsets.block_end,
+            container_insets.block_start, container_insets.block_end,
             has_non_auto_inset.BlockStart(), has_non_auto_inset.BlockEnd(),
             &block_scroll_min, &block_scroll_max)) {
       return std::nullopt;
diff --git a/third_party/blink/renderer/core/layout/out_of_flow_layout_part.h b/third_party/blink/renderer/core/layout/out_of_flow_layout_part.h
index 8e6a068..30ec05dc 100644
--- a/third_party/blink/renderer/core/layout/out_of_flow_layout_part.h
+++ b/third_party/blink/renderer/core/layout/out_of_flow_layout_part.h
@@ -134,6 +134,8 @@
     // The writing direction of the container.
     WritingDirectionMode writing_direction = {WritingMode::kHorizontalTb,
                                               TextDirection::kLtr};
+    // If the container is scrollable.
+    bool is_scroll_container;
     // Size and offset of the container.
     LogicalRect rect;
     // The relative positioned offset to be applied after fragmentation is
diff --git a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
index 5ff3de40..ef1c77b 100644
--- a/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
+++ b/third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.cc
@@ -546,7 +546,8 @@
        (IsRenderingContext2D() &&
         RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()));
 
-  uint32_t shared_image_usage_flags = gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
+  gpu::SharedImageUsageSet shared_image_usage_flags =
+      gpu::SHARED_IMAGE_USAGE_DISPLAY_READ;
   if (use_scanout) {
     shared_image_usage_flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
   }
diff --git a/third_party/blink/renderer/core/style/position_area.cc b/third_party/blink/renderer/core/style/position_area.cc
index d692b944..549c587 100644
--- a/third_party/blink/renderer/core/style/position_area.cc
+++ b/third_party/blink/renderer/core/style/position_area.cc
@@ -291,23 +291,23 @@
 
 std::pair<StyleSelfAlignmentData, StyleSelfAlignmentData>
 PositionArea::AlignJustifySelfFromPhysical(
-    WritingDirectionMode container_writing_direction) const {
-  StyleSelfAlignmentData align(ItemPosition::kStart,
-                               OverflowAlignment::kDefault);
-  StyleSelfAlignmentData align_reverse(ItemPosition::kEnd,
-                                       OverflowAlignment::kDefault);
-  StyleSelfAlignmentData justify(ItemPosition::kStart,
-                                 OverflowAlignment::kDefault);
-  StyleSelfAlignmentData justify_reverse(ItemPosition::kEnd,
-                                         OverflowAlignment::kDefault);
+    WritingDirectionMode container_writing_direction,
+    bool is_containing_block_scrollable) const {
+  const OverflowAlignment overflow = is_containing_block_scrollable
+                                         ? OverflowAlignment::kUnsafe
+                                         : OverflowAlignment::kDefault;
+
+  StyleSelfAlignmentData align(ItemPosition::kStart, overflow);
+  StyleSelfAlignmentData align_reverse(ItemPosition::kEnd, overflow);
+  StyleSelfAlignmentData justify(ItemPosition::kStart, overflow);
+  StyleSelfAlignmentData justify_reverse(ItemPosition::kEnd, overflow);
 
   if ((FirstStart() == PositionAreaRegion::kTop &&
        FirstEnd() == PositionAreaRegion::kBottom) ||
       (FirstStart() == PositionAreaRegion::kCenter &&
        FirstEnd() == PositionAreaRegion::kCenter)) {
     // 'center' or 'all' should align with anchor center.
-    align = align_reverse = {ItemPosition::kAnchorCenter,
-                             OverflowAlignment::kDefault};
+    align = align_reverse = {ItemPosition::kAnchorCenter, overflow};
   } else {
     // 'top' and 'top center' aligns with end, 'bottom' and 'center bottom' with
     // start.
@@ -320,8 +320,7 @@
       (SecondStart() == PositionAreaRegion::kCenter &&
        SecondEnd() == PositionAreaRegion::kCenter)) {
     // 'center' or 'all' should align with anchor center.
-    justify = justify_reverse = {ItemPosition::kAnchorCenter,
-                                 OverflowAlignment::kDefault};
+    justify = justify_reverse = {ItemPosition::kAnchorCenter, overflow};
   } else {
     // 'left' and 'left center' aligns with end, 'right' and 'center right' with
     // start.
@@ -330,6 +329,21 @@
     }
   }
 
+  if ((FirstStart() == PositionAreaRegion::kTop &&
+       FirstEnd() == PositionAreaRegion::kTop) ||
+      (FirstStart() == PositionAreaRegion::kBottom &&
+       FirstEnd() == PositionAreaRegion::kBottom)) {
+    align.SetOverflow(OverflowAlignment::kUnsafe);
+    align_reverse.SetOverflow(OverflowAlignment::kUnsafe);
+  }
+  if ((SecondStart() == PositionAreaRegion::kLeft &&
+       SecondEnd() == PositionAreaRegion::kLeft) ||
+      (SecondStart() == PositionAreaRegion::kRight &&
+       SecondEnd() == PositionAreaRegion::kRight)) {
+    justify.SetOverflow(OverflowAlignment::kUnsafe);
+    justify_reverse.SetOverflow(OverflowAlignment::kUnsafe);
+  }
+
   PhysicalToLogical converter(container_writing_direction, align,
                               justify_reverse, align_reverse, justify);
   return {converter.BlockStart(), converter.InlineStart()};
diff --git a/third_party/blink/renderer/core/style/position_area.h b/third_party/blink/renderer/core/style/position_area.h
index c3f229a..4f36c438 100644
--- a/third_party/blink/renderer/core/style/position_area.h
+++ b/third_party/blink/renderer/core/style/position_area.h
@@ -111,8 +111,8 @@
   // alignments to be passed into ResolvedAlignSelf()/ResolvedJustifySelf().
   // Return value is an <align-self, justify-self> pair.
   std::pair<StyleSelfAlignmentData, StyleSelfAlignmentData>
-  AlignJustifySelfFromPhysical(
-      WritingDirectionMode container_writing_direction) const;
+  AlignJustifySelfFromPhysical(WritingDirectionMode container_writing_direction,
+                               bool is_containing_block_scrollable) const;
 
   // Made public because they are used in unit test expectations.
   static AnchorQuery AnchorTop();
diff --git a/third_party/blink/renderer/modules/ai/ai_text_session.h b/third_party/blink/renderer/modules/ai/ai_text_session.h
index 7194b87..41c3634 100644
--- a/third_party/blink/renderer/modules/ai/ai_text_session.h
+++ b/third_party/blink/renderer/modules/ai/ai_text_session.h
@@ -5,6 +5,8 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_AI_AI_TEXT_SESSION_H_
 #define THIRD_PARTY_BLINK_RENDERER_MODULES_AI_AI_TEXT_SESSION_H_
 
+#include <variant>
+
 #include "base/memory/scoped_refptr.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/types/pass_key.h"
diff --git a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc
index 10b4a8f..2372916 100644
--- a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc
+++ b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.cc
@@ -17,8 +17,8 @@
 DOMWindowLaunchQueue::DOMWindowLaunchQueue(LocalDOMWindow& window)
     : Supplement(window), launch_queue_(MakeGarbageCollected<LaunchQueue>()) {}
 
-Member<LaunchQueue> DOMWindowLaunchQueue::launchQueue(LocalDOMWindow& window) {
-  return FromState(&window)->launch_queue_;
+LaunchQueue* DOMWindowLaunchQueue::launchQueue(LocalDOMWindow& window) {
+  return FromState(&window)->launch_queue_.Get();
 }
 
 void DOMWindowLaunchQueue::UpdateLaunchFiles(
diff --git a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h
index 382ce44..1e6bf16 100644
--- a/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h
+++ b/third_party/blink/renderer/modules/launch/dom_window_launch_queue.h
@@ -28,7 +28,7 @@
   explicit DOMWindowLaunchQueue(LocalDOMWindow& window);
 
   // IDL Interface.
-  static Member<LaunchQueue> launchQueue(LocalDOMWindow&);
+  static LaunchQueue* launchQueue(LocalDOMWindow&);
 
   static void UpdateLaunchFiles(LocalDOMWindow*,
                                 HeapVector<Member<FileSystemHandle>>);
diff --git a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
index ba11b58..80cf81a5 100644
--- a/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
+++ b/third_party/blink/renderer/modules/mediacapturefromelement/html_video_element_capturer_source_unittest.cc
@@ -54,7 +54,7 @@
   void SetVolume(double) override {}
   void SetLatencyHint(double) override {}
   void SetPreservesPitch(bool) override {}
-  void SetWasPlayedWithUserActivation(bool) override {}
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(bool) override {}
   void SetShouldPauseWhenFrameIsHidden(bool) override {}
   void OnRequestPictureInPicture() override {}
   WebTimeRanges Buffered() const override { return WebTimeRanges(); }
diff --git a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
index 9e008c89..2c0e387 100644
--- a/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/h264_encoder.cc
@@ -268,6 +268,14 @@
   init_params.sSpatialLayers[0].sSliceArgument.uiSliceMode =
       SM_FIXEDSLCNUM_SLICE;
 
+  // Reuse SPS/PPS id if possible that will make the fragmented box in the
+  // MP4 blob to reference the `avcC` box, which contains the SPS/PPS of the
+  // first key frame.
+  // TODO: We might have to use CONSTANT_ID (or at least SPS_PPS_LISTING), but
+  // it isn't clear yet how it affects Encoder only operation
+  // (OpenH264VideoEncoder also uses SPS_LISTING).
+  init_params.eSpsPpsIdStrategy = SPS_LISTING;
+
   metrics_provider_->Initialize(
       codec_profile_.profile.value_or(media::H264PROFILE_BASELINE),
       configured_size_, /*is_hardware_encoder=*/false);
diff --git a/third_party/blink/renderer/modules/mediastream/web_media_player_ms.cc b/third_party/blink/renderer/modules/mediastream/web_media_player_ms.cc
index 3549961..3271dcd 100644
--- a/third_party/blink/renderer/modules/mediastream/web_media_player_ms.cc
+++ b/third_party/blink/renderer/modules/mediastream/web_media_player_ms.cc
@@ -917,8 +917,8 @@
   // and thus there should be no pitch-shifting.
 }
 
-void WebMediaPlayerMS::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {}
+void WebMediaPlayerMS::SetWasPlayedWithUserActivationAndHighMediaEngagement(
+    bool was_played_with_user_activation_and_high_media_engagement) {}
 
 void WebMediaPlayerMS::SetShouldPauseWhenFrameIsHidden(
     bool should_pause_when_frame_is_hidden) {
diff --git a/third_party/blink/renderer/modules/webaudio/audio_context.h b/third_party/blink/renderer/modules/webaudio/audio_context.h
index 7422df7..542f56c 100644
--- a/third_party/blink/renderer/modules/webaudio/audio_context.h
+++ b/third_party/blink/renderer/modules/webaudio/audio_context.h
@@ -102,7 +102,7 @@
   // https://webaudio.github.io/web-audio-api/#AudioContext
   double baseLatency() const;
   double outputLatency() const;
-  Member<V8UnionAudioSinkInfoOrString> sinkId() const { return v8_sink_id_; }
+  V8UnionAudioSinkInfoOrString* sinkId() const { return v8_sink_id_.Get(); }
   DEFINE_ATTRIBUTE_EVENT_LISTENER(sinkchange, kSinkchange)
   DEFINE_ATTRIBUTE_EVENT_LISTENER(error, kError)
   AudioTimestamp* getOutputTimestamp(ScriptState*) const;
diff --git a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
index 51dde87..8daef2a 100644
--- a/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
+++ b/third_party/blink/renderer/modules/webcodecs/video_frame_test.cc
@@ -397,7 +397,7 @@
   auto resource_provider = CanvasResourceProvider::CreateSharedImageProvider(
       SkImageInfo::MakeN32Premul(100, 100), cc::PaintFlags::FilterQuality::kLow,
       CanvasResourceProvider::ShouldInitialize::kNo, context_provider_wrapper,
-      RasterMode::kGPU, /*shared_image_usage_flags=*/0u);
+      RasterMode::kGPU, gpu::SharedImageUsageSet());
 
   scoped_refptr<StaticBitmapImage> bitmap =
       resource_provider->Snapshot(FlushReason::kTesting);
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
index 53f49464..f81d328 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -796,8 +796,8 @@
   // This method will copy the contents of `texture` to `resource_provider`'s
   // backing SharedImage via the WebGPU interface. Hence, WEBGPU_WRITE usage
   // must be included on that backing SharedImage.
-  DCHECK(resource_provider->GetSharedImageUsageFlags() &
-         gpu::SHARED_IMAGE_USAGE_WEBGPU_WRITE);
+  DCHECK(resource_provider->GetSharedImageUsageFlags().Has(
+      gpu::SHARED_IMAGE_USAGE_WEBGPU_WRITE));
   DCHECK(resource_provider->IsOriginTopLeft());
 
   base::WeakPtr<WebGraphicsContext3DProviderWrapper> shared_context_wrapper =
diff --git a/third_party/blink/renderer/platform/DEPS b/third_party/blink/renderer/platform/DEPS
index 189e803..8b7a7fc 100644
--- a/third_party/blink/renderer/platform/DEPS
+++ b/third_party/blink/renderer/platform/DEPS
@@ -51,6 +51,7 @@
     "+device",
     "+gpu/GLES2",
     "+gpu/command_buffer/common/sync_token.h",
+    "+gpu/command_buffer/common/shared_image_usage.h",
     "+mojo/core/embedder/embedder.h",
     "+mojo/public",
     "+mozilla",
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
index 2481094..88bc736a 100644
--- a/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
+++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result.cc
@@ -209,9 +209,9 @@
   unsigned glyph_sequence_start = 0;
   unsigned glyph_sequence_end = num_characters_;
   // the advance of the current glyph sequence.
-  float glyph_sequence_advance = 0.0;
+  InlineLayoutUnit glyph_sequence_advance;
   // the accumulated advance up to the current glyph sequence.
-  float accumulated_position = 0;
+  InlineLayoutUnit accumulated_position;
 
   if (IsLtr()) {
     for (unsigned i = 0; i < num_glyphs; ++i) {
@@ -220,7 +220,7 @@
       // cluster at character index glyph_sequence_start, add its advance to the
       // glyph_sequence's advance.
       if (glyph_sequence_start == current_glyph_char_index) {
-        glyph_sequence_advance += glyph_data_[i].advance.ToFloat();
+        glyph_sequence_advance += glyph_data_[i].advance;
         continue;
       }
 
@@ -248,7 +248,7 @@
       // cluster at character index glyph_sequence_start, add its advance to the
       // glyph_sequence's advance.
       if (glyph_sequence_start == current_glyph_char_index) {
-        glyph_sequence_advance += glyph_data_[i].advance.ToFloat();
+        glyph_sequence_advance += glyph_data_[i].advance;
         continue;
       }
 
@@ -289,12 +289,10 @@
           (NumGraphemes(offset - 1, next_offset) != 1);
     }
     glyph_sequence_advance = glyph_sequence_advance / graphemes;
-    if (IsRtl()) {
-      accumulated_position +=
-          glyph_sequence_advance * (graphemes - num_graphemes_to_offset - 1);
-    } else {
-      accumulated_position += glyph_sequence_advance * num_graphemes_to_offset;
-    }
+    const unsigned num_graphemes_from_left =
+        IsLtr() ? num_graphemes_to_offset
+                : graphemes - num_graphemes_to_offset - 1;
+    accumulated_position += glyph_sequence_advance * num_graphemes_from_left;
   }
 
   // Re-adapt based on adjust_mid_cluster. On LTR, if we want AdjustToEnd and
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
index 2c60c0d..d069ddf 100644
--- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
+++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.cc
@@ -109,7 +109,7 @@
 scoped_refptr<AcceleratedStaticBitmapImage>
 AcceleratedStaticBitmapImage::CreateFromExternalMailbox(
     const gpu::MailboxHolder& mailbox_holder,
-    uint32_t usage,
+    gpu::SharedImageUsageSet usage,
     const SkImageInfo& sk_image_info,
     bool is_origin_top_left,
     bool supports_display_compositing,
@@ -563,7 +563,7 @@
   return provider->Snapshot(FlushReason::kNon2DCanvas, orientation_);
 }
 
-uint32_t AcceleratedStaticBitmapImage::GetUsage() const {
+gpu::SharedImageUsageSet AcceleratedStaticBitmapImage::GetUsage() const {
   return ContextProviderWrapper()
       ->ContextProvider()
       ->SharedImageInterface()
diff --git a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
index fda9964b..65cef20 100644
--- a/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
+++ b/third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h
@@ -9,6 +9,7 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_checker.h"
 #include "components/viz/common/resources/release_callback.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "third_party/blink/renderer/platform/graphics/mailbox_ref.h"
 #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread.h"
@@ -95,7 +96,7 @@
   // This takes ownership of the mailbox.
   static scoped_refptr<AcceleratedStaticBitmapImage> CreateFromExternalMailbox(
       const gpu::MailboxHolder& mailbox_holder,
-      uint32_t usage,
+      gpu::SharedImageUsageSet usage,
       const SkImageInfo& sk_image_info,
       bool is_origin_top_left,
       bool supports_display_compositing,
@@ -162,7 +163,7 @@
 
   SkImageInfo GetSkImageInfo() const override;
 
-  uint32_t GetUsage() const override;
+  gpu::SharedImageUsageSet GetUsage() const override;
 
  private:
   struct ReleaseContext {
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.cc b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
index 4ef9ccae..0f989234 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource.cc
@@ -416,16 +416,16 @@
     cc::PaintFlags::FilterQuality filter_quality,
     bool is_origin_top_left,
     bool is_accelerated,
-    uint32_t shared_image_usage_flags)
+    gpu::SharedImageUsageSet shared_image_usage_flags)
     : CanvasResource(std::move(provider), filter_quality, info.colorInfo()),
       context_provider_wrapper_(std::move(context_provider_wrapper)),
       size_(info.width(), info.height()),
       is_origin_top_left_(is_origin_top_left),
       is_accelerated_(is_accelerated),
-      is_overlay_candidate_(shared_image_usage_flags &
-                            gpu::SHARED_IMAGE_USAGE_SCANOUT),
-      supports_display_compositing_(shared_image_usage_flags &
-                                    gpu::SHARED_IMAGE_USAGE_DISPLAY_READ),
+      is_overlay_candidate_(
+          shared_image_usage_flags.Has(gpu::SHARED_IMAGE_USAGE_SCANOUT)),
+      supports_display_compositing_(
+          shared_image_usage_flags.Has(gpu::SHARED_IMAGE_USAGE_DISPLAY_READ)),
       use_oop_rasterization_(is_accelerated &&
                              context_provider_wrapper_->ContextProvider()
                                  ->GetCapabilities()
@@ -502,8 +502,8 @@
   owning_thread_data().texture_id_for_read_access =
       raster_interface->CreateAndConsumeForGpuRaster(client_shared_image);
 
-  if (shared_image_usage_flags &
-      gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
+  if (shared_image_usage_flags.Has(
+          gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE)) {
     owning_thread_data().texture_id_for_write_access =
         raster_interface->CreateAndConsumeForGpuRaster(client_shared_image);
   } else {
@@ -519,7 +519,7 @@
     cc::PaintFlags::FilterQuality filter_quality,
     bool is_origin_top_left,
     bool is_accelerated,
-    uint32_t shared_image_usage_flags) {
+    gpu::SharedImageUsageSet shared_image_usage_flags) {
   TRACE_EVENT0("blink", "CanvasResourceSharedImage::Create");
   auto resource = base::AdoptRef(new CanvasResourceSharedImage(
       info, std::move(context_provider_wrapper), std::move(provider),
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource.h b/third_party/blink/renderer/platform/graphics/canvas_resource.h
index 69462dda..3366b0d 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource.h
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource.h
@@ -19,6 +19,7 @@
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "gpu/command_buffer/client/shared_image_interface.h"
 #include "gpu/command_buffer/common/mailbox.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "gpu/command_buffer/common/sync_token.h"
 #include "skia/buildflags.h"
 #include "third_party/blink/public/platform/web_graphics_shared_image_interface_provider.h"
@@ -322,7 +323,7 @@
       cc::PaintFlags::FilterQuality,
       bool is_origin_top_left,
       bool is_accelerated,
-      uint32_t shared_image_usage_flags);
+      gpu::SharedImageUsageSet shared_image_usage_flags);
   ~CanvasResourceSharedImage() override;
 
   bool IsRecycleable() const final { return true; }
@@ -407,7 +408,7 @@
                             cc::PaintFlags::FilterQuality,
                             bool is_origin_top_left,
                             bool is_accelerated,
-                            uint32_t shared_image_usage_flags);
+                            gpu::SharedImageUsageSet shared_image_usage_flags);
 
   OwningThreadData& owning_thread_data() {
     DCHECK(!is_cross_thread());
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
index 011bf87..ddb56b9 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.cc
@@ -32,6 +32,7 @@
 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
 #include "gpu/command_buffer/common/shared_image_capabilities.h"
 #include "gpu/command_buffer/common/shared_image_trace_utils.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "gpu/config/gpu_driver_bug_workaround_type.h"
 #include "gpu/config/gpu_feature_info.h"
 #include "gpu/config/gpu_feature_type.h"
@@ -279,7 +280,7 @@
           context_provider_wrapper,
       bool is_origin_top_left,
       bool is_accelerated,
-      uint32_t shared_image_usage_flags,
+      gpu::SharedImageUsageSet shared_image_usage_flags,
       CanvasResourceHost* resource_host)
       : CanvasResourceProvider(kSharedImage,
                                info,
@@ -319,8 +320,8 @@
   }
 
   bool SupportsSingleBuffering() const override {
-    return shared_image_usage_flags_ &
-           gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
+    return shared_image_usage_flags_.Has(
+        gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE);
   }
   scoped_refptr<gpu::ClientSharedImage>
   GetBackingClientSharedImageForOverwrite() override {
@@ -333,7 +334,7 @@
     return resource_->GetClientSharedImage();
   }
 
-  uint32_t GetSharedImageUsageFlags() const override {
+  gpu::SharedImageUsageSet GetSharedImageUsageFlags() const override {
     return shared_image_usage_flags_;
   }
 
@@ -759,7 +760,7 @@
   }
 
   const bool is_accelerated_;
-  const uint32_t shared_image_usage_flags_;
+  const gpu::SharedImageUsageSet shared_image_usage_flags_;
   bool current_resource_has_write_access_ = false;
   const bool use_oop_rasterization_;
   bool is_cleared_ = false;
@@ -1039,7 +1040,7 @@
     ShouldInitialize should_initialize,
     base::WeakPtr<WebGraphicsContext3DProviderWrapper> context_provider_wrapper,
     RasterMode raster_mode,
-    uint32_t shared_image_usage_flags,
+    gpu::SharedImageUsageSet shared_image_usage_flags,
     CanvasResourceHost* resource_host) {
   // IsGpuCompositingEnabled can re-create the context if it has been lost, do
   // this up front so that we can fail early and not expose ourselves to
@@ -1068,8 +1069,8 @@
   // Overriding the info to use RGBA instead of N32 is needed because code
   // elsewhere assumes RGBA. OTOH the software path seems to be assuming N32
   // somewhere in the later pipeline but for offscreen canvas only.
-  if (!(shared_image_usage_flags & (gpu::SHARED_IMAGE_USAGE_WEBGPU_READ |
-                                    gpu::SHARED_IMAGE_USAGE_WEBGPU_WRITE))) {
+  if (!shared_image_usage_flags.HasAny(gpu::SHARED_IMAGE_USAGE_WEBGPU_READ |
+                                       gpu::SHARED_IMAGE_USAGE_WEBGPU_WRITE)) {
     adjusted_info = adjusted_info.makeColorType(
         is_accelerated && info.colorType() != kRGBA_F16_SkColorType
             ? kRGBA_8888_SkColorType
@@ -1090,8 +1091,9 @@
                                       ->GetCapabilities();
   if (!is_gpu_memory_buffer_image_allowed ||
       (is_accelerated && !shared_image_caps.supports_scanout_shared_images)) {
-    shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
-    shared_image_usage_flags &= ~gpu::SHARED_IMAGE_USAGE_SCANOUT;
+    shared_image_usage_flags.RemoveAll(
+        gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE |
+        gpu::SHARED_IMAGE_USAGE_SCANOUT);
   }
 
 #if BUILDFLAG(IS_MAC)
@@ -1123,7 +1125,7 @@
 std::unique_ptr<CanvasResourceProvider>
 CanvasResourceProvider::CreateWebGPUImageProvider(
     const SkImageInfo& info,
-    uint32_t shared_image_usage_flags,
+    gpu::SharedImageUsageSet shared_image_usage_flags,
     CanvasResourceHost* resource_host) {
   auto context_provider_wrapper = SharedGpuContext::ContextProviderWrapper();
   // The SharedImages created by this provider serve as a means of import/export
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
index a8f2a68..fa1d543 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider.h
@@ -129,12 +129,12 @@
       ShouldInitialize initialize_provider,
       base::WeakPtr<WebGraphicsContext3DProviderWrapper>,
       RasterMode raster_mode,
-      uint32_t shared_image_usage_flags,
+      gpu::SharedImageUsageSet shared_image_usage_flags,
       CanvasResourceHost* resource_host = nullptr);
 
   static std::unique_ptr<CanvasResourceProvider> CreateWebGPUImageProvider(
       const SkImageInfo& info,
-      uint32_t shared_image_usage_flags = 0,
+      gpu::SharedImageUsageSet shared_image_usage_flags = {},
       CanvasResourceHost* resource_host = nullptr);
 
   static std::unique_ptr<CanvasResourceProvider> CreatePassThroughProvider(
@@ -228,9 +228,9 @@
     NOTREACHED_IN_MIGRATION();
     return nullptr;
   }
-  virtual uint32_t GetSharedImageUsageFlags() const {
+  virtual gpu::SharedImageUsageSet GetSharedImageUsageFlags() const {
     NOTREACHED_IN_MIGRATION();
-    return 0;
+    return gpu::SharedImageUsageSet();
   }
 
   CanvasResourceProvider(const CanvasResourceProvider&) = delete;
diff --git a/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc b/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
index efc6614..157913c 100644
--- a/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
+++ b/third_party/blink/renderer/platform/graphics/canvas_resource_provider_test.cc
@@ -12,6 +12,7 @@
 #include "components/viz/common/resources/release_callback.h"
 #include "components/viz/test/test_context_provider.h"
 #include "components/viz/test/test_gles2_interface.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/public/platform/scheduler/test/renderer_scheduler_test_support.h"
@@ -130,7 +131,7 @@
   const gfx::Size kSize(10, 10);
   const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10);
 
-  const uint32_t shared_image_usage_flags =
+  const gpu::SharedImageUsageSet shared_image_usage_flags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT |
       gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
 
@@ -166,8 +167,7 @@
   auto provider = CanvasResourceProvider::CreateSharedImageProvider(
       kInfo, cc::PaintFlags::FilterQuality::kLow,
       CanvasResourceProvider::ShouldInitialize::kCallClear,
-      context_provider_wrapper_, RasterMode::kGPU,
-      /*shared_image_usage_flags=*/0u);
+      context_provider_wrapper_, RasterMode::kGPU, gpu::SharedImageUsageSet());
 
   EXPECT_EQ(provider->Size(), kSize);
   EXPECT_TRUE(provider->IsValid());
@@ -186,7 +186,7 @@
   const gfx::Size kSize(10, 10);
   const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10);
 
-  const uint32_t shared_image_usage_flags =
+  const gpu::SharedImageUsageSet shared_image_usage_flags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   auto provider = CanvasResourceProvider::CreateSharedImageProvider(
@@ -212,7 +212,7 @@
     base::WeakPtr<WebGraphicsContext3DProviderWrapper>
         context_provider_wrapper) {
   const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10);
-  const uint32_t shared_image_usage_flags =
+  const gpu::SharedImageUsageSet shared_image_usage_flags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   return CanvasResourceProvider::CreateSharedImageProvider(
@@ -244,7 +244,7 @@
   const gfx::Size kSize(10, 10);
   const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10);
 
-  const uint32_t shared_image_usage_flags =
+  const gpu::SharedImageUsageSet shared_image_usage_flags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   auto provider = CanvasResourceProvider::CreateSharedImageProvider(
@@ -391,7 +391,7 @@
        CanvasResourceProviderSharedImageStaticBitmapImage) {
   const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10);
 
-  const uint32_t shared_image_usage_flags =
+  const gpu::SharedImageUsageSet shared_image_usage_flags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   auto provider = CanvasResourceProvider::CreateSharedImageProvider(
@@ -432,7 +432,7 @@
 TEST_F(CanvasResourceProviderTest, NoRecycleIfLastRefCallback) {
   const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10);
 
-  const uint32_t shared_image_usage_flags =
+  const gpu::SharedImageUsageSet shared_image_usage_flags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   auto provider = CanvasResourceProvider::CreateSharedImageProvider(
@@ -480,7 +480,7 @@
 
   const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10);
 
-  const uint32_t shared_image_usage_flags =
+  const gpu::SharedImageUsageSet shared_image_usage_flags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   auto provider = CanvasResourceProvider::CreateSharedImageProvider(
@@ -552,7 +552,7 @@
   const gfx::Size kSize(10, 10);
   const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10);
 
-  const uint32_t shared_image_usage_flags =
+  const gpu::SharedImageUsageSet shared_image_usage_flags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT |
       gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE;
 
@@ -646,22 +646,19 @@
       SkImageInfo::MakeN32Premul(kMaxTextureSize - 1, kMaxTextureSize),
       cc::PaintFlags::FilterQuality::kLow,
       CanvasResourceProvider::ShouldInitialize::kCallClear,
-      context_provider_wrapper_, RasterMode::kGPU,
-      /*shared_image_usage_flags=*/0u);
+      context_provider_wrapper_, RasterMode::kGPU, gpu::SharedImageUsageSet());
   EXPECT_TRUE(provider->SupportsDirectCompositing());
   provider = CanvasResourceProvider::CreateSharedImageProvider(
       SkImageInfo::MakeN32Premul(kMaxTextureSize, kMaxTextureSize),
       cc::PaintFlags::FilterQuality::kLow,
       CanvasResourceProvider::ShouldInitialize::kCallClear,
-      context_provider_wrapper_, RasterMode::kGPU,
-      /*shared_image_usage_flags=*/0u);
+      context_provider_wrapper_, RasterMode::kGPU, gpu::SharedImageUsageSet());
   EXPECT_TRUE(provider->SupportsDirectCompositing());
   provider = CanvasResourceProvider::CreateSharedImageProvider(
       SkImageInfo::MakeN32Premul(kMaxTextureSize + 1, kMaxTextureSize),
       cc::PaintFlags::FilterQuality::kLow,
       CanvasResourceProvider::ShouldInitialize::kCallClear,
-      context_provider_wrapper_, RasterMode::kGPU,
-      /*shared_image_usage_flags=*/0u);
+      context_provider_wrapper_, RasterMode::kGPU, gpu::SharedImageUsageSet());
   // The CanvasResourceProvider for SharedImage should not be created or valid
   // if the texture size is greater than the maximum value
   EXPECT_TRUE(!provider || !provider->IsValid());
@@ -736,14 +733,12 @@
   auto src_provider = CanvasResourceProvider::CreateSharedImageProvider(
       kInfo, cc::PaintFlags::FilterQuality::kMedium,
       CanvasResourceProvider::ShouldInitialize::kCallClear,
-      context_provider_wrapper_, RasterMode::kGPU,
-      /*shared_image_usage_flags=*/0u);
+      context_provider_wrapper_, RasterMode::kGPU, gpu::SharedImageUsageSet());
 
   auto dst_provider = CanvasResourceProvider::CreateSharedImageProvider(
       kInfo, cc::PaintFlags::FilterQuality::kMedium,
       CanvasResourceProvider::ShouldInitialize::kCallClear,
-      context_provider_wrapper_, RasterMode::kGPU,
-      /*shared_image_usage_flags=*/0u);
+      context_provider_wrapper_, RasterMode::kGPU, gpu::SharedImageUsageSet());
 
   MemoryManagedPaintCanvas& dst_canvas = dst_provider->Canvas();
 
diff --git a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
index e2d1a17..c04a751 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/drawing_buffer.cc
@@ -2048,10 +2048,10 @@
   // The SharedImages created here are read to and written from by WebGL. They
   // may also be read via the raster interface for WebGL->video and/or
   // WebGL->canvas conversions.
-  uint32_t usage = gpu::SHARED_IMAGE_USAGE_GLES2_READ |
-                   gpu::SHARED_IMAGE_USAGE_GLES2_WRITE |
-                   gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
-                   gpu::SHARED_IMAGE_USAGE_RASTER_READ;
+  gpu::SharedImageUsageSet usage = gpu::SHARED_IMAGE_USAGE_GLES2_READ |
+                                   gpu::SHARED_IMAGE_USAGE_GLES2_WRITE |
+                                   gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
+                                   gpu::SHARED_IMAGE_USAGE_RASTER_READ;
   if (initial_gpu_ == gl::GpuPreference::kHighPerformance)
     usage |= gpu::SHARED_IMAGE_USAGE_HIGH_PERFORMANCE_GPU;
   GrSurfaceOrigin origin = opengl_flip_y_extension_
@@ -2117,7 +2117,8 @@
       // order to allocate the GMB service-side and avoid a synchronous
       // round-trip to the browser process here.
       gfx::BufferUsage buffer_usage = gfx::BufferUsage::SCANOUT;
-      uint32_t additional_usage_flags = gpu::SHARED_IMAGE_USAGE_SCANOUT;
+      gpu::SharedImageUsageSet additional_usage_flags =
+          gpu::SHARED_IMAGE_USAGE_SCANOUT;
       if (low_latency_enabled()) {
         buffer_usage = gfx::BufferUsage::SCANOUT_FRONT_RENDERING;
         if (disallow_gmb) {
diff --git a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
index 674b065..2717663 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/image_layer_bridge.cc
@@ -52,7 +52,7 @@
   // Always request gpu::SHARED_IMAGE_USAGE_SCANOUT when using gpu compositing,
   // if possible. This is safe because the prerequisite capabilities are checked
   // downstream in CanvasResourceProvider::CreateSharedImageProvider.
-  constexpr uint32_t kSharedImageUsageFlags =
+  constexpr gpu::SharedImageUsageSet kSharedImageUsageFlags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
   auto provider = CanvasResourceProvider::CreateSharedImageProvider(
       image_info, cc::PaintFlags::FilterQuality::kLow,
@@ -198,8 +198,8 @@
                          image_for_compositor->height());
 
     auto* sii = image_for_compositor->ContextProvider()->SharedImageInterface();
-    bool is_overlay_candidate = sii->UsageForMailbox(mailbox_holder.mailbox) &
-                                gpu::SHARED_IMAGE_USAGE_SCANOUT;
+    bool is_overlay_candidate = sii->UsageForMailbox(mailbox_holder.mailbox)
+                                    .Has(gpu::SHARED_IMAGE_USAGE_SCANOUT);
 
     SkColorType color_type = image_for_compositor->GetSkColorInfo().colorType();
     *out_resource = viz::TransferableResource::MakeGpu(
diff --git a/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc b/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc
index 632e97d..dc0a6c3 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context_test.cc
@@ -11,6 +11,7 @@
 #include "components/viz/test/test_gles2_interface.h"
 #include "gpu/command_buffer/client/gles2_interface.h"
 #include "gpu/command_buffer/common/capabilities.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_2d_layer_bridge.h"
@@ -224,7 +225,7 @@
           cc::PaintFlags::FilterQuality::kLow,
           CanvasResourceProvider::ShouldInitialize::kNo,
           SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU,
-          /*shared_image_usage_flags=*/0u);
+          gpu::SharedImageUsageSet());
   EXPECT_FALSE(resource_provider);
 }
 
@@ -251,7 +252,7 @@
           cc::PaintFlags::FilterQuality::kLow,
           CanvasResourceProvider::ShouldInitialize::kNo,
           SharedGpuContext::ContextProviderWrapper(), RasterMode::kGPU,
-          /*shared_image_usage_flags=*/0u);
+          gpu::SharedImageUsageSet());
   EXPECT_TRUE(resource_provider && resource_provider->IsValid());
   EXPECT_TRUE(resource_provider->IsAccelerated());
   EXPECT_TRUE(SharedGpuContext::IsValidWithoutRestoring());
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
index 8f43544..733e134 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
@@ -295,8 +295,8 @@
       current_swap_buffer_->GetSharedImage(), texture_target,
       current_swap_buffer_->GetSyncToken(),
       current_swap_buffer_->GetSharedImage()->size(), Format(),
-      current_swap_buffer_->GetSharedImage()->usage() &
-          gpu::SHARED_IMAGE_USAGE_SCANOUT,
+      current_swap_buffer_->GetSharedImage()->usage().Has(
+          gpu::SHARED_IMAGE_USAGE_SCANOUT),
       viz::TransferableResource::ResourceSource::kWebGPUSwapBuffer);
   out_resource->color_space = PredefinedColorSpaceToGfxColorSpace(color_space_);
   out_resource->hdr_metadata = hdr_metadata_;
diff --git a/third_party/blink/renderer/platform/graphics/scoped_raster_timer_test.cc b/third_party/blink/renderer/platform/graphics/scoped_raster_timer_test.cc
index b80cf38..196cd4c 100644
--- a/third_party/blink/renderer/platform/graphics/scoped_raster_timer_test.cc
+++ b/third_party/blink/renderer/platform/graphics/scoped_raster_timer_test.cc
@@ -83,7 +83,7 @@
   base::ScopedMockElapsedTimersForTest mock_timer;
   const SkImageInfo kInfo = SkImageInfo::MakeN32Premul(10, 10);
 
-  const uint32_t shared_image_usage_flags =
+  const gpu::SharedImageUsageSet shared_image_usage_flags =
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 
   std::unique_ptr<CanvasResourceProvider> provider =
@@ -124,8 +124,7 @@
   auto provider = CanvasResourceProvider::CreateSharedImageProvider(
       kInfo, cc::PaintFlags::FilterQuality::kMedium,
       CanvasResourceProvider::ShouldInitialize::kCallClear,
-      context_provider_wrapper_, RasterMode::kGPU,
-      /*shared_image_usage_flags=*/0u);
+      context_provider_wrapper_, RasterMode::kGPU, gpu::SharedImageUsageSet());
 
   ASSERT_TRUE(!!provider);
 
diff --git a/third_party/blink/renderer/platform/graphics/static_bitmap_image.h b/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
index 8ba3965..2fcafc6 100644
--- a/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
+++ b/third_party/blink/renderer/platform/graphics/static_bitmap_image.h
@@ -9,6 +9,7 @@
 #include "base/notreached.h"
 #include "gpu/command_buffer/client/client_shared_image.h"
 #include "gpu/command_buffer/common/mailbox_holder.h"
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
 #include "third_party/blink/renderer/platform/graphics/graphics_types.h"
 #include "third_party/blink/renderer/platform/graphics/image.h"
@@ -106,9 +107,9 @@
   // For gpu based images the Usage is a bitmap indicating set of API(s) and
   // underlying gpu::SharedImage may be used with.
   // The gpu::SharedImageInterface is using uint32_t directly.
-  virtual uint32_t GetUsage() const {
+  virtual gpu::SharedImageUsageSet GetUsage() const {
     NOTREACHED_IN_MIGRATION();
-    return 0;
+    return gpu::SharedImageUsageSet();
   }
   bool IsPremultiplied() const {
     return GetSkImageInfo().alphaType() == SkAlphaType::kPremul_SkAlphaType;
diff --git a/third_party/blink/renderer/platform/graphics/test/fake_canvas_resource_host.h b/third_party/blink/renderer/platform/graphics/test/fake_canvas_resource_host.h
index 765060d..75310151 100644
--- a/third_party/blink/renderer/platform/graphics/test/fake_canvas_resource_host.h
+++ b/third_party/blink/renderer/platform/graphics/test/fake_canvas_resource_host.h
@@ -5,6 +5,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TEST_FAKE_CANVAS_RESOURCE_HOST_H_
 #define THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_TEST_FAKE_CANVAS_RESOURCE_HOST_H_
 
+#include "gpu/command_buffer/common/shared_image_usage.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_host.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
@@ -48,7 +49,7 @@
     std::unique_ptr<CanvasResourceProvider> provider;
     if (hint == RasterModeHint::kPreferGPU ||
         RuntimeEnabledFeatures::Canvas2dImageChromiumEnabled()) {
-      constexpr uint32_t kSharedImageUsageFlags =
+      constexpr gpu::SharedImageUsageSet kSharedImageUsageFlags =
           gpu::SHARED_IMAGE_USAGE_DISPLAY_READ |
           gpu::SHARED_IMAGE_USAGE_SCANOUT;
       provider = CanvasResourceProvider::CreateSharedImageProvider(
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.cc b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
index 93665c0..da236d8 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl.cc
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.cc
@@ -1187,11 +1187,11 @@
   pipeline_controller_->SetPreservesPitch(preserves_pitch);
 }
 
-void WebMediaPlayerImpl::SetWasPlayedWithUserActivation(
-    bool was_played_with_user_activation) {
+void WebMediaPlayerImpl::SetWasPlayedWithUserActivationAndHighMediaEngagement(
+    bool was_played_with_user_activation_and_high_media_engagement) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
-  pipeline_controller_->SetWasPlayedWithUserActivation(
-      was_played_with_user_activation);
+  pipeline_controller_->SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      was_played_with_user_activation_and_high_media_engagement);
 }
 
 void WebMediaPlayerImpl::SetShouldPauseWhenFrameIsHidden(
@@ -1249,33 +1249,38 @@
   return pipeline_metadata_.has_audio;
 }
 
-void WebMediaPlayerImpl::EnabledAudioTracksChanged(
-    const WebVector<WebMediaPlayer::TrackId>& enabledTrackIds) {
+void WebMediaPlayerImpl::OnEnabledAudioTracksChanged(
+    std::vector<media::MediaTrack::Id> enabled) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
+  media_log_->AddEvent<MediaLogEvent::kAudioTrackChange>(enabled);
+  pipeline_controller_->OnEnabledAudioTracksChanged(enabled);
+}
 
-  std::ostringstream logstr;
-  std::vector<MediaTrack::Id> enabledMediaTrackIds;
-  for (const auto& blinkTrackId : enabledTrackIds) {
-    const auto track_id = MediaTrack::Id(blinkTrackId.Utf8().data());
-    logstr << track_id << " ";
-    enabledMediaTrackIds.push_back(track_id);
+void WebMediaPlayerImpl::OnSelectedVideoTrackChanged(
+    std::optional<media::MediaTrack::Id> selected) {
+  DCHECK(main_task_runner_->BelongsToCurrentThread());
+  media_log_->AddEvent<MediaLogEvent::kVideoTrackChange>(selected);
+  pipeline_controller_->OnSelectedVideoTrackChanged(selected);
+}
+
+void WebMediaPlayerImpl::EnabledAudioTracksChanged(
+    const WebVector<WebMediaPlayer::TrackId>& enabled_track_ids) {
+  DCHECK(main_task_runner_->BelongsToCurrentThread());
+  std::vector<MediaTrack::Id> enabled_tracks;
+  for (const auto& blinkTrackId : enabled_track_ids) {
+    enabled_tracks.push_back(MediaTrack::Id(blinkTrackId.Utf8().data()));
   }
-  MEDIA_LOG(INFO, media_log_.get())
-      << "Enabled audio tracks: [" << logstr.str() << "]";
-  pipeline_controller_->OnEnabledAudioTracksChanged(enabledMediaTrackIds);
+  OnEnabledAudioTracksChanged(std::move(enabled_tracks));
 }
 
 void WebMediaPlayerImpl::SelectedVideoTrackChanged(
-    WebMediaPlayer::TrackId* selectedTrackId) {
+    std::optional<WebMediaPlayer::TrackId> selected_track_id) {
   DCHECK(main_task_runner_->BelongsToCurrentThread());
-
-  std::optional<MediaTrack::Id> selected_video_track_id;
-  if (selectedTrackId && !video_track_disabled_)
-    selected_video_track_id = MediaTrack::Id(selectedTrackId->Utf8().data());
-  MEDIA_LOG(INFO, media_log_.get())
-      << "Selected video track: ["
-      << selected_video_track_id.value_or(MediaTrack::Id()) << "]";
-  pipeline_controller_->OnSelectedVideoTrackChanged(selected_video_track_id);
+  std::optional<MediaTrack::Id> selected_track;
+  if (selected_track_id.has_value()) {
+    selected_track = MediaTrack::Id(selected_track_id->Utf8().data());
+  }
+  OnSelectedVideoTrackChanged(selected_track);
 }
 
 gfx::Size WebMediaPlayerImpl::NaturalSize() const {
@@ -3785,8 +3790,7 @@
   if (video_track_disabled_) {
     video_track_disabled_ = false;
     if (client_->HasSelectedVideoTrack()) {
-      WebMediaPlayer::TrackId trackId = client_->GetSelectedVideoTrackId();
-      SelectedVideoTrackChanged(&trackId);
+      SelectedVideoTrackChanged(client_->GetSelectedVideoTrackId());
     }
   }
 }
@@ -3800,7 +3804,7 @@
 
   if (!video_track_disabled_ && ShouldDisableVideoWhenHidden()) {
     video_track_disabled_ = true;
-    SelectedVideoTrackChanged(nullptr);
+    SelectedVideoTrackChanged(std::nullopt);
   }
 }
 
diff --git a/third_party/blink/renderer/platform/media/web_media_player_impl.h b/third_party/blink/renderer/platform/media/web_media_player_impl.h
index d3c37dd8..e18b7db 100644
--- a/third_party/blink/renderer/platform/media/web_media_player_impl.h
+++ b/third_party/blink/renderer/platform/media/web_media_player_impl.h
@@ -185,8 +185,8 @@
   void SetVolume(double volume) override;
   void SetLatencyHint(double seconds) override;
   void SetPreservesPitch(bool preserves_pitch) override;
-  void SetWasPlayedWithUserActivation(
-      bool was_played_with_user_activation) override;
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(
+      bool was_played_with_user_activation_and_high_media_engagement) override;
   void OnRequestPictureInPicture() override;
   void OnTimeUpdate() override;
   bool SetSinkId(const WebString& sink_id,
@@ -213,9 +213,12 @@
   bool HasAudio() const override;
 
   void EnabledAudioTracksChanged(
-      const WebVector<WebMediaPlayer::TrackId>& enabledTrackIds) override;
+      const WebVector<WebMediaPlayer::TrackId>& enabled_track_ids) override;
   void SelectedVideoTrackChanged(
-      WebMediaPlayer::TrackId* selectedTrackId) override;
+      std::optional<WebMediaPlayer::TrackId> selected_track_id) override;
+
+  void OnEnabledAudioTracksChanged(std::vector<media::MediaTrack::Id>);
+  void OnSelectedVideoTrackChanged(std::optional<media::MediaTrack::Id>);
 
   // Dimensions of the video.
   gfx::Size NaturalSize() const override;
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index fb3037d..b347f8c 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -3187,6 +3187,13 @@
       name: "PointerEventTargetsInEventLists",
       status: "stable",
     },
+    // TODO(crbug.com/364669918) This enables these two new functionalities:
+    // 1. add an imperative way to set invoker relationships between popovers.
+    // 2. invoker relationships create implicit anchor element references.
+    {
+      name: "PopoverAnchorRelationships",
+      status: "experimental",
+    },
     // This is a killswitch for the behavior of <dialog popover autofocus>,
     // which landed in M130 and can be removed in M132.
     {
@@ -3880,12 +3887,6 @@
       status: "stable",
     },
     {
-      // Skips calling update type if the HTMLInputElement is created by parser.
-      // This flag can be removed in M127 if no issues reported.
-      name: "SkipUpdateTypeForHTMLInputElementCreatedByParser",
-      status: "stable",
-    },
-    {
       name: "SmartCard",
       status: {"Android": "", "default": "test"},
     },
diff --git a/third_party/blink/renderer/platform/testing/empty_web_media_player.h b/third_party/blink/renderer/platform/testing/empty_web_media_player.h
index 51cd271f..f382909 100644
--- a/third_party/blink/renderer/platform/testing/empty_web_media_player.h
+++ b/third_party/blink/renderer/platform/testing/empty_web_media_player.h
@@ -34,7 +34,7 @@
   void SetVolume(double) override {}
   void SetLatencyHint(double) override {}
   void SetPreservesPitch(bool) override {}
-  void SetWasPlayedWithUserActivation(bool) override {}
+  void SetWasPlayedWithUserActivationAndHighMediaEngagement(bool) override {}
   void SetShouldPauseWhenFrameIsHidden(bool) override {}
   void OnRequestPictureInPicture() override {}
   WebTimeRanges Buffered() const override;
diff --git a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
index 95fa6b6..f5e4f08 100644
--- a/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
+++ b/third_party/blink/renderer/platform/video_capture/video_capture_impl.cc
@@ -574,7 +574,7 @@
   // The SharedImages here are used to back VideoFrames. They may be read by the
   // raster interface for format conversion (e.g., for 2-copy import into WebGL)
   // as well as by the GLES2 interface for one-copy import into WebGL.
-  uint32_t usage =
+  gpu::SharedImageUsageSet usage =
       gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_RASTER_READ |
       gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
 #if BUILDFLAG(IS_APPLE)
diff --git a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
index 270a6c8..dac38cd 100755
--- a/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
+++ b/third_party/blink/tools/blinkpy/presubmit/audit_non_blink_usage.py
@@ -929,16 +929,21 @@
             # Flags to be used to set up sharedImage
             'gpu::SHARED_IMAGE_USAGE_DISPLAY_READ',
             'gpu::SHARED_IMAGE_USAGE_SCANOUT',
+            'gpu::SharedImageUsageSet'
         ],
     },
     {
         'paths': [
-            'third_party/blink/renderer/core/html/canvas/canvas_rendering_context_host.cc'
+            'third_party/blink/renderer/core',
+            'third_party/blink/public/common/messaging/accelerated_image_info.h',
+            'third_party/blink/public/common/messaging/accelerated_static_bitmap_image_mojom_traits.h',
+            'third_party/blink/common/messaging/accelerated_static_bitmap_image_mojom_traits.cc'
         ],
         'allowed': [
             'gpu::SHARED_IMAGE_USAGE_DISPLAY_READ',
             'gpu::SHARED_IMAGE_USAGE_SCANOUT',
             'gpu::SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE',
+            'gpu::SharedImageUsageSet'
         ],
     },
     {
@@ -1389,6 +1394,7 @@
             'gpu::raster::RasterInterface',
             'gpu::SHARED_IMAGE_USAGE_.+',
             'gpu::SharedImageInterface',
+            'gpu::SharedImageUsageSet',
             'gpu::SyncToken',
             'gpu::webgpu::ReservedTexture',
             'media::IsOpaque',
@@ -1644,6 +1650,7 @@
             'gpu::raster::RasterInterface',
             'gpu::SHARED_IMAGE_.+',
             'gpu::SharedImageInterface',
+            'gpu::SharedImageUsageSet',
             'gpu::SyncToken',
             'libgav1::.+',
             'libyuv::.+',
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations
index 43fb26c..e463470 100644
--- a/third_party/blink/web_tests/MSANExpectations
+++ b/third_party/blink/web_tests/MSANExpectations
@@ -119,3 +119,4 @@
 
 # Chrome crashes on start up
 crbug.com/360008882 external/wpt/secure-payment-confirmation/* [ Skip ]
+crbug.com/360008882 wpt_internal/nav-tracking-mitigations/stateful-client-bounce.sub.https.html [ Skip ]
diff --git a/third_party/blink/web_tests/SlowTests b/third_party/blink/web_tests/SlowTests
index 22f376e1..0859d963 100644
--- a/third_party/blink/web_tests/SlowTests
+++ b/third_party/blink/web_tests/SlowTests
@@ -153,7 +153,6 @@
 crbug.com/1229701 [ Release Win ] http/tests/inspector-protocol/network/disable-cache-media-resource.js [ Slow ]
 crbug.com/1300409 http/tests/inspector-protocol/network/websocket/offline-no-send.js [ Slow ]
 crbug.com/1280873 http/tests/inspector-protocol/network/xhr-cors-preflight-redirect-failure.js [ Slow ]
-crbug.com/1280697 http/tests/inspector-protocol/network/block_cross_site_document_load.js [ Slow ]
 crbug.com/1280585 http/tests/inspector-protocol/network/xhr-post-replay-cors.js [ Slow ]
 crbug.com/1280537 http/tests/inspector-protocol/network/blocked-cookie-same-site-lax-browser-navigate.js [ Slow ]
 crbug.com/1280537 [ Linux ] http/tests/inspector-protocol/network/blocked-cookie-same-site-lax-js-navigate.js [ Slow ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 2ab6457..ea08cd7 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -1234,7 +1234,6 @@
 crbug.com/1098801 external/wpt/css/css-text/overflow-wrap/overflow-wrap-normal-keep-all-001.html [ Failure ]
 
 # CSS Inline `text-box-trim` and `text-box-edge` properties.
-crbug.com/359926563 external/wpt/css/css-inline/text-box-trim/text-box-trim-float-clear-br-003.html [ Failure ]
 crbug.com/359926563 external/wpt/css/css-inline/text-box-trim/text-box-trim-half-leading-block-box-004.html [ Failure ]
 crbug.com/359926563 external/wpt/css/css-inline/text-box-trim/text-box-trim-half-leading-block-box-005.html [ Failure ]
 
diff --git a/third_party/blink/web_tests/TestLists/chrome.filter b/third_party/blink/web_tests/TestLists/chrome.filter
index ad6947b..df5cae2 100644
--- a/third_party/blink/web_tests/TestLists/chrome.filter
+++ b/third_party/blink/web_tests/TestLists/chrome.filter
@@ -9,3 +9,7 @@
 
 # crbug.com/336866597 set_spc_transaction_mode not implemented for content shell
 external/wpt/secure-payment-confirmation/*
+
+# crbug.com/40279363 run_bounce_tracking_mitigations and the bounce tracking
+# mitigations feature are not implemented for content shell yet.
+wpt_internal/nav-tracking-mitigations/stateful-client-bounce.sub.https.html
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites
index 7e5f9aed..03bf52a 100644
--- a/third_party/blink/web_tests/VirtualTestSuites
+++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -1447,9 +1447,7 @@
     "prefix": "html-anchor-attribute-disabled",
     "owners": ["masonf@chromium.org"],
     "platforms": ["Linux", "Mac", "Win"],
-    "bases": [
-      "external/wpt/html/semantics/popovers"
-    ],
+    "bases": ["external/wpt/html/semantics/popovers"],
     "args": ["--disable-blink-features=HTMLAnchorAttribute"],
     "expires": "Jun 1, 2025"
   },
@@ -1462,6 +1460,14 @@
     "expires": "Dec 1, 2024"
   },
   {
+    "prefix": "popover-anchor-relationships-disabled",
+    "owners": ["masonf@chromium.org"],
+    "platforms": ["Linux"],
+    "bases": ["external/wpt/html/semantics/popovers"],
+    "args": ["--disable-blink-features=PopoverAnchorRelationships"],
+    "expires": "Jun 1, 2025"
+  },
+  {
     "owners": [
       "haoliuk@chromium.org"
     ],
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-ltr-htb.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-ltr-htb.html
new file mode 100644
index 0000000..3e5bc482
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-ltr-htb.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  align-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-ltr-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-ltr-vrl.html
new file mode 100644
index 0000000..7144bb15
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-ltr-vrl.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  align-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-rtl-htb.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-rtl-htb.html
new file mode 100644
index 0000000..c041d8efa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-rtl-htb.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: horizontal-tb;
+  direction: rtl;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  align-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-rtl-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-rtl-vrl.html
new file mode 100644
index 0000000..0174fd0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-htb-rtl-vrl.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: horizontal-tb;
+  direction: rtl;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  align-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-ltr-htb.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-ltr-htb.html
new file mode 100644
index 0000000..a9a6413
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-ltr-htb.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  align-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-ltr-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-ltr-vrl.html
new file mode 100644
index 0000000..e3be64a
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-ltr-vrl.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  align-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-rtl-htb.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-rtl-htb.html
new file mode 100644
index 0000000..9c1b7792
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-rtl-htb.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: vertical-rl;
+  direction: rtl;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  align-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-rtl-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-rtl-vrl.html
new file mode 100644
index 0000000..eaebcf0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/align-self-default-overflow-vrl-rtl-vrl.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: vertical-rl;
+  direction: rtl;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  align-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-ltr-htb.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-ltr-htb.html
new file mode 100644
index 0000000..753001068
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-ltr-htb.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  justify-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: 20px; right: 10px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="left: 20px; right: 10px;" data-offset-x="15">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 20px; right: 10px;" data-offset-x="5">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 20px; right: 10px;" data-offset-x="0">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -20px; right: -10px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -20px; right: -10px;" data-offset-x="-15">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: -20px; right: -10px;" data-offset-x="-20">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: 20px; right: 10px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="left: 20px; right: 10px;" data-offset-x="15">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 20px; right: 10px;" data-offset-x="5">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 20px; right: 10px;" data-offset-x="0">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -20px; right: -10px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -20px; right: -10px;" data-offset-x="-15">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: -20px; right: -10px;" data-offset-x="-20">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-ltr-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-ltr-vrl.html
new file mode 100644
index 0000000..26bba3e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-ltr-vrl.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  justify-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: 20px; right: 10px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="left: 20px; right: 10px;" data-offset-x="15">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 20px; right: 10px;" data-offset-x="5">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 20px; right: 10px;" data-offset-x="0">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -20px; right: -10px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -20px; right: -10px;" data-offset-x="-15">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: -20px; right: -10px;" data-offset-x="-20">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: 20px; right: 10px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="left: 20px; right: 10px;" data-offset-x="15">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 20px; right: 10px;" data-offset-x="5">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 20px; right: 10px;" data-offset-x="0">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -20px; right: -10px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -20px; right: -10px;" data-offset-x="-15">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: -20px; right: -10px;" data-offset-x="-20">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-rtl-htb.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-rtl-htb.html
new file mode 100644
index 0000000..f3b46447e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-rtl-htb.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: horizontal-tb;
+  direction: rtl;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  justify-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-rtl-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-rtl-vrl.html
new file mode 100644
index 0000000..adf9b30
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-htb-rtl-vrl.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: horizontal-tb;
+  direction: rtl;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  justify-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="5">
+    <div class="inner" style="width: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="0">
+    <div class="inner" style="width: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: 10px; right: 20px;" data-offset-x="-20">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-5">
+    <div class="inner" style="width: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="left: -10px; right: -20px;" data-offset-x="-40">
+    <div class="inner" style="width: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-ltr-htb.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-ltr-htb.html
new file mode 100644
index 0000000..cc53c97
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-ltr-htb.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  justify-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-ltr-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-ltr-vrl.html
new file mode 100644
index 0000000..92fa800
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-ltr-vrl.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  justify-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="15">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="5">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 20px; bottom: 10px;" data-offset-y="0">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-15">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: -20px; bottom: -10px;" data-offset-y="-20">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-rtl-htb.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-rtl-htb.html
new file mode 100644
index 0000000..6c117f3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-rtl-htb.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: vertical-rl;
+  direction: rtl;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: horizontal-tb;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  justify-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: 10px; bottom: 20px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="top: 10px; bottom: 20px;" data-offset-y="5">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 10px; bottom: 20px;" data-offset-y="0">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 10px; bottom: 20px;" data-offset-y="-20">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -10px; bottom: -20px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -10px; bottom: -20px;" data-offset-y="-5">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: -10px; bottom: -20px;" data-offset-y="-40">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: 10px; bottom: 20px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="top: 10px; bottom: 20px;" data-offset-y="5">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 10px; bottom: 20px;" data-offset-y="0">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 10px; bottom: 20px;" data-offset-y="-20">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -10px; bottom: -20px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -10px; bottom: -20px;" data-offset-y="-5">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: -10px; bottom: -20px;" data-offset-y="-40">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-rtl-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-rtl-vrl.html
new file mode 100644
index 0000000..ea1f8cc
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-align/abspos/justify-self-default-overflow-vrl-rtl-vrl.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-align-3/#align-abspos">
+<style>
+body {
+  margin: 0;
+}
+
+.container {
+  writing-mode: vertical-rl;
+  direction: rtl;
+  display: inline-block;
+  position: relative;
+  margin: 20px;
+  border: solid 4px;
+  width: 100px;
+  height: 100px;
+}
+
+.item {
+  writing-mode: vertical-rl;
+  direction: ltr;
+  position: absolute;
+  background: green;
+  justify-self: center;
+}
+
+.inner {
+  width: 20px;
+  height: 20px;
+}
+
+.rtl {
+  direction: rtl;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+
+<body onload="checkLayout('.item')">
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: 10px; bottom: 20px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item" style="top: 10px; bottom: 20px;" data-offset-y="5">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 10px; bottom: 20px;" data-offset-y="0">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: 10px; bottom: 20px;" data-offset-y="-20">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -10px; bottom: -20px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item" style="top: -10px; bottom: -20px;" data-offset-y="-5">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item" style="top: -10px; bottom: -20px;" data-offset-y="-40">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
+
+<!-- RTL items. -->
+<br>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: 10px; bottom: 20px;" data-offset-y="35">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- Overflows IMCB, but not CB. -->
+<div class="container">
+  <div class="item rtl" style="top: 10px; bottom: 20px;" data-offset-y="5">
+    <div class="inner" style="height: 80px;"></div>
+  </div>
+</div>
+
+<!-- Overflows weak CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 10px; bottom: 20px;" data-offset-y="0">
+    <div class="inner" style="height: 95px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: 10px; bottom: 20px;" data-offset-y="-20">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -10px; bottom: -20px;" data-offset-y="45">
+    <div class="inner"></div>
+  </div>
+</div>
+
+<!-- No overflow, centered in IMCB. -->
+<div class="container">
+  <div class="item rtl" style="top: -10px; bottom: -20px;" data-offset-y="-5">
+    <div class="inner" style="height: 120px;"></div>
+  </div>
+</div>
+
+<!-- Overflows strong CB edge, shifted. -->
+<div class="container">
+  <div class="item rtl" style="top: -10px; bottom: -20px;" data-offset-y="-40">
+    <div class="inner" style="height: 160px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-htb-htb.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-htb-htb.html
index 20abb2e..50fc090 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-htb-htb.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-htb-htb.html
@@ -43,34 +43,44 @@
 <!-- no insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" data-expected-width="70" data-offset-x="30"></div>
+  <div class="target" data-expected-width="100" data-offset-x="0"></div>
+</div>
+
+<div class="container">
+  <div class="anchor"></div>
+  <div class="target" style="max-width: 60px;" data-expected-width="60" data-offset-x="35"></div>
 </div>
 
 <!-- single insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="left: 20px;" data-expected-width="70" data-offset-x="30"></div>
+  <div class="target" style="left: 20px;" data-expected-width="80" data-offset-x="20"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="right: 20px;" data-expected-width="30" data-offset-x="50"></div>
+  <div class="target" style="right: 20px;" data-expected-width="80" data-offset-x="20"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="right: -20px;" data-expected-width="110" data-offset-x="10"></div>
+  <div class="target" style="right: -20px;" data-expected-width="120" data-offset-x="0"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="right: -100px;" data-expected-width="130" data-offset-x="0"></div>
+  <div class="target" style="max-width: 100px; right: -20px;" data-expected-width="100" data-offset-x="15"></div>
+</div>
+
+<div class="container">
+  <div class="anchor"></div>
+  <div class="target" style="right: -50px;" data-expected-width="150" data-offset-x="0"></div>
 </div>
 
 <!-- both insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="left: 10px; right: 20px;" data-expected-width="30" data-offset-x="50"></div>
+  <div class="target" style="left: 10px; right: 20px;" data-expected-width="70" data-offset-x="30"></div>
 </div>
 
 <div class="container">
@@ -80,5 +90,5 @@
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="left: -10px; right: -50px;" data-expected-width="150" data-offset-x="-10"></div>
+  <div class="target" style="left: -10px; right: -50px;" data-expected-width="160" data-offset-x="-10"></div>
 </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-htb-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-htb-vrl.html
index 099d9cd..eba72d6 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-htb-vrl.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-htb-vrl.html
@@ -44,34 +44,44 @@
 <!-- no insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" data-expected-height="70" data-offset-y="30"></div>
+  <div class="target" data-expected-height="100" data-offset-y="0"></div>
+</div>
+
+<div class="container">
+  <div class="anchor"></div>
+  <div class="target" style="max-height: 60px;" data-expected-height="60" data-offset-y="35"></div>
 </div>
 
 <!-- single insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="top: 20px;" data-expected-height="70" data-offset-y="30"></div>
+  <div class="target" style="top: 20px;" data-expected-height="80" data-offset-y="20"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="bottom: 20px;" data-expected-height="30" data-offset-y="50"></div>
+  <div class="target" style="bottom: 20px;" data-expected-height="80" data-offset-y="20"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="bottom: -20px;" data-expected-height="110" data-offset-y="10"></div>
+  <div class="target" style="bottom: -20px;" data-expected-height="120" data-offset-y="0"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="bottom: -100px;" data-expected-height="130" data-offset-y="0"></div>
+  <div class="target" style="max-height: 100px; bottom: -20px;" data-expected-height="100" data-offset-y="15"></div>
+</div>
+
+<div class="container">
+  <div class="anchor"></div>
+  <div class="target" style="bottom: -50px;" data-expected-height="150" data-offset-y="0"></div>
 </div>
 
 <!-- both insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="top: 10px; bottom: 20px;" data-expected-height="30" data-offset-y="50"></div>
+  <div class="target" style="top: 10px; bottom: 20px;" data-expected-height="70" data-offset-y="30"></div>
 </div>
 
 <div class="container">
@@ -81,5 +91,5 @@
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="top: -10px; bottom: -50px;" data-expected-height="150" data-offset-y="-10"></div>
+  <div class="target" style="top: -10px; bottom: -50px;" data-expected-height="160" data-offset-y="-10"></div>
 </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-vrl-htb.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-vrl-htb.html
index 3e4f485..8f7af041 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-vrl-htb.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-vrl-htb.html
@@ -45,34 +45,44 @@
 <!-- no insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" data-expected-width="70" data-offset-x="30"></div>
+  <div class="target" data-expected-width="100" data-offset-x="0"></div>
+</div>
+
+<div class="container">
+  <div class="anchor"></div>
+  <div class="target" style="max-width: 60px;" data-expected-width="60" data-offset-x="35"></div>
 </div>
 
 <!-- single insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="left: 20px;" data-expected-width="70" data-offset-x="30"></div>
+  <div class="target" style="left: 20px;" data-expected-width="80" data-offset-x="20"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="right: 20px;" data-expected-width="30" data-offset-x="50"></div>
+  <div class="target" style="right: 20px;" data-expected-width="80" data-offset-x="20"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="right: -20px;" data-expected-width="110" data-offset-x="10"></div>
+  <div class="target" style="right: -20px;" data-expected-width="120" data-offset-x="0"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="right: -100px;" data-expected-width="130" data-offset-x="0"></div>
+  <div class="target" style="max-width: 100px; right: -20px;" data-expected-width="100" data-offset-x="15"></div>
+</div>
+
+<div class="container">
+  <div class="anchor"></div>
+  <div class="target" style="right: -50px;" data-expected-width="150" data-offset-x="0"></div>
 </div>
 
 <!-- both insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="left: 10px; right: 20px;" data-expected-width="30" data-offset-x="50"></div>
+  <div class="target" style="left: 10px; right: 20px;" data-expected-width="70" data-offset-x="30"></div>
 </div>
 
 <div class="container">
@@ -82,5 +92,5 @@
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="left: -10px; right: -50px;" data-expected-width="150" data-offset-x="-10"></div>
+  <div class="target" style="left: -10px; right: -50px;" data-expected-width="160" data-offset-x="-10"></div>
 </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-vrl-vrl.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-vrl-vrl.html
index fe40c731..d8e9005 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-vrl-vrl.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/anchor-center-vrl-vrl.html
@@ -44,34 +44,44 @@
 <!-- no insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" data-expected-height="70" data-offset-y="30"></div>
+  <div class="target" data-expected-height="100" data-offset-y="0"></div>
+</div>
+
+<div class="container">
+  <div class="anchor"></div>
+  <div class="target" style="max-height: 60px;" data-expected-height="60" data-offset-y="35"></div>
 </div>
 
 <!-- single insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="top: 20px;" data-expected-height="70" data-offset-y="30"></div>
+  <div class="target" style="top: 20px;" data-expected-height="80" data-offset-y="20"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="bottom: 20px;" data-expected-height="30" data-offset-y="50"></div>
+  <div class="target" style="bottom: 20px;" data-expected-height="80" data-offset-y="20"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="bottom: -20px;" data-expected-height="110" data-offset-y="10"></div>
+  <div class="target" style="bottom: -20px;" data-expected-height="120" data-offset-y="0"></div>
 </div>
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="bottom: -100px;" data-expected-height="130" data-offset-y="0"></div>
+  <div class="target" style="max-height: 100px; bottom: -20px;" data-expected-height="100" data-offset-y="15"></div>
+</div>
+
+<div class="container">
+  <div class="anchor"></div>
+  <div class="target" style="bottom: -50px;" data-expected-height="150" data-offset-y="0"></div>
 </div>
 
 <!-- both insets -->
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="top: 10px; bottom: 20px;" data-expected-height="30" data-offset-y="50"></div>
+  <div class="target" style="top: 10px; bottom: 20px;" data-expected-height="70" data-offset-y="30"></div>
 </div>
 
 <div class="container">
@@ -81,5 +91,5 @@
 
 <div class="container">
   <div class="anchor"></div>
-  <div class="target" style="top: -10px; bottom: -50px;" data-expected-height="150" data-offset-y="-10"></div>
+  <div class="target" style="top: -10px; bottom: -50px;" data-expected-height="160" data-offset-y="-10"></div>
 </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-anchor-position/auto-margins-position-area.html b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/auto-margins-position-area.html
new file mode 100644
index 0000000..83014100
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-anchor-position/auto-margins-position-area.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/">
+<style>
+.container {
+  position: relative;
+  width: 100px;
+  height: 100px;
+  border: solid 3px;
+}
+
+.anchor {
+  anchor-name: --a;
+  background: lime;
+  width: 20px;
+  height: 20px;
+  position: relative;
+  left: 20px;
+  top: 30px;
+}
+
+.abspos {
+  background: cornflowerblue;
+  margin: auto;
+  position: absolute;
+  position-area: bottom;
+  position-anchor: --a;
+}
+</style>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/check-layout-th.js"></script>
+<body onload="checkLayout('.abspos')">
+<div class="container">
+  <div class="anchor"></div>
+  <div class="abspos" data-offset-x=10 data-offset-y=65>
+    <div style="width: 80px; height: 20px;"></div>
+  </div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-trim-float-clear-br-003-ref.html b/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-trim-float-clear-br-003-ref.html
index 8c147700..c192242a 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-trim-float-clear-br-003-ref.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-trim-float-clear-br-003-ref.html
@@ -15,7 +15,7 @@
 .float {
   float: left;
   width: 100px;
-  height: 100px;
+  height: 90px;
   background: yellow;
 }
 .clear { clear: both; }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-trim-float-clear-br-003.html b/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-trim-float-clear-br-003.html
index e04d18ec..cfb0c14 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-trim-float-clear-br-003.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-trim-float-clear-br-003.html
@@ -2,7 +2,7 @@
 <title>text-box-trim does not interfere with clearance less than trim amount</title>
 <link rel="help" href="https://drafts.csswg.org/css-inline-3/#text-box-trim">
 <link rel="help" href="https://drafts.csswg.org/css-inline-3/#text-box-edge">
-<link rel="match" href="text-box-trim-float-clear-br-002-ref.html">
+<link rel="match" href="text-box-trim-float-clear-br-003-ref.html">
 <style>
 @import "support/MetricsTestFont.css";
 
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/popovers/imperative-invokers.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/popovers/imperative-invokers.tentative.html
new file mode 100644
index 0000000..f810d11
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/popovers/imperative-invokers.tentative.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:masonf@chromium.org">
+<link rel=help href="https://github.com/whatwg/html/pull/9144#issuecomment-2195095228">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id=unrelated></div>
+<div id=popover popover=auto>
+  <div id=contained></div>
+  popover 1
+</div>
+<div id=popover2 popover=auto style="top:50px">
+  popover 2
+</div>
+
+<script>
+function testOneCase(shouldBeIndependent,popover2Opener,msg) {
+  test((t) => {
+    assert_false(popover.matches(':popover-open'),'starting state');
+    assert_false(popover2.matches(':popover-open'),'starting state');
+    t.add_cleanup(() => {popover.hidePopover();popover2.hidePopover()});
+    popover.showPopover();
+    assert_true(popover.matches(':popover-open'));
+    popover2Opener();
+    assert_true(popover2.matches(':popover-open'),'opener should open popover2');
+    if (shouldBeIndependent) {
+      assert_false(popover.matches(':popover-open'),'popovers should not be related');
+    } else {
+      assert_true(popover.matches(':popover-open'),'popovers should be related to each other');
+    }
+  },msg);
+}
+
+testOneCase(true,() => popover2.showPopover(),'normal opening');
+testOneCase(true,() => popover2.showPopover({invoker: unrelated}),'showPopover(unrelated)');
+testOneCase(false,() => popover2.showPopover({invoker: popover}),'showPopover(popover)');
+testOneCase(false,() => popover2.showPopover({invoker: contained}),'showPopover(contained)');
+
+testOneCase(true,() => popover2.togglePopover(true),'togglePopover(true)');
+testOneCase(true,() => popover2.togglePopover({force:true}),'togglePopover({force})');
+testOneCase(true,() => popover2.togglePopover({invoker:unrelated}),'togglePopover(unrelated)');
+testOneCase(false,() => popover2.togglePopover({invoker: popover}),'togglePopover(popover)');
+testOneCase(false,() => popover2.togglePopover({force:true, invoker: popover}),'togglePopover({force, popover})');
+
+test(() => {
+  assert_false(popover.matches(':popover-open'));
+  assert_throws_js(TypeError,() => popover2.showPopover({invoker: null}),'showPopover(null)');
+  assert_throws_js(TypeError,() => popover2.togglePopover({invoker:null}),'togglePopover(null)');
+  assert_false(popover.matches(':popover-open'));
+},'null isn\'t a valid Element');
+</script>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/cors-issues.js b/third_party/blink/web_tests/http/tests/inspector-protocol/issues/cors-issues.js
deleted file mode 100644
index fbac58b..0000000
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/issues/cors-issues.js
+++ /dev/null
@@ -1,54 +0,0 @@
-(async function(/** @type {import('test_runner').TestRunner} */ testRunner) {
-  const {page, session, dp} = await testRunner.startBlank(
-      `Test to make sure CORS issues are correctly reported.`);
-
-  // This url should be cross origin.
-  const url = `https://127.0.0.1:8443/inspector-protocol/network/resources`;
-
-
-  await dp.Audits.enable();
-  const issues = [];
-  const issuesReceived =
-      new Promise(resolve => dp.Audits.onIssueAdded(issue => {
-        issues.push(issue.params.issue);
-        if (issues.length === 4)
-          resolve();
-      }));
-
-  await dp.Runtime.enable();
-  const issueIdToException = new Map();
-  const exceptionsThrown =
-      new Promise(resolve => dp.Runtime.onExceptionThrown(exception => {
-        const metaData = exception.params.exceptionDetails.exceptionMetaData;
-        issueIdToException.set(metaData.issueId, exception.params);
-        if (issueIdToException.size === 4)
-          resolve();
-      }));
-
-  session.evaluate(`
-    fetch('${url}/cors-headers.php');
-
-    fetch('${url}/cors-headers.php?origin=${
-      encodeURIComponent('http://127.0.0.1')}');
-
-    fetch("${url}/cors-headers.php?methods=GET&origin=1", {method: 'POST',
-    mode: 'cors', body: 'FOO', cache: 'no-cache',
-    headers: { 'Content-Type': 'application/json'} });
-
-    fetch("${url}/cors-redirect.php");
-  `);
-
-  await issuesReceived;
-  await exceptionsThrown;
-
-  issues.sort(
-      (a, b) =>
-          a.details?.corsIssueDetails?.corsErrorStatus?.corsError.localeCompare(
-              b.details?.corsIssueDetails?.corsErrorStatus?.corsError));
-  for (const issue of issues) {
-    testRunner.log(issue, 'Cors issue: ', ['requestId', 'issueId']);
-    testRunner.log(`Issue link present: ${
-        Boolean(issueIdToException.get(issue.issueId))}`);
-  }
-  testRunner.completeTest();
-})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/network/block_cross_site_document_load.js b/third_party/blink/web_tests/http/tests/inspector-protocol/network/block_cross_site_document_load.js
deleted file mode 100644
index 700f551..0000000
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/network/block_cross_site_document_load.js
+++ /dev/null
@@ -1,76 +0,0 @@
-(async function(/** @type {import('test_runner').TestRunner} */ testRunner) {
-  var {page, session, dp} = await testRunner.startURL(
-      '../resources/test-page.html',
-      `Tests that CORB/ORB blocking gets reported as an issue to DevTools.`);
-
-  await dp.Audits.enable();
-
-  // Returns a promise that returns true if a ResponseWasBlockedByORB issue
-  // was added. It expectes a "probe" issue for a fetch to `probe_url` in
-  // order to determine (without a race condition) at what point in time the
-  // issue should have been received.
-  // We do some sanity checks on the issue parameters while we're here.
-  function expectIssueAdded(issueHasBeenAdded) {
-    return dp.Audits.onceIssueAdded().then(issue => {
-      const genericIssueDetails = issue?.params?.issue?.details?.genericIssueDetails;
-      if (!genericIssueDetails)
-        throw new Error('Unexpected issue shape.');
-      if (genericIssueDetails.errorType !== 'ResponseWasBlockedByORB')
-        throw new Error('Unexpected issue errorType.');
-      if (!genericIssueDetails?.request?.url)
-        throw new Error('Unexpected issue shape.');
-      if (genericIssueDetails.request.url.includes('probe.test'))
-        return issueHasBeenAdded;
-      return expectIssueAdded(true);
-    });
-  }
-
-  function shouldReportCorbBlocking() {
-    // This returns a promise which returns whether a DevTools issue (other
-    // than for "probe.test") was added.
-    return expectIssueAdded(false);
-  }
-
-  // In order to recognize whether the sub-test a completed, we'll always
-  // follow up with a URL that definitely gets (C)ORB-blocked. We'll complete
-  // the test when we receive an issue for that probe url. That gives us a
-  // non-racy point in time where the previous url - which we want to test
-  // for - must have been received.
-  const probe_url = 'http://probe.test:8000/inspector-protocol/network/resources/nosniff.pl';
-  function loadImageAndProbe(url) {
-    return `
-        probe = function() { new Image().src = '${probe_url}'; }
-        img = new Image();
-        img.src = '${url}';
-        img.onerror = probe;
-        img.onload = probe;
-    `;
-  }
-
-  let blocked_urls = [
-    'http://devtools.oopif.test:8000/inspector-protocol/network/resources/nosniff.pl',
-    'http://devtools.oopif.test:8000/inspector-protocol/network/resources/simple-iframe.html',
-    'http://devtools.oopif.test:8000/inspector-protocol/network/resources/404.pl',
-    'http://devtools.oopif.test:8000/inspector-protocol/network/resources/content-length-0.pl',
-  ];
-  for (const url of blocked_urls) {
-    session.evaluate(loadImageAndProbe(url));
-    testRunner.log(
-        `Blocking cross-site document at ${url}: ` +
-        `shouldReportCorbBlocking=${await shouldReportCorbBlocking()}.`);
-  }
-
-  let allowed_urls = [
-    'http://127.0.0.1:8000/inspector-protocol/network/resources/nosniff.pl',
-    'http://127.0.0.1:8000/inspector-protocol/network/resources/simple-iframe.html',
-    'http://devtools.oopif.test:8000/inspector-protocol/network/resources/test.css',
-  ]
-  for (const url of allowed_urls) {
-    session.evaluate(loadImageAndProbe(url));
-    testRunner.log(
-        `Allowing cross-site document at ${url}: ` +
-        `shouldReportCorbBlocking=${await shouldReportCorbBlocking()}.`);
-  }
-
-  testRunner.completeTest();
-})
diff --git a/third_party/blink/web_tests/virtual/popover-anchor-relationships-disabled/README.md b/third_party/blink/web_tests/virtual/popover-anchor-relationships-disabled/README.md
new file mode 100644
index 0000000..8e261bce
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/popover-anchor-relationships-disabled/README.md
@@ -0,0 +1,4 @@
+# Overview
+
+This suite runs a subset of tests with `--disable-features=PopoverAnchorRelationships`, to make
+sure no new behavior is inadvertently exposed when the feature is disabled.
diff --git a/third_party/blink/web_tests/virtual/popover-anchor-relationships-disabled/external/wpt/html/semantics/popovers/imperative-invokers.tentative-expected.txt b/third_party/blink/web_tests/virtual/popover-anchor-relationships-disabled/external/wpt/html/semantics/popovers/imperative-invokers.tentative-expected.txt
new file mode 100644
index 0000000..688d2f7
--- /dev/null
+++ b/third_party/blink/web_tests/virtual/popover-anchor-relationships-disabled/external/wpt/html/semantics/popovers/imperative-invokers.tentative-expected.txt
@@ -0,0 +1,11 @@
+This is a testharness.js-based test.
+[FAIL] showPopover(popover)
+  assert_true: popovers should be related to each other expected true got false
+[FAIL] showPopover(contained)
+  assert_true: popovers should be related to each other expected true got false
+[FAIL] togglePopover(popover)
+  assert_true: popovers should be related to each other expected true got false
+[FAIL] togglePopover({force, popover})
+  assert_true: popovers should be related to each other expected true got false
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/DIR_METADATA b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/DIR_METADATA
new file mode 100644
index 0000000..7e7eba9
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/DIR_METADATA
@@ -0,0 +1,10 @@
+monorail {
+  component: "Privacy>NavTracking"
+}
+team_email: "navtracking-team@google.com"
+buganizer_public: {
+  component_id: 1456144
+}
+wpt {
+  notify: YES
+}
diff --git a/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/META.yml b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/META.yml
new file mode 100644
index 0000000..dfde5e52
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/META.yml
@@ -0,0 +1,7 @@
+spec: https://privacycg.github.io/nav-tracking-mitigations/
+suggested_reviewers:
+  - amaliev
+  - hoodjoshua
+  - njeunje
+  - rtarpine-google
+  - wanderview
diff --git a/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/cross-origin-client-redirect-with-cookie-header.sub.https.html b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/cross-origin-client-redirect-with-cookie-header.sub.https.html
new file mode 100644
index 0000000..7676378
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/cross-origin-client-redirect-with-cookie-header.sub.https.html
@@ -0,0 +1,15 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+  // `document.cookie` is set using the `Set-Cookie` HTTP header in
+  // cross-origin-client-redirect-with-cookie-header.sub.https.html.headers.
+  assert_equals(document.cookie, 'example=test');
+
+  const url = new URL('redirect-chain-end.sub.https.html',
+                      window.location.href);
+  url.hostname = '{{host}}';
+
+  window.location = url;
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/cross-origin-client-redirect-with-cookie-header.sub.https.html.headers b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/cross-origin-client-redirect-with-cookie-header.sub.https.html.headers
new file mode 100644
index 0000000..64415c3
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/cross-origin-client-redirect-with-cookie-header.sub.https.html.headers
@@ -0,0 +1,2 @@
+Content-Type: text/html
+Set-Cookie: example=test
diff --git a/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/redirect-chain-end.sub.https.html b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/redirect-chain-end.sub.https.html
new file mode 100644
index 0000000..54966d6
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/redirect-chain-end.sub.https.html
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Bounce Tracking Mitigations: Stateful Client Bounce (End Page)</title>
+<script>
+  // Notify the main test page that the redirect flow has completed.
+  window.opener.postMessage(true, '*');
+
+  // This will end the redirect chain.
+  window.close();
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/redirect-chain-start.sub.https.html b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/redirect-chain-start.sub.https.html
new file mode 100644
index 0000000..a1655f4
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/resources/redirect-chain-start.sub.https.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Bounce Tracking Mitigations: Stateful Client Bounce (Start Page)</title>
+<body></body>
+<script src=/resources/testdriver.js></script>
+<script>
+  const url = new URL(
+    'cross-origin-client-redirect-with-cookie-header.sub.https.html',
+    window.location.href);
+  url.hostname = '{{hosts[alt][]}}';
+
+  const link = document.createElement('a');
+  link.href = url;
+  // Used by the main test page to retrieve the button.
+  link.id = 'navigate-link';
+  link.text = 'navigate to redirecting page';
+  document.body.append(link);
+</script>
diff --git a/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/stateful-client-bounce.sub.https.html b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/stateful-client-bounce.sub.https.html
new file mode 100644
index 0000000..bcfda26
--- /dev/null
+++ b/third_party/blink/web_tests/wpt_internal/nav-tracking-mitigations/stateful-client-bounce.sub.https.html
@@ -0,0 +1,50 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Bounce Tracking Mitigations: Stateful Client Bounce</title>
+<body>body for test_driver.bless</body>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/testdriver.js></script>
+<script src=/resources/testdriver-vendor.js></script>
+<script>
+  promise_setup(async () => {
+    try {
+      await test_driver.set_storage_access('*', '*', 'blocked');
+    } catch (e) {
+      // Ignore, can be unimplemented if the platform blocks cross-site
+      // cookies by default. If this failed without default blocking the test
+      // will fail.
+    }
+  });
+
+  promise_test(async t => {
+    const {promise: getLinkPromise, resolve: getLinkResolver} =
+      Promise.withResolvers();
+
+    // Open a new tab and retrieve the link to start the test.
+    await test_driver.bless('open page to start test', async () => {
+      const otherTab = window.open(
+        'resources/redirect-chain-start.sub.https.html');
+
+      await new Promise(resolve => otherTab.addEventListener('load', resolve));
+      getLinkResolver(otherTab.document.getElementById('navigate-link'));
+    });
+
+    // Click the link in the new tab.
+    //
+    // Ideally, we would click this from within the page, but because the page
+    // immediately navigates away, test_driver fails as it expects the page to
+    // not navigate away. Doing this from the main test page avoids the issue.
+    const link = await getLinkPromise;
+    test_driver.click(link);
+
+    await new Promise(resolve => window.addEventListener('message', resolve));
+
+    let result = [];
+    while (result.length == 0) {
+      result = await test_driver.run_bounce_tracking_mitigations();
+    }
+
+    assert_array_equals(result, ['{{hosts[alt][]}}']);
+  }, 'Bounce tracking mitigations deleting state for a bounce tracker');
+</script>
diff --git a/third_party/catapult b/third_party/catapult
index 753e45c..51cd0db 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit 753e45cfb999f676e785e60d6fb01aba62a2d5cf
+Subproject commit 51cd0db6db2f574b40b8261daa7d55e9ffb57df8
diff --git a/third_party/dawn b/third_party/dawn
index 73d7f7e..c440212 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit 73d7f7ee1b320591b78dfbc35ceec83e6baea621
+Subproject commit c440212fcfff6a0e11ef41db0f884a9676a04e37
diff --git a/third_party/depot_tools b/third_party/depot_tools
index 653e86a..8258c13 160000
--- a/third_party/depot_tools
+++ b/third_party/depot_tools
@@ -1 +1 @@
-Subproject commit 653e86a6f020e89e7f9249d40a22b25a8d6ba02a
+Subproject commit 8258c1340ad8681925118da131a2fdfec19ddfbd
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index 7ae8cb3..644a998 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit 7ae8cb30b21435841a28f345b03624cc31029418
+Subproject commit 644a99897c4e4ccfc00f77b5dd2f5a5c2cff5b39
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index a058cb5..b15f4a8 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit a058cb54ecbbb8630ccc3b959b209b20d7ad2fa8
+Subproject commit b15f4a8c0754de1220114b21b33be7ca47374d63
diff --git a/third_party/skia b/third_party/skia
index 7c2ab74..9bea959 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit 7c2ab74e6d1b9c3017114a8d13a200a888fc5b10
+Subproject commit 9bea95918e6982e9d9a3a2ee5a009f8ce8b5d4d2
diff --git a/third_party/wpt_tools/README.chromium b/third_party/wpt_tools/README.chromium
index e1d117b..e2782116 100644
--- a/third_party/wpt_tools/README.chromium
+++ b/third_party/wpt_tools/README.chromium
@@ -1,7 +1,7 @@
 Name: web-platform-tests - Test Suites for Web Platform specifications
 Short Name: wpt
 URL: https://github.com/web-platform-tests/wpt/
-Version: 91ed316e1b0bf1006f10f0603fb713fc9d668f10
+Version: d65cf80018b0d3b15f4454dcc98312e4ef136534
 License: LICENSES FOR W3C TEST SUITES (https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html)
 Security Critical: no
 Shipped: no
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
index 994cdc2..850d9fd 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/executorwebdriver.py
@@ -625,6 +625,8 @@
         self.webdriver.start()
 
     def teardown(self):
+        if not self.webdriver:
+            return
         self.logger.debug("Hanging up on WebDriver session")
         try:
             self.webdriver.end()
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py
index c5b12ee..0d982f85 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testrunner.py
@@ -110,7 +110,6 @@
 
     def teardown(self):
         self.executor.teardown()
-        self.send_message("runner_teardown")
         self.result_queue = None
         self.command_queue = None
         self.browser = None
@@ -140,12 +139,7 @@
     def run(self):
         """Main loop accepting commands over the pipe and triggering
         the associated methods"""
-        try:
-            self.setup()
-        except Exception:
-            self.logger.warning("An error occured during executor setup:\n%s" %
-                                traceback.format_exc())
-            raise
+        self.setup()
         commands = {"run_test": self.run_test,
                     "switch_executor": self.switch_executor,
                     "reset": self.reset,
@@ -531,9 +525,8 @@
             RunnerManagerState.error: {},
             RunnerManagerState.stop: {},
             None: {
-                "runner_teardown": self.runner_teardown,
                 "log": self.log,
-                "error": self.error
+                "error": self.error,
             }
         }
         try:
@@ -553,6 +546,7 @@
                 self.logger.debug("Debugger exited")
                 return RunnerManagerState.stop(False)
 
+            # `test_runner_proc` must be nonnull in the manager's `running` state.
             if (isinstance(self.state, RunnerManagerState.running) and
                 not self.test_runner_proc.is_alive()):
                 if not self.command_queue.empty():
@@ -956,34 +950,33 @@
     def stop_runner(self, force=False):
         """Stop the TestRunner and the browser binary."""
         self.recording.set(["testrunner", "stop_runner"])
-        if self.test_runner_proc is None:
-            return
-
-        if self.test_runner_proc.is_alive():
-            self.send_message("stop")
         try:
-            self.browser.stop(force=force)
-            self.ensure_runner_stopped()
+            # Stop the runner process before the browser process so that the
+            # former can gracefully tear down the protocol (e.g., closing an
+            # active WebDriver session).
+            self._ensure_runner_stopped()
+            # TODO(web-platform-tests/wpt#48030): Consider removing the
+            # `stop(force=...)` argument.
+            self.browser.stop(force=True)
         except (OSError, PermissionError):
-            self.logger.error("Failed to stop the runner")
+            self.logger.error("Failed to stop either the runner or the browser process",
+                              exc_info=True)
         finally:
             self.cleanup()
 
     def teardown(self):
         self.logger.debug("TestRunnerManager teardown")
-        self.test_runner_proc = None
         self.command_queue.close()
         self.remote_queue.close()
         self.command_queue = None
         self.remote_queue = None
         self.recording.pause()
 
-    def ensure_runner_stopped(self):
-        self.logger.debug("ensure_runner_stopped")
+    def _ensure_runner_stopped(self):
         if self.test_runner_proc is None:
             return
-
-        self.browser.stop(force=True)
+        self.logger.debug("Stopping runner process")
+        self.send_message("stop")
         self.test_runner_proc.join(10)
         mp = mpcontext.get_context()
         if self.test_runner_proc.is_alive():
@@ -1007,10 +1000,7 @@
             self.remote_queue = mp.Queue()
         else:
             self.logger.debug("Runner process exited with code %i" % self.test_runner_proc.exitcode)
-
-    def runner_teardown(self):
-        self.ensure_runner_stopped()
-        return RunnerManagerState.stop(False)
+        self.test_runner_proc = None
 
     def send_message(self, command, *args):
         """Send a message to the remote queue (to Executor)."""
@@ -1034,11 +1024,6 @@
             else:
                 if cmd == "log":
                     self.log(*data)
-                elif cmd == "runner_teardown":
-                    # It's OK for the "runner_teardown" message to be left in
-                    # the queue during cleanup, as we will already have tried
-                    # to stop the TestRunner in `stop_runner`.
-                    pass
                 else:
                     self.logger.warning(f"Command left in command_queue during cleanup: {cmd!r}, {data!r}")
         while True:
diff --git a/tools/fuchsia/3pp/test-scripts/3pp/install.sh b/tools/fuchsia/3pp/test-scripts/3pp/install.sh
index c070035..03c3e514 100755
--- a/tools/fuchsia/3pp/test-scripts/3pp/install.sh
+++ b/tools/fuchsia/3pp/test-scripts/3pp/install.sh
@@ -14,6 +14,18 @@
 
 PREFIX="$1"
 
+# The internal image version is only used in chromium, and shouldn't be
+# published altogether with test scripts.
+rm -f linux_internal.sdk.sha1
+
+# Presubmit tests should be executed in chromium.
+rm -f PRESUBMIT.py
+rm -f test/PRESUBMIT.py
+
+# Code coverage and coding style only apply to chromium.
+rm -f test/.coveragerc
+rm -f test/.style.yapf
+
 # Use "--parents" to reserve the relative paths, e.g.
 # common/py_utils -> $PREFIX/common/py_utils
 cp -rf --parents * "$PREFIX"/
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec
index f34d6a1..075d8c10 100644
--- a/tools/gritsettings/resource_ids.spec
+++ b/tools/gritsettings/resource_ids.spec
@@ -759,7 +759,7 @@
     "structures": [5600],
   },
   "<(SHARED_INTERMEDIATE_DIR)/chrome/test/data/webui/resources.grd": {
-    "META": {"sizes": {"includes": [2000],}},
+    "META": {"sizes": {"includes": [2500],}},
     "includes": [5620],
   },
   # END chrome/ miscellaneous section.
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index b4c34909..286c9cd2 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -16053,6 +16053,7 @@
   <int value="-1916060206" label="enable-display-zoom-setting"/>
   <int value="-1915854488" label="enable-offline-pages"/>
   <int value="-1914773324" label="TerminalSftp:disabled"/>
+  <int value="-1914389617" label="EnableWifiQosEnterprise:enabled"/>
   <int value="-1913801713"
       label="UploadCrashReportsUsingJobScheduler:disabled"/>
   <int value="-1913734393" label="CrosPrivacyHub:disabled"/>
@@ -17074,6 +17075,7 @@
   <int value="-1483131886" label="ExperimentalWebAppProfileIsolation:disabled"/>
   <int value="-1482730792" label="stop-in-background:enabled"/>
   <int value="-1482685863" label="enable-request-tablet-site"/>
+  <int value="-1482577709" label="EnableWifiQosEnterprise:disabled"/>
   <int value="-1481990501" label="Windows10CustomTitlebar:disabled"/>
   <int value="-1481918315" label="SmsReceiverCrossDevice:enabled"/>
   <int value="-1481777496" label="DragAndDropAndroid:disabled"/>
diff --git a/tools/metrics/histograms/metadata/compose/histograms.xml b/tools/metrics/histograms/metadata/compose/histograms.xml
index 0a6594d7..686fa18 100644
--- a/tools/metrics/histograms/metadata/compose/histograms.xml
+++ b/tools/metrics/histograms/metadata/compose/histograms.xml
@@ -352,10 +352,11 @@
   </summary>
   <token key="PageLanguageStatus">
     <variant name="PageLanguageSupported"
-        summary="page whose language is supported by Compose"/>
+        summary="page whose client-assessed language is expected to be
+                 supported by Compose"/>
     <variant name="PageLanguageUnsupported"
-        summary="page whose language is not supported by Compose (but usage
-                 was still allowed)."/>
+        summary="page whose client-assessed language is expected to be not
+                 supported by Compose (but usage was still allowed)."/>
   </token>
   <token key="ComposeEvalLocation" variants="ComposeEvalLocation"/>
 </histogram>
diff --git a/tools/metrics/histograms/metadata/extensions/enums.xml b/tools/metrics/histograms/metadata/extensions/enums.xml
index a2f8248..f26ee5fb 100644
--- a/tools/metrics/histograms/metadata/extensions/enums.xml
+++ b/tools/metrics/histograms/metadata/extensions/enums.xml
@@ -2461,8 +2461,8 @@
   <int value="1616" label="FILEMANAGERPRIVATE_GETFRAMECOLOR"/>
   <int value="1617" label="DEVELOPERPRIVATE_ADDUSERSPECIFIEDSITES"/>
   <int value="1618" label="DEVELOPERPRIVATE_REMOVEUSERSPECIFIEDSITES"/>
-  <int value="1619" label="AUTOTESTPRIVATE_STARTARC"/>
-  <int value="1620" label="AUTOTESTPRIVATE_STOPARC"/>
+  <int value="1619" label="DELETED_AUTOTESTPRIVATE_STARTARC"/>
+  <int value="1620" label="DELETED_AUTOTESTPRIVATE_STOPARC"/>
   <int value="1621" label="PASSWORDSPRIVATE_MUTEINSECURECREDENTIAL"/>
   <int value="1622" label="WEB_AUTHENTICATION_PROXY_COMPLETE_GET_REQUEST"/>
   <int value="1623" label="PASSWORDSPRIVATE_UNMUTEINSECURECREDENTIAL"/>
diff --git a/tools/metrics/histograms/metadata/navigation/enums.xml b/tools/metrics/histograms/metadata/navigation/enums.xml
index 657092b..456fd5db 100644
--- a/tools/metrics/histograms/metadata/navigation/enums.xml
+++ b/tools/metrics/histograms/metadata/navigation/enums.xml
@@ -262,6 +262,16 @@
   <int value="1" label="Commit"/>
 </enum>
 
+<!-- LINT.IfChange(HistoryNavigationDirection) -->
+
+<enum name="HistoryNavigationDirection">
+  <int value="0" label="Back"/>
+  <int value="1" label="Forward"/>
+  <int value="2" label="Same entry (e.g. session restore)"/>
+</enum>
+
+<!-- LINT.ThenChange(//content/browser/renderer_host/back_forward_cache_metrics.h:HistoryNavigationDirection) -->
+
 <enum name="HistoryNavType">
   <int value="0" label="kMainFrame"/>
   <int value="1" label="kMainFrameAndSubframe"/>
diff --git a/tools/metrics/histograms/metadata/navigation/histograms.xml b/tools/metrics/histograms/metadata/navigation/histograms.xml
index ac86c0c..85b06fc 100644
--- a/tools/metrics/histograms/metadata/navigation/histograms.xml
+++ b/tools/metrics/histograms/metadata/navigation/histograms.xml
@@ -404,6 +404,22 @@
   </summary>
 </histogram>
 
+<histogram name="BackForwardCache.NonRestoredNavigationDirection"
+    enum="HistoryNavigationDirection" expires_after="2025-03-01">
+  <owner>rakina@chromium.org</owner>
+  <owner>bfcache-dev@chromium.org</owner>
+  <summary>
+    When navigating back to a page in the session history that does not restore
+    a page from the back/forward cache, this records the history navigation
+    direction (back/forward/same entry).
+
+    This is recorded when committing a navigation where the back/forward cache
+    is enabled for this navigation (back/forward cache feature is enabled and
+    the domain is in the scope of the experiment) but the navigation does not
+    restore a page from back/forward cache.
+  </summary>
+</histogram>
+
 <histogram name="BackForwardCache.PageWithForm.RestoreResult"
     enum="BackForwardCacheHistoryNavigationOutcome" expires_after="2025-02-10">
   <owner>wenyufu@chromium.org</owner>
@@ -466,6 +482,22 @@
   </summary>
 </histogram>
 
+<histogram name="BackForwardCache.RestoredNavigationDirection"
+    enum="HistoryNavigationDirection" expires_after="2025-03-01">
+  <owner>rakina@chromium.org</owner>
+  <owner>bfcache-dev@chromium.org</owner>
+  <summary>
+    When navigating back to a page in the session history that restores a page
+    from the back/forward cache, this records the history navigation direction
+    (back/forward/same entry).
+
+    This is recorded when committing a navigation where the back/forward cache
+    is enabled for this navigation (back/forward cache feature is enabled and
+    the domain is in the scope of the experiment) and the navigation restores a
+    page from back/forward cache.
+  </summary>
+</histogram>
+
 <histogram
     name="BackForwardCache.UnexpectedRendererToBrowserMessage.InterfaceName"
     enum="MojoInterfaceName" expires_after="2025-02-10">
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml
index e7a7da0..1c5e563 100644
--- a/tools/metrics/histograms/metadata/others/histograms.xml
+++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -6153,7 +6153,7 @@
 </histogram>
 
 <histogram base="true" name="Mouse.ScrollSensitivity" enum="PointerSensitivity"
-    expires_after="2024-09-01">
+    expires_after="2025-09-01">
 <!-- Name completed by histogram_suffixes name="PreferenceChangeType" -->
 
   <owner>zhangwenyu@google.com</owner>
@@ -9420,7 +9420,7 @@
 </histogram>
 
 <histogram name="Touchpad.HapticFeedback.Changed" enum="BooleanEnabled"
-    expires_after="2024-09-01">
+    expires_after="2025-09-01">
   <owner>gavinwill@chromium.org</owner>
   <owner>cros-peripherals@chromium.org</owner>
   <summary>
@@ -9430,7 +9430,7 @@
 </histogram>
 
 <histogram name="Touchpad.HapticFeedback.Started" enum="BooleanEnabled"
-    expires_after="2024-09-01">
+    expires_after="2025-09-01">
   <owner>gavinwill@chromium.org</owner>
   <owner>cros-peripherals@chromium.org</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml
index c6f5bfa..5b54453 100644
--- a/tools/metrics/histograms/metadata/page/histograms.xml
+++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -336,6 +336,7 @@
     <variant name="BookmarksStar"/>
     <variant name="ClickToCall"/>
     <variant name="CookieControls"/>
+    <variant name="Discounts"/>
     <variant name="FileSystemAccess"/>
     <variant name="Find"/>
     <variant name="IntentPicker"/>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
index b069d902..f35ece4 100644
--- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
+++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -2704,10 +2704,22 @@
   <owner>pkotwicz@chromium.org</owner>
   <owner>chrome-counter-abuse-core@google.com</owner>
   <summary>
-    Logged after each page navigation. Logs the matching user-familiarity
-    heuristics for the site. If the site satisifies multiple heuristics the
-    metric will be logged multiple times. NO_HEURISTIC_MATCH is logged if no
-    user-familiarity heuristics match for the site.
+    Logged after each non-incognito page navigation. Logs the matching
+    user-familiarity heuristics for the site. If the site satisifies multiple
+    heuristics the metric will be logged multiple times. NO_HEURISTIC_MATCH is
+    logged if no user-familiarity heuristics match for the site.
+  </summary>
+</histogram>
+
+<histogram name="SafeBrowsing.SiteProtection.FamiliarityHeuristic.OffTheRecord"
+    enum="SiteFamiliarityHeuristicName" expires_after="2025-01-05">
+  <owner>pkotwicz@chromium.org</owner>
+  <owner>chrome-counter-abuse-core@google.com</owner>
+  <summary>
+    Logged after each off-the-record page navigation. Logs the matching
+    user-familiarity heuristics for the site. If the site satisifies multiple
+    heuristics the metric will be logged multiple times. NO_HEURISTIC_MATCH is
+    logged if no user-familiarity heuristics match for the site.
   </summary>
 </histogram>
 
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index ba09fef..199347f 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@
             "full_remote_path": "perfetto-luci-artifacts/baf3dcdc408c406ec523e3fde052e2672a3c37d2/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "2a3e07f6278fd5d874171dcd84968f193ae65fc6",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/180231fef057dc2e575e58bdf13be8fd88ecad6e/trace_processor_shell.exe"
+            "hash": "e19231631901165200a0413711e003fc90b50219",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/bea7f2f92cb9ecf6923ecea52120c312840494a0/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "53f993fc3201982cd949c5b8de884682bb56de83",
@@ -22,7 +22,7 @@
         },
         "linux": {
             "hash": "e55fb237f68c9dff2fcaca25a9ca96d4ce6528a4",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/180231fef057dc2e575e58bdf13be8fd88ecad6e/trace_processor_shell"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/bea7f2f92cb9ecf6923ecea52120c312840494a0/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/android/java/res/values/color_palette.xml b/ui/android/java/res/values/color_palette.xml
index 6554ec02..b65d1df 100644
--- a/ui/android/java/res/values/color_palette.xml
+++ b/ui/android/java/res/values/color_palette.xml
@@ -16,6 +16,7 @@
     <color name="baseline_primary_80_alpha_20">#33A8C7FA</color>
     <color name="baseline_primary_80_alpha_50">#80A8C7FA</color>
     <color name="baseline_primary_60">#4C8DF6</color>
+    <color name="baseline_primary_50">#1B6EF3</color>
     <color name="baseline_primary_40">#0B57D0</color>
     <color name="baseline_primary_40_alpha_6">#0F0B57D0</color>
     <color name="baseline_primary_40_alpha_10">#190B57D0</color>
@@ -143,6 +144,7 @@
     <color name="material_primary_90">@color/baseline_primary_90</color>
     <color name="material_primary_80">@color/baseline_primary_80</color>
     <color name="material_primary_60">@color/baseline_primary_60</color>
+    <color name="material_primary_50">@color/baseline_primary_50</color>
     <color name="material_primary_40">@color/baseline_primary_40</color>
     <color name="material_primary_20">@color/baseline_primary_20</color>
     <color name="material_primary_10">@color/baseline_primary_10</color>
diff --git a/v8 b/v8
index 9927247..00eda72 160000
--- a/v8
+++ b/v8
@@ -1 +1 @@
-Subproject commit 9927247d821b1fefa9d225acee0d67f2cbdbfd0f
+Subproject commit 00eda7279f265f2a645ef0256059b583209075af