diff --git a/DEPS b/DEPS
index 915281db0..77f7958c 100644
--- a/DEPS
+++ b/DEPS
@@ -276,11 +276,11 @@
   # 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': '988e04e61c5fc061c4443c7b9a0c3ffa8e3bb0d8',
+  'src_internal_revision': '7b0552739dbba05794c3ffa8f35aa0eccc8400f4',
   # 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': 'b2f3e3f6263ad231a042a2632bd98bfd26ab8ed7',
+  'skia_revision': 'e56496eb35a3e20114d1a0052348e43b363f3cd4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -288,7 +288,7 @@
   # 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': 'ae97e569de2cc1e8cb9414b6900ab1886c273c90',
+  'angle_revision': 'db8e5617bafaa8374b0cd2465de3fce54622f00e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -348,11 +348,11 @@
   # 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': 'abd0e1e8ccd7f38681b8c9503bbf4c14220c86f3',
+  'catapult_revision': '6349b2a0fe82a0f7b941c066fa4e0de03b5fccfa',
   # 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.
-  'chromium_variations_revision': '75345f6fdba14f81b63ccf0530c6fb5adfc9a103',
+  'chromium_variations_revision': '5474b284a49865e22821f85678c54f8ed0a20f24',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # 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 devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': 'de2be85f2be617e9893f0a947b0ccee1ce0b5e84',
+  'devtools_frontend_revision': '435b93d9d72ecd3e120010bdcb955aab030afb75',
   # 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.
@@ -496,7 +496,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling llvm-libc
   # and whatever else without interference from each other.
-  'llvm_libc_revision':    '8345f5d50fb880cc14f06116b5eda267ec222b83',
+  'llvm_libc_revision':    '3605d6cf39c46e69796ae71e4555ed997a31ff3f',
 
   # If you change this, also update the libc++ revision in
   # //buildtools/deps_revisions.gni.
@@ -1304,12 +1304,12 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '773685ed2b08bc452886504e9d8efbfb8d7349be',
+    '39154b6f5dc2836f6dac6e46c711d1c737beb3fd',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
   'src/docs/website': {
-    'url': Var('chromium_git') + '/website.git' + '@' + '31a2f432dc14e60054e2a361f4fa16ffff65e01b',
+    'url': Var('chromium_git') + '/website.git' + '@' + '24d837acc5671ab1bffac9b8a49de5847c0025a6',
   },
 
   'src/ios/third_party/earl_grey2/src': {
@@ -1463,7 +1463,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'X8VGzIbXIia42rI-y1pFq5mocj0qeoQ4kg-qA2bzQuIC',
+          'version': 'Tbd2jzkigki1yjkveky90Wa1TceQZfJlwasTJ1ObNY8C',
       },
     ],
     'condition': 'checkout_android and non_git_source',
@@ -2301,7 +2301,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '5bf4e2a65d76d5a603ff175222d1513f71d28a0b',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '2f24aafc7f8c3f4ca349224bbadab9f54a3e3559',
 
   'src/base/tracing/test/data': {
     'bucket': 'perfetto',
@@ -2497,7 +2497,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/r8',
-              'version': 'o7pbwAFk68RQBPYLlCUm0mQ6B3Bj9pykXOPvv8akR5kC',
+              'version': 'q_wvk54XItTBlBNQMHkS4NRMp-tapPW97M292KTXHrsC',
           },
       ],
       'condition': 'checkout_android and non_git_source',
@@ -2663,13 +2663,13 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '450cceb587613ac1469c5a131fac15935c99e0e7',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '975839c060fb6cc79bb89e7e5b971c1c8deb8000',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '40d0e32190eb3bcc9c71b408d7b67302477c05ad',
 
   'src/third_party/webpagereplay':
     Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'),
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '588dbe6fa77914ac09af6bf5c010923fea37a10b',
+    Var('webrtc_git') + '/src.git' + '@' + 'b766572d2b4aaa82b644a12a9413794da5e02e56',
 
   # Wuffs' canonical repository is at github.com/google/wuffs, but we use
   # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file.
@@ -4431,7 +4431,7 @@
 
   'src/components/optimization_guide/internal': {
       'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' +
-        'e70be79b11bd34dc7e788c4debc9329eb2edc4cd',
+        'f922d0d5ccb76da8ca58e7feeac432cd43b0d214',
       'condition': 'checkout_src_internal',
   },
 
@@ -4497,7 +4497,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '178cb6bc81569dcbfdcdb991ea73a8c35944a104',
+        'ea8b061b465214cc89a4d539ac35c26f01670698',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc
index 59fbb8f3..a5b9bc2 100644
--- a/ash/constants/ash_switches.cc
+++ b/ash/constants/ash_switches.cc
@@ -782,9 +782,6 @@
 // path should be to a directory that contains a binary named 'chrome'.
 const char kLacrosChromePath[] = "lacros-chrome-path";
 
-// When this flag is set, the lacros-selection policy is ignored.
-const char kLacrosSelectionPolicyIgnore[] = "lacros-selection-policy-ignore";
-
 // If set, it passes the ids of additional extensions allowed to run in
 // both ash and lacros when lacros is enabled. The ids are separated by ",".
 // This should only used for testing.
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h
index 788d56d..2460071 100644
--- a/ash/constants/ash_switches.h
+++ b/ash/constants/ash_switches.h
@@ -253,8 +253,6 @@
 extern const char kKioskSplashScreenMinTimeSeconds[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kLacrosChromePath[];
 COMPONENT_EXPORT(ASH_CONSTANTS)
-extern const char kLacrosSelectionPolicyIgnore[];
-COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const char kExtensionsRunInBothAshAndLacros[];
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const char kExtensionAppsRunInBothAshAndLacros[];
diff --git a/ash/lobster/lobster_controller.cc b/ash/lobster/lobster_controller.cc
index bf02e1e..a2e2b90 100644
--- a/ash/lobster/lobster_controller.cc
+++ b/ash/lobster/lobster_controller.cc
@@ -19,12 +19,10 @@
 
 namespace ash {
 
-LobsterController::Trigger::Trigger(LobsterController* controller,
-                                    std::unique_ptr<LobsterClient> client,
+LobsterController::Trigger::Trigger(std::unique_ptr<LobsterClient> client,
                                     LobsterEntryPoint entry_point,
                                     LobsterMode mode)
-    : controller_(controller),
-      client_(std::move(client)),
+    : client_(std::move(client)),
       state_(State::kReady),
       entry_point_(entry_point),
       mode_(mode) {}
@@ -37,8 +35,19 @@
   }
 
   state_ = State::kDisabled;
-  controller_->StartSession(std::move(client_), std::move(query), entry_point_,
-                            mode_);
+
+  if (ash::Shell::Get() == nullptr) {
+    return;
+  }
+
+  LobsterController* controller = ash::Shell::Get()->lobster_controller();
+
+  if (controller == nullptr) {
+    return;
+  }
+
+  controller->StartSession(std::move(client_), std::move(query), entry_point_,
+                           mode_);
 }
 
 LobsterController::LobsterController() = default;
@@ -56,13 +65,13 @@
     return nullptr;
   }
   std::unique_ptr<LobsterClient> client = client_factory_->CreateClient();
-  if (client == nullptr || !client->UserHasAccess()) {
+  if (client == nullptr) {
     return nullptr;
   }
 
   LobsterSystemState system_state = client->GetSystemState();
   return system_state.status != LobsterStatus::kBlocked
-             ? std::make_unique<Trigger>(this, std::move(client), entry_point,
+             ? std::make_unique<Trigger>(std::move(client), entry_point,
                                          support_image_insertion
                                              ? LobsterMode::kInsert
                                              : LobsterMode::kDownload)
@@ -73,9 +82,6 @@
                                      std::optional<std::string> query,
                                      LobsterEntryPoint entry_point,
                                      LobsterMode mode) {
-  if (!client->UserHasAccess()) {
-    return;
-  }
   // Before creating a new session, we need to inform the lobster client and
   // lobster session to clear their pointer to the session that is about to be
   // destroyed. This is to prevent them from holding a dangling pointer to the
diff --git a/ash/lobster/lobster_controller.h b/ash/lobster/lobster_controller.h
index 16901a6..e8dae62 100644
--- a/ash/lobster/lobster_controller.h
+++ b/ash/lobster/lobster_controller.h
@@ -12,6 +12,7 @@
 #include "ash/ash_export.h"
 #include "ash/lobster/lobster_entry_point_enums.h"
 #include "ash/public/cpp/lobster/lobster_enums.h"
+#include "ash/shell.h"
 #include "base/memory/raw_ptr.h"
 
 namespace ash {
@@ -24,8 +25,7 @@
  public:
   class Trigger {
    public:
-    explicit Trigger(LobsterController* controller,
-                     std::unique_ptr<LobsterClient> client,
+    explicit Trigger(std::unique_ptr<LobsterClient> client,
                      LobsterEntryPoint entry_point,
                      LobsterMode mode);
     ~Trigger();
@@ -38,9 +38,6 @@
       kDisabled,
     };
 
-    // Not owned by this class
-    raw_ptr<LobsterController> controller_;
-
     // The client to use for the session created with this trigger.
     std::unique_ptr<LobsterClient> client_;
 
diff --git a/ash/lobster/lobster_session_impl_unittest.cc b/ash/lobster/lobster_session_impl_unittest.cc
index 0216344..a0d978c 100644
--- a/ash/lobster/lobster_session_impl_unittest.cc
+++ b/ash/lobster/lobster_session_impl_unittest.cc
@@ -81,7 +81,6 @@
               (override));
   MOCK_METHOD(void, ShowUI, (), (override));
   MOCK_METHOD(void, CloseUI, (), (override));
-  MOCK_METHOD(bool, UserHasAccess, (), (override));
 };
 
 class LobsterSessionImplTest : public AshTestBase {
diff --git a/ash/public/cpp/ash_web_view.h b/ash/public/cpp/ash_web_view.h
index 0a80bd6..39043a64 100644
--- a/ash/public/cpp/ash_web_view.h
+++ b/ash/public/cpp/ash_web_view.h
@@ -12,8 +12,8 @@
 #include "ui/base/metadata/metadata_header_macros.h"
 #include "ui/gfx/geometry/rounded_corners_f.h"
 #include "ui/views/view.h"
+#include "url/gurl.h"
 
-class GURL;
 enum class WindowOpenDisposition;
 
 namespace ash {
@@ -74,6 +74,10 @@
     // Used to override the Media Controls source title. Empty strings will
     // trigger default parent behavior.
     std::string source_title;
+
+    // URL to open when AshWebView contents are activated but the widget is not
+    // activatable. Empty GURLs will trigger default parent behavior.
+    GURL activation_url;
   };
 
   // An observer which receives AshWebView events.
diff --git a/ash/public/cpp/lobster/lobster_client.h b/ash/public/cpp/lobster/lobster_client.h
index 5d214a4..dbe568a6 100644
--- a/ash/public/cpp/lobster/lobster_client.h
+++ b/ash/public/cpp/lobster/lobster_client.h
@@ -38,7 +38,6 @@
   virtual void LoadUI(std::optional<std::string> query, LobsterMode mode) = 0;
   virtual void ShowUI() = 0;
   virtual void CloseUI() = 0;
-  virtual bool UserHasAccess() = 0;
 };
 
 }  // namespace ash
diff --git a/ash/quick_insert/views/quick_insert_strings.cc b/ash/quick_insert/views/quick_insert_strings.cc
index fc28863..5253f4c 100644
--- a/ash/quick_insert/views/quick_insert_strings.cc
+++ b/ash/quick_insert/views/quick_insert_strings.cc
@@ -27,20 +27,20 @@
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
       return l10n_util::GetStringUTF16(IDS_EDITOR_MENU_WRITE_CARD_TITLE);
 #else
-      return u"";
+      return u"Editor";
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
     case QuickInsertCategory::kEditorRewrite:
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
       return l10n_util::GetStringUTF16(IDS_EDITOR_MENU_REWRITE_CARD_TITLE);
 #else
-      return u"";
+      return u"Editor";
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
     case QuickInsertCategory::kLobsterWithNoSelectedText:
     case QuickInsertCategory::kLobsterWithSelectedText:
 #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
       return l10n_util::GetStringUTF16(IDS_PICKER_LOBSTER_SELECTION_LABEL);
 #else
-      return u"";
+      return u"Lobster";
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
     case QuickInsertCategory::kLinks:
       return l10n_util::GetStringUTF16(IDS_PICKER_LINKS_CATEGORY_LABEL);
diff --git a/ash/quick_insert/views/quick_insert_zero_state_view_unittest.cc b/ash/quick_insert/views/quick_insert_zero_state_view_unittest.cc
index 57ef6df3..4b13231 100644
--- a/ash/quick_insert/views/quick_insert_zero_state_view_unittest.cc
+++ b/ash/quick_insert/views/quick_insert_zero_state_view_unittest.cc
@@ -535,7 +535,7 @@
                            l10n_util::GetStringUTF16(
                                IDS_PICKER_LOBSTER_SELECTION_LABEL)
 #else
-                           u""
+                           u"Lobster"
 #endif  // BUILDFLAG(GOOGLE_CHROME_BRANDING)
                                )))))))));
 }
diff --git a/ash/system/focus_mode/focus_mode_controller.cc b/ash/system/focus_mode/focus_mode_controller.cc
index f4feec7..09dc887 100644
--- a/ash/system/focus_mode/focus_mode_controller.cc
+++ b/ash/system/focus_mode/focus_mode_controller.cc
@@ -30,8 +30,10 @@
 #include "ash/system/status_area_widget.h"
 #include "ash/system/toast/anchored_nudge_manager_impl.h"
 #include "ash/system/unified/unified_system_tray.h"
+#include "base/check_op.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/rand_util.h"
+#include "base/strings/strcat.h"
 #include "base/time/time.h"
 #include "chromeos/ash/components/audio/sounds.h"
 #include "chromeos/ash/components/audio/system_sounds_delegate.h"
@@ -55,6 +57,12 @@
 
 constexpr base::TimeDelta kEndingMomentBounceAnimationDelay = base::Minutes(1);
 
+// YouTube Music API playlist name prefix.
+constexpr std::string_view kPlaylistIdPrefix = "playlists/";
+constexpr std::string_view kBasePlaylistUrl =
+    "https://music.youtube.com/playlist?list=";
+constexpr std::string_view kYouTubeMusicUrl = "https://music.youtube.com/";
+
 bool IsQuietModeOnSetByFocusMode() {
   auto* message_center = message_center::MessageCenter::Get();
   return message_center->IsQuietMode() &&
@@ -143,6 +151,25 @@
   std::move(callback).Run(task);
 }
 
+// Returns the direct URL to view info for the associated YouTube Music
+// `playlist`.
+GURL GetYouTubeMusicPlaylistUrl(focus_mode_util::SelectedPlaylist playlist) {
+  CHECK_EQ(playlist.type, focus_mode_util::SoundType::kYouTubeMusic);
+
+  if (playlist.id.starts_with(kPlaylistIdPrefix)) {
+    // Strip the prefix from `playlist.id` to get the actual playlist id and
+    // construct the URL.
+    return GURL(base::StrCat(
+        {kBasePlaylistUrl, playlist.id.substr(kPlaylistIdPrefix.length())}));
+  }
+
+  // The expected api playlist name should have the prefix "playlists/". Check
+  // the playlists api documentation:
+  // https://developers.google.com/youtube/mediaconnect/reference/rest/v1/playlists#Playlist"
+  LOG(WARNING) << "YTM playlist name format is invalid";
+  return GURL(kYouTubeMusicUrl);
+}
+
 }  // namespace
 
 FocusModeController::FocusModeController(
@@ -877,6 +904,14 @@
   web_view_params.source_title =
       focus_mode_util::GetSourceTitleForMediaControls(
           focus_mode_sounds_controller_->selected_playlist());
+  // Provide the playlist source URL to show for when users click on the media
+  // controls view.
+  if (focus_mode_sounds_controller_->selected_playlist().type ==
+      focus_mode_util::SoundType::kYouTubeMusic) {
+    web_view_params.activation_url = GetYouTubeMusicPlaylistUrl(
+        focus_mode_sounds_controller_->selected_playlist());
+  }
+
   focus_mode_media_view_ = media_widget_->SetContentsView(
       AshWebViewFactory::Get()->Create(web_view_params));
   focus_mode_media_view_->Navigate(GURL(chrome::kChromeUIFocusModeMediaURL));
diff --git a/ash/system/focus_mode/focus_mode_ending_moment_view.cc b/ash/system/focus_mode/focus_mode_ending_moment_view.cc
index bd68109c..f85d2f3e 100644
--- a/ash/system/focus_mode/focus_mode_ending_moment_view.cc
+++ b/ash/system/focus_mode/focus_mode_ending_moment_view.cc
@@ -129,7 +129,8 @@
   auto* spacer_view = AddChildView(std::make_unique<views::View>());
   spacer_view->SetProperty(
       views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
+      views::FlexSpecification(views::LayoutOrientation::kHorizontal,
+                               views::MinimumFlexSizeRule::kScaleToZero,
                                views::MaximumFlexSizeRule::kUnbounded));
 
   // Add the vertical box layout for the button container that holds the "Done"
diff --git a/ash/system/focus_mode/focus_mode_util.cc b/ash/system/focus_mode/focus_mode_util.cc
index 9c049dc..cf83ba1 100644
--- a/ash/system/focus_mode/focus_mode_util.cc
+++ b/ash/system/focus_mode/focus_mode_util.cc
@@ -46,6 +46,8 @@
                        u"☑"),
 };
 
+constexpr const char* kYouTubeMusicUrl = "music.youtube.com";
+
 }  // namespace
 
 SelectedPlaylist::SelectedPlaylist() = default;
@@ -143,10 +145,10 @@
     return "";
   }
 
-  return l10n_util::GetStringUTF8(
-      playlist.type == SoundType::kYouTubeMusic
-          ? IDS_ASH_STATUS_TRAY_FOCUS_MODE_SOUNDS_YOUTUBE_MUSIC_BUTTON
-          : IDS_ASH_STATUS_TRAY_FOCUS_MODE_SOUNDS_SOUNDSCAPE_BUTTON);
+  return playlist.type == SoundType::kYouTubeMusic
+             ? kYouTubeMusicUrl
+             : l10n_util::GetStringUTF8(
+                   IDS_ASH_STATUS_TRAY_FOCUS_MODE_SOUNDS_SOUNDSCAPE_BUTTON);
 }
 
 std::u16string GetCongratulatoryText(const size_t index) {
diff --git a/ash/system/focus_mode/focus_mode_util_unittest.cc b/ash/system/focus_mode/focus_mode_util_unittest.cc
index b58bd8e..5ee7c29 100644
--- a/ash/system/focus_mode/focus_mode_util_unittest.cc
+++ b/ash/system/focus_mode/focus_mode_util_unittest.cc
@@ -22,7 +22,8 @@
   SelectedPlaylist selected_playlist;
   selected_playlist.id = "id0";
   selected_playlist.type = SoundType::kYouTubeMusic;
-  EXPECT_EQ(GetSourceTitleForMediaControls(selected_playlist), "YouTube Music");
+  EXPECT_EQ(GetSourceTitleForMediaControls(selected_playlist),
+            "music.youtube.com");
 }
 
 // Verify the Soundscape source string.
diff --git a/ash/system/focus_mode/sounds/sound_section_view.cc b/ash/system/focus_mode/sounds/sound_section_view.cc
index d7f05ec..59c8bbd 100644
--- a/ash/system/focus_mode/sounds/sound_section_view.cc
+++ b/ash/system/focus_mode/sounds/sound_section_view.cc
@@ -29,8 +29,10 @@
   auto spacer_view = std::make_unique<views::View>();
   spacer_view->SetProperty(
       views::kFlexBehaviorKey,
-      views::FlexSpecification(views::MinimumFlexSizeRule::kScaleToZero,
-                               views::MaximumFlexSizeRule::kUnbounded));
+      views::FlexSpecification(views::LayoutOrientation::kHorizontal,
+                               views::MinimumFlexSizeRule::kScaleToZero,
+                               views::MaximumFlexSizeRule::kUnbounded)
+          .WithWeight(1));
   return spacer_view;
 }
 
@@ -130,13 +132,7 @@
     // Before appending a new `PlaylistView`, we add a spacer view to make the
     // spacing between each of the `PlaylistView` equal.
     if (i > 0) {
-      auto* spacer_view =
-          playlist_views_container_->AddChildView(CreateSpacerView());
-      spacer_view->SetProperty(
-          views::kFlexBehaviorKey,
-          views::FlexSpecification(views::MinimumFlexSizeRule::kPreferred,
-                                   views::MaximumFlexSizeRule::kUnbounded)
-              .WithWeight(1));
+      playlist_views_container_->AddChildView(CreateSpacerView());
     }
 
     // `FocusModeSoundsController` is owned by `FocusModeController` which
diff --git a/base/android/java/src/org/chromium/base/BuildInfo.java b/base/android/java/src/org/chromium/base/BuildInfo.java
index f7dfe034..92b8a6c 100644
--- a/base/android/java/src/org/chromium/base/BuildInfo.java
+++ b/base/android/java/src/org/chromium/base/BuildInfo.java
@@ -46,8 +46,8 @@
     private static final int MAX_FINGERPRINT_LENGTH = 128;
 
     private static @Nullable PackageInfo sBrowserPackageInfo;
-    private static @Nullable ApplicationInfo sBrowserApplicationInfo;
     private static boolean sInitialized;
+    private ApplicationInfo mBrowserApplicationInfo;
 
     /**
      * The package name of the host app which has loaded WebView, retrieved from the application
@@ -230,8 +230,8 @@
     /**
      * @return ApplicationInfo for Chrome/WebView (as opposed to host app).
      */
-    public @Nullable ApplicationInfo getBrowserApplicationInfo() {
-        return sBrowserApplicationInfo;
+    public ApplicationInfo getBrowserApplicationInfo() {
+        return mBrowserApplicationInfo;
     }
 
     public static BuildInfo getInstance() {
@@ -298,7 +298,7 @@
             versionName = providedPackageVersionName;
             packageName = providedPackageName;
 
-            sBrowserApplicationInfo = appContext.getApplicationInfo();
+            mBrowserApplicationInfo = appContext.getApplicationInfo();
         } else {
             // The SDK Qualified package name will retrieve the same information as
             // appInstalledPackageName but prefix it with the SDK Sandbox process so that we can
@@ -333,12 +333,12 @@
             if (sBrowserPackageInfo != null) {
                 packageName = sBrowserPackageInfo.packageName;
                 versionName = nullToEmpty(sBrowserPackageInfo.versionName);
-                sBrowserApplicationInfo = sBrowserPackageInfo.applicationInfo;
+                mBrowserApplicationInfo = sBrowserPackageInfo.applicationInfo;
                 sBrowserPackageInfo = null;
             } else {
                 packageName = appContextPackageName;
                 versionName = nullToEmpty(pi.versionName);
-                sBrowserApplicationInfo = appContext.getApplicationInfo();
+                mBrowserApplicationInfo = appContext.getApplicationInfo();
             }
         }
 
diff --git a/base/android/java/src/org/chromium/base/process_launcher/BindService.java b/base/android/java/src/org/chromium/base/process_launcher/BindService.java
index d5ff40b..c002b23d 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/BindService.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/BindService.java
@@ -17,13 +17,16 @@
 import androidx.annotation.RequiresApi;
 
 import org.chromium.build.BuildConfig;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.lang.reflect.Method;
 import java.util.concurrent.Executor;
 
 /** Class of static helper methods to call Context.bindService variants. */
+@NullMarked
 final class BindService {
-    private static Method sBindServiceAsUserMethod;
+    private static @Nullable Method sBindServiceAsUserMethod;
 
     static boolean supportVariableConnections() {
         return Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q
@@ -39,7 +42,7 @@
             int flags,
             Handler handler,
             Executor executor,
-            String instanceName) {
+            @Nullable String instanceName) {
         if (supportVariableConnections() && instanceName != null) {
             return context.bindIsolatedService(intent, flags, instanceName, executor, connection);
         }
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java b/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java
index 6dfab33..b6089206 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java
@@ -24,6 +24,8 @@
 import org.chromium.base.PackageUtils;
 import org.chromium.base.ResettersForTesting;
 import org.chromium.base.SysUtils;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.util.ArrayDeque;
 import java.util.ArrayList;
@@ -31,10 +33,10 @@
 import java.util.Queue;
 
 /**
- * This class is responsible for allocating and managing connections to child
- * process services. These connections are in a pool (the services are defined
- * in the AndroidManifest.xml).
+ * This class is responsible for allocating and managing connections to child process services.
+ * These connections are in a pool (the services are defined in the AndroidManifest.xml).
  */
+@NullMarked
 public abstract class ChildConnectionAllocator {
     private static final String TAG = "ChildConnAllocator";
     private static final String ZYGOTE_SUFFIX = "0";
@@ -46,11 +48,11 @@
         ChildProcessConnection createConnection(
                 Context context,
                 ComponentName serviceName,
-                ComponentName fallbackServiceName,
+                @Nullable ComponentName fallbackServiceName,
                 boolean bindToCaller,
                 boolean bindAsExternalService,
                 Bundle serviceBundle,
-                String instanceName);
+                @Nullable String instanceName);
     }
 
     /** Default implementation of the ConnectionFactory that creates actual connections. */
@@ -59,11 +61,11 @@
         public ChildProcessConnection createConnection(
                 Context context,
                 ComponentName serviceName,
-                ComponentName fallbackServiceName,
+                @Nullable ComponentName fallbackServiceName,
                 boolean bindToCaller,
                 boolean bindAsExternalService,
                 Bundle serviceBundle,
-                String instanceName) {
+                @Nullable String instanceName) {
             return new ChildProcessConnection(
                     context,
                     serviceName,
@@ -94,7 +96,7 @@
 
     /* package */ final String mPackageName;
     /* package */ final String mServiceClassName;
-    /* package */ final String mFallbackServiceClassName;
+    /* package */ final @Nullable String mFallbackServiceClassName;
     /* package */ final boolean mBindToCaller;
     /* package */ final boolean mBindAsExternalService;
     /* package */ final boolean mUseStrongBinding;
@@ -286,7 +288,7 @@
             Runnable freeSlotCallback,
             String packageName,
             String serviceClassName,
-            String fallbackServiceClassName,
+            @Nullable String fallbackServiceClassName,
             boolean bindToCaller,
             boolean bindAsExternalService,
             boolean useStrongBinding) {
@@ -304,7 +306,7 @@
     /**
      * @return a bound connection, or null if there are no free slots.
      */
-    public ChildProcessConnection allocate(
+    public @Nullable ChildProcessConnection allocate(
             Context context,
             Bundle serviceBundle,
             final ChildProcessConnection.ServiceCallback serviceCallback) {
@@ -420,7 +422,7 @@
         return mLauncherHandler.getLooper() == Looper.myLooper();
     }
 
-    /* package */ abstract ChildProcessConnection doAllocate(
+    /* package */ abstract @Nullable ChildProcessConnection doAllocate(
             Context context,
             Bundle serviceBundle,
             ChildProcessConnection.ServiceCallback serviceCallback);
@@ -431,7 +433,7 @@
     @VisibleForTesting
     public static class FixedSizeAllocatorImpl extends ChildConnectionAllocator {
         // Connections to services. Indices of the array correspond to the service numbers.
-        private final ChildProcessConnection[] mChildProcessConnections;
+        private final @Nullable ChildProcessConnection[] mChildProcessConnections;
 
         // The list of free (not bound) service indices.
         private final ArrayList<Integer> mFreeConnectionIndices;
@@ -464,7 +466,8 @@
         }
 
         @Override
-        /* package */ ChildProcessConnection doAllocate(
+        /* package */ @Nullable
+        ChildProcessConnection doAllocate(
                 Context context,
                 Bundle serviceBundle,
                 ChildProcessConnection.ServiceCallback serviceCallback) {
@@ -531,7 +534,8 @@
             return mChildProcessConnections.length - mFreeConnectionIndices.size();
         }
 
-        public ChildProcessConnection getChildProcessConnectionAtSlotForTesting(int slotNumber) {
+        public @Nullable ChildProcessConnection getChildProcessConnectionAtSlotForTesting(
+                int slotNumber) {
             return mChildProcessConnections[slotNumber];
         }
 
@@ -553,7 +557,7 @@
                 Runnable freeSlotCallback,
                 String packageName,
                 String serviceClassName,
-                String fallbackServiceClassName,
+                @Nullable String fallbackServiceClassName,
                 boolean bindToCaller,
                 boolean bindAsExternalService,
                 boolean useStrongBinding,
@@ -572,7 +576,8 @@
         }
 
         @Override
-        /* package */ ChildProcessConnection doAllocate(
+        /* package */ @Nullable
+        ChildProcessConnection doAllocate(
                 Context context,
                 Bundle serviceBundle,
                 ChildProcessConnection.ServiceCallback serviceCallback) {
@@ -583,7 +588,8 @@
             return connection;
         }
 
-        /* package */ ChildProcessConnection tryAllocate(
+        /* package */ @Nullable
+        ChildProcessConnection tryAllocate(
                 Context context,
                 Bundle serviceBundle,
                 ChildProcessConnection.ServiceCallback serviceCallback) {
@@ -595,7 +601,7 @@
             return connection;
         }
 
-        private ChildProcessConnection allocate(Context context, Bundle serviceBundle) {
+        private @Nullable ChildProcessConnection allocate(Context context, Bundle serviceBundle) {
             if (mAllocatedConnections.size() >= mMaxAllocated) {
                 Log.w(TAG, "Ran out of UIDs to allocate.");
                 return null;
@@ -703,7 +709,8 @@
         }
 
         @Override
-        /* package */ ChildProcessConnection doAllocate(
+        /* package */ @Nullable
+        ChildProcessConnection doAllocate(
                 Context context,
                 Bundle serviceBundle,
                 ChildProcessConnection.ServiceCallback serviceCallback) {
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
index 25cb33e..e9d39f2c 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConnection.java
@@ -4,6 +4,8 @@
 
 package org.chromium.base.process_launcher;
 
+import static org.chromium.build.NullUtil.assumeNonNull;
+
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -16,7 +18,6 @@
 import android.os.Looper;
 import android.os.RemoteException;
 
-import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.BuildInfo;
@@ -31,6 +32,8 @@
 import org.chromium.base.memory.SelfFreezeCallback;
 import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.build.BuildConfig;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.util.Arrays;
 import java.util.List;
@@ -40,6 +43,7 @@
 import javax.annotation.concurrent.GuardedBy;
 
 /** Manages a connection between the browser activity and a child service. */
+@NullMarked
 public class ChildProcessConnection {
     private static final String TAG = "ChildProcessConn";
     private static final int FALLBACK_TIMEOUT_IN_SECONDS = 10;
@@ -76,9 +80,10 @@
     public interface ConnectionCallback {
         /**
          * Called when the connection to the service is established.
+         *
          * @param connection the connection object to the child process
          */
-        void onConnected(ChildProcessConnection connection);
+        void onConnected(@Nullable ChildProcessConnection connection);
     }
 
     /**
@@ -141,7 +146,7 @@
     private final Handler mLauncherHandler;
     private final Executor mLauncherExecutor;
     private ComponentName mServiceName;
-    private final ComponentName mFallbackServiceName;
+    private final @Nullable ComponentName mFallbackServiceName;
 
     // Parameters passed to the child process through the service binding intent.
     // If the service gets recreated by the framework the intent will be reused, so these parameters
@@ -154,11 +159,13 @@
 
     private static class ConnectionParams {
         final Bundle mConnectionBundle;
-        final List<IBinder> mClientInterfaces;
-        final IBinder mBinderBox;
+        final @Nullable List<IBinder> mClientInterfaces;
+        final @Nullable IBinder mBinderBox;
 
         ConnectionParams(
-                Bundle connectionBundle, List<IBinder> clientInterfaces, IBinder binderBox) {
+                Bundle connectionBundle,
+                @Nullable List<IBinder> clientInterfaces,
+                @Nullable IBinder binderBox) {
             mConnectionBundle = connectionBundle;
             mClientInterfaces = clientInterfaces;
             mBinderBox = binderBox;
@@ -166,22 +173,22 @@
     }
 
     // This is set in start() and is used in onServiceConnected().
-    private ServiceCallback mServiceCallback;
+    private @Nullable ServiceCallback mServiceCallback;
 
     // This is set in setupConnection() and is later used in doConnectionSetup(), after which the
     // variable is cleared. Therefore this is only valid while the connection is being set up.
-    private ConnectionParams mConnectionParams;
+    private @Nullable ConnectionParams mConnectionParams;
 
     // Callback provided in setupConnection() that will communicate the result to the caller. This
     // has to be called exactly once after setupConnection(), even if setup fails, so that the
     // caller can free up resources associated with the setup attempt. This is set to null after the
     // call.
-    private ConnectionCallback mConnectionCallback;
+    private @Nullable ConnectionCallback mConnectionCallback;
 
     // Callback provided in setupConnection().
-    private ZygoteInfoCallback mZygoteInfoCallback;
+    private @Nullable ZygoteInfoCallback mZygoteInfoCallback;
 
-    private IChildProcessService mService;
+    private @Nullable IChildProcessService mService;
 
     // Set to true when the service connection callback runs. This differs from
     // mServiceConnectComplete, which tracks that the connection completed successfully.
@@ -218,7 +225,7 @@
 
     // Instance named used on Android 10 and above to create separate instances from the same
     // <service> manifest declaration.
-    private final String mInstanceName;
+    private final @Nullable String mInstanceName;
 
     // Use Context.BIND_EXTERNAL_SERVICE flag for this service.
     private final boolean mBindAsExternalService;
@@ -233,7 +240,7 @@
 
     // On Android Q+ a not perceptible binding will make the service priority below that of a
     // perceptible process of a backgrounded app. Only created on Android Q+.
-    private ChildServiceConnection mNotPerceptibleBinding;
+    private @Nullable ChildServiceConnection mNotPerceptibleBinding;
 
     // Low priority binding maintained in the entire lifetime of the connection, i.e. between calls
     // to start() and stop().
@@ -262,13 +269,13 @@
     @GuardedBy("mBindingStateLock")
     private boolean mKilledByUs;
 
-    private MemoryPressureCallback mMemoryPressureCallback;
-    private SelfFreezeCallback mSelfFreezeCallback;
+    private @Nullable MemoryPressureCallback mMemoryPressureCallback;
+    private @Nullable SelfFreezeCallback mSelfFreezeCallback;
 
     // If the process threw an exception before entering the main loop, the exception
     // string is reported here.
     @GuardedBy("mBindingStateLock")
-    private String mExceptionInServiceDuringInit;
+    private @Nullable String mExceptionInServiceDuringInit;
 
     // Whether the process exited cleanly or not.
     @GuardedBy("mBindingStateLock")
@@ -277,11 +284,11 @@
     public ChildProcessConnection(
             Context context,
             ComponentName serviceName,
-            ComponentName fallbackServiceName,
+            @Nullable ComponentName fallbackServiceName,
             boolean bindToCaller,
             boolean bindAsExternalService,
             Bundle serviceBundle,
-            String instanceName) {
+            @Nullable String instanceName) {
         this(
                 context,
                 serviceName,
@@ -297,12 +304,12 @@
     public ChildProcessConnection(
             final Context context,
             ComponentName serviceName,
-            ComponentName fallbackServiceName,
+            @Nullable ComponentName fallbackServiceName,
             boolean bindToCaller,
             boolean bindAsExternalService,
             Bundle serviceBundle,
-            ChildServiceConnectionFactory connectionFactory,
-            String instanceName) {
+            @Nullable ChildServiceConnectionFactory connectionFactory,
+            @Nullable String instanceName) {
         mLauncherHandler = new Handler();
         mLauncherExecutor =
                 (Runnable runnable) -> {
@@ -329,7 +336,7 @@
                                 Intent bindIntent,
                                 int bindFlags,
                                 ChildServiceConnectionDelegate delegate,
-                                String instanceName) {
+                                @Nullable String instanceName) {
                             return new ChildServiceConnectionImpl(
                                     context,
                                     bindIntent,
@@ -410,7 +417,7 @@
                         mInstanceName);
     }
 
-    public final IChildProcessService getService() {
+    public final @Nullable IChildProcessService getService() {
         assert isRunningOnLauncherThread();
         return mService;
     }
@@ -701,7 +708,7 @@
         s.append("bindings:");
         s.append(mWaivedBinding.isBound() ? "W" : " ");
         s.append(mVisibleBinding.isBound() ? "V" : " ");
-        s.append(supportNotPerceptibleBinding() && mNotPerceptibleBinding.isBound() ? "N" : " ");
+        s.append(mNotPerceptibleBinding != null && mNotPerceptibleBinding.isBound() ? "N" : " ");
         s.append(mStrongBinding.isBound() ? "S" : " ");
         return s.toString();
     }
@@ -892,7 +899,7 @@
         boolean isStrongBindingBound = mStrongBinding.isBound();
         boolean isVisibleBindingBound = mVisibleBinding.isBound();
         boolean isNotPerceptibleBindingBound =
-                supportNotPerceptibleBinding() && mNotPerceptibleBinding.isBound();
+                mNotPerceptibleBinding != null && mNotPerceptibleBinding.isBound();
         boolean isWaivedBindingBound = mWaivedBinding.isBound();
         retireAndCreateFallbackBindings();
         // Expect all bindings to succeed or fail together. So early out as soon as
@@ -908,7 +915,7 @@
             }
         }
         if (isNotPerceptibleBindingBound) {
-            if (!mNotPerceptibleBinding.bindServiceConnection()) {
+            if (!assumeNonNull(mNotPerceptibleBinding).bindServiceConnection()) {
                 return false;
             }
         }
@@ -925,7 +932,7 @@
         Log.w(TAG, "Fallback to %s", mFallbackServiceName);
         mStrongBinding.retire();
         mVisibleBinding.retire();
-        if (supportNotPerceptibleBinding()) {
+        if (mNotPerceptibleBinding != null) {
             mNotPerceptibleBinding.retire();
         }
         mWaivedBinding.retire();
@@ -940,7 +947,7 @@
         mUnbound = true;
         mStrongBinding.unbindServiceConnection();
         mWaivedBinding.unbindServiceConnection();
-        if (supportNotPerceptibleBinding()) {
+        if (mNotPerceptibleBinding != null) {
             mNotPerceptibleBinding.unbindServiceConnection();
         }
         mVisibleBinding.unbindServiceConnection();
@@ -1050,7 +1057,7 @@
 
     public boolean isNotPerceptibleBindingBound() {
         assert isRunningOnLauncherThread();
-        return supportNotPerceptibleBinding() && mNotPerceptibleBinding.isBound();
+        return mNotPerceptibleBinding != null && mNotPerceptibleBinding.isBound();
     }
 
     public int getNotPerceptibleBindingCount() {
@@ -1066,7 +1073,7 @@
             return;
         }
         if (mNotPerceptibleBindingCount == 0) {
-            mNotPerceptibleBinding.bindServiceConnection();
+            assumeNonNull(mNotPerceptibleBinding).bindServiceConnection();
             updateBindingState();
         }
         mNotPerceptibleBindingCount++;
@@ -1081,7 +1088,7 @@
         assert mNotPerceptibleBindingCount > 0;
         mNotPerceptibleBindingCount--;
         if (mNotPerceptibleBindingCount == 0) {
-            mNotPerceptibleBinding.unbindServiceConnection();
+            assumeNonNull(mNotPerceptibleBinding).unbindServiceConnection();
             updateBindingState();
         }
     }
@@ -1151,7 +1158,7 @@
             newBindingState = ChildBindingState.STRONG;
         } else if (mVisibleBinding.isBound()) {
             newBindingState = ChildBindingState.VISIBLE;
-        } else if (supportNotPerceptibleBinding() && mNotPerceptibleBinding.isBound()) {
+        } else if (mNotPerceptibleBinding != null && mNotPerceptibleBinding.isBound()) {
             newBindingState = ChildBindingState.NOT_PERCEPTIBLE;
         } else {
             assert mWaivedBinding.isBound();
@@ -1181,7 +1188,7 @@
 
     public void crashServiceForTesting() {
         try {
-            mService.forceKill();
+            assumeNonNull(mService).forceKill();
         } catch (RemoteException e) {
             // Expected. Ignore.
         }
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConstants.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConstants.java
index 872d49b..8cc6e3c 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConstants.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessConstants.java
@@ -4,7 +4,10 @@
 
 package org.chromium.base.process_launcher;
 
+import org.chromium.build.annotations.NullMarked;
+
 /** Constants to be used by child processes. */
+@NullMarked
 public interface ChildProcessConstants {
     // Below are the names for the items placed in the bind or start command intent.
     // Note that because that intent maybe reused if a service is restarted, none should be process
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessLauncher.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessLauncher.java
index 7957b859..86b41ad 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessLauncher.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessLauncher.java
@@ -4,6 +4,8 @@
 
 package org.chromium.base.process_launcher;
 
+import static org.chromium.build.NullUtil.assumeNonNull;
+
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -12,11 +14,15 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.TraceEvent;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
+import org.chromium.build.annotations.RequiresNonNull;
 
 import java.io.IOException;
 import java.util.List;
 
 /** This class is used to start a child process by connecting to a ChildProcessService. */
+@NullMarked
 public class ChildProcessLauncher {
     private static final String TAG = "ChildProcLauncher";
 
@@ -25,16 +31,16 @@
         /**
          * Called when the launcher is about to start. Gives the embedder a chance to provide an
          * already bound connection if it has one. (allowing for warm-up connections: connections
-         * that are already bound in advance to speed up child process start-up time).
-         * Note that onBeforeConnectionAllocated will not be called if this method returns a
-         * connection.
+         * that are already bound in advance to speed up child process start-up time). Note that
+         * onBeforeConnectionAllocated will not be called if this method returns a connection.
+         *
          * @param connectionAllocator the allocator the returned connection should have been
-         * allocated of.
+         *     allocated of.
          * @param serviceCallback the service callback that the connection should use.
          * @return a bound connection to use to connect to the child process service, or null if a
-         * connection should be allocated and bound by the launcher.
+         *     connection should be allocated and bound by the launcher.
          */
-        public ChildProcessConnection getBoundConnection(
+        public @Nullable ChildProcessConnection getBoundConnection(
                 ChildConnectionAllocator connectionAllocator,
                 ChildProcessConnection.ServiceCallback serviceCallback) {
             return null;
@@ -102,7 +108,7 @@
 
     // The actual service connection. Set once we have connected to the service. Volatile as it is
     // accessed from threads other than the Launcher thread.
-    private volatile ChildProcessConnection mConnection;
+    private volatile @Nullable ChildProcessConnection mConnection;
 
     /**
      * Constructor.
@@ -198,7 +204,7 @@
         }
     }
 
-    public ChildProcessConnection getConnection() {
+    public @Nullable ChildProcessConnection getConnection() {
         return mConnection;
     }
 
@@ -235,6 +241,7 @@
         return true;
     }
 
+    @RequiresNonNull("mConnection")
     private void setupConnection() {
         ChildProcessConnection.ZygoteInfoCallback zygoteInfoCallback =
                 new ChildProcessConnection.ZygoteInfoCallback() {
@@ -247,7 +254,7 @@
         ChildProcessConnection.ConnectionCallback connectionCallback =
                 new ChildProcessConnection.ConnectionCallback() {
                     @Override
-                    public void onConnected(ChildProcessConnection connection) {
+                    public void onConnected(@Nullable ChildProcessConnection connection) {
                         onServiceConnected(connection);
                     }
                 };
@@ -261,13 +268,15 @@
                 zygoteInfoCallback);
     }
 
-    private void onServiceConnected(ChildProcessConnection connection) {
+    private void onServiceConnected(@Nullable ChildProcessConnection connection) {
+        ChildProcessConnection curConnection = mConnection;
         assert isRunningOnLauncherThread();
-        assert mConnection == connection || connection == null;
+        assert curConnection != null;
+        assert curConnection == connection || connection == null;
 
-        Log.d(TAG, "on connect callback, pid=%d", mConnection.getPid());
+        Log.d(TAG, "on connect callback, pid=%d", curConnection.getPid());
 
-        mDelegate.onConnectionEstablished(mConnection);
+        mDelegate.onConnectionEstablished(curConnection);
 
         // Proactively close the FDs rather than waiting for the GC to do it.
         try {
@@ -281,7 +290,8 @@
 
     public int getPid() {
         assert isRunningOnLauncherThread();
-        return mConnection == null ? NULL_PROCESS_HANDLE : mConnection.getPid();
+        ChildProcessConnection connection = mConnection;
+        return connection == null ? NULL_PROCESS_HANDLE : connection.getPid();
     }
 
     public List<IBinder> getClientInterfaces() {
@@ -304,15 +314,15 @@
     }
 
     private void onChildProcessDied() {
-        assert isRunningOnLauncherThread();
         if (getPid() != 0) {
-            mDelegate.onConnectionLost(mConnection);
+            mDelegate.onConnectionLost(assumeNonNull(mConnection));
         }
     }
 
     public void stop() {
         assert isRunningOnLauncherThread();
-        Log.d(TAG, "stopping child connection: pid=%d", mConnection.getPid());
-        mConnection.stop();
+        ChildProcessConnection connection = assumeNonNull(mConnection);
+        Log.d(TAG, "stopping child connection: pid=%d", connection.getPid());
+        connection.stop();
     }
 }
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java
index 186c212..8dbc2f4 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessService.java
@@ -35,6 +35,8 @@
 import org.chromium.base.library_loader.LibraryLoader;
 import org.chromium.base.memory.MemoryPressureMonitor;
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.util.List;
 
@@ -61,6 +63,7 @@
  */
 @JNINamespace("base::android")
 @SuppressWarnings("SynchronizeOnNonFinalField") // mMainThread assigned in onCreate().
+@NullMarked
 public class ChildProcessService {
     private static final String MAIN_THREAD_NAME = "ChildProcessMain";
     private static final String TAG = "ChildProcessService";
@@ -87,16 +90,17 @@
     private int mBoundCallingPid;
 
     @GuardedBy("mBinderLock")
-    private String mBoundCallingClazz;
+    private @Nullable String mBoundCallingClazz;
 
     // This is the native "Main" thread for the renderer / utility process.
+    @SuppressWarnings("NullAway.Init")
     private Thread mMainThread;
 
     // Parameters received via IPC, only accessed while holding the mMainThread monitor.
-    private String[] mCommandLineParams;
+    private String @Nullable [] mCommandLineParams;
 
     // File descriptors that should be registered natively.
-    private FileDescriptorInfo[] mFdInfos;
+    private FileDescriptorInfo @Nullable [] mFdInfos;
 
     @GuardedBy("mLibraryInitializedLock")
     private boolean mLibraryInitialized;
@@ -106,6 +110,7 @@
     private boolean mServiceBound;
 
     // Interface to send notifications to the parent process.
+    @SuppressWarnings("NullAway.Init")
     private IParentProcess mParentProcess;
 
     public ChildProcessService(
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessServiceDelegate.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessServiceDelegate.java
index 08f7c5a2..2bb8eed6 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessServiceDelegate.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessServiceDelegate.java
@@ -10,9 +10,12 @@
 import android.os.IBinder;
 import android.util.SparseArray;
 
+import org.chromium.build.annotations.NullMarked;
+
 import java.util.List;
 
 /** The interface that embedders should implement to specialize child service creation. */
+@NullMarked
 public interface ChildProcessServiceDelegate {
     /** Invoked when the service was created. This is the first method invoked on the delegate. */
     void onServiceCreated();
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnection.java b/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnection.java
index 560fe9d..0b4a281 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnection.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnection.java
@@ -4,7 +4,10 @@
 
 package org.chromium.base.process_launcher;
 
+import org.chromium.build.annotations.NullMarked;
+
 /** Interface representing a connection to the Android service. Can be mocked in unit-tests. */
+@NullMarked
 /* package */ interface ChildServiceConnection {
     boolean bindServiceConnection();
 
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionDelegate.java b/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionDelegate.java
index 3439856..940ab3c 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionDelegate.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionDelegate.java
@@ -6,10 +6,13 @@
 
 import android.os.IBinder;
 
+import org.chromium.build.annotations.NullMarked;
+
 /**
- * Delegate that ChildServiceConnection should call when the service connects/disconnects.
- * These callbacks are expected to happen on a background thread.
+ * Delegate that ChildServiceConnection should call when the service connects/disconnects. These
+ * callbacks are expected to happen on a background thread.
  */
+@NullMarked
 /* package */ interface ChildServiceConnectionDelegate {
     void onServiceConnected(IBinder service);
 
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionFactory.java b/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionFactory.java
index 21b1521b..52bda26 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionFactory.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionFactory.java
@@ -6,10 +6,14 @@
 
 import android.content.Intent;
 
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
+
+@NullMarked
 /* package */ interface ChildServiceConnectionFactory {
     ChildServiceConnection createConnection(
             Intent bindIntent,
             int bindFlags,
             ChildServiceConnectionDelegate delegate,
-            String instanceName);
+            @Nullable String instanceName);
 }
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionImpl.java b/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionImpl.java
index a25d2cb5..a3576825 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionImpl.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/ChildServiceConnectionImpl.java
@@ -13,10 +13,13 @@
 
 import org.chromium.base.Log;
 import org.chromium.base.TraceEvent;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.util.concurrent.Executor;
 
 /** Implementation of ChildServiceConnection that does connect to a service. */
+@NullMarked
 /* package */ class ChildServiceConnectionImpl
         implements ChildServiceConnection, ServiceConnection {
     private static final String TAG = "ChildServiceConn";
@@ -26,8 +29,8 @@
     private final int mBindFlags;
     private final Handler mHandler;
     private final Executor mExecutor;
-    private ChildServiceConnectionDelegate mDelegate;
-    private final String mInstanceName;
+    private @Nullable ChildServiceConnectionDelegate mDelegate;
+    private final @Nullable String mInstanceName;
     private boolean mBound;
 
     /* package */ ChildServiceConnectionImpl(
@@ -37,7 +40,7 @@
             Handler handler,
             Executor executor,
             ChildServiceConnectionDelegate delegate,
-            String instanceName) {
+            @Nullable String instanceName) {
         mContext = context;
         mBindIntent = bindIntent;
         mBindFlags = bindFlags;
diff --git a/base/android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java b/base/android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java
index 62f2f1fb..5ecf70c 100644
--- a/base/android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java
+++ b/base/android/java/src/org/chromium/base/process_launcher/FileDescriptorInfo.java
@@ -8,16 +8,18 @@
 import android.os.ParcelFileDescriptor;
 import android.os.Parcelable;
 
+import org.chromium.build.annotations.NullMarked;
 import org.chromium.build.annotations.UsedByReflection;
 
 import javax.annotation.concurrent.Immutable;
 
 /**
- * Parcelable class that contains file descriptor and file region information to
- * be passed to child processes.
+ * Parcelable class that contains file descriptor and file region information to be passed to child
+ * processes.
  */
 @Immutable
 @UsedByReflection("child_process_launcher_helper_android.cc")
+@NullMarked
 public final class FileDescriptorInfo implements Parcelable {
     public final int id;
     public final ParcelFileDescriptor fd;
@@ -33,7 +35,9 @@
 
     FileDescriptorInfo(Parcel in) {
         id = in.readInt();
-        fd = in.readParcelable(ParcelFileDescriptor.class.getClassLoader());
+        ParcelFileDescriptor gotFd = in.readParcelable(ParcelFileDescriptor.class.getClassLoader());
+        assert gotFd != null;
+        fd = gotFd;
         offset = in.readLong();
         size = in.readLong();
     }
diff --git a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
index 3cb0bffb..5355820e 100644
--- a/cc/benchmarks/rasterize_and_record_benchmark_impl.cc
+++ b/cc/benchmarks/rasterize_and_record_benchmark_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/351564777): Remove this and convert code to safer constructs.
-#pragma allow_unsafe_buffers
-#endif
-
 #include "cc/benchmarks/rasterize_and_record_benchmark_impl.h"
 
 #include <stddef.h>
diff --git a/cc/benchmarks/rasterize_and_record_benchmark_impl.h b/cc/benchmarks/rasterize_and_record_benchmark_impl.h
index 77c8ff4..73e125c 100644
--- a/cc/benchmarks/rasterize_and_record_benchmark_impl.h
+++ b/cc/benchmarks/rasterize_and_record_benchmark_impl.h
@@ -7,6 +7,8 @@
 
 #include <stddef.h>
 
+#include <array>
+
 #include "base/task/single_thread_task_runner.h"
 #include "base/time/time.h"
 #include "cc/benchmarks/micro_benchmark_impl.h"
@@ -38,8 +40,8 @@
     int pixels_rasterized;
     int pixels_rasterized_with_non_solid_color;
     int pixels_rasterized_as_opaque;
-    int visible_pixels_by_lcd_text_disallowed_reason
-        [kLCDTextDisallowedReasonCount];
+    std::array<int, kLCDTextDisallowedReasonCount>
+        visible_pixels_by_lcd_text_disallowed_reason;
     base::TimeDelta total_best_time;
     int total_layers;
     int total_picture_layers;
diff --git a/cc/layers/heads_up_display_layer.cc b/cc/layers/heads_up_display_layer.cc
index 9eed3f1..4d3b5c0d 100644
--- a/cc/layers/heads_up_display_layer.cc
+++ b/cc/layers/heads_up_display_layer.cc
@@ -24,6 +24,7 @@
   if (!typeface_.Read(*this)) {
     typeface_.Write(*this) =
         skia::MakeTypefaceFromName("monospace", SkFontStyle::Bold());
+    SetNeedsPushProperties();
   }
   DCHECK(typeface_.Read(*this).get());
   SetIsDrawable(true);
@@ -84,21 +85,25 @@
 void HeadsUpDisplayLayer::SetLayoutShiftRects(
     const std::vector<gfx::Rect>& rects) {
   layout_shift_rects_.Write(*this) = rects;
+  SetNeedsPushProperties();
 }
 
-
-void HeadsUpDisplayLayer::PushPropertiesTo(
+void HeadsUpDisplayLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  Layer::PushPropertiesTo(layer, commit_state, unsafe_state);
-  TRACE_EVENT0("cc", "HeadsUpDisplayLayer::PushPropertiesTo");
-  HeadsUpDisplayLayerImpl* layer_impl =
-      static_cast<HeadsUpDisplayLayerImpl*>(layer);
+  Layer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state, unsafe_state);
 
-  layer_impl->SetHUDTypeface(typeface_.Write(*this));
-  layer_impl->SetLayoutShiftRects(LayoutShiftRects());
-  layout_shift_rects_.Write(*this).clear();
+  if (dirty_flag & kChangedGeneralProperty) {
+    TRACE_EVENT0("cc", "HeadsUpDisplayLayer::PushPropertiesTo");
+    HeadsUpDisplayLayerImpl* layer_impl =
+        static_cast<HeadsUpDisplayLayerImpl*>(layer);
+
+    layer_impl->SetHUDTypeface(typeface_.Write(*this));
+    layer_impl->SetLayoutShiftRects(LayoutShiftRects());
+    layout_shift_rects_.Write(*this).clear();
+  }
 }
 
 }  // namespace cc
diff --git a/cc/layers/heads_up_display_layer.h b/cc/layers/heads_up_display_layer.h
index 7a7d6db..79132f5 100644
--- a/cc/layers/heads_up_display_layer.h
+++ b/cc/layers/heads_up_display_layer.h
@@ -34,15 +34,17 @@
   std::unique_ptr<LayerImpl> CreateLayerImpl(
       LayerTreeImpl* tree_impl) const override;
 
-  // Layer overrides.
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
-
  protected:
   HeadsUpDisplayLayer();
   bool HasDrawableContent() const override;
 
+  // Layer overrides.
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
  private:
   ~HeadsUpDisplayLayer() override;
 
diff --git a/cc/layers/layer.cc b/cc/layers/layer.cc
index 4d52063..f51e549 100644
--- a/cc/layers/layer.cc
+++ b/cc/layers/layer.cc
@@ -50,7 +50,8 @@
   SameSizeAsLayer();
   ~SameSizeAsLayer() override;
 
-  void* pointers[2];
+  void* pointers[4];
+
   struct {
     LayerList children;
     gfx::Size bounds;
@@ -60,12 +61,14 @@
     ElementId element_id;
     raw_ptr<void> rare_inputs;
   } inputs;
-  raw_ptr<void> layer_tree_inputs;
   gfx::Rect update_rect;
   int int_fields[7];
   gfx::Vector2dF offset;
-  unsigned bitfields;
-  std::unique_ptr<int> debug_info;
+  bool bool_fields[2];
+#if DCHECK_IS_ON()
+  bool allow_remove_for_readd;
+#endif
+  uint8_t bit_fields[2];
 };
 
 static_assert(sizeof(Layer) == sizeof(SameSizeAsLayer),
@@ -109,8 +112,9 @@
       scroll_tree_index_(kInvalidPropertyNodeId),
       property_tree_sequence_number_(-1),
       ignore_set_needs_commit_for_test_(false),
+      subtree_property_changed_(false),
       bitflags_(0u),
-      subtree_property_changed_(false) {}
+      changed_properties_(0u) {}
 
 Layer::~Layer() {
   // Our parent should be holding a reference to us so there should be no
@@ -173,13 +177,16 @@
   // See comment in layer.h to learn why this assignment is so weird.
   const_cast<raw_ptr<LayerTreeHost>&>(layer_tree_host_) = host;
 
+  if (host) {
+    // When changing hosts, the layer needs to commit its properties to
+    // the impl side for the new host.
+    changed_properties_.Write(*this) |= kChangedAllProperties;
+    host->AddLayerShouldPushProperties(this);
+  }
+
   if (property_tree_indices_invalid)
     InvalidatePropertyTreesIndices();
 
-  // When changing hosts, the layer needs to commit its properties to the impl
-  // side for the new host.
-  SetNeedsPushProperties();
-
   for (auto child : inputs.children)
     child->SetLayerTreeHost(host);
 
@@ -222,9 +229,17 @@
   layer_tree_host()->SetNeedsFullTreeSync();
 }
 
-void Layer::SetNeedsPushProperties() {
-  if (IsAttached())
-    layer_tree_host()->AddLayerShouldPushProperties(this);
+void Layer::SetNeedsPushProperties(uint8_t changed_props) {
+  uint8_t& changed = changed_properties_.Write(*this);
+  if (!::features::IsCCSlimmingEnabled()) {
+    changed_props = kChangedAllProperties;
+  }
+  if ((changed & changed_props) != changed_props) {
+    if (!changed && IsAttached()) {
+      layer_tree_host()->AddLayerShouldPushProperties(this);
+    }
+    changed |= changed_props;
+  }
 }
 
 bool Layer::IsPropertyChangeAllowed() const {
@@ -1206,7 +1221,7 @@
     return;
   SetHasTransformNode(index != kInvalidPropertyNodeId);
   transform_tree_index_.Write(*this) = index;
-  SetNeedsPushProperties();
+  SetNeedsPushProperties(kChangedPropertyTreeIndex);
 }
 
 int Layer::transform_tree_index(const PropertyTrees& property_trees) const {
@@ -1235,7 +1250,7 @@
   if (clip_tree_index_.Read(*this) == index)
     return;
   clip_tree_index_.Write(*this) = index;
-  SetNeedsPushProperties();
+  SetNeedsPushProperties(kChangedPropertyTreeIndex);
 }
 
 int Layer::clip_tree_index(const PropertyTrees& property_trees) const {
@@ -1264,7 +1279,7 @@
   if (effect_tree_index_.Read(*this) == index)
     return;
   effect_tree_index_.Write(*this) = index;
-  SetNeedsPushProperties();
+  SetNeedsPushProperties(kChangedPropertyTreeIndex);
 }
 
 int Layer::effect_tree_index(const PropertyTrees& property_trees) const {
@@ -1293,7 +1308,7 @@
   if (scroll_tree_index_.Read(*this) == index)
     return;
   scroll_tree_index_.Write(*this) = index;
-  SetNeedsPushProperties();
+  SetNeedsPushProperties(kChangedPropertyTreeIndex);
 }
 
 int Layer::scroll_tree_index(const PropertyTrees& property_trees) const {
@@ -1422,78 +1437,99 @@
   return false;
 }
 
-void Layer::PushPropertiesTo(LayerImpl* layer,
+void Layer::PushDirtyPropertiesTo(LayerImpl* layer,
+                                  uint8_t dirty_flag,
+                                  const CommitState& commit_state,
+                                  const ThreadUnsafeCommitState& unsafe_state) {
+  const PropertyTrees& property_trees = unsafe_state.property_trees;
+
+  if (dirty_flag & kChangedPropertyTreeIndex) {
+    layer->SetTransformTreeIndex(transform_tree_index(property_trees));
+    layer->SetHasTransformNode(has_transform_node());
+    layer->SetEffectTreeIndex(effect_tree_index(property_trees));
+    layer->SetClipTreeIndex(clip_tree_index(property_trees));
+    layer->SetScrollTreeIndex(scroll_tree_index(property_trees));
+  }
+
+  if (dirty_flag & kChangedGeneralProperty) {
+    // The element id should be set first because other setters may
+    // depend on it. Referencing element id on a layer is
+    // deprecated. http://crbug.com/709137
+    const auto& inputs = inputs_.Read(*this);
+
+    layer->SetElementId(inputs.element_id);
+    layer->SetBackgroundColor(inputs.background_color);
+    layer->SetSafeOpaqueBackgroundColor(SafeOpaqueBackgroundColor());
+    layer->SetBounds(inputs.bounds);
+
+    layer->SetOffsetToTransformParent(offset_to_transform_parent_.Read(*this));
+    layer->SetDrawsContent(draws_content());
+    layer->SetHitTestOpaqueness(inputs.hit_test_opaqueness);
+    // subtree_property_changed_ is propagated to all descendants while building
+    // property trees. So, it is enough to check it only for the current layer.
+    if (subtree_property_changed_.Read(*this)) {
+      layer->NoteLayerPropertyChanged();
+    }
+    layer->set_may_contain_video(may_contain_video());
+    layer->SetTouchActionRegion(inputs.touch_action_region);
+    layer->SetContentsOpaque(inputs.contents_opaque);
+    layer->SetContentsOpaqueForText(inputs.contents_opaque_for_text);
+    layer->SetShouldCheckBackfaceVisibility(should_check_backface_visibility());
+
+    // The property trees must be safe to access because they will be used below
+    // to call |SetScrollOffsetClobberActiveValue|.
+    DCHECK(layer->layer_tree_impl()->lifecycle().AllowsPropertyTreeAccess());
+
+    // When a scroll offset animation is interrupted the new scroll position on
+    // the pending tree will clobber any impl-side scrolling occurring on the
+    // active tree. To do so, avoid scrolling the pending tree along with it
+    // instead of trying to undo that scrolling later.
+    if (unsafe_state.mutator_host->ScrollOffsetAnimationWasInterrupted(
+            element_id())) {
+      PropertyTrees* trees = layer->layer_tree_impl()->property_trees();
+      trees->scroll_tree_mutable().SetScrollOffsetClobberActiveValue(
+          layer->element_id());
+    }
+
+    layer->UnionUpdateRect(update_rect_.Read(*this));
+
+    // debug_info_->invalidations, if exist, will be cleared in the function.
+    layer->UpdateDebugInfo(debug_info_.Write(*this).get());
+
+    if (inputs.rare_inputs) {
+      layer->SetFilterQuality(inputs.rare_inputs->filter_quality);
+      layer->SetDynamicRangeLimit(inputs.rare_inputs->dynamic_range_limit);
+      layer->SetMainThreadScrollHitTestRegion(
+          inputs.rare_inputs->main_thread_scroll_hit_test_region);
+      layer->SetNonCompositedScrollHitTestRects(
+          inputs.rare_inputs->non_composited_scroll_hit_test_rects);
+      layer->SetCaptureBounds(inputs.rare_inputs->capture_bounds);
+      layer->SetWheelEventHandlerRegion(inputs.rare_inputs->wheel_event_region);
+    } else {
+      layer->ResetRareProperties();
+    }
+
+    // Reset any state that should be cleared for the next update.
+    subtree_property_changed_.Write(*this) = false;
+    update_rect_.Write(*this) = gfx::Rect();
+  }
+
+  layer->SetNeedsPushProperties();
+}
+
+void Layer::PushPropertiesTo(LayerImpl* layer_impl,
                              const CommitState& commit_state,
                              const ThreadUnsafeCommitState& unsafe_state) {
   TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
                "Layer::PushPropertiesTo");
   DCHECK(IsAttached());
 
-  const PropertyTrees& property_trees = unsafe_state.property_trees;
+  const uint8_t changed_props = changed_properties_.Read(*this);
 
-  // The element id should be set first because other setters may
-  // depend on it. Referencing element id on a layer is
-  // deprecated. http://crbug.com/709137
-  const auto& inputs = inputs_.Read(*this);
-  layer->SetElementId(inputs.element_id);
-  layer->SetHasTransformNode(has_transform_node());
-  layer->SetBackgroundColor(inputs.background_color);
-  layer->SetSafeOpaqueBackgroundColor(SafeOpaqueBackgroundColor());
-  layer->SetBounds(inputs.bounds);
-  layer->SetTransformTreeIndex(transform_tree_index(property_trees));
-  layer->SetEffectTreeIndex(effect_tree_index(property_trees));
-  layer->SetClipTreeIndex(clip_tree_index(property_trees));
-  layer->SetScrollTreeIndex(scroll_tree_index(property_trees));
-  layer->SetOffsetToTransformParent(offset_to_transform_parent_.Read(*this));
-  layer->SetDrawsContent(draws_content());
-  layer->SetHitTestOpaqueness(inputs.hit_test_opaqueness);
-  // subtree_property_changed_ is propagated to all descendants while building
-  // property trees. So, it is enough to check it only for the current layer.
-  if (subtree_property_changed_.Read(*this))
-    layer->NoteLayerPropertyChanged();
-  layer->set_may_contain_video(may_contain_video());
-  layer->SetTouchActionRegion(inputs.touch_action_region);
-  layer->SetContentsOpaque(inputs.contents_opaque);
-  layer->SetContentsOpaqueForText(inputs.contents_opaque_for_text);
-  layer->SetShouldCheckBackfaceVisibility(should_check_backface_visibility());
+  PushDirtyPropertiesTo(layer_impl, changed_props, commit_state, unsafe_state);
 
-  // The property trees must be safe to access because they will be used below
-  // to call |SetScrollOffsetClobberActiveValue|.
-  DCHECK(layer->layer_tree_impl()->lifecycle().AllowsPropertyTreeAccess());
-
-  // When a scroll offset animation is interrupted the new scroll position on
-  // the pending tree will clobber any impl-side scrolling occuring on the
-  // active tree. To do so, avoid scrolling the pending tree along with it
-  // instead of trying to undo that scrolling later.
-  if (unsafe_state.mutator_host->ScrollOffsetAnimationWasInterrupted(
-          element_id())) {
-    PropertyTrees* trees = layer->layer_tree_impl()->property_trees();
-    trees->scroll_tree_mutable().SetScrollOffsetClobberActiveValue(
-        layer->element_id());
-  }
-
-  layer->UnionUpdateRect(update_rect_.Read(*this));
-  layer->SetNeedsPushProperties();
-
-  // debug_info_->invalidations, if exist, will be cleared in the function.
-  layer->UpdateDebugInfo(debug_info_.Write(*this).get());
-
-  if (inputs.rare_inputs) {
-    layer->SetFilterQuality(inputs.rare_inputs->filter_quality);
-    layer->SetDynamicRangeLimit(inputs.rare_inputs->dynamic_range_limit);
-    layer->SetMainThreadScrollHitTestRegion(
-        inputs.rare_inputs->main_thread_scroll_hit_test_region);
-    layer->SetNonCompositedScrollHitTestRects(
-        inputs.rare_inputs->non_composited_scroll_hit_test_rects);
-    layer->SetCaptureBounds(inputs.rare_inputs->capture_bounds);
-    layer->SetWheelEventHandlerRegion(inputs.rare_inputs->wheel_event_region);
-  } else {
-    layer->ResetRareProperties();
-  }
-
-  // Reset any state that should be cleared for the next update.
-  subtree_property_changed_.Write(*this) = false;
-  update_rect_.Write(*this) = gfx::Rect();
+  // Reset change flags for next update.
+  changed_properties_.Write(*this) = 0u;
 }
 
 void Layer::TakeCopyRequests(
diff --git a/cc/layers/layer.h b/cc/layers/layer.h
index 2354ffcf..66e644e 100644
--- a/cc/layers/layer.h
+++ b/cc/layers/layer.h
@@ -730,9 +730,9 @@
   // that state as well. The |layer| passed in will be of the type created by
   // CreateLayerImpl(), so can be safely down-casted if the subclass uses a
   // different type for the compositor thread.
-  virtual void PushPropertiesTo(LayerImpl* layer,
-                                const CommitState& commit_state,
-                                const ThreadUnsafeCommitState& unsafe_state);
+  void PushPropertiesTo(LayerImpl* layer,
+                        const CommitState& commit_state,
+                        const ThreadUnsafeCommitState& unsafe_state);
 
   // Internal method to be overridden by Layer subclasses that need to do work
   // during a main frame. The method should compute any state that will need to
@@ -765,7 +765,12 @@
   // compositor thread during the next commit. The PushPropertiesTo() method
   // will be called for this layer during the next commit only if this method
   // was called before it.
-  void SetNeedsPushProperties();
+  void SetNeedsPushProperties(uint8_t changed_props = kChangedGeneralProperty);
+
+  // Clear cached properties
+  void ClearChangedPushPropertiesForTesting() {
+    changed_properties_.Write(*this) = 0u;
+  }
 
   // Internal to property tree construction. A generation number for the
   // property trees, to verify the layer's indices are pointers into the trees
@@ -876,6 +881,13 @@
   Layer();
   ~Layer() override;
 
+  // This is implementation helper for PushPropertiesTo().
+  virtual void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state);
+
   // These SetNeeds functions are in order of severity of update:
 
   // See SetNeedsCommit() above - it belongs here in the order of severity.
@@ -914,6 +926,12 @@
         &ignore_set_needs_commit_for_test_.Write(*this), true);
   }
 
+  enum : uint8_t {
+    kChangedPropertyTreeIndex = 1 << 0,
+    kChangedGeneralProperty = 1 << 1,
+    kChangedAllProperties = kChangedPropertyTreeIndex | kChangedGeneralProperty,
+  };
+
  private:
   friend class base::RefCounted<Layer>;
   friend class LayerTreeHostCommon;
@@ -1132,11 +1150,13 @@
   // SetLayerTreeHost() uses a custom protected sequence check, and then uses
   // const_cast to do the assignment.
   const raw_ptr<LayerTreeHost> layer_tree_host_;
-
-  ProtectedSequenceReadable<Inputs> inputs_;
   ProtectedSequenceReadable<std::unique_ptr<LayerTreeInputs>>
       layer_tree_inputs_;
 
+  // Keep pointers together to reduce alignment padding on 64bit
+  ProtectedSequenceWritable<std::unique_ptr<LayerDebugInfo>> debug_info_;
+
+  ProtectedSequenceReadable<Inputs> inputs_;
   ProtectedSequenceWritable<gfx::Rect> update_rect_;
 
   const int layer_id_;
@@ -1154,6 +1174,11 @@
   // will be handled implicitly after the update completes. Not a bitfield
   // because it's used in base::AutoReset.
   ProtectedSequenceReadable<bool> ignore_set_needs_commit_for_test_;
+  ProtectedSequenceWritable<bool> subtree_property_changed_;
+
+#if DCHECK_IS_ON()
+  bool allow_remove_for_readd_ = false;
+#endif
 
   enum : uint8_t {
     kDrawsContentFlagMask = 1 << 0,
@@ -1166,8 +1191,7 @@
     kSubtreeHasCopyRequestFlagMask = 1 << 7
   };
   ProtectedSequenceReadable<uint8_t> bitflags_;
-
-  ProtectedSequenceWritable<bool> subtree_property_changed_;
+  ProtectedSequenceWritable<uint8_t> changed_properties_;
 
 #if DCHECK_IS_ON()
   class AllowRemoveForReadd {
@@ -1195,7 +1219,6 @@
     raw_ptr<Layer> layer_;
   };
 
-  bool allow_remove_for_readd_ = false;
 #else
   class AllowRemoveForReadd {
    public:
@@ -1206,8 +1229,6 @@
   };
 #endif
 
-  ProtectedSequenceWritable<std::unique_ptr<LayerDebugInfo>> debug_info_;
-
   static constexpr gfx::Transform kIdentityTransform{};
   static constexpr gfx::RoundedCornersF kNoRoundedCornersF{};
 };
diff --git a/cc/layers/layer_unittest.cc b/cc/layers/layer_unittest.cc
index 9a681a9..c58e972 100644
--- a/cc/layers/layer_unittest.cc
+++ b/cc/layers/layer_unittest.cc
@@ -148,6 +148,13 @@
                              base::SingleThreadTaskRunner::GetCurrentDefault());
   }
 
+  void ClearPendingLayerCommitStates() {
+    for (auto layer :
+         pending_commit_state()->layers_that_should_push_properties) {
+      layer->ClearChangedPushPropertiesForTesting();
+    }
+    pending_commit_state()->layers_that_should_push_properties.clear();
+  }
   CommitState* GetPendingCommitState() { return pending_commit_state(); }
   ThreadUnsafeCommitState& GetThreadUnsafeCommitState() {
     return thread_unsafe_commit_state();
@@ -363,6 +370,8 @@
   EXPECT_CALL_MOCK_DELEGATE(*layer_tree_host_, SetNeedsFullTreeSync());
   EXPECT_CALL_MOCK_DELEGATE(*layer_tree_host_, SetNeedsCommit())
       .Times(AtLeast(1));
+
+  layer_tree_host_->ClearPendingLayerCommitStates();
   auto commit_state = layer_tree_host_->WillCommit(/*completion=*/nullptr,
                                                    /*has_updates=*/true);
   EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetMaskLayer(mask_layer1));
@@ -766,8 +775,7 @@
   EXPECT_EQ(child3, parent->children()[2]);
 
   // This is normally done by TreeSynchronizer::PushLayerProperties().
-  layer_tree_host_->GetPendingCommitState()
-      ->layers_that_should_push_properties.clear();
+  layer_tree_host_->ClearPendingLayerCommitStates();
 
   LayerList new_children_order;
   new_children_order.emplace_back(child3);
@@ -1806,8 +1814,7 @@
   test_layer->SetLayerTreeHost(layer_tree_host_.get());
 
   // This is normally done by TreeSynchronizer::PushLayerProperties().
-  layer_tree_host_->GetPendingCommitState()
-      ->layers_that_should_push_properties.clear();
+  layer_tree_host_->ClearPendingLayerCommitStates();
 
   layer_tree_host_->property_trees()->set_needs_rebuild(false);
   EXPECT_EQ(0, test_layer->mirror_count());
@@ -1824,8 +1831,7 @@
                                  ->layers_that_should_push_properties,
                              test_layer.get()));
 
-  layer_tree_host_->GetPendingCommitState()
-      ->layers_that_should_push_properties.clear();
+  layer_tree_host_->ClearPendingLayerCommitStates();
   layer_tree_host_->property_trees()->set_needs_rebuild(false);
 
   // Incrementing mirror count from non-zero should not trigger property trees
@@ -1837,8 +1843,7 @@
                                  ->layers_that_should_push_properties,
                              test_layer.get()));
 
-  layer_tree_host_->GetPendingCommitState()
-      ->layers_that_should_push_properties.clear();
+  layer_tree_host_->ClearPendingLayerCommitStates();
 
   // Decrementing mirror count to non-zero should not trigger property trees
   // rebuild.
diff --git a/cc/layers/mirror_layer.cc b/cc/layers/mirror_layer.cc
index d13edf9..b1fd89b 100644
--- a/cc/layers/mirror_layer.cc
+++ b/cc/layers/mirror_layer.cc
@@ -15,14 +15,17 @@
   return MirrorLayerImpl::Create(tree_impl, id());
 }
 
-void MirrorLayer::PushPropertiesTo(
+void MirrorLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  Layer::PushPropertiesTo(layer, commit_state, unsafe_state);
+  Layer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state, unsafe_state);
 
-  auto* mirror_layer = static_cast<MirrorLayerImpl*>(layer);
-  mirror_layer->SetMirroredLayerId(mirrored_layer_->id());
+  if (dirty_flag & kChangedGeneralProperty) {
+    auto* mirror_layer = static_cast<MirrorLayerImpl*>(layer);
+    mirror_layer->SetMirroredLayerId(mirrored_layer_->id());
+  }
 }
 
 void MirrorLayer::SetLayerTreeHost(LayerTreeHost* host) {
diff --git a/cc/layers/mirror_layer.h b/cc/layers/mirror_layer.h
index 2e56d9e9..e88447f 100644
--- a/cc/layers/mirror_layer.h
+++ b/cc/layers/mirror_layer.h
@@ -26,14 +26,18 @@
   // Layer overrides.
   std::unique_ptr<LayerImpl> CreateLayerImpl(
       LayerTreeImpl* tree_impl) const override;
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
   void SetLayerTreeHost(LayerTreeHost* host) override;
 
  protected:
   explicit MirrorLayer(scoped_refptr<Layer> mirrored_layer);
 
+  // Layer overrides.
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
  private:
   ~MirrorLayer() override;
 
diff --git a/cc/layers/mirror_layer_unittest.cc b/cc/layers/mirror_layer_unittest.cc
index a93f6bd..6db8fae 100644
--- a/cc/layers/mirror_layer_unittest.cc
+++ b/cc/layers/mirror_layer_unittest.cc
@@ -89,6 +89,7 @@
   auto mirrored = Layer::Create();
   mirrored->SetLayerTreeHost(layer_tree_host_.get());
 
+  layer_tree_host_->ClearPendingLayerCommitStates();
   auto commit_state = layer_tree_host_->WillCommit(/*completion_event=*/nullptr,
                                                    /*has_updates=*/true);
   layer_tree_host_->CommitComplete(commit_state->source_frame_number,
diff --git a/cc/layers/nine_patch_layer.cc b/cc/layers/nine_patch_layer.cc
index bc7fbd7..32e8aaf 100644
--- a/cc/layers/nine_patch_layer.cc
+++ b/cc/layers/nine_patch_layer.cc
@@ -56,19 +56,24 @@
   SetNeedsCommit();
 }
 
-void NinePatchLayer::PushPropertiesTo(
+void NinePatchLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  UIResourceLayer::PushPropertiesTo(layer, commit_state, unsafe_state);
-  TRACE_EVENT0("cc", "NinePatchLayer::PushPropertiesTo");
-  NinePatchLayerImpl* layer_impl = static_cast<NinePatchLayerImpl*>(layer);
+  UIResourceLayer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state,
+                                         unsafe_state);
 
-  if (resource_id()) {
-    DCHECK(IsAttached());
-    layer_impl->SetLayout(image_aperture_.Read(*this), border_.Read(*this),
-                          layer_occlusion_.Read(*this),
-                          fill_center_.Read(*this));
+  if (dirty_flag & kChangedGeneralProperty) {
+    TRACE_EVENT0("cc", "NinePatchLayer::PushPropertiesTo");
+    NinePatchLayerImpl* layer_impl = static_cast<NinePatchLayerImpl*>(layer);
+
+    if (resource_id()) {
+      DCHECK(IsAttached());
+      layer_impl->SetLayout(image_aperture_.Read(*this), border_.Read(*this),
+                            layer_occlusion_.Read(*this),
+                            fill_center_.Read(*this));
+    }
   }
 }
 
diff --git a/cc/layers/nine_patch_layer.h b/cc/layers/nine_patch_layer.h
index 8f5dfff..ecbbaf3 100644
--- a/cc/layers/nine_patch_layer.h
+++ b/cc/layers/nine_patch_layer.h
@@ -22,10 +22,6 @@
   NinePatchLayer(const NinePatchLayer&) = delete;
   NinePatchLayer& operator=(const NinePatchLayer&) = delete;
 
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
-
   // |border| is the space around the center rectangular region in layer space
   // (known as aperture in image space).  |border.x()| and |border.y()| are the
   // size of the left and top boundary, respectively.
@@ -53,6 +49,12 @@
   std::unique_ptr<LayerImpl> CreateLayerImpl(
       LayerTreeImpl* tree_impl) const override;
 
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
   ProtectedSequenceReadable<gfx::Rect> border_;
   ProtectedSequenceReadable<bool> fill_center_;
 
diff --git a/cc/layers/nine_patch_thumb_scrollbar_layer.cc b/cc/layers/nine_patch_thumb_scrollbar_layer.cc
index b387111..e9b488b 100644
--- a/cc/layers/nine_patch_thumb_scrollbar_layer.cc
+++ b/cc/layers/nine_patch_thumb_scrollbar_layer.cc
@@ -63,48 +63,52 @@
   return true;
 }
 
-void NinePatchThumbScrollbarLayer::PushPropertiesTo(
+void NinePatchThumbScrollbarLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  ScrollbarLayerBase::PushPropertiesTo(layer, commit_state, unsafe_state);
+  ScrollbarLayerBase::PushDirtyPropertiesTo(layer, dirty_flag, commit_state,
+                                            unsafe_state);
 
-  NinePatchThumbScrollbarLayerImpl* scrollbar_layer =
-      static_cast<NinePatchThumbScrollbarLayerImpl*>(layer);
+  if (dirty_flag & kChangedGeneralProperty) {
+    NinePatchThumbScrollbarLayerImpl* scrollbar_layer =
+        static_cast<NinePatchThumbScrollbarLayerImpl*>(layer);
 
-  if (orientation() == ScrollbarOrientation::kHorizontal) {
-    scrollbar_layer->SetThumbThickness(thumb_size_.Read(*this).height());
-    scrollbar_layer->SetThumbLength(thumb_size_.Read(*this).width());
-    scrollbar_layer->SetTrackStart(track_rect_.Read(*this).x());
-    scrollbar_layer->SetTrackLength(track_rect_.Read(*this).width());
-  } else {
-    scrollbar_layer->SetThumbThickness(thumb_size_.Read(*this).width());
-    scrollbar_layer->SetThumbLength(thumb_size_.Read(*this).height());
-    scrollbar_layer->SetTrackStart(track_rect_.Read(*this).y());
-    scrollbar_layer->SetTrackLength(track_rect_.Read(*this).height());
-  }
+    if (orientation() == ScrollbarOrientation::kHorizontal) {
+      scrollbar_layer->SetThumbThickness(thumb_size_.Read(*this).height());
+      scrollbar_layer->SetThumbLength(thumb_size_.Read(*this).width());
+      scrollbar_layer->SetTrackStart(track_rect_.Read(*this).x());
+      scrollbar_layer->SetTrackLength(track_rect_.Read(*this).width());
+    } else {
+      scrollbar_layer->SetThumbThickness(thumb_size_.Read(*this).width());
+      scrollbar_layer->SetThumbLength(thumb_size_.Read(*this).height());
+      scrollbar_layer->SetTrackStart(track_rect_.Read(*this).y());
+      scrollbar_layer->SetTrackLength(track_rect_.Read(*this).height());
+    }
 
-  if (thumb_resource_.Read(*this)) {
-    auto iter =
-        commit_state.ui_resource_sizes.find(thumb_resource_.Read(*this)->id());
-    gfx::Size image_bounds = (iter == commit_state.ui_resource_sizes.end())
-                                 ? gfx::Size()
-                                 : iter->second;
-    scrollbar_layer->SetImageBounds(image_bounds);
-    scrollbar_layer->SetAperture(aperture_.Read(*this));
-    scrollbar_layer->set_thumb_ui_resource_id(
-        thumb_resource_.Read(*this)->id());
-  } else {
-    scrollbar_layer->SetImageBounds(gfx::Size());
-    scrollbar_layer->SetAperture(gfx::Rect());
-    scrollbar_layer->set_thumb_ui_resource_id(0);
-  }
+    if (thumb_resource_.Read(*this)) {
+      auto iter = commit_state.ui_resource_sizes.find(
+          thumb_resource_.Read(*this)->id());
+      gfx::Size image_bounds = (iter == commit_state.ui_resource_sizes.end())
+                                   ? gfx::Size()
+                                   : iter->second;
+      scrollbar_layer->SetImageBounds(image_bounds);
+      scrollbar_layer->SetAperture(aperture_.Read(*this));
+      scrollbar_layer->set_thumb_ui_resource_id(
+          thumb_resource_.Read(*this)->id());
+    } else {
+      scrollbar_layer->SetImageBounds(gfx::Size());
+      scrollbar_layer->SetAperture(gfx::Rect());
+      scrollbar_layer->set_thumb_ui_resource_id(0);
+    }
 
-  if (track_and_buttons_resource_.Read(*this)) {
-    scrollbar_layer->set_track_and_buttons_ui_resource_id(
-        track_and_buttons_resource_.Read(*this)->id());
-  } else {
-    scrollbar_layer->set_track_and_buttons_ui_resource_id(0);
+    if (track_and_buttons_resource_.Read(*this)) {
+      scrollbar_layer->set_track_and_buttons_ui_resource_id(
+          track_and_buttons_resource_.Read(*this)->id());
+    } else {
+      scrollbar_layer->set_track_and_buttons_ui_resource_id(0);
+    }
   }
 }
 
diff --git a/cc/layers/nine_patch_thumb_scrollbar_layer.h b/cc/layers/nine_patch_thumb_scrollbar_layer.h
index 46d6c088..29dd76c0 100644
--- a/cc/layers/nine_patch_thumb_scrollbar_layer.h
+++ b/cc/layers/nine_patch_thumb_scrollbar_layer.h
@@ -36,9 +36,6 @@
   bool OpacityCanAnimateOnImplThread() const override;
   bool Update() override;
   void SetLayerTreeHost(LayerTreeHost* host) override;
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
 
   ScrollbarLayerType GetScrollbarLayerType() const override;
 
@@ -46,6 +43,12 @@
   explicit NinePatchThumbScrollbarLayer(scoped_refptr<Scrollbar> scrollbar);
   ~NinePatchThumbScrollbarLayer() override;
 
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
  private:
   template <typename T>
   bool UpdateProperty(const T value, T* prop) {
diff --git a/cc/layers/painted_scrollbar_layer.cc b/cc/layers/painted_scrollbar_layer.cc
index f1dc544..6d2b2c5 100644
--- a/cc/layers/painted_scrollbar_layer.cc
+++ b/cc/layers/painted_scrollbar_layer.cc
@@ -60,69 +60,73 @@
   return is_overlay_;
 }
 
-void PaintedScrollbarLayer::PushPropertiesTo(
+void PaintedScrollbarLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  ScrollbarLayerBase::PushPropertiesTo(layer, commit_state, unsafe_state);
+  ScrollbarLayerBase::PushDirtyPropertiesTo(layer, dirty_flag, commit_state,
+                                            unsafe_state);
 
-  PaintedScrollbarLayerImpl* scrollbar_layer =
-      static_cast<PaintedScrollbarLayerImpl*>(layer);
+  if (dirty_flag & kChangedGeneralProperty) {
+    PaintedScrollbarLayerImpl* scrollbar_layer =
+        static_cast<PaintedScrollbarLayerImpl*>(layer);
 
-  scrollbar_layer->set_internal_contents_scale_and_bounds(
-      internal_contents_scale_.Read(*this),
-      internal_content_bounds_.Read(*this));
+    scrollbar_layer->set_internal_contents_scale_and_bounds(
+        internal_contents_scale_.Read(*this),
+        internal_content_bounds_.Read(*this));
 
-  scrollbar_layer->SetJumpOnTrackClick(jump_on_track_click_.Read(*this));
-  scrollbar_layer->SetSupportsDragSnapBack(supports_drag_snap_back_);
-  scrollbar_layer->SetBackButtonRect(back_button_rect_.Read(*this));
-  scrollbar_layer->SetForwardButtonRect(forward_button_rect_.Read(*this));
-  scrollbar_layer->SetTrackRect(track_rect_.Read(*this));
-  if (orientation() == ScrollbarOrientation::kHorizontal) {
-    scrollbar_layer->SetThumbThickness(thumb_size_.Read(*this).height());
-    scrollbar_layer->SetThumbLength(thumb_size_.Read(*this).width());
-  } else {
-    scrollbar_layer->SetThumbThickness(thumb_size_.Read(*this).width());
-    scrollbar_layer->SetThumbLength(thumb_size_.Read(*this).height());
+    scrollbar_layer->SetJumpOnTrackClick(jump_on_track_click_.Read(*this));
+    scrollbar_layer->SetSupportsDragSnapBack(supports_drag_snap_back_);
+    scrollbar_layer->SetBackButtonRect(back_button_rect_.Read(*this));
+    scrollbar_layer->SetForwardButtonRect(forward_button_rect_.Read(*this));
+    scrollbar_layer->SetTrackRect(track_rect_.Read(*this));
+    if (orientation() == ScrollbarOrientation::kHorizontal) {
+      scrollbar_layer->SetThumbThickness(thumb_size_.Read(*this).height());
+      scrollbar_layer->SetThumbLength(thumb_size_.Read(*this).width());
+    } else {
+      scrollbar_layer->SetThumbThickness(thumb_size_.Read(*this).width());
+      scrollbar_layer->SetThumbLength(thumb_size_.Read(*this).height());
+    }
+
+    if (track_and_buttons_resource_.Read(*this)) {
+      scrollbar_layer->set_track_and_buttons_ui_resource_id(
+          track_and_buttons_resource_.Read(*this)->id());
+    } else {
+      scrollbar_layer->set_track_and_buttons_ui_resource_id(0);
+    }
+    if (thumb_resource_.Read(*this)) {
+      scrollbar_layer->set_thumb_ui_resource_id(
+          thumb_resource_.Read(*this)->id());
+    } else {
+      scrollbar_layer->set_thumb_ui_resource_id(0);
+    }
+
+    scrollbar_layer->SetScrollbarPaintedOpacity(painted_opacity_.Read(*this));
+
+    scrollbar_layer->set_is_overlay_scrollbar(is_overlay_);
+    scrollbar_layer->set_is_web_test(is_web_test_);
+
+    if (thumb_color_.Read(*this).has_value()) {
+      scrollbar_layer->SetThumbColor(thumb_color_.Read(*this).value());
+    }
+    if (uses_nine_patch_track_and_buttons_ &&
+        track_and_buttons_resource_.Read(*this)) {
+      const auto iter = commit_state.ui_resource_sizes.find(
+          track_and_buttons_resource_.Read(*this)->id());
+      const gfx::Size image_bounds =
+          (iter == commit_state.ui_resource_sizes.end()) ? gfx::Size()
+                                                         : iter->second;
+      scrollbar_layer->SetTrackAndButtonsImageBounds(image_bounds);
+      scrollbar_layer->SetTrackAndButtonsAperture(
+          track_and_buttons_aperture_.Read(*this));
+    } else {
+      scrollbar_layer->SetTrackAndButtonsImageBounds(gfx::Size());
+      scrollbar_layer->SetTrackAndButtonsAperture(gfx::Rect());
+    }
+    scrollbar_layer->set_uses_nine_patch_track_and_buttons(
+        uses_nine_patch_track_and_buttons_);
   }
-
-  if (track_and_buttons_resource_.Read(*this)) {
-    scrollbar_layer->set_track_and_buttons_ui_resource_id(
-        track_and_buttons_resource_.Read(*this)->id());
-  } else {
-    scrollbar_layer->set_track_and_buttons_ui_resource_id(0);
-  }
-  if (thumb_resource_.Read(*this)) {
-    scrollbar_layer->set_thumb_ui_resource_id(
-        thumb_resource_.Read(*this)->id());
-  } else {
-    scrollbar_layer->set_thumb_ui_resource_id(0);
-  }
-
-  scrollbar_layer->SetScrollbarPaintedOpacity(painted_opacity_.Read(*this));
-
-  scrollbar_layer->set_is_overlay_scrollbar(is_overlay_);
-  scrollbar_layer->set_is_web_test(is_web_test_);
-
-  if (thumb_color_.Read(*this).has_value()) {
-    scrollbar_layer->SetThumbColor(thumb_color_.Read(*this).value());
-  }
-  if (uses_nine_patch_track_and_buttons_ &&
-      track_and_buttons_resource_.Read(*this)) {
-    const auto iter = commit_state.ui_resource_sizes.find(
-        track_and_buttons_resource_.Read(*this)->id());
-    const gfx::Size image_bounds =
-        (iter == commit_state.ui_resource_sizes.end()) ? gfx::Size()
-                                                       : iter->second;
-    scrollbar_layer->SetTrackAndButtonsImageBounds(image_bounds);
-    scrollbar_layer->SetTrackAndButtonsAperture(
-        track_and_buttons_aperture_.Read(*this));
-  } else {
-    scrollbar_layer->SetTrackAndButtonsImageBounds(gfx::Size());
-    scrollbar_layer->SetTrackAndButtonsAperture(gfx::Rect());
-  }
-  scrollbar_layer->set_uses_nine_patch_track_and_buttons(
-      uses_nine_patch_track_and_buttons_);
 }
 
 void PaintedScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
diff --git a/cc/layers/painted_scrollbar_layer.h b/cc/layers/painted_scrollbar_layer.h
index 428ecea..275d297c 100644
--- a/cc/layers/painted_scrollbar_layer.h
+++ b/cc/layers/painted_scrollbar_layer.h
@@ -39,9 +39,6 @@
   bool OpacityCanAnimateOnImplThread() const override;
   bool Update() override;
   void SetLayerTreeHost(LayerTreeHost* host) override;
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
 
   const gfx::Size& internal_content_bounds() const {
     return internal_content_bounds_.Read(*this);
@@ -53,6 +50,12 @@
   explicit PaintedScrollbarLayer(scoped_refptr<Scrollbar> scrollbar);
   ~PaintedScrollbarLayer() override;
 
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
   // For unit tests
   UIResourceId track_and_buttons_resource_id() {
     if (const auto* resource = track_and_buttons_resource_.Read(*this)) {
diff --git a/cc/layers/picture_layer.cc b/cc/layers/picture_layer.cc
index e2ea1328..2eda179 100644
--- a/cc/layers/picture_layer.cc
+++ b/cc/layers/picture_layer.cc
@@ -41,28 +41,34 @@
   return PictureLayerImpl::Create(tree_impl, id());
 }
 
-void PictureLayer::PushPropertiesTo(
+void PictureLayer::PushDirtyPropertiesTo(
     LayerImpl* base_layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
+  Layer::PushDirtyPropertiesTo(base_layer, dirty_flag, commit_state,
+                               unsafe_state);
 
-  if (!update_rect().IsEmpty()) {
-    layer_impl->set_has_non_animated_image_update_rect();
+  if (dirty_flag & kChangedGeneralProperty) {
+    TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
+                 "PictureLayer::PushPropertiesTo");
+    DropRecordingSourceContentIfInvalid(
+        base_layer->layer_tree_impl()->source_frame_number());
+
+    PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer);
+
+    if (!update_rect().IsEmpty()) {
+      layer_impl->set_has_non_animated_image_update_rect();
+    }
+
+    layer_impl->set_gpu_raster_max_texture_size(
+        commit_state.device_viewport_rect.size());
+    layer_impl->SetIsBackdropFilterMask(is_backdrop_filter_mask());
+
+    layer_impl->UpdateRasterSource(CreateRasterSource(),
+                                   &last_updated_invalidation_.Write(*this));
   }
 
-  Layer::PushPropertiesTo(base_layer, commit_state, unsafe_state);
-  TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
-               "PictureLayer::PushPropertiesTo");
-  DropRecordingSourceContentIfInvalid(
-      base_layer->layer_tree_impl()->source_frame_number());
-
-  layer_impl->set_gpu_raster_max_texture_size(
-      commit_state.device_viewport_rect.size());
-  layer_impl->SetIsBackdropFilterMask(is_backdrop_filter_mask());
-
-  layer_impl->UpdateRasterSource(CreateRasterSource(),
-                                 &last_updated_invalidation_.Write(*this));
   DCHECK(last_updated_invalidation_.Read(*this).IsEmpty());
 }
 
diff --git a/cc/layers/picture_layer.h b/cc/layers/picture_layer.h
index ad5f93f..be6dc3a 100644
--- a/cc/layers/picture_layer.h
+++ b/cc/layers/picture_layer.h
@@ -37,9 +37,6 @@
   std::unique_ptr<LayerImpl> CreateLayerImpl(
       LayerTreeImpl* tree_impl) const override;
   void SetLayerTreeHost(LayerTreeHost* host) override;
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
   void SetNeedsDisplayRect(const gfx::Rect& layer_rect) override;
   bool RequiresSetNeedsDisplayOnHdrHeadroomChange() const override;
   sk_sp<const SkPicture> GetPicture() const override;
@@ -64,6 +61,12 @@
   explicit PictureLayer(ContentLayerClient* client);
   ~PictureLayer() override;
 
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
   bool HasDrawableContent() const override;
 
   // Can be overridden in tests to customize RasterSource.
diff --git a/cc/layers/scrollbar_layer_base.cc b/cc/layers/scrollbar_layer_base.cc
index cd5134a..004de16 100644
--- a/cc/layers/scrollbar_layer_base.cc
+++ b/cc/layers/scrollbar_layer_base.cc
@@ -79,19 +79,22 @@
   return true;
 }
 
-void ScrollbarLayerBase::PushPropertiesTo(
+void ScrollbarLayerBase::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  Layer::PushPropertiesTo(layer, commit_state, unsafe_state);
+  Layer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state, unsafe_state);
 
-  auto* scrollbar_layer_impl = static_cast<ScrollbarLayerImplBase*>(layer);
-  DCHECK_EQ(scrollbar_layer_impl->orientation(), orientation_);
-  DCHECK_EQ(scrollbar_layer_impl->is_left_side_vertical_scrollbar(),
-            is_left_side_vertical_scrollbar_);
-  scrollbar_layer_impl->SetHasFindInPageTickmarks(
-      has_find_in_page_tickmarks_.Read(*this));
-  scrollbar_layer_impl->SetScrollElementId(scroll_element_id_.Read(*this));
+  if (dirty_flag & kChangedGeneralProperty) {
+    auto* scrollbar_layer_impl = static_cast<ScrollbarLayerImplBase*>(layer);
+    DCHECK_EQ(scrollbar_layer_impl->orientation(), orientation_);
+    DCHECK_EQ(scrollbar_layer_impl->is_left_side_vertical_scrollbar(),
+              is_left_side_vertical_scrollbar_);
+    scrollbar_layer_impl->SetHasFindInPageTickmarks(
+        has_find_in_page_tickmarks_.Read(*this));
+    scrollbar_layer_impl->SetScrollElementId(scroll_element_id_.Read(*this));
+  }
 }
 
 bool ScrollbarLayerBase::IsScrollbarLayerForTesting() const {
diff --git a/cc/layers/scrollbar_layer_base.h b/cc/layers/scrollbar_layer_base.h
index 899cb7e..584bc69 100644
--- a/cc/layers/scrollbar_layer_base.h
+++ b/cc/layers/scrollbar_layer_base.h
@@ -29,10 +29,6 @@
   }
   bool SetHasFindInPageTickmarks(bool has_find_in_page_tickmarks);
 
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
-
   enum ScrollbarLayerType {
     kSolidColor,
     kPainted,
@@ -45,6 +41,12 @@
                      bool is_left_side_vertical_scrollbar);
   ~ScrollbarLayerBase() override;
 
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
  private:
   bool IsScrollbarLayerForTesting() const final;
 
diff --git a/cc/layers/solid_color_scrollbar_layer.cc b/cc/layers/solid_color_scrollbar_layer.cc
index e8c2f58..e91101d5 100644
--- a/cc/layers/solid_color_scrollbar_layer.cc
+++ b/cc/layers/solid_color_scrollbar_layer.cc
@@ -91,12 +91,17 @@
   return kSolidColor;
 }
 
-void SolidColorScrollbarLayer::PushPropertiesTo(
+void SolidColorScrollbarLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  ScrollbarLayerBase::PushPropertiesTo(layer, commit_state, unsafe_state);
-  static_cast<SolidColorScrollbarLayerImpl*>(layer)->set_color(color());
+  ScrollbarLayerBase::PushDirtyPropertiesTo(layer, dirty_flag, commit_state,
+                                            unsafe_state);
+
+  if (dirty_flag & kChangedGeneralProperty) {
+    static_cast<SolidColorScrollbarLayerImpl*>(layer)->set_color(color());
+  }
 }
 
 void SolidColorScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
diff --git a/cc/layers/solid_color_scrollbar_layer.h b/cc/layers/solid_color_scrollbar_layer.h
index f6c1b48..d084df0 100644
--- a/cc/layers/solid_color_scrollbar_layer.h
+++ b/cc/layers/solid_color_scrollbar_layer.h
@@ -38,9 +38,6 @@
   void SetOpacity(float opacity) override;
   void SetNeedsDisplayRect(const gfx::Rect& rect) override;
   void SetLayerTreeHost(LayerTreeHost* host) override;
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
 
   int thumb_thickness() const { return thumb_thickness_; }
   int track_start() const { return track_start_; }
@@ -50,6 +47,13 @@
 
   ScrollbarLayerType GetScrollbarLayerType() const override;
 
+ protected:
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
  private:
   SolidColorScrollbarLayer(ScrollbarOrientation orientation,
                            int thumb_thickness,
diff --git a/cc/layers/surface_layer.cc b/cc/layers/surface_layer.cc
index 3c98d0b..effd0fff 100644
--- a/cc/layers/surface_layer.cc
+++ b/cc/layers/surface_layer.cc
@@ -187,35 +187,39 @@
     layer_tree_host()->AddSurfaceRange(surface_range_.Read(*this));
 }
 
-void SurfaceLayer::PushPropertiesTo(
+void SurfaceLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  Layer::PushPropertiesTo(layer, commit_state, unsafe_state);
-  TRACE_EVENT0("cc", "SurfaceLayer::PushPropertiesTo");
-  SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
-  layer_impl->SetRange(surface_range_.Read(*this),
-                       std::move(deadline_in_frames_.Write(*this)));
-  // Unless the client explicitly calls SetSurfaceId again after this
-  // commit, don't block on |surface_range_| again.
-  deadline_in_frames_.Write(*this) = 0u;
-  layer_impl->SetIsReflection(is_reflection_.Read(*this));
-  layer_impl->SetOverrideChildPaintFlags(
-      override_child_paint_flags_.Read(*this));
-  layer_impl->SetStretchContentToFillBounds(
-      stretch_content_to_fill_bounds_.Read(*this));
-  layer_impl->SetSurfaceHitTestable(surface_hit_testable_.Read(*this));
-  layer_impl->SetHasPointerEventsNone(has_pointer_events_none_.Read(*this));
-  layer_impl->set_may_contain_video(may_contain_video_.Read(*this));
+  Layer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state, unsafe_state);
 
-  if (callback_layer_tree_host_changed_.Read(*this)) {
-    // Anytime SetLayerTreeHost is called and
-    // `update_submission_state_callback_` is defined, the callback will be used
-    // to reset the visibility state. We must share this information with the
-    // SurfaceLayerImpl since it also tracks visibility state so it can avoid
-    // unnecessary invocations of the callback.
-    layer_impl->ResetStateForUpdateSubmissionStateCallback();
-    callback_layer_tree_host_changed_.Write(*this) = false;
+  if (dirty_flag & kChangedGeneralProperty) {
+    TRACE_EVENT0("cc", "SurfaceLayer::PushPropertiesTo");
+    SurfaceLayerImpl* layer_impl = static_cast<SurfaceLayerImpl*>(layer);
+    layer_impl->SetRange(surface_range_.Read(*this),
+                         std::move(deadline_in_frames_.Write(*this)));
+    // Unless the client explicitly calls SetSurfaceId again after this
+    // commit, don't block on |surface_range_| again.
+    deadline_in_frames_.Write(*this) = 0u;
+    layer_impl->SetIsReflection(is_reflection_.Read(*this));
+    layer_impl->SetOverrideChildPaintFlags(
+        override_child_paint_flags_.Read(*this));
+    layer_impl->SetStretchContentToFillBounds(
+        stretch_content_to_fill_bounds_.Read(*this));
+    layer_impl->SetSurfaceHitTestable(surface_hit_testable_.Read(*this));
+    layer_impl->SetHasPointerEventsNone(has_pointer_events_none_.Read(*this));
+    layer_impl->set_may_contain_video(may_contain_video_.Read(*this));
+
+    if (callback_layer_tree_host_changed_.Read(*this)) {
+      // Anytime SetLayerTreeHost is called and
+      // `update_submission_state_callback_` is defined, the callback will be
+      // used to reset the visibility state. We must share this information with
+      // the SurfaceLayerImpl since it also tracks visibility state so it can
+      // avoid unnecessary invocations of the callback.
+      layer_impl->ResetStateForUpdateSubmissionStateCallback();
+      callback_layer_tree_host_changed_.Write(*this) = false;
+    }
   }
 }
 
diff --git a/cc/layers/surface_layer.h b/cc/layers/surface_layer.h
index a9d82ea..b19abae 100644
--- a/cc/layers/surface_layer.h
+++ b/cc/layers/surface_layer.h
@@ -68,9 +68,6 @@
       LayerTreeImpl* tree_impl) const override;
   bool RequiresSetNeedsDisplayOnHdrHeadroomChange() const override;
   void SetLayerTreeHost(LayerTreeHost* host) override;
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
 
   const viz::SurfaceId& surface_id() const {
     return surface_range_.Read(*this).end();
@@ -89,6 +86,12 @@
   explicit SurfaceLayer(UpdateSubmissionStateCB);
   bool HasDrawableContent() const override;
 
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
  private:
   ~SurfaceLayer() override;
 
diff --git a/cc/layers/texture_layer.cc b/cc/layers/texture_layer.cc
index 73b49f7b..82127f76 100644
--- a/cc/layers/texture_layer.cc
+++ b/cc/layers/texture_layer.cc
@@ -202,47 +202,54 @@
   return true;
 }
 
-void TextureLayer::PushPropertiesTo(
+void TextureLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  Layer::PushPropertiesTo(layer, commit_state, unsafe_state);
-  TRACE_EVENT0("cc", "TextureLayer::PushPropertiesTo");
+  Layer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state, unsafe_state);
 
-  TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer);
-  texture_layer->SetUVTopLeft(uv_top_left_.Read(*this));
-  texture_layer->SetUVBottomRight(uv_bottom_right_.Read(*this));
-  texture_layer->SetPremultipliedAlpha(premultiplied_alpha_.Read(*this));
-  texture_layer->SetBlendBackgroundColor(blend_background_color_.Read(*this));
-  texture_layer->SetForceTextureToOpaque(force_texture_to_opaque_.Read(*this));
-  if (needs_set_resource_.Read(*this)) {
-    viz::TransferableResource resource;
-    viz::ReleaseCallback release_callback;
-    if (auto& resource_holder = resource_holder_.Write(*this)) {
-      resource = resource_holder->resource();
-      release_callback =
-          base::BindOnce(&TransferableResourceHolder::Return, resource_holder,
-                         base::RetainedRef(layer->layer_tree_impl()
-                                               ->task_runner_provider()
-                                               ->MainThreadTaskRunner()));
+  if (dirty_flag & kChangedGeneralProperty) {
+    TRACE_EVENT0("cc", "TextureLayer::PushPropertiesTo");
+
+    TextureLayerImpl* texture_layer = static_cast<TextureLayerImpl*>(layer);
+    texture_layer->SetUVTopLeft(uv_top_left_.Read(*this));
+    texture_layer->SetUVBottomRight(uv_bottom_right_.Read(*this));
+    texture_layer->SetPremultipliedAlpha(premultiplied_alpha_.Read(*this));
+    texture_layer->SetBlendBackgroundColor(blend_background_color_.Read(*this));
+    texture_layer->SetForceTextureToOpaque(
+        force_texture_to_opaque_.Read(*this));
+    if (needs_set_resource_.Read(*this)) {
+      viz::TransferableResource resource;
+      viz::ReleaseCallback release_callback;
+      if (auto& resource_holder = resource_holder_.Write(*this)) {
+        resource = resource_holder->resource();
+        release_callback =
+            base::BindOnce(&TransferableResourceHolder::Return, resource_holder,
+                           base::RetainedRef(layer->layer_tree_impl()
+                                                 ->task_runner_provider()
+                                                 ->MainThreadTaskRunner()));
+      }
+      texture_layer->SetTransferableResource(resource,
+                                             std::move(release_callback));
+      needs_set_resource_.Write(*this) = false;
     }
-    texture_layer->SetTransferableResource(resource,
-                                           std::move(release_callback));
-    needs_set_resource_.Write(*this) = false;
+    auto& to_register_bitmaps = to_register_bitmaps_.Write(*this);
+    for (auto& pair : to_register_bitmaps) {
+      texture_layer->RegisterSharedBitmapId(pair.first, pair.second);
+    }
+    // Store the registered SharedBitmapIds in case we get a new
+    // TextureLayerImpl, in a new tree, to re-send them to.
+    registered_bitmaps_.Write(*this).insert(
+        std::make_move_iterator(to_register_bitmaps.begin()),
+        std::make_move_iterator(to_register_bitmaps.end()));
+    to_register_bitmaps.clear();
+    auto& to_unregister_bitmap_ids = to_unregister_bitmap_ids_.Write(*this);
+    for (const auto& id : to_unregister_bitmap_ids) {
+      texture_layer->UnregisterSharedBitmapId(id);
+    }
+    to_unregister_bitmap_ids.clear();
   }
-  auto& to_register_bitmaps = to_register_bitmaps_.Write(*this);
-  for (auto& pair : to_register_bitmaps)
-    texture_layer->RegisterSharedBitmapId(pair.first, pair.second);
-  // Store the registered SharedBitmapIds in case we get a new TextureLayerImpl,
-  // in a new tree, to re-send them to.
-  registered_bitmaps_.Write(*this).insert(
-      std::make_move_iterator(to_register_bitmaps.begin()),
-      std::make_move_iterator(to_register_bitmaps.end()));
-  to_register_bitmaps.clear();
-  auto& to_unregister_bitmap_ids = to_unregister_bitmap_ids_.Write(*this);
-  for (const auto& id : to_unregister_bitmap_ids)
-    texture_layer->UnregisterSharedBitmapId(id);
-  to_unregister_bitmap_ids.clear();
 }
 
 SharedBitmapIdRegistration TextureLayer::RegisterSharedBitmapId(
diff --git a/cc/layers/texture_layer.h b/cc/layers/texture_layer.h
index 5334bfb..685665c 100644
--- a/cc/layers/texture_layer.h
+++ b/cc/layers/texture_layer.h
@@ -122,9 +122,6 @@
   bool RequiresSetNeedsDisplayOnHdrHeadroomChange() const override;
   bool Update() override;
   bool IsSnappedToPixelGridInTarget() const override;
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
 
   // Request a mapping from SharedBitmapId to SharedMemory be registered via the
   // LayerTreeFrameSink with the display compositor. Once this mapping is
@@ -150,6 +147,11 @@
  protected:
   explicit TextureLayer(TextureLayerClient* client);
   ~TextureLayer() override;
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
   bool HasDrawableContent() const override;
 
  private:
diff --git a/cc/layers/ui_resource_layer.cc b/cc/layers/ui_resource_layer.cc
index 2e0a928..5bdb1aa 100644
--- a/cc/layers/ui_resource_layer.cc
+++ b/cc/layers/ui_resource_layer.cc
@@ -72,23 +72,27 @@
   return resource_id_.Read(*this) && Layer::HasDrawableContent();
 }
 
-void UIResourceLayer::PushPropertiesTo(
+void UIResourceLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  Layer::PushPropertiesTo(layer, commit_state, unsafe_state);
-  TRACE_EVENT0("cc", "UIResourceLayer::PushPropertiesTo");
-  UIResourceLayerImpl* layer_impl = static_cast<UIResourceLayerImpl*>(layer);
+  Layer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state, unsafe_state);
 
-  UIResourceId resource_id = resource_id_.Read(*this);
-  layer_impl->SetUIResourceId(resource_id);
-  if (resource_id) {
-    auto iter = commit_state.ui_resource_sizes.find(resource_id);
-    gfx::Size image_bounds = (iter == commit_state.ui_resource_sizes.end())
-                                 ? gfx::Size()
-                                 : iter->second;
-    layer_impl->SetImageBounds(image_bounds);
-    layer_impl->SetUV(uv_top_left_.Read(*this), uv_bottom_right_.Read(*this));
+  if (dirty_flag & kChangedGeneralProperty) {
+    TRACE_EVENT0("cc", "UIResourceLayer::PushPropertiesTo");
+    UIResourceLayerImpl* layer_impl = static_cast<UIResourceLayerImpl*>(layer);
+
+    UIResourceId resource_id = resource_id_.Read(*this);
+    layer_impl->SetUIResourceId(resource_id);
+    if (resource_id) {
+      auto iter = commit_state.ui_resource_sizes.find(resource_id);
+      gfx::Size image_bounds = (iter == commit_state.ui_resource_sizes.end())
+                                   ? gfx::Size()
+                                   : iter->second;
+      layer_impl->SetImageBounds(image_bounds);
+      layer_impl->SetUV(uv_top_left_.Read(*this), uv_bottom_right_.Read(*this));
+    }
   }
 }
 
diff --git a/cc/layers/ui_resource_layer.h b/cc/layers/ui_resource_layer.h
index adcd6cb..99ffec8f3 100644
--- a/cc/layers/ui_resource_layer.h
+++ b/cc/layers/ui_resource_layer.h
@@ -24,10 +24,6 @@
   UIResourceLayer(const UIResourceLayer&) = delete;
   UIResourceLayer& operator=(const UIResourceLayer&) = delete;
 
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
-
   void SetLayerTreeHost(LayerTreeHost* host) override;
 
   // Sets the resource. If they don't exist already, the shared UI resource and
@@ -49,6 +45,12 @@
   UIResourceLayer();
   ~UIResourceLayer() override;
 
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
   bool HasDrawableContent() const override;
 
   UIResourceId resource_id() const { return resource_id_.Read(*this); }
diff --git a/cc/layers/view_transition_content_layer.cc b/cc/layers/view_transition_content_layer.cc
index 0e9a74bb..01ad47d 100644
--- a/cc/layers/view_transition_content_layer.cc
+++ b/cc/layers/view_transition_content_layer.cc
@@ -48,13 +48,16 @@
   SetNeedsCommit();
 }
 
-void ViewTransitionContentLayer::PushPropertiesTo(
+void ViewTransitionContentLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  Layer::PushPropertiesTo(layer, commit_state, unsafe_state);
-  static_cast<ViewTransitionContentLayerImpl*>(layer)->SetMaxExtentsRect(
-      max_extents_rect_.Read(*this));
+  Layer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state, unsafe_state);
+  if (dirty_flag & kChangedGeneralProperty) {
+    static_cast<ViewTransitionContentLayerImpl*>(layer)->SetMaxExtentsRect(
+        max_extents_rect_.Read(*this));
+  }
 }
 
 }  // namespace cc
diff --git a/cc/layers/view_transition_content_layer.h b/cc/layers/view_transition_content_layer.h
index 311875f..b559e15b 100644
--- a/cc/layers/view_transition_content_layer.h
+++ b/cc/layers/view_transition_content_layer.h
@@ -47,9 +47,11 @@
   explicit ViewTransitionContentLayer(
       const viz::ViewTransitionElementResourceId& resource_id,
       bool is_live_content_layer);
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
 
  private:
   ~ViewTransitionContentLayer() override;
diff --git a/cc/test/fake_layer_tree_host.cc b/cc/test/fake_layer_tree_host.cc
index 67a799a..d9fb85b 100644
--- a/cc/test/fake_layer_tree_host.cc
+++ b/cc/test/fake_layer_tree_host.cc
@@ -32,6 +32,14 @@
   client_->SetLayerTreeHost(this);
 }
 
+void FakeLayerTreeHost::ClearPendingLayerCommitStates() {
+  for (auto layer :
+       pending_commit_state()->layers_that_should_push_properties) {
+    layer->ClearChangedPushPropertiesForTesting();
+  }
+  pending_commit_state()->layers_that_should_push_properties.clear();
+}
+
 std::unique_ptr<FakeLayerTreeHost> FakeLayerTreeHost::Create(
     FakeLayerTreeHostClient* client,
     TestTaskGraphRunner* task_graph_runner,
diff --git a/cc/test/fake_layer_tree_host.h b/cc/test/fake_layer_tree_host.h
index 86aec0f..8931229 100644
--- a/cc/test/fake_layer_tree_host.h
+++ b/cc/test/fake_layer_tree_host.h
@@ -66,6 +66,7 @@
 
   void SetNeedsCommit() override;
   void SetNeedsUpdateLayers() override {}
+  void ClearPendingLayerCommitStates();
 
   std::unique_ptr<LayerTreeHostImpl> CreateLayerTreeHostImplInternal(
       LayerTreeHostImplClient* client,
diff --git a/cc/test/fake_scrollbar_layer.h b/cc/test/fake_scrollbar_layer.h
index 98c37ac..27beeeb 100644
--- a/cc/test/fake_scrollbar_layer.h
+++ b/cc/test/fake_scrollbar_layer.h
@@ -31,13 +31,6 @@
     return updated;
   }
 
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override {
-    BaseLayer::PushPropertiesTo(layer, commit_state, unsafe_state);
-    ++push_properties_count_;
-  }
-
   using BaseLayer::IgnoreSetNeedsCommitForTest;
 
   size_t push_properties_count() const { return push_properties_count_; }
@@ -59,6 +52,16 @@
 
   ~FakeScrollbarLayer() override = default;
 
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override {
+    BaseLayer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state,
+                                     unsafe_state);
+    ++push_properties_count_;
+  }
+
  private:
   int update_count_;
   size_t push_properties_count_;
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc
index a3c1845..fc5a06e 100644
--- a/cc/test/layer_tree_test.cc
+++ b/cc/test/layer_tree_test.cc
@@ -431,7 +431,7 @@
       bool,
       PaintHoldingReason,
       std::optional<PaintHoldingCommitTrigger>) override {}
-  void OnCommitRequested() override {}
+  void OnCommitRequested() override { test_hooks_->OnCommitRequested(); }
 
   void RecordStartOfFrameMetrics() override {}
   void RecordEndOfFrameMetrics(base::TimeTicks,
diff --git a/cc/test/push_properties_counting_layer.cc b/cc/test/push_properties_counting_layer.cc
index 2d390b2..39a50c5 100644
--- a/cc/test/push_properties_counting_layer.cc
+++ b/cc/test/push_properties_counting_layer.cc
@@ -21,11 +21,12 @@
 
 PushPropertiesCountingLayer::~PushPropertiesCountingLayer() = default;
 
-void PushPropertiesCountingLayer::PushPropertiesTo(
+void PushPropertiesCountingLayer::PushDirtyPropertiesTo(
     LayerImpl* layer,
+    uint8_t dirty_flag,
     const CommitState& commit_state,
     const ThreadUnsafeCommitState& unsafe_state) {
-  Layer::PushPropertiesTo(layer, commit_state, unsafe_state);
+  Layer::PushDirtyPropertiesTo(layer, dirty_flag, commit_state, unsafe_state);
   AddPushPropertiesCount();
 }
 
diff --git a/cc/test/push_properties_counting_layer.h b/cc/test/push_properties_counting_layer.h
index 25d56cea..7044d91 100644
--- a/cc/test/push_properties_counting_layer.h
+++ b/cc/test/push_properties_counting_layer.h
@@ -23,10 +23,6 @@
   PushPropertiesCountingLayer& operator=(const PushPropertiesCountingLayer&) =
       delete;
 
-  // Layer implementation.
-  void PushPropertiesTo(LayerImpl* layer,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override;
   std::unique_ptr<LayerImpl> CreateLayerImpl(
       LayerTreeImpl* tree_impl) const override;
 
@@ -36,6 +32,14 @@
   size_t push_properties_count() const { return push_properties_count_; }
   void reset_push_properties_count() { push_properties_count_ = 0; }
 
+ protected:
+  // Layer implementation.
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override;
+
  private:
   PushPropertiesCountingLayer();
   ~PushPropertiesCountingLayer() override;
diff --git a/cc/test/test_hooks.h b/cc/test/test_hooks.h
index 2026a95e..0ad5325e 100644
--- a/cc/test/test_hooks.h
+++ b/cc/test/test_hooks.h
@@ -115,6 +115,7 @@
   virtual void DidInitializeLayerTreeFrameSink() {}
   virtual void DidFailToInitializeLayerTreeFrameSink() {}
   virtual void DidAddAnimation() {}
+  virtual void OnCommitRequested() {}
   virtual void WillCommit(const CommitState&) {}
   virtual void DidCommit() {}
   virtual void DidCommitAndDrawFrame() {}
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc
index 5789f6c..5b08ed55 100644
--- a/cc/trees/layer_tree_host_unittest.cc
+++ b/cc/trees/layer_tree_host_unittest.cc
@@ -10633,7 +10633,7 @@
     layer_id_ = layer_on_main_->id();
   }
 
-  void WillCommit(const CommitState&) override {
+  void OnCommitRequested() override {
     switch (layer_tree_host()->SourceFrameNumber()) {
       case 0:
         // First frame enables LCD text by marking the layer opaque.
@@ -10679,6 +10679,7 @@
                   LCDTextDisallowedReason::kContentsNotOpaque);
         EXPECT_FALSE(layer_impl->HighResTiling()->can_use_lcd_text());
         host_impl->GetInputHandler().PinchGestureEnd(gfx::Point(1, 1));
+        PostSetNeedsCommitToMainThread();
         break;
       case 2:
         ASSERT_FALSE(host_impl->IsPinchGestureActive());
diff --git a/cc/trees/tree_synchronizer_unittest.cc b/cc/trees/tree_synchronizer_unittest.cc
index 6290529c..d865344 100644
--- a/cc/trees/tree_synchronizer_unittest.cc
+++ b/cc/trees/tree_synchronizer_unittest.cc
@@ -80,10 +80,13 @@
     return MockLayerImpl::Create(tree_impl, id());
   }
 
-  void PushPropertiesTo(LayerImpl* layer_impl,
-                        const CommitState& commit_state,
-                        const ThreadUnsafeCommitState& unsafe_state) override {
-    Layer::PushPropertiesTo(layer_impl, commit_state, unsafe_state);
+  void PushDirtyPropertiesTo(
+      LayerImpl* layer_impl,
+      uint8_t dirty_flag,
+      const CommitState& commit_state,
+      const ThreadUnsafeCommitState& unsafe_state) override {
+    Layer::PushDirtyPropertiesTo(layer_impl, dirty_flag, commit_state,
+                                 unsafe_state);
 
     MockLayerImpl* mock_layer_impl = static_cast<MockLayerImpl*>(layer_impl);
     mock_layer_impl->SetLayerImplDestructionList(layer_impl_destruction_list_);
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 3b75cf5f..c9a9ab6 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -372,6 +372,7 @@
   "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/MotionEventFilter.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/MotionEventHandler.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/eventfilter/OverlayPanelEventFilter.java",
+  "java/src/org/chromium/chrome/browser/compositor/layouts/phone/NewTabAnimationLayout.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/phone/NewTabBackgroundAnimationLayout.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/phone/SimpleAnimationLayout.java",
   "java/src/org/chromium/chrome/browser/compositor/layouts/phone/stack/StackScroller.java",
@@ -943,6 +944,7 @@
   "java/src/org/chromium/chrome/browser/provider/ChromeBrowserProviderImpl.java",
   "java/src/org/chromium/chrome/browser/provider/ChromeBrowserProviderSuggestionsCursor.java",
   "java/src/org/chromium/chrome/browser/provider/PageContentProviderImpl.java",
+  "java/src/org/chromium/chrome/browser/provider/PageContentProviderMetrics.java",
   "java/src/org/chromium/chrome/browser/provider/SearchColumns.java",
   "java/src/org/chromium/chrome/browser/push_messaging/PushMessagingServiceObserver.java",
   "java/src/org/chromium/chrome/browser/quick_delete/QuickDeleteDelegateImpl.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni
index db76eaba..87b9776 100644
--- a/chrome/android/chrome_junit_test_java_sources.gni
+++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -1,4 +1,5 @@
 chrome_junit_test_java_sources = [
+  "java/src/org/chromium/chrome/browser/compositor/layouts/phone/NewTabAnimationLayoutUnitTest.java",
   "java/src/org/chromium/chrome/browser/hub/HubLayoutUnitTest.java",
   "java/src/org/chromium/chrome/browser/hub/HubProviderUnitTest.java",
   "java/src/org/chromium/chrome/browser/hub/HubTabSwitcherMetricsRecorderUnitTest.java",
@@ -390,7 +391,6 @@
   "junit/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilUnitTest.java",
   "junit/src/org/chromium/chrome/browser/toolbar/AppThemeColorProviderUnitTest.java",
   "junit/src/org/chromium/chrome/browser/toolbar/LocationBarModelUnitTest.java",
-  "junit/src/org/chromium/chrome/browser/toolbar/ToolbarIphControllerUnitTest.java",
   "junit/src/org/chromium/chrome/browser/toolbar/ToolbarTabControllerImplTest.java",
   "junit/src/org/chromium/chrome/browser/toolbar/adaptive/OptionalNewTabButtonControllerActivityTest.java",
   "junit/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlockerUnitTest.java",
diff --git a/chrome/android/expectations/lint-suppressions.xml b/chrome/android/expectations/lint-suppressions.xml
index b176e86..e6f3ee5 100644
--- a/chrome/android/expectations/lint-suppressions.xml
+++ b/chrome/android/expectations/lint-suppressions.xml
@@ -250,9 +250,6 @@
     <!--TODO(crbug.com/40208161): Remove unused resources when UX is finalized. -->
     <ignore regexp="The resource `R.string.price_tracking_title` appears to be unused"/>
 
-    <!-- Temporarily suppressed until impelmentation is ready, see: https://crbug.com/1330631 -->
-    <ignore regexp="The resource `R.string.price_drop_spotted_iph` appears to be unused"/>
-
     <!-- TODO(crbug.com/40227734): Remove unused resources when UX is finalized. -->
     <ignore regexp="The resource `R.string.search_resumption_module_title_short` appears to be unused"/>
 
diff --git a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryIntegrationTest.java b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryIntegrationTest.java
index 2a01369..153e830 100644
--- a/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryIntegrationTest.java
+++ b/chrome/android/features/keyboard_accessory/javatests/src/org/chromium/chrome/browser/keyboard_accessory/sheet_tabs/AddressAccessoryIntegrationTest.java
@@ -22,6 +22,7 @@
 import static org.chromium.chrome.browser.keyboard_accessory.ManualFillingTestHelper.selectTabWithDescription;
 import static org.chromium.chrome.browser.keyboard_accessory.ManualFillingTestHelper.whenDisplayed;
 
+import android.os.Build;
 import android.widget.TextView;
 
 import androidx.test.filters.MediumTest;
@@ -34,6 +35,7 @@
 
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.Features;
 import org.chromium.chrome.browser.ChromeWindow;
 import org.chromium.chrome.browser.autofill.AutofillTestHelper;
@@ -127,6 +129,11 @@
 
     @Test
     @MediumTest
+    @DisableIf.Build(
+            sdk_is_less_than = Build.VERSION_CODES.TIRAMISU,
+            sdk_is_greater_than = Build.VERSION_CODES.P,
+            supported_abis_includes = "x86_64",
+            message = "crbug.com/40190628")
     public void testFillsSuggestionOnClick() throws TimeoutException {
         loadTestPage(FakeKeyboard::new);
         mHelper.clickNodeAndShowKeyboard("NAME_FIRST", 1);
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
index 605a575..ec40a155 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListCoordinator.java
@@ -664,10 +664,6 @@
         mMediator.softCleanup();
     }
 
-    void hardCleanup() {
-        mMediator.hardCleanup();
-    }
-
     private void registerLayoutChangeListener() {
         if (mListLayoutListener != null) {
             // TODO(crbug.com/40288028): There might be a timing or race condition that
@@ -692,7 +688,6 @@
     void prepareTabSwitcherPaneView() {
         registerLayoutChangeListener();
         mRecyclerView.setupCustomItemAnimator();
-        mMediator.registerOnScrolledListener(mRecyclerView);
     }
 
     private void initializeEmptyStateView() {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
index 256fd49..589209c2 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -40,8 +40,6 @@
 import androidx.annotation.VisibleForTesting;
 import androidx.recyclerview.widget.GridLayoutManager;
 import androidx.recyclerview.widget.ItemTouchHelper;
-import androidx.recyclerview.widget.RecyclerView;
-import androidx.recyclerview.widget.RecyclerView.OnScrollListener;
 
 import org.chromium.base.Callback;
 import org.chromium.base.CollectionUtil;
@@ -333,7 +331,6 @@
 
     private static final String TAG = "TabListMediator";
     private static Map<Integer, Integer> sTabClosedFromMapTabClosedFromMap = new HashMap<>();
-    private static Set<Integer> sViewedTabIds = new HashSet<>();
 
     private final ValueChangedCallback<TabGroupModelFilter> mOnTabGroupModelFilterChanged =
             new ValueChangedCallback<>(this::onTabGroupModelFilterChanged);
@@ -370,10 +367,6 @@
     private Size mDefaultGridCardSize;
     private ComponentCallbacks mComponentCallbacks;
     private GridLayoutManager mGridLayoutManager;
-    // mRecyclerView and mOnScrollListener are null, unless the the price drop IPH or badge is
-    // enabled.
-    private @Nullable RecyclerView mRecyclerView;
-    private @Nullable OnScrollListener mOnScrollListener;
     // Set to true after a `resetWithListOfTabs` that used a non-null list of tabs. Remains true
     // until `postHiding` is invoked or the mediator is destroyed. While true, this mediator is
     // actively tracking updates to a TabModel.
@@ -1456,23 +1449,9 @@
         return false;
     }
 
-    /**
-     * Add the tab id of a {@Tab} that has been viewed to the sViewedTabIds set.
-     *
-     * @param tabIndex The tab index of a {@Tab} the user has viewed.
-     */
-    private void addViewedTabId(int tabIndex) {
-        TabModel tabModel = mCurrentTabGroupModelFilterSupplier.get().getTabModel();
-        assert !tabModel.isIncognito();
-        int tabId = mModelList.get(tabIndex).model.get(TabProperties.TAB_ID);
-        assert tabModel.getTabById(tabId) != null;
-        sViewedTabIds.add(tabId);
-    }
-
     void postHiding() {
         removeObservers(mCurrentTabGroupModelFilterSupplier.get());
         mShowingTabs = false;
-        unregisterOnScrolledListener();
         // if tab was marked for add later, add to model and mark as selected.
         if (mTabToAddDelayed != null) {
             int index = onTabAdded(mTabToAddDelayed, !mActionsOnAllRelatedTabs);
@@ -1504,11 +1483,6 @@
         }
     }
 
-    void hardCleanup() {
-        assert !mShowingTabs;
-        sViewedTabIds.clear();
-    }
-
     private void updateTab(int index, Tab tab, boolean isUpdatingId, boolean quickMode) {
         if (index < 0 || index >= mModelList.size()) return;
 
@@ -1566,10 +1540,6 @@
         return filter.isTabInTabGroup(tab);
     }
 
-    public Set<Integer> getViewedTabIdsForTesting() {
-        return sViewedTabIds;
-    }
-
     /**
      * @return The callback that hosts the logic for swipe and drag related actions.
      */
@@ -1634,52 +1604,6 @@
     }
 
     /**
-     * Adds an on scroll listener to {@link TabListRecyclerView} that determines whether a tab
-     * thumbnail is within view after a scroll is completed.
-     *
-     * @param recyclerView the {@link TabListRecyclerView} to add the listener too.
-     */
-    void registerOnScrolledListener(RecyclerView recyclerView) {
-        // For InstantStart, this can be called before native is initialized, so ensure the Profile
-        // is available before proceeding.
-        if (mOriginalProfile == null) return;
-
-        if (!mCurrentTabGroupModelFilterSupplier.get().isIncognitoBranded()
-                && PriceTrackingUtilities.isTrackPricesOnTabsEnabled(mOriginalProfile)
-                && (PriceTrackingFeatures.isPriceDropIphEnabled(mOriginalProfile)
-                        || PriceTrackingFeatures.isPriceDropBadgeEnabled(mOriginalProfile))) {
-            mRecyclerView = recyclerView;
-            mOnScrollListener =
-                    new OnScrollListener() {
-                        @Override
-                        public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
-                            if (!mCurrentTabGroupModelFilterSupplier
-                                    .get()
-                                    .getTabModel()
-                                    .isIncognito()) {
-                                for (int i = 0; i < mRecyclerView.getChildCount(); i++) {
-                                    if (mRecyclerView
-                                            .getLayoutManager()
-                                            .isViewPartiallyVisible(
-                                                    mRecyclerView.getChildAt(i), false, true)) {
-                                        addViewedTabId(i);
-                                    }
-                                }
-                            }
-                        }
-                    };
-            mRecyclerView.addOnScrollListener(mOnScrollListener);
-        }
-    }
-
-    private void unregisterOnScrolledListener() {
-        if (mRecyclerView != null && mOnScrollListener != null) {
-            mRecyclerView.removeOnScrollListener(mOnScrollListener);
-            mOnScrollListener = null;
-        }
-    }
-
-    /**
      * Span count is computed based on screen width for tablets and orientation for phones. When in
      * multi-window mode on phone, the span count is fixed to 2 to keep tab card size reasonable.
      */
@@ -1744,7 +1668,6 @@
         if (mComponentCallbacks != null) {
             mActivity.unregisterComponentCallbacks(mComponentCallbacks);
         }
-        unregisterOnScrolledListener();
     }
 
     void setTabActionState(@TabActionState int tabActionState) {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneCoordinator.java
index f2a6efc..9cd1af22 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneCoordinator.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherPaneCoordinator.java
@@ -461,7 +461,6 @@
 
     /** Performs hard cleanup which saves price drop information. */
     public void hardCleanup() {
-        mTabListCoordinator.hardCleanup();
         // TODO(crbug.com/40946413): The pre-fork implementation resets the tab list, this seems
         // suboptimal. Consider not doing this.
         resetWithTabList(null);
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
index 7c94139b..6c5041db 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
@@ -1198,6 +1198,10 @@
     @Test
     @MediumTest
     @EnableFeatures({TAB_GROUP_SYNC_ANDROID, TAB_GROUP_PANE_ANDROID})
+    @DisableIf.Build(
+            sdk_is_less_than = Build.VERSION_CODES.TIRAMISU,
+            supported_abis_includes = "x86_64",
+            message = "crbug.com/40122331")
     public void testSwipeToDismiss_Dialog() {
         ChromeTabbedActivity cta = sActivityTestRule.getActivity();
         // Create 2 tabs and merge them into one group.
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMultiWindowTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMultiWindowTest.java
index 7424e9c..b8833dc 100644
--- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMultiWindowTest.java
+++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMultiWindowTest.java
@@ -56,7 +56,7 @@
     ChromeSwitches.DISABLE_TAB_MERGING_FOR_TESTING
 })
 @Restriction({DeviceFormFactor.PHONE, RESTRICTION_TYPE_NON_LOW_END_DEVICE})
-@DisableIf.Build(sdk_is_greater_than = VERSION_CODES.S_V2) // https://crbug.com/1297370
+@DisableIf.Build(sdk_is_greater_than = VERSION_CODES.R) // https://crbug.com/1297370
 // TODO(crbug.com/344669867): Failing when batched, batch this again.
 public class TabSwitcherMultiWindowTest {
     @ClassRule
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
index cfa4b9c..dba413c 100644
--- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
+++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -188,7 +188,6 @@
 import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
 import java.util.stream.Collectors;
 
 /** Tests for {@link TabListMediator}. */
@@ -3927,31 +3926,6 @@
     }
 
     @Test
-    public void testPriceDropSeen() throws TimeoutException {
-        setPriceTrackingEnabledForTesting(true);
-        PriceTrackingFeatures.setIsSignedInAndSyncEnabledForTesting(true);
-        PriceTrackingUtilities.SHARED_PREFERENCES_MANAGER.writeBoolean(
-                PriceTrackingUtilities.TRACK_PRICES_ON_TABS, true);
-
-        doReturn(false).when(mTab1).isIncognito();
-        doReturn(false).when(mTab2).isIncognito();
-
-        List<Tab> tabs = new ArrayList<>();
-        tabs.add(mTabModel.getTabAt(0));
-        tabs.add(mTabModel.getTabAt(1));
-
-        mMediator.resetWithListOfTabs(tabs, /* quickMode= */ false);
-
-        prepareRecyclerViewForScroll();
-        mMediator.registerOnScrolledListener(mRecyclerView);
-        verify(mRecyclerView).addOnScrollListener(mOnScrollListenerCaptor.capture());
-        mOnScrollListenerCaptor
-                .getValue()
-                .onScrolled(mRecyclerView, /* dx= */ mTabModel.getCount(), /* dy= */ 0);
-        assertEquals(2, mMediator.getViewedTabIdsForTesting().size());
-    }
-
-    @Test
     public void testSelectableUpdates_withoutRelated() {
         when(mSelectionDelegate.isItemSelected(TAB1_ID)).thenReturn(true);
         when(mSelectionDelegate.isItemSelected(TAB2_ID)).thenReturn(false);
@@ -4978,16 +4952,6 @@
         doReturn(mPriceDrop).when(mShoppingPersistedTabData).getPriceDrop();
     }
 
-    private void prepareRecyclerViewForScroll() {
-        View seenView = mock(View.class);
-        for (int i = 0; i < mTabModel.getCount(); i++) {
-            when(mRecyclerView.getChildAt(i)).thenReturn(seenView);
-        }
-
-        doReturn(true).when(mGridLayoutManager).isViewPartiallyVisible(seenView, false, true);
-        doReturn(mTabModel.getCount()).when(mRecyclerView).getChildCount();
-    }
-
     private ThumbnailProvider getTabThumbnailCallback() {
         return new TabContentManagerThumbnailProvider(mTabContentManager);
     }
@@ -4995,10 +4959,6 @@
     private static void setPriceTrackingEnabledForTesting(boolean value) {
         FeatureList.TestValues testValues = new FeatureList.TestValues();
         testValues.addFeatureFlagOverride(ChromeFeatureList.PRICE_ANNOTATIONS, true);
-        testValues.addFieldTrialParamOverride(
-                ChromeFeatureList.PRICE_ANNOTATIONS,
-                PriceTrackingFeatures.PRICE_DROP_IPH_ENABLED_PARAM,
-                String.valueOf(value));
         FeatureList.mergeTestValues(testValues, /* replace= */ true);
 
         PriceTrackingFeatures.setPriceAnnotationsEnabledForTesting(value);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
index 46200fd..27e3504 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -142,6 +142,7 @@
 import org.chromium.chrome.browser.profiles.ProfileManager;
 import org.chromium.chrome.browser.profiles.ProfileProvider;
 import org.chromium.chrome.browser.provider.PageContentProviderImpl;
+import org.chromium.chrome.browser.provider.PageContentProviderMetrics;
 import org.chromium.chrome.browser.readaloud.ReadAloudController;
 import org.chromium.chrome.browser.selection.SelectionPopupBackPressHandler;
 import org.chromium.chrome.browser.settings.SettingsNavigationFactory;
@@ -1479,6 +1480,7 @@
         // No information is provided in incognito mode and overview mode.
         if (tab != null && !tab.isIncognito() && !isInOverviewMode()) {
             outContent.setWebUri(Uri.parse(tab.getUrl().getSpec()));
+            PageContentProviderMetrics.recordUrlAttachedToAssistContent(true);
 
             if (ChromeFeatureList.isEnabled(ChromeFeatureList.ANDROID_PDF_ASSIST_CONTENT)
                     && tab.getNativePage() instanceof PdfPage pdfPage) {
@@ -1488,6 +1490,8 @@
                         "Android.Pdf.AssistContent.IsEnterpriseInfoCached", state != null);
                 if (state == null) return;
                 String structuredData = pdfPage.requestAssistContent(state.mProfileOwned);
+                PageContentProviderMetrics.recordPdfStructuredDataAttachedToAssistContent(
+                        structuredData != null);
                 if (structuredData != null) {
                     outContent.setStructuredData(structuredData);
                 }
@@ -1496,10 +1500,14 @@
                 String pageContentStructuredData =
                         PageContentProviderImpl.getAssistContentStructuredDataForUrl(
                                 tab.getUrl().getSpec(), getActivityTabProvider());
+                PageContentProviderMetrics.recordWebStructuredDataAttachedToAssistContent(
+                        pageContentStructuredData != null);
                 if (pageContentStructuredData != null) {
                     outContent.setStructuredData(pageContentStructuredData);
                 }
             }
+        } else {
+            PageContentProviderMetrics.recordUrlAttachedToAssistContent(false);
         }
     }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java
index 77d1f791f..20f3d50 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerChromePhone.java
@@ -9,7 +9,9 @@
 
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.base.supplier.Supplier;
+import org.chromium.chrome.browser.compositor.layouts.phone.NewTabAnimationLayout;
 import org.chromium.chrome.browser.compositor.layouts.phone.SimpleAnimationLayout;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.hub.HubLayoutDependencyHolder;
 import org.chromium.chrome.browser.layouts.LayoutType;
 import org.chromium.chrome.browser.tab.Tab;
@@ -26,8 +28,9 @@
  * phone.
  */
 public class LayoutManagerChromePhone extends LayoutManagerChrome {
-    // Layouts
-    private SimpleAnimationLayout mSimpleAnimationLayout;
+    // TODO(crbug.com/40282469): Rename SimpleAnimationLayout to NewTabAnimationLayout once it is
+    // rolled out.
+    private Layout mSimpleAnimationLayout;
 
     /**
      * Creates an instance of a {@link LayoutManagerChromePhone}.
@@ -61,6 +64,12 @@
     }
 
     @Override
+    public void destroy() {
+        super.destroy();
+        mSimpleAnimationLayout.destroy();
+    }
+
+    @Override
     public void init(
             TabModelSelector selector,
             TabCreatorManager creator,
@@ -71,9 +80,15 @@
         Context context = mHost.getContext();
         LayoutRenderHost renderHost = mHost.getLayoutRenderHost();
 
-        // Build Layouts
-        mSimpleAnimationLayout =
-                new SimpleAnimationLayout(context, this, renderHost, getContentContainer());
+        if (ChromeFeatureList.sShowNewTabAnimations.isEnabled()) {
+            // TODO(crbug.com/40282469): Change from getContentContainer() as it is z-indexed behind
+            // the NTP.
+            mSimpleAnimationLayout =
+                    new NewTabAnimationLayout(context, this, renderHost, getContentContainer());
+        } else {
+            mSimpleAnimationLayout =
+                    new SimpleAnimationLayout(context, this, renderHost, getContentContainer());
+        }
 
         super.init(
                 selector,
@@ -120,7 +135,7 @@
                 && overlaysHandleTabCreating()
                 && getActiveLayout().handlesTabCreating()) {
             // If the current layout in the foreground, let it handle the tab creation animation.
-            // This check allows us to switch from the StackLayout to the SimpleAnimationLayout
+            // This check allows us to switch from the HubLayout to the SimpleAnimationLayout
             // smoothly.
             getActiveLayout().onTabCreating(sourceId);
         } else if (animationsEnabled()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/NewTabAnimationLayout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/NewTabAnimationLayout.java
new file mode 100644
index 0000000..4609d74a
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/NewTabAnimationLayout.java
@@ -0,0 +1,270 @@
+// 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.
+
+package org.chromium.chrome.browser.compositor.layouts.phone;
+
+import android.content.Context;
+import android.graphics.RectF;
+import android.os.Build;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.Nullable;
+
+import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider;
+import org.chromium.chrome.browser.compositor.layouts.Layout;
+import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost;
+import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
+import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.BlackHoleEventFilter;
+import org.chromium.chrome.browser.compositor.scene_layer.StaticTabSceneLayer;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.layouts.EventFilter;
+import org.chromium.chrome.browser.layouts.LayoutType;
+import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabLaunchType;
+import org.chromium.chrome.browser.tab.TabSelectionType;
+import org.chromium.chrome.browser.tab_ui.TabContentManager;
+import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelUtils;
+import org.chromium.components.sensitive_content.SensitiveContentClient;
+import org.chromium.components.sensitive_content.SensitiveContentFeatures;
+import org.chromium.ui.resources.ResourceManager;
+
+import java.util.Collections;
+
+/**
+ * Layout for showing animations when new tabs are created. This is a drop-in replacement for the
+ * {@link SimpleAnimationLayout} that uses Android animators rather than compositor animations and
+ * uses modern UX designs.
+ */
+public class NewTabAnimationLayout extends Layout {
+    private final ViewGroup mAnimationHostView;
+    private final BlackHoleEventFilter mBlackHoleEventFilter;
+
+    private @Nullable StaticTabSceneLayer mSceneLayer;
+    private int mNextTabId = Tab.INVALID_TAB_ID;
+
+    /**
+     * Creates an instance of the {@link NewTabAnimationLayout}.
+     *
+     * @param context The current Android's context.
+     * @param updateHost The {@link LayoutUpdateHost} view for this layout.
+     * @param renderHost The {@link LayoutRenderHost} view for this layout.
+     * @param animationHostView The host view to use for animations and content sensitivity.
+     */
+    public NewTabAnimationLayout(
+            Context context,
+            LayoutUpdateHost updateHost,
+            LayoutRenderHost renderHost,
+            ViewGroup animationHostView) {
+        super(context, updateHost, renderHost);
+        mAnimationHostView = animationHostView;
+        mBlackHoleEventFilter = new BlackHoleEventFilter(context);
+    }
+
+    @Override
+    public void onFinishNativeInitialization() {
+        ensureSceneLayerExists();
+    }
+
+    @Override
+    public void destroy() {
+        if (mSceneLayer != null) {
+            mSceneLayer.destroy();
+            mSceneLayer = null;
+        }
+    }
+
+    @Override
+    public void setTabContentManager(TabContentManager tabContentManager) {
+        super.setTabContentManager(tabContentManager);
+        if (mSceneLayer != null && tabContentManager != null) {
+            mSceneLayer.setTabContentManager(tabContentManager);
+        }
+    }
+
+    @Override
+    public @ViewportMode int getViewportMode() {
+        return ViewportMode.USE_PREVIOUS_BROWSER_CONTROLS_STATE;
+    }
+
+    @Override
+    public boolean handlesTabCreating() {
+        return true;
+    }
+
+    @Override
+    public boolean handlesTabClosing() {
+        return false;
+    }
+
+    @Override
+    protected EventFilter getEventFilter() {
+        return mBlackHoleEventFilter;
+    }
+
+    @Override
+    public SceneLayer getSceneLayer() {
+        return mSceneLayer;
+    }
+
+    @Override
+    public int getLayoutType() {
+        return LayoutType.SIMPLE_ANIMATION;
+    }
+
+    @Override
+    public void show(long time, boolean animate) {
+        super.show(time, animate);
+
+        mNextTabId = Tab.INVALID_TAB_ID;
+        reset();
+
+        if (mTabModelSelector == null || mTabContentManager == null) return;
+
+        @Nullable Tab tab = mTabModelSelector.getCurrentTab();
+        if (tab != null && tab.isNativePage()) {
+            mTabContentManager.cacheTabThumbnail(tab);
+        }
+    }
+
+    @Override
+    public void doneHiding() {
+        TabModelUtils.selectTabById(mTabModelSelector, mNextTabId, TabSelectionType.FROM_USER);
+        super.doneHiding();
+        updateAnimationHostViewSensitivity(Tab.INVALID_TAB_ID);
+    }
+
+    @Override
+    protected void forceAnimationToFinish() {
+        // TODO(crbug.com/40282469): Implement this.
+    }
+
+    @Override
+    public void onTabCreating(int sourceTabId) {
+        reset();
+
+        ensureSourceTabCreated(sourceTabId);
+        updateAnimationHostViewSensitivity(sourceTabId);
+    }
+
+    @Override
+    public void onTabCreated(
+            long time,
+            int id,
+            int index,
+            int sourceId,
+            boolean newIsIncognito,
+            boolean background,
+            float originX,
+            float originY) {
+        assert mTabModelSelector != null;
+        Tab newTab = mTabModelSelector.getModel(newIsIncognito).getTabById(id);
+        if (newTab != null
+                && newTab.getLaunchType() == TabLaunchType.FROM_COLLABORATION_BACKGROUND_IN_GROUP) {
+            return;
+        }
+
+        ensureSourceTabCreated(sourceId);
+        updateAnimationHostViewSensitivity(sourceId);
+
+        // TODO(crbug.com/40282469): Implement this.
+        // if (background) {
+        // } else {
+        // }
+    }
+
+    @Override
+    protected void updateLayout(long time, long dt) {
+        ensureSceneLayerExists();
+        if (!hasLayoutTab()) return;
+
+        boolean needUpdate = updateSnap(dt, getLayoutTab());
+        if (needUpdate) requestUpdate();
+    }
+
+    @Override
+    protected void updateSceneLayer(
+            RectF viewport,
+            RectF contentViewport,
+            TabContentManager tabContentManager,
+            ResourceManager resourceManager,
+            BrowserControlsStateProvider browserControls) {
+        ensureSceneLayerExists();
+
+        LayoutTab layoutTab = getLayoutTab();
+        layoutTab.set(LayoutTab.IS_ACTIVE_LAYOUT_SUPPLIER, this::isActive);
+        layoutTab.set(LayoutTab.CONTENT_OFFSET, browserControls.getContentOffset());
+        mSceneLayer.update(layoutTab);
+    }
+
+    private void reset() {
+        mLayoutTabs = null;
+    }
+
+    private boolean hasLayoutTab() {
+        return mLayoutTabs != null && mLayoutTabs.length > 0;
+    }
+
+    private LayoutTab getLayoutTab() {
+        assert hasLayoutTab();
+        return mLayoutTabs[0];
+    }
+
+    private void ensureSceneLayerExists() {
+        if (mSceneLayer != null) return;
+
+        mSceneLayer = new StaticTabSceneLayer();
+        if (mTabContentManager == null) return;
+
+        mSceneLayer.setTabContentManager(mTabContentManager);
+    }
+
+    private void ensureSourceTabCreated(int sourceTabId) {
+        if (hasLayoutTab() && mLayoutTabs[0].getId() == sourceTabId) return;
+
+        @Nullable Tab tab = mTabModelSelector.getTabById(sourceTabId);
+        if (tab == null) return;
+        LayoutTab sourceLayoutTab = createLayoutTab(sourceTabId, tab.isIncognitoBranded());
+
+        mLayoutTabs = new LayoutTab[] {sourceLayoutTab};
+        updateCacheVisibleIds(Collections.singletonList(sourceTabId));
+    }
+
+    private void updateAnimationHostViewSensitivity(int sourceTabId) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.VANILLA_ICE_CREAM
+                || !ChromeFeatureList.isEnabled(SensitiveContentFeatures.SENSITIVE_CONTENT)
+                || !ChromeFeatureList.isEnabled(
+                        SensitiveContentFeatures.SENSITIVE_CONTENT_WHILE_SWITCHING_TABS)) {
+            return;
+        }
+
+        if (sourceTabId != TabModel.INVALID_TAB_INDEX) {
+            // This code can be reached from both {@link SimpleAnimationLayout.onTabCreating}
+            // and {@link SimpleAnimationLayout.onTabCreated}. If the content container is
+            // already sensitive, there is no need to mark it as sensitive again.
+            if (mAnimationHostView.getContentSensitivity() == View.CONTENT_SENSITIVITY_SENSITIVE) {
+                return;
+            }
+            @Nullable Tab tab = mTabModelSelector.getTabById(sourceTabId);
+            if (tab == null || !tab.getTabHasSensitiveContent()) {
+                return;
+            }
+            mAnimationHostView.setContentSensitivity(View.CONTENT_SENSITIVITY_SENSITIVE);
+            RecordHistogram.recordEnumeratedHistogram(
+                    "SensitiveContent.SensitiveTabSwitchingAnimations",
+                    SensitiveContentClient.TabSwitchingAnimation.NEW_TAB_IN_BACKGROUND,
+                    SensitiveContentClient.TabSwitchingAnimation.COUNT);
+        } else {
+            mAnimationHostView.setContentSensitivity(View.CONTENT_SENSITIVITY_NOT_SENSITIVE);
+        }
+    }
+
+    protected void setNextTabIdForTesting(int nextTabId) {
+        mNextTabId = nextTabId;
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/NewTabAnimationLayoutUnitTest.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/NewTabAnimationLayoutUnitTest.java
new file mode 100644
index 0000000..4d7468b1
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/phone/NewTabAnimationLayoutUnitTest.java
@@ -0,0 +1,225 @@
+// 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.
+
+package org.chromium.chrome.browser.compositor.layouts.phone;
+
+import static org.hamcrest.Matchers.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import static org.chromium.ui.test.util.MockitoHelper.doCallback;
+
+import android.app.Activity;
+import android.view.View;
+import android.widget.FrameLayout;
+
+import androidx.test.ext.junit.rules.ActivityScenarioRule;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+import org.robolectric.annotation.Config;
+
+import org.chromium.base.test.BaseRobolectricTestRunner;
+import org.chromium.base.test.util.Features.EnableFeatures;
+import org.chromium.chrome.browser.compositor.layouts.Layout.ViewportMode;
+import org.chromium.chrome.browser.compositor.layouts.LayoutRenderHost;
+import org.chromium.chrome.browser.compositor.layouts.LayoutUpdateHost;
+import org.chromium.chrome.browser.compositor.layouts.components.LayoutTab;
+import org.chromium.chrome.browser.compositor.layouts.eventfilter.BlackHoleEventFilter;
+import org.chromium.chrome.browser.compositor.scene_layer.StaticTabSceneLayer;
+import org.chromium.chrome.browser.compositor.scene_layer.StaticTabSceneLayerJni;
+import org.chromium.chrome.browser.flags.ChromeFeatureList;
+import org.chromium.chrome.browser.layouts.LayoutType;
+import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer;
+import org.chromium.chrome.browser.layouts.scene_layer.SceneLayerJni;
+import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.tab.TabSelectionType;
+import org.chromium.chrome.browser.tab_ui.TabContentManager;
+import org.chromium.chrome.browser.tabmodel.TabModel;
+import org.chromium.chrome.browser.tabmodel.TabModelSelector;
+import org.chromium.ui.base.TestActivity;
+
+/** Unit tests for {@link NewTabAnimationLayout}. */
+@RunWith(BaseRobolectricTestRunner.class)
+@Config(sdk = 35)
+@EnableFeatures({
+    ChromeFeatureList.SENSITIVE_CONTENT,
+    ChromeFeatureList.SENSITIVE_CONTENT_WHILE_SWITCHING_TABS
+})
+public class NewTabAnimationLayoutUnitTest {
+    private static final long FAKE_TIME = 0;
+    private static final int CURRENT_TAB_ID = 321;
+    private static final int NEW_TAB_ID = 123;
+    private static final long FAKE_NATIVE_ADDRESS_1 = 498723734L;
+    private static final long FAKE_NATIVE_ADDRESS_2 = 123210L;
+
+    @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+    @Rule
+    public ActivityScenarioRule<TestActivity> mActivityScenarioRule =
+            new ActivityScenarioRule<>(TestActivity.class);
+
+    @Mock private SceneLayer.Natives mSceneLayerJni;
+    @Mock private StaticTabSceneLayer.Natives mStaticTabSceneLayerJni;
+    @Mock private LayoutUpdateHost mUpdateHost;
+    @Mock private LayoutRenderHost mRenderHost;
+    @Mock private TabContentManager mTabContentManager;
+    @Mock private TabModelSelector mTabModelSelector;
+    @Mock private TabModel mTabModel;
+    @Mock private Tab mCurrentTab;
+    @Mock private Tab mNewTab;
+    @Mock private LayoutTab mLayoutTab;
+
+    private NewTabAnimationLayout mNewTabAnimationLayout;
+    private FrameLayout mAnimationHostView;
+
+    @Before
+    public void setUp() {
+        SceneLayerJni.setInstanceForTesting(mSceneLayerJni);
+        StaticTabSceneLayerJni.setInstanceForTesting(mStaticTabSceneLayerJni);
+        when(mSceneLayerJni.init(any()))
+                .thenReturn(FAKE_NATIVE_ADDRESS_1)
+                .thenReturn(FAKE_NATIVE_ADDRESS_2);
+        doCallback(
+                        /* index= */ 1,
+                        (SceneLayer sceneLayer) -> {
+                            sceneLayer.setNativePtr(0L);
+                        })
+                .when(mSceneLayerJni)
+                .destroy(anyLong(), any());
+        doAnswer(
+                        invocation -> {
+                            ((SceneLayer) invocation.getArguments()[0])
+                                    .setNativePtr(FAKE_NATIVE_ADDRESS_1);
+                            return FAKE_NATIVE_ADDRESS_1;
+                        })
+                .when(mStaticTabSceneLayerJni)
+                .init(any());
+
+        when(mTabModelSelector.getModelForTabId(anyInt())).thenReturn(mTabModel);
+        when(mTabModelSelector.getModel(false)).thenReturn(mTabModel);
+        when(mTabModelSelector.getTabById(CURRENT_TAB_ID)).thenReturn(mCurrentTab);
+        when(mTabModelSelector.getTabById(NEW_TAB_ID)).thenReturn(mNewTab);
+        when(mTabModel.getCount()).thenReturn(2);
+        when(mTabModel.getTabAt(0)).thenReturn(mCurrentTab);
+        when(mTabModel.getTabAt(1)).thenReturn(mNewTab);
+        when(mTabModel.getTabById(CURRENT_TAB_ID)).thenReturn(mCurrentTab);
+        when(mTabModel.getTabById(NEW_TAB_ID)).thenReturn(mNewTab);
+        when(mCurrentTab.getId()).thenReturn(CURRENT_TAB_ID);
+        when(mNewTab.getId()).thenReturn(NEW_TAB_ID);
+
+        when(mLayoutTab.isInitFromHostNeeded()).thenReturn(true);
+        when(mUpdateHost.createLayoutTab(anyInt(), anyBoolean(), anyFloat(), anyFloat()))
+                .thenReturn(mLayoutTab);
+
+        mActivityScenarioRule.getScenario().onActivity(this::onActivity);
+    }
+
+    public void onActivity(Activity activity) {
+        mAnimationHostView = new FrameLayout(activity);
+        activity.setContentView(mAnimationHostView);
+        mNewTabAnimationLayout =
+                new NewTabAnimationLayout(activity, mUpdateHost, mRenderHost, mAnimationHostView);
+        mNewTabAnimationLayout.setTabModelSelector(mTabModelSelector);
+        mNewTabAnimationLayout.setTabContentManager(mTabContentManager);
+        mNewTabAnimationLayout.onFinishNativeInitialization();
+    }
+
+    @After
+    public void tearDown() {
+        mNewTabAnimationLayout.destroy();
+    }
+
+    @Test
+    public void testConstants() {
+        assertEquals(
+                mNewTabAnimationLayout.getViewportMode(),
+                ViewportMode.USE_PREVIOUS_BROWSER_CONTROLS_STATE);
+        assertTrue(mNewTabAnimationLayout.handlesTabCreating());
+        assertFalse(mNewTabAnimationLayout.handlesTabClosing());
+        assertThat(mNewTabAnimationLayout.getEventFilter(), instanceOf(BlackHoleEventFilter.class));
+        assertThat(mNewTabAnimationLayout.getSceneLayer(), instanceOf(StaticTabSceneLayer.class));
+        assertEquals(mNewTabAnimationLayout.getLayoutType(), LayoutType.SIMPLE_ANIMATION);
+    }
+
+    @Test
+    public void testShowWithNativePage() {
+        when(mTabModelSelector.getCurrentTab()).thenReturn(mCurrentTab);
+        when(mCurrentTab.isNativePage()).thenReturn(true);
+
+        mNewTabAnimationLayout.show(FAKE_TIME, /* animate= */ true);
+        verify(mTabContentManager).cacheTabThumbnail(mCurrentTab);
+    }
+
+    @Test
+    public void testShowWithoutNativePage() {
+        // No tab.
+        mNewTabAnimationLayout.show(FAKE_TIME, /* animate= */ true);
+
+        // Tab is not native page.
+        when(mTabModelSelector.getCurrentTab()).thenReturn(mCurrentTab);
+        mNewTabAnimationLayout.show(FAKE_TIME, /* animate= */ true);
+
+        verify(mTabContentManager, never()).cacheTabThumbnail(mCurrentTab);
+    }
+
+    @Test
+    public void testDoneHiding() {
+        mAnimationHostView.setContentSensitivity(View.CONTENT_SENSITIVITY_SENSITIVE);
+        mNewTabAnimationLayout.setNextTabIdForTesting(NEW_TAB_ID);
+
+        mNewTabAnimationLayout.doneHiding();
+        verify(mTabModel).setIndex(1, TabSelectionType.FROM_USER);
+
+        assertEquals(
+                mAnimationHostView.getContentSensitivity(), View.CONTENT_SENSITIVITY_NOT_SENSITIVE);
+    }
+
+    @Test
+    public void testOnTabCreating_ContentSensitivity() {
+        when(mCurrentTab.getTabHasSensitiveContent()).thenReturn(true);
+
+        mNewTabAnimationLayout.onTabCreating(CURRENT_TAB_ID);
+        assertEquals(
+                mAnimationHostView.getContentSensitivity(), View.CONTENT_SENSITIVITY_SENSITIVE);
+    }
+
+    @Test
+    public void testOnTabCreated_ContentSensitivty() {
+        when(mCurrentTab.getTabHasSensitiveContent()).thenReturn(true);
+
+        mNewTabAnimationLayout.onTabCreated(
+                FAKE_TIME,
+                NEW_TAB_ID,
+                /* index= */ 1,
+                CURRENT_TAB_ID,
+                /* newIsIncognito= */ false,
+                /* background= */ false,
+                /* originX= */ 0f,
+                /* originY= */ 0f);
+        assertEquals(
+                mAnimationHostView.getContentSensitivity(), View.CONTENT_SENSITIVITY_SENSITIVE);
+    }
+
+    // TODO(crbug.com/40282469): Tests for forceAnimationToFinish, updateLayout, and
+    // updateSceneLayer depend on the implementation of onTabCreated being finished so that
+    // mLayoutTabs gets populated.
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ReorderDelegate.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ReorderDelegate.java
index eabdf77d..dd7dbdc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ReorderDelegate.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ReorderDelegate.java
@@ -432,6 +432,7 @@
                 @ReorderType int reorderType) {
             RecordUserAction.record("MobileToolbarStartReorderTab");
             setInteractingTab((StripLayoutTab) interactingTab);
+            interactingTab.setIsForegrounded(/* isForegrounded= */ true);
 
             // 1. Set reorder mode to true before selecting this tab to prevent unnecessarily
             // triggering #bringSelectedTabToVisibleArea for edge tabs when the tab strip is full.
@@ -530,7 +531,7 @@
         mReorderScrollState = REORDER_SCROLL_NONE;
         setInReorderMode(false);
 
-        // 2. Reset the interacting view (clear any offset and reattach the container).
+        // 2. Animate offsets back to 0, reattach the container, and clear the margins.
         mAnimationHost.finishAnimationsAndPushTabUpdates();
         // mInteractingTab may be null if reordering for external view drag drop.
         if (mInteractingTab != null) {
@@ -540,22 +541,26 @@
                             mInteractingTab,
                             StripLayoutView.X_OFFSET,
                             mInteractingTab.getOffsetX(),
-                            0f,
+                            /* endValue= */ 0f,
                             ANIM_TAB_MOVE_MS));
 
             if (!mInteractingTab.getFolioAttached()) {
                 updateTabAttachState(mInteractingTab, /* attached= */ true, animationList);
             }
         }
-
-        // 3. Clear any tab group margins.
         resetTabGroupMargins(groupTitles, stripTabs, animationList);
 
-        // 4. Clear the interacting view.
-        setInteractingTab(null);
-
-        // 5. Start animations.
-        mAnimationHost.startAnimations(animationList, /* listener= */ null);
+        // 3. Start animations. Reset foregrounded state after the tabs have slid back to their
+        // ideal positions, so the z-indexing is retained during the animation.
+        mAnimationHost.startAnimations(
+                animationList,
+                new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        mInteractingTab.setIsForegrounded(/* isForegrounded= */ false);
+                        setInteractingTab(null);
+                    }
+                });
     }
 
     void prepareStripForReorder(float startX) {
@@ -809,6 +814,11 @@
                     StripLayoutUtils.getGroupedTabs(
                             mModel, stripTabs, mInteractingGroupTitle.getRootId()));
 
+            // Foreground the interacting views as they will be dragged over top other views.
+            for (StripLayoutView view : mInteractingViews) {
+                view.setIsForegrounded(/* isForegrounded= */ true);
+            }
+
             setInReorderMode(true);
             prepareStripForReorder(startPoint.x);
             StripLayoutUtils.performHapticFeedback(mContainerView);
@@ -862,11 +872,22 @@
             if (mSelectedTab != null) {
                 updateTabAttachState(mSelectedTab, /* attached= */ true, animationList);
             }
-            mAnimationHost.startAnimations(animationList, /* listener= */ null);
+            mAnimationHost.startAnimations(
+                    animationList,
+                    new AnimatorListenerAdapter() {
+                        @Override
+                        public void onAnimationEnd(Animator animation) {
+                            // Clear after the tabs have slid back to their ideal positions, so the
+                            // z-indexing is retained during the animation.
+                            for (StripLayoutView view : mInteractingViews) {
+                                view.setIsForegrounded(/* isForegrounded= */ false);
+                            }
+                            mInteractingViews.clear();
+                        }
+                    });
 
             // 3. Clear the interacting views now that the animations have been kicked off.
             mInteractingGroupTitle = null;
-            mInteractingViews.clear();
             mSelectedTab = null;
         }
 
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutGroupTitle.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutGroupTitle.java
index bec63c62..a9d13a5e 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutGroupTitle.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutGroupTitle.java
@@ -453,13 +453,6 @@
     }
 
     /**
-     * @return The padding between the title text and the notification bubble.
-     */
-    public float getBubblePadding() {
-        return NOTIFICATION_BUBBLE_PADDING_DP;
-    }
-
-    /**
      * @return The size of the notification bubble circle.
      */
     public float getBubbleSize() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutView.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutView.java
index 3bdfef7..8378c40 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutView.java
@@ -73,6 +73,7 @@
     private boolean mVisible = true;
     private boolean mCollapsed;
     private boolean mIsIncognito;
+    private boolean mIsForegrounded;
 
     // A11y variables.
     private String mAccessibilityDescription = "";
@@ -251,6 +252,18 @@
         mIsIncognito = state;
     }
 
+    /** Returns {@code true} if the view is foregrounded for reorder, {@code false} otherwise. */
+    public boolean isForegrounded() {
+        return mIsForegrounded;
+    }
+
+    /**
+     * @param isForegrounded Whether or not the given view should be foregrounded for reorder.
+     */
+    void setIsForegrounded(boolean isForegrounded) {
+        mIsForegrounded = isForegrounded;
+    }
+
     /**
      * Get a list of virtual views for accessibility events.
      *
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
index 1b44d000..ba3c86f9 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
@@ -225,75 +225,51 @@
 
         // TODO(crbug.com/40270147): Cleanup params, as some don't change and others are now
         //  unused.
-        StripLayoutTab selectedTab = null;
         for (int i = 0; i < tabsCount; i++) {
-            final StripLayoutTab stripTab = stripTabs[i];
-            // Skip pushing selected tab here, will be pushed last to make this the top layer.
-            if (stripTab.getTabId() == selectedTabId) {
-                selectedTab = stripTab;
-                continue;
-            }
-            pushTab(stripTab, layoutHelper, layerTitleCache, resourceManager, hoveredTabId, false);
-        }
-        // Push selected tab.
-        if (selectedTab != null) {
-            pushTab(
-                    selectedTab,
-                    layoutHelper,
-                    layerTitleCache,
-                    resourceManager,
-                    hoveredTabId,
-                    true);
-        }
-    }
+            final StripLayoutTab st = stripTabs[i];
+            boolean isSelected = st.getTabId() == selectedTabId;
+            boolean isHovered = st.getTabId() == hoveredTabId;
+            boolean shouldShowOutline = layoutHelper.shouldShowTabOutline(st);
 
-    private void pushTab(
-            StripLayoutTab st,
-            StripLayoutHelperManager layoutHelper,
-            LayerTitleCache layerTitleCache,
-            ResourceManager resourceManager,
-            int hoveredTabId,
-            boolean isSelected) {
-        boolean isHovered = st.getTabId() == hoveredTabId;
-        boolean shouldShowOutline = layoutHelper.shouldShowTabOutline(st);
-
-        // TODO(crbug.com/326301060): Update tab outline placeholder color with color picker.
-        TabStripSceneLayerJni.get()
-                .putStripTabLayer(
-                        mNativePtr,
-                        TabStripSceneLayer.this,
-                        st.getTabId(),
-                        st.getCloseButton().getResourceId(),
-                        st.getCloseButton().getBackgroundResourceId(),
-                        st.getDividerResourceId(),
-                        st.getResourceId(),
-                        st.getOutlineResourceId(),
-                        st.getCloseButton().getTint(),
-                        st.getCloseButton().getBackgroundTint(),
-                        st.getDividerTint(),
-                        st.getTint(isSelected, isHovered),
-                        layoutHelper.getSelectedOutlineGroupTint(st.getTabId(), shouldShowOutline),
-                        isSelected,
-                        shouldShowOutline,
-                        st.getClosePressed(),
-                        layoutHelper.getWidth() * mDpToPx,
-                        st.getDrawX() * mDpToPx,
-                        st.getDrawY() * mDpToPx,
-                        st.getWidth() * mDpToPx,
-                        st.getHeight() * mDpToPx,
-                        st.getContentOffsetY() * mDpToPx,
-                        st.getDividerOffsetX() * mDpToPx,
-                        st.getBottomMargin() * mDpToPx,
-                        st.getTopMargin() * mDpToPx,
-                        st.getCloseButtonPadding() * mDpToPx,
-                        st.getCloseButton().getOpacity(),
-                        st.isStartDividerVisible(),
-                        st.isEndDividerVisible(),
-                        st.isLoading(),
-                        st.getLoadingSpinnerRotation(),
-                        st.getContainerOpacity(),
-                        layerTitleCache,
-                        resourceManager);
+            // TODO(crbug.com/326301060): Update tab outline placeholder color with color picker.
+            TabStripSceneLayerJni.get()
+                    .putStripTabLayer(
+                            mNativePtr,
+                            TabStripSceneLayer.this,
+                            st.getTabId(),
+                            st.getCloseButton().getResourceId(),
+                            st.getCloseButton().getBackgroundResourceId(),
+                            st.getDividerResourceId(),
+                            st.getResourceId(),
+                            st.getOutlineResourceId(),
+                            st.getCloseButton().getTint(),
+                            st.getCloseButton().getBackgroundTint(),
+                            st.getDividerTint(),
+                            st.getTint(isSelected, isHovered),
+                            layoutHelper.getSelectedOutlineGroupTint(
+                                    st.getTabId(), shouldShowOutline),
+                            st.isForegrounded(),
+                            shouldShowOutline,
+                            st.getClosePressed(),
+                            layoutHelper.getWidth() * mDpToPx,
+                            st.getDrawX() * mDpToPx,
+                            st.getDrawY() * mDpToPx,
+                            st.getWidth() * mDpToPx,
+                            st.getHeight() * mDpToPx,
+                            st.getContentOffsetY() * mDpToPx,
+                            st.getDividerOffsetX() * mDpToPx,
+                            st.getBottomMargin() * mDpToPx,
+                            st.getTopMargin() * mDpToPx,
+                            st.getCloseButtonPadding() * mDpToPx,
+                            st.getCloseButton().getOpacity(),
+                            st.isStartDividerVisible(),
+                            st.isEndDividerVisible(),
+                            st.isLoading(),
+                            st.getLoadingSpinnerRotation(),
+                            st.getContainerOpacity(),
+                            layerTitleCache,
+                            resourceManager);
+        }
     }
 
     private void pushGroupIndicators(
@@ -308,6 +284,7 @@
                             mNativePtr,
                             TabStripSceneLayer.this,
                             gt.isIncognito(),
+                            gt.isForegrounded(),
                             gt.getRootId(),
                             gt.getTint(),
                             gt.getPaddedX() * mDpToPx,
@@ -445,6 +422,7 @@
                 long nativeTabStripSceneLayer,
                 TabStripSceneLayer caller,
                 boolean incognito,
+                boolean foreground,
                 int id,
                 int tint,
                 float x,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java
index 12248c77..05820e4 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/modaldialog/TabModalLifetimeHandler.java
@@ -144,13 +144,6 @@
         if (mPresenter.getDialogModel() != null) mPresenter.updateContainerHierarchy(!hasFocus);
     }
 
-    /** Handle a back press event. */
-    public boolean onBackPressed() {
-        if (!shouldInterceptBackPress()) return false;
-        mPresenter.dismissCurrentDialog(DialogDismissalCause.NAVIGATE_BACK);
-        return true;
-    }
-
     @Override
     public @BackPressResult int handleBackPress() {
         int result = shouldInterceptBackPress() ? BackPressResult.SUCCESS : BackPressResult.FAILURE;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderImpl.java
index 4d11231..27ef0bed0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderImpl.java
@@ -24,7 +24,9 @@
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.ThreadUtils;
+import org.chromium.base.TimeUtils;
 import org.chromium.base.TraceEvent;
+import org.chromium.base.metrics.RecordHistogram;
 import org.chromium.base.task.PostTask;
 import org.chromium.base.task.TaskTraits;
 import org.chromium.build.annotations.UsedByReflection;
@@ -34,6 +36,7 @@
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.gsa.GSAUtils;
 import org.chromium.chrome.browser.provider.PageContentProviderImpl.PageContentInvocationState.PageExtractionState;
+import org.chromium.chrome.browser.provider.PageContentProviderMetrics.PageContentProviderEvent;
 import org.chromium.chrome.browser.tab.Tab;
 import org.chromium.content_public.browser.RenderFrameHost;
 
@@ -77,6 +80,7 @@
             mInvokedUrl = invokedUrl;
             mActivityTabProvider = activityTabProvider;
             mExtractionState = PageExtractionState.NOT_STARTED;
+            mInvocationStartTimestampMs = TimeUtils.elapsedRealtimeMillis();
         }
 
         @NonNull private final String mInvocationId;
@@ -84,6 +88,10 @@
         @Nullable private String mPageContents;
         @PageExtractionState private int mExtractionState;
         @NonNull private final ActivityTabProvider mActivityTabProvider;
+
+        private long mInvocationStartTimestampMs;
+        private long mExtractionStartTimestampMs;
+        private long mExtractionFinishedTimestampMs;
     }
 
     private static final String AUTHORITY_SUFFIX = ".PageContentProvider";
@@ -139,12 +147,17 @@
             }
 
             synchronized (sLock) {
+                PageContentProviderMetrics.recordPageProviderEvent(PageContentProviderEvent.QUERY);
                 ensureUriMatcherInitialized();
                 final int match = mUriMatcher.match(uri);
 
                 switch (match) {
                     case URI_MATCH_INVOCATION_URL -> {}
-                    default -> throw new IllegalArgumentException("Unknown URL");
+                    default -> {
+                        PageContentProviderMetrics.recordPageProviderEvent(
+                                PageContentProviderEvent.QUERY_FAILED_INVALID_URL);
+                        throw new IllegalArgumentException("Unknown URL");
+                    }
                 }
 
                 String id = uri.getLastPathSegment();
@@ -154,6 +167,8 @@
                 if (id == null
                         || sInvocationState == null
                         || !id.equals(sInvocationState.mInvocationId)) {
+                    PageContentProviderMetrics.recordPageProviderEvent(
+                            PageContentProviderEvent.QUERY_FAILED_INVALID_ID);
                     return cursor;
                 }
 
@@ -182,6 +197,10 @@
 
                 if (currentTabUrlAndFrameHost == null
                         || !sInvocationState.mInvokedUrl.equals(currentTabUrlAndFrameHost.first)) {
+                    PageContentProviderMetrics.recordPageProviderEvent(
+                            currentTabUrlAndFrameHost == null
+                                    ? PageContentProviderEvent.QUERY_FAILED_TO_GET_CURRENT_TAB
+                                    : PageContentProviderEvent.QUERY_FAILED_CURRENT_TAB_CHANGED);
                     return cursor;
                 }
 
@@ -190,11 +209,21 @@
                         sInvocationState.mExtractionState == PageExtractionState.COMPLETE;
                 if (isFinishedLoading) {
                     pageContents = sInvocationState.mPageContents;
+                    recordExtractionEndToFinalQueryLatency();
                     clearCachedContent();
+                    PageContentProviderMetrics.recordPageProviderEvent(
+                            PageContentProviderEvent.QUERY_SUCCEEDED_RETURNED_EXTRACTED);
                 } else if (sInvocationState.mExtractionState == PageExtractionState.NOT_STARTED) {
                     requestPageContents(
                             sInvocationState.mInvokedUrl, currentTabUrlAndFrameHost.second);
+                    recordCreateToExtractionStartLatency();
+                    PageContentProviderMetrics.recordPageProviderEvent(
+                            PageContentProviderEvent.QUERY_SUCCEEDED_STARTED_EXTRACTION);
                     sInvocationState.mExtractionState = PageExtractionState.STARTED;
+
+                } else {
+                    PageContentProviderMetrics.recordPageProviderEvent(
+                            PageContentProviderEvent.QUERY_SUCCEEDED_ALREADY_EXTRACTING);
                 }
 
                 cursor.addRow(
@@ -342,6 +371,7 @@
                 return;
             }
 
+            PageContentProviderMetrics.recordPageProviderEvent(PageContentProviderEvent.TIMEOUT);
             clearCachedContent();
         }
     }
@@ -364,6 +394,57 @@
         }
     }
 
+    private static void recordCreateToExtractionStartLatency() {
+        synchronized (sLock) {
+            if (sInvocationState == null) return;
+
+            if (sInvocationState.mInvocationStartTimestampMs != 0) {
+                RecordHistogram.recordMediumTimesHistogram(
+                        "Android.AssistContent.WebPageContentProvider.Latency.CreateToExtractionStart",
+                        TimeUtils.elapsedRealtimeMillis()
+                                - sInvocationState.mInvocationStartTimestampMs);
+                sInvocationState.mExtractionStartTimestampMs = TimeUtils.elapsedRealtimeMillis();
+            }
+        }
+    }
+
+    private static void recordExtractionStartToEndLatency() {
+        synchronized (sLock) {
+            if (sInvocationState == null) return;
+
+            if (sInvocationState.mExtractionStartTimestampMs != 0) {
+                RecordHistogram.recordMediumTimesHistogram(
+                        "Android.AssistContent.WebPageContentProvider.Latency.ExtractionStartToEnd",
+                        TimeUtils.elapsedRealtimeMillis()
+                                - sInvocationState.mExtractionStartTimestampMs);
+                sInvocationState.mExtractionStartTimestampMs = 0;
+                sInvocationState.mExtractionFinishedTimestampMs = TimeUtils.elapsedRealtimeMillis();
+            }
+        }
+    }
+
+    private static void recordExtractionEndToFinalQueryLatency() {
+        synchronized (sLock) {
+            if (sInvocationState == null) return;
+
+            if (sInvocationState.mExtractionFinishedTimestampMs != 0) {
+                RecordHistogram.recordMediumTimesHistogram(
+                        "Android.AssistContent.WebPageContentProvider.Latency.ExtractionEndToFinalQuery",
+                        TimeUtils.elapsedRealtimeMillis()
+                                - sInvocationState.mExtractionFinishedTimestampMs);
+                sInvocationState.mExtractionFinishedTimestampMs = 0;
+            }
+
+            if (sInvocationState.mInvocationStartTimestampMs != 0) {
+                RecordHistogram.recordMediumTimesHistogram(
+                        "Android.AssistContent.WebPageContentProvider.Latency.CreateToFinalQuery",
+                        TimeUtils.elapsedRealtimeMillis()
+                                - sInvocationState.mInvocationStartTimestampMs);
+                sInvocationState.mInvocationStartTimestampMs = 0;
+            }
+        }
+    }
+
     private void onPageTextReceived(String requestedUrl, Optional<String> pageText) {
         try (var u = TraceEvent.scoped("PageContentProvider.onPageTextReceived")) {
             synchronized (sLock) {
@@ -371,6 +452,10 @@
                 if (sInvocationState == null
                         || !sInvocationState.mInvokedUrl.equals(requestedUrl)
                         || pageText.isEmpty()) {
+                    PageContentProviderMetrics.recordPageProviderEvent(
+                            pageText.isEmpty()
+                                    ? PageContentProviderEvent.TEXT_EXTRACTION_FAILED_EMPTY_RESULT
+                                    : PageContentProviderEvent.TEXT_EXTRACTION_FAILED_TAB_CHANGED);
                     return;
                 }
 
@@ -380,6 +465,9 @@
                 ContextUtils.getApplicationContext()
                         .getContentResolver()
                         .notifyChange(uriToNotify, null);
+                PageContentProviderMetrics.recordPageProviderEvent(
+                        PageContentProviderEvent.TEXT_EXTRACTION_SUCCEEDED);
+                recordExtractionStartToEndLatency();
             }
         }
     }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderImplUnitTest.java b/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderImplUnitTest.java
index c0c7111..a584597 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderImplUnitTest.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderImplUnitTest.java
@@ -32,9 +32,11 @@
 
 import org.chromium.base.Callback;
 import org.chromium.base.ContextUtils;
+import org.chromium.base.FakeTimeTestRule;
 import org.chromium.base.test.BaseRobolectricTestRunner;
 import org.chromium.base.test.util.CallbackHelper;
 import org.chromium.base.test.util.Features.EnableFeatures;
+import org.chromium.base.test.util.HistogramWatcher;
 import org.chromium.chrome.browser.ActivityTabProvider;
 import org.chromium.chrome.browser.content_extraction.InnerTextBridge;
 import org.chromium.chrome.browser.content_extraction.InnerTextBridgeJni;
@@ -55,6 +57,7 @@
 public class PageContentProviderImplUnitTest {
 
     @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule();
+    @Rule public FakeTimeTestRule mFakeTimeTestRule = new FakeTimeTestRule();
 
     @Mock private RenderFrameHost mRenderFrameHost;
     @Mock private WebContents mWebContents;
@@ -93,8 +96,16 @@
         var contentUri =
                 PageContentProviderImpl.getContentUriForUrl(
                         mTab.getUrl().getSpec(), mActivityTabProvider);
-        var resultCursor = mProvider.query(Uri.parse(contentUri), null, null, null, null);
-
+        // Wait 300ms between creating URI and querying it.
+        mFakeTimeTestRule.advanceMillis(300);
+        Cursor resultCursor;
+        // Time between creating URI and querying it should be recorded.
+        try (HistogramWatcher histogramWatcher =
+                HistogramWatcher.newSingleRecordWatcher(
+                        "Android.AssistContent.WebPageContentProvider.Latency.CreateToExtractionStart",
+                        300)) {
+            resultCursor = mProvider.query(Uri.parse(contentUri), null, null, null, null);
+        }
         assertCursorContainsValues(
                 resultCursor,
                 mTab.getUrl().getSpec(),
@@ -112,6 +123,7 @@
         var contentUri =
                 PageContentProviderImpl.getContentUriForUrl(
                         mTab.getUrl().getSpec(), mActivityTabProvider);
+        mFakeTimeTestRule.advanceMillis(250);
         mProvider.query(Uri.parse(contentUri), null, null, null, null);
         verify(mInnerTextNatives).getInnerText(any(), innerTextCallbackCaptor.capture());
 
@@ -127,7 +139,15 @@
                             }
                         });
 
-        innerTextCallbackCaptor.getValue().onResult(Optional.of("Inner text of page"));
+        // Wait 600ms between starting the text extraction process and it completing.
+        mFakeTimeTestRule.advanceMillis(600);
+        // Time it took to extract text should have been recorded.
+        try (var histogramWatcher =
+                HistogramWatcher.newSingleRecordWatcher(
+                        "Android.AssistContent.WebPageContentProvider.Latency.ExtractionStartToEnd",
+                        600)) {
+            innerTextCallbackCaptor.getValue().onResult(Optional.of("Inner text of page"));
+        }
         shadowOf(Looper.getMainLooper()).idle();
 
         contentObserverCallbackHelper.waitForCallback(0);
@@ -141,12 +161,29 @@
         var contentUri =
                 PageContentProviderImpl.getContentUriForUrl(
                         mTab.getUrl().getSpec(), mActivityTabProvider);
+        mFakeTimeTestRule.advanceMillis(100);
         mProvider.query(Uri.parse(contentUri), null, null, null, null);
         verify(mInnerTextNatives).getInnerText(any(), innerTextCallbackCaptor.capture());
 
+        mFakeTimeTestRule.advanceMillis(200);
         innerTextCallbackCaptor.getValue().onResult(Optional.of("Inner text of page"));
 
-        var secondResultCursor = mProvider.query(Uri.parse(contentUri), null, null, null, null);
+        mFakeTimeTestRule.advanceMillis(300);
+        Cursor secondResultCursor;
+
+        // Time between completing text extraction and second query should be recorded, as well as
+        // the total time passed.
+        try (var histogramWatcher =
+                HistogramWatcher.newBuilder()
+                        .expectIntRecord(
+                                "Android.AssistContent.WebPageContentProvider.Latency.ExtractionEndToFinalQuery",
+                                300)
+                        .expectIntRecord(
+                                "Android.AssistContent.WebPageContentProvider.Latency.CreateToFinalQuery",
+                                100 + 200 + 300)
+                        .build()) {
+            secondResultCursor = mProvider.query(Uri.parse(contentUri), null, null, null, null);
+        }
         assertCursorContainsValues(
                 secondResultCursor,
                 mTab.getUrl().getSpec(),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderMetrics.java b/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderMetrics.java
new file mode 100644
index 0000000..2deca9a
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/provider/PageContentProviderMetrics.java
@@ -0,0 +1,70 @@
+// 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.
+
+package org.chromium.chrome.browser.provider;
+
+import androidx.annotation.IntDef;
+
+import org.chromium.base.metrics.RecordHistogram;
+
+public class PageContentProviderMetrics {
+
+    @IntDef({
+        PageContentProviderEvent.GET_CONTENT_URI_FAILED,
+        PageContentProviderEvent.QUERY,
+        PageContentProviderEvent.QUERY_FAILED_CURRENT_TAB_CHANGED,
+        PageContentProviderEvent.QUERY_FAILED_INVALID_URL,
+        PageContentProviderEvent.QUERY_FAILED_INVALID_ID,
+        PageContentProviderEvent.QUERY_FAILED_TO_GET_CURRENT_TAB,
+        PageContentProviderEvent.QUERY_SUCCEEDED_ALREADY_EXTRACTING,
+        PageContentProviderEvent.QUERY_SUCCEEDED_RETURNED_EXTRACTED,
+        PageContentProviderEvent.QUERY_SUCCEEDED_STARTED_EXTRACTION,
+        PageContentProviderEvent.TEXT_EXTRACTION_FAILED_EMPTY_RESULT,
+        PageContentProviderEvent.TEXT_EXTRACTION_FAILED_TAB_CHANGED,
+        PageContentProviderEvent.TEXT_EXTRACTION_SUCCEEDED,
+        PageContentProviderEvent.TIMEOUT,
+    })
+    public static @interface PageContentProviderEvent {
+
+        int GET_CONTENT_URI_FAILED = 0;
+        int QUERY = 1;
+        int QUERY_FAILED_CURRENT_TAB_CHANGED = 2;
+        int QUERY_FAILED_INVALID_URL = 3;
+        int QUERY_FAILED_INVALID_ID = 4;
+        int QUERY_FAILED_TO_GET_CURRENT_TAB = 5;
+        int QUERY_SUCCEEDED_ALREADY_EXTRACTING = 6;
+        int QUERY_SUCCEEDED_RETURNED_EXTRACTED = 7;
+        int QUERY_SUCCEEDED_STARTED_EXTRACTION = 8;
+        int TEXT_EXTRACTION_FAILED_EMPTY_RESULT = 9;
+        int TEXT_EXTRACTION_FAILED_TAB_CHANGED = 10;
+        int TEXT_EXTRACTION_SUCCEEDED = 11;
+        int TIMEOUT = 12;
+        int NUM_ENTRIES = 13;
+    }
+
+    public static void recordPageProviderEvent(@PageContentProviderEvent int event) {
+        RecordHistogram.recordEnumeratedHistogram(
+                "Android.AssistContent.WebPageContentProvider.Events",
+                event,
+                PageContentProviderEvent.NUM_ENTRIES);
+    }
+
+    public static void recordUrlAttachedToAssistContent(boolean urlAttached) {
+        RecordHistogram.recordBooleanHistogram("Android.AssistContent.AttachedUrl", urlAttached);
+    }
+
+    public static void recordPdfStructuredDataAttachedToAssistContent(
+            boolean pdfStructuredDataAttached) {
+        RecordHistogram.recordBooleanHistogram(
+                "Android.AssistContent.StructuredDataAttachedSuccess.Pdf",
+                pdfStructuredDataAttached);
+    }
+
+    public static void recordWebStructuredDataAttachedToAssistContent(
+            boolean webStructuredDataAttached) {
+        RecordHistogram.recordBooleanHistogram(
+                "Android.AssistContent.StructuredDataAttachedSuccess.WebPage",
+                webStructuredDataAttached);
+    }
+}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarIphController.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarIphController.java
index 0cd8895..5f62c107 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarIphController.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarIphController.java
@@ -31,18 +31,6 @@
     public void showPriceDropIph(View anchorView) {
         HighlightParams params = new HighlightParams(HighlightShape.CIRCLE);
         params.setBoundsRespectPadding(true);
-        int yInset = mContext.getResources().getDimensionPixelOffset(R.dimen.toolbar_iph_y_inset);
-        mEducationHelper.requestShowIph(
-                new IphCommandBuilder(
-                                mContext.getResources(),
-                                FeatureConstants.PRICE_DROP_NTP_FEATURE,
-                                R.string.price_drop_spotted_iph,
-                                R.string.price_drop_spotted_iph)
-                        .setInsetRect(new Rect(0, 0, 0, -yInset))
-                        .setAnchorView(anchorView)
-                        .setHighlightParams(params)
-                        .setDismissOnTouch(true)
-                        .build());
     }
 
     @VisibleForTesting
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
index b0e4255c..82e3c45 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -98,8 +98,6 @@
 import org.chromium.chrome.browser.page_info.ChromePageInfo;
 import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations;
 import org.chromium.chrome.browser.preferences.ChromeSharedPreferences;
-import org.chromium.chrome.browser.price_tracking.PriceTrackingFeatures;
-import org.chromium.chrome.browser.price_tracking.PriceTrackingUtilities;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.readaloud.ReadAloudController;
 import org.chromium.chrome.browser.search_engines.TemplateUrlServiceFactory;
@@ -111,7 +109,6 @@
 import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper;
 import org.chromium.chrome.browser.tab.TabObscuringHandler;
 import org.chromium.chrome.browser.tab.TabSelectionType;
-import org.chromium.chrome.browser.tab.state.ShoppingPersistedTabData;
 import org.chromium.chrome.browser.tab_ui.TabContentManager;
 import org.chromium.chrome.browser.tabmodel.IncognitoStateProvider;
 import org.chromium.chrome.browser.tabmodel.TabCreatorManager;
@@ -2484,35 +2481,6 @@
         checkIfNtpLoaded();
     }
 
-    /**
-     * Checks to to see if there are any unseen price drops, and if so attempts to show the price
-     * drop IPH. An unseen price drop occurs when there is a tab with a price drop that has not been
-     * viewed in the tab switcher grid.
-     */
-    private void maybeShowPriceDropIph() {
-        if (mTabModelSelector == null) return;
-        Profile profile = mTabModelSelector.getCurrentModel().getProfile();
-        if (profile.isOffTheRecord()) return;
-
-        if (!PriceTrackingUtilities.isTrackPricesOnTabsEnabled(profile)
-                || !PriceTrackingFeatures.isPriceDropIphEnabled(profile)) {
-            return;
-        }
-        TabModel tabModel = mTabModelSelector.getCurrentModel();
-        for (int i = 0; i < tabModel.getCount(); i++) {
-            ShoppingPersistedTabData.from(
-                    tabModel.getTabAt(i),
-                    (shoppingPersistedTabData) -> {
-                        if (shoppingPersistedTabData != null
-                                && shoppingPersistedTabData.getPriceDrop() != null
-                                && !shoppingPersistedTabData.getIsCurrentPriceDropSeen()) {
-                            mIphController.showPriceDropIph(
-                                    mControlContainer.findViewById(R.id.tab_switcher_button));
-                        }
-                    });
-        }
-    }
-
     private void maybeShowBottomToolbarIph() {
         if (!ToolbarPositionController.isToolbarPositionCustomizationEnabled(
                 mActivity, mIsCustomTab)) {
@@ -2528,7 +2496,6 @@
         if (ntp != null) {
             ntp.setOmniboxStub(mLocationBar.getOmniboxStub());
             mLocationBarModel.notifyNtpStartedLoading();
-            maybeShowPriceDropIph();
             mIsNtpShowingSupplier.set(true);
         } else {
             maybeShowBottomToolbarIph();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java
index 21f6410..de7e82b6 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/customtabs/CustomTabExternalNavigationTest.java
@@ -260,8 +260,11 @@
     @SmallTest
     @DisableIf.Build(
             supported_abis_includes = "x86",
-            sdk_is_greater_than = VERSION_CODES.O_MR1,
-            sdk_is_less_than = VERSION_CODES.Q,
+            sdk_equals = VERSION_CODES.P,
+            message = "crbug.com/1188920")
+    @DisableIf.Build(
+            supported_abis_includes = "x86_64",
+            sdk_is_less_than = VERSION_CODES.TIRAMISU,
             message = "crbug.com/1188920")
     public void testIntentPickerNotShownForNormalUrl() throws TimeoutException {
         setUpTwa();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/ManifestHWATest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/ManifestHWATest.java
index 15a1b56..499c6d85 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/ManifestHWATest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/hardware_acceleration/ManifestHWATest.java
@@ -7,6 +7,7 @@
 import android.content.pm.ActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.os.Build;
 
 import androidx.test.filters.SmallTest;
 
@@ -17,11 +18,17 @@
 import org.chromium.base.PackageUtils;
 import org.chromium.base.test.BaseJUnit4ClassRunner;
 import org.chromium.base.test.util.Batch;
+import org.chromium.base.test.util.DisableIf;
 import org.chromium.chrome.browser.app.ChromeActivity;
 
 /** Hardware acceleration-related manifest tests. */
 @RunWith(BaseJUnit4ClassRunner.class)
 @Batch(Batch.UNIT_TESTS)
+@DisableIf.Build(
+        sdk_is_greater_than = Build.VERSION_CODES.P,
+        sdk_is_less_than = Build.VERSION_CODES.TIRAMISU,
+        supported_abis_includes = "x86_64",
+        message = "vr tests do not apply to emulator")
 public class ManifestHWATest {
     @Test
     @SmallTest
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoPermissionLeakageTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoPermissionLeakageTest.java
index 72796d5..613f1e4 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoPermissionLeakageTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoPermissionLeakageTest.java
@@ -16,6 +16,8 @@
 
 import static org.chromium.ui.test.util.ViewUtils.onViewWaiting;
 
+import android.os.Build;
+
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.espresso.Espresso;
 import androidx.test.espresso.NoMatchingViewException;
@@ -38,6 +40,7 @@
 import org.chromium.base.test.util.CommandLineFlags;
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
+import org.chromium.base.test.util.DisableIf;
 import org.chromium.chrome.browser.customtabs.IncognitoCustomTabActivityTestRule;
 import org.chromium.chrome.browser.flags.ChromeSwitches;
 import org.chromium.chrome.browser.incognito.IncognitoDataTestUtils.ActivityType;
@@ -145,6 +148,7 @@
     @Test
     @LargeTest
     @UseMethodParameter(RegularAndIncognito.class)
+    @DisableIf.Build(sdk_equals = Build.VERSION_CODES.S_V2, message = "crbug.com/40704641")
     public void testAllowPermissionDoNotLeakBetweenRegularAndIncognito(
             String activityType1, String activityType2) throws Exception {
         ActivityType activity1 = ActivityType.valueOf(activityType1);
@@ -172,6 +176,7 @@
     @Test
     @LargeTest
     @UseMethodParameter(TestParams.IncognitoToIncognito.class)
+    @DisableIf.Build(sdk_equals = Build.VERSION_CODES.S_V2, message = "crbug.com/40704641")
     public void testAllowPermissionDoNotLeakFromIncognitoToIncognito(
             String incognitoActivityType1, String incognitoActivityType2) throws Exception {
         // At least one of the incognitoActivity is an incognito CCT.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java
index 5faa252..c857f14b 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/incognito/IncognitoTabLauncherTest.java
@@ -9,6 +9,7 @@
 
 import android.content.Context;
 import android.content.Intent;
+import android.os.Build;
 import android.os.Bundle;
 
 import androidx.browser.customtabs.CustomTabsIntent;
@@ -26,6 +27,7 @@
 
 import org.chromium.base.ThreadUtils;
 import org.chromium.base.test.util.CommandLineFlags;
+import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.base.test.util.Feature;
 import org.chromium.base.test.util.Features.EnableFeatures;
@@ -44,6 +46,9 @@
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
 @EnableFeatures({ChromeFeatureList.ALLOW_NEW_INCOGNITO_TAB_INTENTS})
+@DisableIf.Build(
+        sdk_is_greater_than = Build.VERSION_CODES.O,
+        message = "Flaky, see crbug.com/1246132")
 public class IncognitoTabLauncherTest {
     @Rule
     public final ChromeTabbedActivityTestRule mActivityRule = new ChromeTabbedActivityTestRule();
@@ -71,6 +76,7 @@
     @Test
     @Feature("Incognito")
     @MediumTest
+    @DisabledTest(message = "crbug.com/1237504")
     public void testLaunchIncognitoNewTab() throws TimeoutException {
         ChromeTabbedActivity activity = launchIncognitoTab(false);
         assertIncognitoTabLaunched(activity, false);
@@ -79,6 +85,7 @@
     @Test
     @Feature("Incognito")
     @MediumTest
+    @DisabledTest(message = "crbug.com/1237504")
     public void testLaunchIncognitoNewTab_omniboxFocused_enabled_thirdParty()
             throws TimeoutException {
         ChromeTabbedActivity activity = launchIncognitoTab(false);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowIntegrationTest.java
index 5fe2713..fe18b63 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowIntegrationTest.java
@@ -104,7 +104,7 @@
     @Test
     @MediumTest
     @DisableIf.Device(DeviceFormFactor.TABLET) // https://crbug.com/338976206
-    @DisableIf.Build(sdk_is_greater_than = VERSION_CODES.S_V2) // https://crbug.com/1297370
+    @DisableIf.Build(sdk_is_greater_than = VERSION_CODES.R) // https://crbug.com/1297370
     @Feature("MultiWindow")
     @CommandLineFlags.Add({
         ChromeSwitches.DISABLE_TAB_MERGING_FOR_TESTING,
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtilsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtilsTest.java
index 66809f2..4b4f338f 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtilsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/multiwindow/MultiWindowUtilsTest.java
@@ -53,7 +53,7 @@
 /** Class for testing MultiWindowUtils. */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@DisableIf.Build(sdk_is_greater_than = VERSION_CODES.S_V2) // https://crbug.com/1297370
+@DisableIf.Build(sdk_is_greater_than = VERSION_CODES.R) // https://crbug.com/1297370
 public class MultiWindowUtilsTest {
     @Rule
     public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SwitchToTabTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SwitchToTabTest.java
index 26992ebd..511c5166 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SwitchToTabTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/SwitchToTabTest.java
@@ -9,6 +9,7 @@
 import static org.chromium.chrome.browser.multiwindow.MultiWindowTestHelper.waitForSecondChromeTabbedActivity;
 
 import android.app.Activity;
+import android.os.Build;
 import android.text.TextUtils;
 import android.view.ViewGroup;
 import android.widget.ImageView;
@@ -29,6 +30,7 @@
 import org.chromium.base.test.util.Criteria;
 import org.chromium.base.test.util.CriteriaHelper;
 import org.chromium.base.test.util.CriteriaNotSatisfiedException;
+import org.chromium.base.test.util.DisableIf;
 import org.chromium.base.test.util.DisabledTest;
 import org.chromium.chrome.browser.ChromeTabbedActivity;
 import org.chromium.chrome.browser.ChromeTabbedActivity2;
@@ -231,6 +233,7 @@
 
     @Test
     @MediumTest
+    @DisableIf.Build(sdk_is_greater_than = Build.VERSION_CODES.P, message = "crbug.com/1195129")
     public void testSwitchToTabSuggestion() throws InterruptedException {
         mTestServer =
                 EmbeddedTestServer.createAndStartHTTPSServer(
@@ -304,6 +307,7 @@
 
     @Test
     @MediumTest
+    @DisableIf.Build(sdk_is_greater_than = Build.VERSION_CODES.P, message = "crbug.com/1195129")
     public void testNoSwitchToIncognitoTabFromNormalModel() throws InterruptedException {
         mTestServer =
                 EmbeddedTestServer.createAndStartHTTPSServer(
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
index 67d7f3a..4c39ee12 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/settings/MainSettingsFragmentTest.java
@@ -616,6 +616,7 @@
     @LargeTest
     @Feature({"RenderTest"})
     @EnableFeatures(ChromeFeatureList.REPLACE_SYNC_PROMOS_WITH_SIGN_IN_PROMOS)
+    @DisabledTest(message = "https://crbug.com/380957937")
     public void testRenderOnIdentityErrorForSignedInUsers_withReplaceSyncPromos()
             throws IOException {
         FakeSyncServiceImpl fakeSyncService =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTestUtils.java
index c6a6c9b..31995ca11 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTestUtils.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tab/state/ShoppingPersistedTabDataTestUtils.java
@@ -29,7 +29,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.Optional;
 import java.util.concurrent.Semaphore;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
@@ -113,26 +112,6 @@
         return res.get();
     }
 
-    static ShoppingPersistedTabData createShoppingPersistedTabDataWithPriceDropOnUiThread(Tab tab) {
-        AtomicReference<ShoppingPersistedTabData> res = new AtomicReference<>();
-        ThreadUtils.runOnUiThreadBlocking(
-                () -> {
-                    ShoppingPersistedTabData shoppingPersistedTabData =
-                            new ShoppingPersistedTabData(tab);
-                    ObservableSupplierImpl<Boolean> supplier = new ObservableSupplierImpl<>();
-                    supplier.set(true);
-                    shoppingPersistedTabData.registerIsTabSaveEnabledSupplier(supplier);
-                    shoppingPersistedTabData.setPriceMicros(UPDATED_PRICE_MICROS);
-                    shoppingPersistedTabData.setPreviousPriceMicros(PRICE_MICROS);
-                    shoppingPersistedTabData.setLastUpdatedMs(
-                            System.currentTimeMillis() - TimeUnit.DAYS.toMillis(2));
-                    shoppingPersistedTabData.setPriceDropGurl(DEFAULT_GURL);
-                    shoppingPersistedTabData.setCurrencyCode(UNITED_STATES_CURRENCY_CODE);
-                    res.set(shoppingPersistedTabData);
-                });
-        return res.get();
-    }
-
     static ShoppingPersistedTabData createShoppingPersistedTabDataWithCurrencyCode(
             int tabId, Profile profile, String currencyCode) {
         ShoppingPersistedTabData shoppingPersistedTabData =
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelMergingTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelMergingTest.java
index 9595a4a..618a35b0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelMergingTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/TabModelMergingTest.java
@@ -59,7 +59,7 @@
 /** Tests merging tab models for Android N+ multi-instance. */
 @RunWith(ChromeJUnit4ClassRunner.class)
 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE})
-@DisableIf.Build(sdk_is_greater_than = VERSION_CODES.S_V2) // https://crbug.com/1297370
+@DisableIf.Build(sdk_is_greater_than = VERSION_CODES.R) // https://crbug.com/1297370
 public class TabModelMergingTest {
     @Rule
     public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
index c4180f0..09bcb8e0 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/tabmodel/UndoTabModelTest.java
@@ -281,7 +281,7 @@
     @Test
     @MediumTest
     @DisableIf.Device(DeviceFormFactor.TABLET) // https://crbug.com/338997949
-    @DisableIf.Build(sdk_is_greater_than = VERSION_CODES.S_V2) // https://crbug.com/1297370
+    @DisableIf.Build(sdk_is_greater_than = VERSION_CODES.R) // https://crbug.com/1297370
     @CommandLineFlags.Add(ChromeSwitches.DISABLE_TAB_MERGING_FOR_TESTING)
     public void testOpenRecentlyClosedTabMultiWindow() throws TimeoutException {
         final ChromeTabbedActivity2 secondActivity =
@@ -367,7 +367,7 @@
     @Test
     @MediumTest
     @DisableIf.Device(DeviceFormFactor.TABLET) // https://crbug.com/338997949
-    @DisableIf.Build(sdk_is_greater_than = VERSION_CODES.S_V2) // https://crbug.com/1297370
+    @DisableIf.Build(sdk_is_greater_than = VERSION_CODES.R) // https://crbug.com/1297370
     @MinAndroidSdkLevel(24)
     @CommandLineFlags.Add(ChromeSwitches.DISABLE_TAB_MERGING_FOR_TESTING)
     public void testOpenRecentlyClosedTabMultiWindowFallback() throws TimeoutException {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/ToolbarIphControllerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/ToolbarIphControllerUnitTest.java
deleted file mode 100644
index 3d37eb6..0000000
--- a/chrome/android/junit/src/org/chromium/chrome/browser/toolbar/ToolbarIphControllerUnitTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-// 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.
-
-package org.chromium.chrome.browser.toolbar;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.verify;
-
-import android.content.Context;
-import android.graphics.Rect;
-import android.view.View;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.chrome.R;
-import org.chromium.chrome.browser.user_education.IphCommand;
-import org.chromium.chrome.browser.user_education.UserEducationHelper;
-import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightParams;
-import org.chromium.components.browser_ui.widget.highlight.ViewHighlighter.HighlightShape;
-
-@RunWith(BaseRobolectricTestRunner.class)
-public class ToolbarIphControllerUnitTest {
-    public @Rule MockitoRule mMockitoRule = MockitoJUnit.rule();
-    private @Mock UserEducationHelper mEducationHelper;
-    private @Mock View mAnchorView;
-
-    private Context mContext;
-    private ToolbarIphController mToolbarIphController;
-
-    @Before
-    public void setUp() {
-        mContext = ContextUtils.getApplicationContext();
-        mToolbarIphController = new ToolbarIphController(mContext, mEducationHelper);
-    }
-
-    @Test
-    public void testShowPriceDropIph() {
-        int y_inset = mContext.getResources().getDimensionPixelSize(R.dimen.toolbar_iph_y_inset);
-        mToolbarIphController.showPriceDropIph(mAnchorView);
-
-        HighlightParams expectedParams = new HighlightParams(HighlightShape.CIRCLE);
-        expectedParams.setBoundsRespectPadding(true);
-        Rect expectedRect = new Rect(0, 0, 0, -y_inset);
-
-        ArgumentCaptor<IphCommand> captor = ArgumentCaptor.forClass(IphCommand.class);
-        verify(mEducationHelper).requestShowIph(captor.capture());
-
-        IphCommand cmd = captor.getValue();
-        assertEquals(R.string.price_drop_spotted_iph, cmd.accessibilityStringId);
-        assertEquals(R.string.price_drop_spotted_iph, cmd.stringId);
-        assertEquals(mAnchorView, cmd.anchorView);
-        assertEquals(expectedRect, cmd.insetRect);
-        assertEquals(HighlightShape.CIRCLE, cmd.highlightParams.getShape());
-        assertTrue(cmd.dismissOnTouch);
-    }
-}
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 059f686..23dabc33 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -17479,6 +17479,14 @@
         QR code
       </message>
 
+      <message name="IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTING_TITLE" desc="The title of a dialog that is shown when the computer is connecting to a phone or tablet." translateable="false">
+        Connecting to your device
+      </message>
+
+      <message name="IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTED_TITLE" desc="The title of a dialog that shows once the computer has successfully connected to the user's phone or tablet. That phone/tablet will be showing instructions for what to do next and the user should follow those instructions." translateable="false">
+        Follow the steps on your device
+      </message>
+
     <!-- Interstitial shown prior to making digital identity request to wallet -->
     <!-- Android strings are declared in android_chrome_strings.grd. -->
     <message name="IDS_WEB_DIGITAL_CREDENTIALS_INTERSTITIAL_DIALOG_TITLE" translateable="false">
diff --git a/chrome/app/generated_resources_grd/IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTED_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTED_TITLE.png.sha1
new file mode 100644
index 0000000..bedb395
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTED_TITLE.png.sha1
@@ -0,0 +1 @@
+b6780cdeffac47992dc8ca188d72220ab8b82066
\ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTING_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTING_TITLE.png.sha1
new file mode 100644
index 0000000..21a75cc
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTING_TITLE.png.sha1
@@ -0,0 +1 @@
+8c2f5ee2298c0f000286713a6d1052feb3c4a25d
\ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 7b82313..6c8d5a7 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -2572,6 +2572,8 @@
       "android/compositor/layer/content_layer.h",
       "android/compositor/layer/contextual_search_layer.cc",
       "android/compositor/layer/contextual_search_layer.h",
+      "android/compositor/layer/group_indicator_layer.cc",
+      "android/compositor/layer/group_indicator_layer.h",
       "android/compositor/layer/layer.h",
       "android/compositor/layer/overlay_panel_layer.cc",
       "android/compositor/layer/overlay_panel_layer.h",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 1e638bc..fa37153 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -308,7 +308,6 @@
 #include "chromeos/ash/components/assistant/buildflags.h"
 #include "chromeos/ash/components/memory/swap_configuration.h"
 #include "chromeos/ash/components/standalone_browser/channel_util.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 #include "chromeos/ash/components/standalone_browser/standalone_browser_features.h"
 #include "chromeos/ash/services/assistant/public/cpp/features.h"
 #include "chromeos/constants/chromeos_switches.h"
@@ -1025,23 +1024,9 @@
 const char kArcEnableVirtioBlkForDataInternalName[] =
     "arc-enable-virtio-blk-for-data";
 
-const char kLacrosSelectionInternalName[] = "lacros-selection";
 const char kProjectorServerSideSpeechRecognition[] =
     "enable-projector-server-side-speech-recognition";
 
-const FeatureEntry::Choice kLacrosSelectionChoices[] = {
-    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
-    {flag_descriptions::kLacrosSelectionStatefulDescription,
-     ash::standalone_browser::kLacrosSelectionSwitch,
-     ash::standalone_browser::kLacrosSelectionStateful},
-    {flag_descriptions::kLacrosSelectionRootfsDescription,
-     ash::standalone_browser::kLacrosSelectionSwitch,
-     ash::standalone_browser::kLacrosSelectionRootfs},
-};
-
-const char kLacrosSelectionPolicyIgnoreInternalName[] =
-    "lacros-selection-ignore";
-
 const char kArcEnableAttestationFlag[] = "arc-enable-attestation";
 
 #endif  // BUILDFLAG(IS_CHROMEOS)
@@ -2231,6 +2216,18 @@
          std::size(kResamplingScrollEventsPredictionFramesBasedEnabled),
          nullptr}};
 
+const FeatureEntry::FeatureParam
+    kShowWarningsForSuspiciousNotificationsScoreThreshold70[] = {
+        {"ShowWarningsForSuspiciousNotificationsScoreThreshold", "70"}};
+
+const FeatureEntry::FeatureVariation
+    kShowWarningsForSuspiciousNotificationsVariations[] = {
+        {"with suspicious score 70",
+         kShowWarningsForSuspiciousNotificationsScoreThreshold70,
+         std::size(kShowWarningsForSuspiciousNotificationsScoreThreshold70),
+         nullptr},
+};
+
 #if BUILDFLAG(IS_ANDROID)
 const FeatureEntry::FeatureParam kStartSurfaceReturnTime_Immediate[] = {
     {"start_surface_return_time_seconds", "0"},
@@ -4791,13 +4788,6 @@
      flag_descriptions::kLacrosProfileBackwardMigrationName,
      flag_descriptions::kLacrosProfileBackwardMigrationDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kLacrosProfileBackwardMigration)},
-    {kLacrosSelectionInternalName, flag_descriptions::kLacrosSelectionName,
-     flag_descriptions::kLacrosSelectionDescription, kOsCrOS,
-     MULTI_VALUE_TYPE(kLacrosSelectionChoices)},
-    {kLacrosSelectionPolicyIgnoreInternalName,
-     flag_descriptions::kLacrosSelectionPolicyIgnoreName,
-     flag_descriptions::kLacrosSelectionPolicyIgnoreDescription, kOsCrOS,
-     SINGLE_VALUE_TYPE(ash::switches::kLacrosSelectionPolicyIgnore)},
     {"list-all-display-modes", flag_descriptions::kListAllDisplayModesName,
      flag_descriptions::kListAllDisplayModesDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(display::features::kListAllDisplayModes)},
@@ -7416,6 +7406,15 @@
      FEATURE_VALUE_TYPE(chrome::android::kShowNewTabAnimations)},
 #endif  // BUILDFLAG(IS_ANDROID)
 
+    {"show-warnings-for-suspicious-notifications",
+     flag_descriptions::kShowWarningsForSuspiciousNotificationsName,
+     flag_descriptions::kShowWarningsForSuspiciousNotificationsDescription,
+     kOsAndroid,
+     FEATURE_WITH_PARAMS_VALUE_TYPE(
+         safe_browsing::kShowWarningsForSuspiciousNotifications,
+         kShowWarningsForSuspiciousNotificationsVariations,
+         "ShowWarningsForSuspiciousNotifications")},
+
     {"unsafely-treat-insecure-origin-as-secure",
      flag_descriptions::kTreatInsecureOriginAsSecureName,
      flag_descriptions::kTreatInsecureOriginAsSecureDescription, kOsAll,
@@ -11222,6 +11221,9 @@
      FEATURE_WITH_PARAMS_VALUE_TYPE(features::kTabstripDeclutter,
                                     kTabstripDeclutterVariations,
                                     "TabstripDeclutter")},
+    {"tabstrip-dedupe", flag_descriptions::kTabstripDedupeName,
+     flag_descriptions::kTabstripDedupeDescription, kOsDesktop,
+     FEATURE_VALUE_TYPE(features::kTabstripDedupe)},
 #endif
 
 #if !BUILDFLAG(IS_ANDROID)
@@ -11988,12 +11990,6 @@
     return true;
   }
 
-  // Skip lacros-selection if it is controlled by LacrosSelection policy.
-  if (!strcmp(kLacrosSelectionInternalName, entry.internal_name)) {
-    return ash::standalone_browser::GetCachedLacrosSelectionPolicy() !=
-           ash::standalone_browser::LacrosSelectionPolicy::kUserChoice;
-  }
-
   // Skip arc-enable-attestation if it is enabled by ash switch.
   if (!strcmp(kArcEnableAttestationFlag, entry.internal_name)) {
     return base::CommandLine::ForCurrentProcess()->HasSwitch(
diff --git a/chrome/browser/android/compositor/layer/OWNERS b/chrome/browser/android/compositor/layer/OWNERS
index e5a14fb9..03ee27e 100644
--- a/chrome/browser/android/compositor/layer/OWNERS
+++ b/chrome/browser/android/compositor/layer/OWNERS
@@ -1 +1,2 @@
-per-file *tab_handle*=file://chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/OWNERS
\ No newline at end of file
+per-file *tab_handle*=file://chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/OWNERS
+per-file *group_indicator*=file://chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/OWNERS
diff --git a/chrome/browser/android/compositor/layer/group_indicator_layer.cc b/chrome/browser/android/compositor/layer/group_indicator_layer.cc
new file mode 100644
index 0000000..d313f81
--- /dev/null
+++ b/chrome/browser/android/compositor/layer/group_indicator_layer.cc
@@ -0,0 +1,139 @@
+// 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/android/compositor/layer/group_indicator_layer.h"
+
+#include "cc/slim/solid_color_layer.h"
+#include "chrome/browser/android/compositor/decoration_icon_title.h"
+#include "chrome/browser/android/compositor/layer_title_cache.h"
+#include "ui/base/l10n/l10n_util_android.h"
+
+namespace android {
+
+// static
+scoped_refptr<GroupIndicatorLayer> GroupIndicatorLayer::Create(
+    LayerTitleCache* layer_title_cache) {
+  return base::WrapRefCounted(new GroupIndicatorLayer(layer_title_cache));
+}
+
+void GroupIndicatorLayer::SetProperties(int id,
+                                        int tint,
+                                        int bubble_tint,
+                                        bool incognito,
+                                        bool foreground,
+                                        bool show_bubble,
+                                        float x,
+                                        float y,
+                                        float width,
+                                        float height,
+                                        float title_start_padding,
+                                        float title_end_padding,
+                                        float corner_radius,
+                                        float bottom_indicator_width,
+                                        float bottom_indicator_height,
+                                        float bubble_size,
+                                        float tab_strip_height) {
+  // Update group indicator properties.
+  foreground_ = foreground;
+  group_indicator_->SetPosition(gfx::PointF(x, y));
+  group_indicator_->SetBounds(gfx::Size(width, height));
+  group_indicator_->SetRoundedCorner(gfx::RoundedCornersF(
+      corner_radius, corner_radius, corner_radius, corner_radius));
+  group_indicator_->SetBackgroundColor(SkColor4f::FromColor(tint));
+
+  // Show title if needed.
+  DecorationIconTitle* title_layer = nullptr;
+  // Only pull if group id is valid.
+  if (layer_title_cache_ && id != -1) {
+    title_layer = layer_title_cache_->GetGroupTitleLayer(id, incognito);
+  }
+  if (title_layer) {
+    // Ensure we're using the updated title bitmap prior to accessing/updating
+    // any properties.
+    title_layer->SetUIResourceIds();
+
+    float title_y = (height - title_layer->size().height()) / 2.f;
+    title_layer->setBounds(
+        gfx::Size(width - title_start_padding - title_end_padding, height));
+    title_layer_ = title_layer->layer();
+    title_layer_->SetPosition(gfx::PointF(title_start_padding, title_y));
+
+    unsigned expected_children = 2;
+    if (group_indicator_->children().size() < expected_children) {
+      group_indicator_->AddChild(title_layer_);
+    } else {
+      group_indicator_->ReplaceChild(
+          group_indicator_->children()[expected_children - 1].get(),
+          title_layer_);
+    }
+  } else if (title_layer_.get()) {
+    title_layer_->RemoveFromParent();
+    title_layer_ = nullptr;
+  }
+
+  // Show notification bubble if needed.
+  if (show_bubble) {
+    float bubble_x = l10n_util::IsLayoutRtl()
+                         ? title_end_padding
+                         : width - title_end_padding - bubble_size;
+    float bubble_y = (height - bubble_size) / 2.0f;
+    float corner_size = bubble_size / 2.0f;
+
+    notification_bubble_->SetIsDrawable(true);
+    notification_bubble_->SetBounds(gfx::Size(bubble_size, bubble_size));
+    notification_bubble_->SetPosition(gfx::PointF(bubble_x, bubble_y));
+    notification_bubble_->SetBackgroundColor(SkColor4f::FromColor(bubble_tint));
+    notification_bubble_->SetRoundedCorner(gfx::RoundedCornersF(
+        corner_size, corner_size, corner_size, corner_size));
+  } else {
+    notification_bubble_->SetIsDrawable(false);
+  }
+
+  // Set bottom indicator properties.
+  float bottom_indicator_x = x;
+  float bottom_indicator_y = tab_strip_height - bottom_indicator_height;
+  if (l10n_util::IsLayoutRtl()) {
+    bottom_indicator_x -= (bottom_indicator_width - width);
+  }
+
+  // Use ceiling value to prevent height float from getting truncated, otherwise
+  // it could result in bottom indicator looks thinner than intended in certain
+  // screen densities.
+  bottom_outline_->SetBounds(
+      gfx::Size(bottom_indicator_width, ceil(bottom_indicator_height)));
+
+  // Use the floor value to position vertically to prevent bottom indicator from
+  // getting cut off in certain screen densities.
+  bottom_outline_->SetPosition(
+      gfx::PointF(bottom_indicator_x, floor(bottom_indicator_y)));
+  bottom_outline_->SetBackgroundColor(SkColor4f::FromColor(tint));
+}
+
+bool GroupIndicatorLayer::foreground() {
+  return foreground_;
+}
+
+scoped_refptr<cc::slim::Layer> GroupIndicatorLayer::layer() {
+  return layer_;
+}
+
+GroupIndicatorLayer::GroupIndicatorLayer(LayerTitleCache* layer_title_cache)
+    : layer_title_cache_(layer_title_cache),
+      layer_(cc::slim::Layer::Create()),
+      group_indicator_(cc::slim::SolidColorLayer::Create()),
+      bottom_outline_(cc::slim::SolidColorLayer::Create()),
+      notification_bubble_(cc::slim::SolidColorLayer::Create()),
+      foreground_(false) {
+  group_indicator_->SetIsDrawable(true);
+  bottom_outline_->SetIsDrawable(true);
+  notification_bubble_->SetIsDrawable(false);
+
+  layer_->AddChild(group_indicator_);
+  layer_->AddChild(bottom_outline_);
+  group_indicator_->AddChild(notification_bubble_);
+}
+
+GroupIndicatorLayer::~GroupIndicatorLayer() {}
+
+}  // namespace android
diff --git a/chrome/browser/android/compositor/layer/group_indicator_layer.h b/chrome/browser/android/compositor/layer/group_indicator_layer.h
new file mode 100644
index 0000000..13187de
--- /dev/null
+++ b/chrome/browser/android/compositor/layer/group_indicator_layer.h
@@ -0,0 +1,66 @@
+// 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_ANDROID_COMPOSITOR_LAYER_GROUP_INDICATOR_LAYER_H_
+#define CHROME_BROWSER_ANDROID_COMPOSITOR_LAYER_GROUP_INDICATOR_LAYER_H_
+
+#include "base/memory/raw_ptr.h"
+#include "chrome/browser/android/compositor/layer/layer.h"
+
+namespace cc::slim {
+class Layer;
+class SolidColorLayer;
+}  // namespace cc::slim
+
+namespace android {
+
+class LayerTitleCache;
+
+class GroupIndicatorLayer : public Layer {
+ public:
+  static scoped_refptr<GroupIndicatorLayer> Create(
+      LayerTitleCache* layer_title_cache);
+
+  GroupIndicatorLayer(const GroupIndicatorLayer&) = delete;
+  GroupIndicatorLayer& operator=(const GroupIndicatorLayer&) = delete;
+
+  void SetProperties(int id,
+                     int tint,
+                     int bubble_tint,
+                     bool incognito,
+                     bool foreground,
+                     bool show_bubble,
+                     float x,
+                     float y,
+                     float width,
+                     float height,
+                     float title_start_padding,
+                     float title_end_padding,
+                     float corner_radius,
+                     float bottom_indicator_width,
+                     float bottom_indicator_height,
+                     float bubble_size,
+                     float tab_strip_height);
+  bool foreground();
+  scoped_refptr<cc::slim::Layer> layer() override;
+
+ protected:
+  explicit GroupIndicatorLayer(LayerTitleCache* layer_title_cache);
+  ~GroupIndicatorLayer() override;
+
+ private:
+  raw_ptr<LayerTitleCache> layer_title_cache_;
+
+  scoped_refptr<cc::slim::Layer> layer_;
+  scoped_refptr<cc::slim::SolidColorLayer> group_indicator_;
+  scoped_refptr<cc::slim::SolidColorLayer> bottom_outline_;
+  scoped_refptr<cc::slim::SolidColorLayer> notification_bubble_;
+  scoped_refptr<cc::slim::Layer> title_layer_;
+
+  bool foreground_;
+};
+
+}  // namespace android
+
+#endif  // CHROME_BROWSER_ANDROID_COMPOSITOR_LAYER_GROUP_INDICATOR_LAYER_H_
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.cc b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
index 5144d08..1de7fbd 100644
--- a/chrome/browser/android/compositor/layer/tab_handle_layer.cc
+++ b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
@@ -8,19 +8,11 @@
 
 #include <vector>
 
-#include "base/feature_list.h"
-#include "base/i18n/rtl.h"
-#include "base/metrics/field_trial_params.h"
-#include "cc/resources/scoped_ui_resource.h"
-#include "cc/slim/filter.h"
 #include "cc/slim/layer.h"
 #include "cc/slim/nine_patch_layer.h"
-#include "cc/slim/solid_color_layer.h"
 #include "chrome/browser/android/compositor/decoration_tab_title.h"
 #include "chrome/browser/android/compositor/layer_title_cache.h"
-#include "chrome/browser/flags/android/chrome_feature_list.h"
 #include "ui/android/resources/nine_patch_resource.h"
-#include "ui/android/resources/resource_manager.h"
 #include "ui/base/l10n/l10n_util_android.h"
 
 namespace android {
@@ -268,6 +260,10 @@
   }
 }
 
+bool TabHandleLayer::foreground() {
+  return foreground_;
+}
+
 scoped_refptr<cc::slim::Layer> TabHandleLayer::layer() {
   return layer_;
 }
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.h b/chrome/browser/android/compositor/layer/tab_handle_layer.h
index fdd8fd8..2cf23a4 100644
--- a/chrome/browser/android/compositor/layer/tab_handle_layer.h
+++ b/chrome/browser/android/compositor/layer/tab_handle_layer.h
@@ -56,6 +56,7 @@
                      bool is_loading,
                      float spinner_rotation,
                      float opacity);
+  bool foreground();
   scoped_refptr<cc::slim::Layer> layer() override;
 
  protected:
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
index 5259204..81a621fc 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
@@ -5,21 +5,15 @@
 #include "chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h"
 
 #include "base/android/jni_android.h"
-#include "base/feature_list.h"
-#include "cc/resources/scoped_ui_resource.h"
 #include "cc/slim/layer.h"
 #include "cc/slim/solid_color_layer.h"
 #include "cc/slim/ui_resource_layer.h"
-#include "chrome/browser/android/compositor/decoration_icon_title.h"
-#include "chrome/browser/android/compositor/decoration_title.h"
+#include "chrome/browser/android/compositor/layer/group_indicator_layer.h"
 #include "chrome/browser/android/compositor/layer/tab_handle_layer.h"
 #include "chrome/browser/android/compositor/layer_title_cache.h"
-#include "chrome/browser/flags/android/chrome_feature_list.h"
 #include "ui/android/resources/nine_patch_resource.h"
 #include "ui/android/resources/resource_manager_impl.h"
-#include "ui/base/l10n/l10n_util_android.h"
 #include "ui/gfx/geometry/point_f.h"
-#include "ui/gfx/geometry/rounded_corners_f.h"
 #include "ui/gfx/geometry/transform.h"
 
 // Must come after all headers that specialize FromJniType() / ToJniType().
@@ -34,8 +28,9 @@
                                        const JavaRef<jobject>& jobj)
     : SceneLayer(env, jobj),
       tab_strip_layer_(cc::slim::SolidColorLayer::Create()),
+      group_ui_parent_layer_(cc::slim::Layer::Create()),
       scrollable_strip_layer_(cc::slim::Layer::Create()),
-      group_indicator_layer_(cc::slim::Layer::Create()),
+      foreground_layer_(cc::slim::Layer::Create()),
       new_tab_button_(cc::slim::UIResourceLayer::Create()),
       new_tab_button_background_(cc::slim::UIResourceLayer::Create()),
       left_fade_(cc::slim::UIResourceLayer::Create()),
@@ -61,11 +56,13 @@
   // while the incognito button and left/right fade stay fixed. Put the new tab
   // button and tabs in a separate layer placed visually below the others. Put
   // tab group indicators in a separate layer placed visually below the tabs.
-  group_indicator_layer_->SetIsDrawable(true);
+  group_ui_parent_layer_->SetIsDrawable(true);
   scrollable_strip_layer_->SetIsDrawable(true);
+  foreground_layer_->SetIsDrawable(true);
   tab_strip_layer_->SetIsDrawable(true);
-  tab_strip_layer_->AddChild(group_indicator_layer_);
+  tab_strip_layer_->AddChild(group_ui_parent_layer_);
   tab_strip_layer_->AddChild(scrollable_strip_layer_);
+  tab_strip_layer_->AddChild(foreground_layer_);
 
   tab_strip_layer_->AddChild(left_fade_);
   tab_strip_layer_->AddChild(right_fade_);
@@ -122,18 +119,13 @@
     tab_handle_layers_[i]->layer()->RemoveFromParent();
   }
   for (unsigned i = group_write_index_; i < group_title_layers_.size(); ++i) {
-    group_title_layers_[i]->RemoveFromParent();
-  }
-  for (unsigned i = group_write_index_; i < group_bottom_layers_.size(); ++i) {
-    group_bottom_layers_[i]->RemoveFromParent();
+    group_title_layers_[i]->layer()->RemoveFromParent();
   }
 
   tab_handle_layers_.erase(tab_handle_layers_.begin() + write_index_,
                            tab_handle_layers_.end());
   group_title_layers_.erase(group_title_layers_.begin() + group_write_index_,
                             group_title_layers_.end());
-  group_bottom_layers_.erase(group_bottom_layers_.begin() + group_write_index_,
-                             group_bottom_layers_.end());
 }
 
 void TabStripSceneLayer::UpdateOffsetTag(
@@ -164,8 +156,8 @@
   scrollable_strip_layer_->SetBounds(gfx::Size(width, scrollable_strip_height));
   scrollable_strip_layer_->SetPosition(gfx::PointF(0, top_padding));
 
-  group_indicator_layer_->SetBounds(gfx::Size(width, scrollable_strip_height));
-  group_indicator_layer_->SetPosition(gfx::PointF(0, top_padding));
+  group_ui_parent_layer_->SetBounds(gfx::Size(width, scrollable_strip_height));
+  group_ui_parent_layer_->SetPosition(gfx::PointF(0, top_padding));
 
   // Content tree should not be affected by tab strip scene layer visibility.
   if (content_tree_)
@@ -414,9 +406,18 @@
     const JavaParamRef<jobject>& jresource_manager) {
   LayerTitleCache* layer_title_cache =
       LayerTitleCache::FromJavaObject(jlayer_title_cache);
+  scoped_refptr<TabHandleLayer> layer = GetNextTabLayer(layer_title_cache);
+
+  if (foreground != layer->foreground()) {
+    if (foreground) {
+      foreground_layer_->AddChild(layer->layer());
+    } else {
+      scrollable_strip_layer_->AddChild(layer->layer());
+    }
+  }
+
   ui::ResourceManager* resource_manager =
       ui::ResourceManagerImpl::FromJavaObject(jresource_manager);
-  scoped_refptr<TabHandleLayer> layer = GetNextLayer(layer_title_cache);
   ui::NinePatchResource* tab_handle_resource =
       ui::NinePatchResource::From(resource_manager->GetStaticResourceWithTint(
           handle_resource_id, handle_tint, true));
@@ -426,13 +427,12 @@
   ui::Resource* close_button_resource =
       resource_manager->GetStaticResourceWithTint(close_resource_id,
                                                   close_tint);
-
   ui::Resource* close_button_hover_resource =
       resource_manager->GetStaticResourceWithTint(close_hover_bg_resource_id,
                                                   close_hover_bg_tint, true);
-
   ui::Resource* divider_resource = resource_manager->GetStaticResourceWithTint(
       divider_resource_id, divider_tint, true);
+
   layer->SetProperties(
       id, close_button_resource, close_button_hover_resource, divider_resource,
       tab_handle_resource, tab_handle_outline_resource, foreground,
@@ -446,6 +446,7 @@
     JNIEnv* env,
     const base::android::JavaParamRef<jobject>& jobj,
     jboolean incognito,
+    jboolean foreground,
     jint id,
     jint tint,
     jfloat x,
@@ -465,96 +466,26 @@
       LayerTitleCache::FromJavaObject(jlayer_title_cache);
 
   // Reuse existing layer if it exists.
-  scoped_refptr<cc::slim::SolidColorLayer> title_indicator_layer =
-      GetNextGroupTitleLayer();
-  scoped_refptr<cc::slim::SolidColorLayer> bottom_indicator_layer =
-      GetNextGroupBottomLayer();
-  group_write_index_++;
+  scoped_refptr<GroupIndicatorLayer> layer =
+      GetNextGroupIndicatorLayer(layer_title_cache);
 
-  // Set title indicator container properties.
-  title_indicator_layer->SetPosition(gfx::PointF(x, y));
-  title_indicator_layer->SetBounds(gfx::Size(width, height));
-  title_indicator_layer->SetRoundedCorner(gfx::RoundedCornersF(
-      corner_radius, corner_radius, corner_radius, corner_radius));
-  title_indicator_layer->SetBackgroundColor(SkColor4f::FromColor(tint));
-
-  // Create notification bubble if needed.
-  if (show_bubble && !group_indicator_bubble_layer_) {
-    int bubble_x = l10n_util::IsLayoutRtl()
-                       ? title_end_padding
-                       : width - title_end_padding - bubble_size;
-    int bubble_y = (height - bubble_size) / 2.0f;
-    CreateGroupTitleBubble(bubble_size, bubble_tint, bubble_x, bubble_y);
-  }
-
-  // Set title.
-  DecorationIconTitle* title_layer =
-      layer_title_cache->GetGroupTitleLayer(id, incognito);
-  if (title_layer) {
-    // Ensure we're using the updated title bitmap prior to accessing/updating
-    // any properties.
-    title_layer->SetUIResourceIds();
-
-    float title_y = (height - title_layer->size().height()) / 2.f;
-    title_layer->setOpacity(1.0f);
-    title_layer->setBounds(
-        gfx::Size(width - title_start_padding - title_end_padding, height));
-    title_layer->layer()->SetPosition(
-        gfx::PointF(title_start_padding, title_y));
-    if (title_indicator_layer->children().size() == 0) {
-      title_indicator_layer->AddChild(title_layer->layer());
-      if (show_bubble) {
-        title_indicator_layer->AddChild(group_indicator_bubble_layer_);
-      }
+  // Foreground if needed.
+  if (foreground != layer->foreground()) {
+    if (foreground) {
+      foreground_layer_->AddChild(layer->layer());
     } else {
-      title_indicator_layer->RemoveAllChildren();
-      title_indicator_layer->AddChild(title_layer->layer());
-      if (show_bubble) {
-        title_indicator_layer->AddChild(group_indicator_bubble_layer_);
-      }
+      group_ui_parent_layer_->AddChild(layer->layer());
     }
-  } else {
-    title_indicator_layer->RemoveAllChildren();
   }
 
-  // Set bottom indicator properties.
-  float bottom_indicator_x = x;
-  float bottom_indicator_y =
-      group_indicator_layer_->bounds().height() - bottom_indicator_height;
-  if (l10n_util::IsLayoutRtl()) {
-    bottom_indicator_x -= (bottom_indicator_width - width);
-  }
-
-  // Use ceiling value to prevent height float from getting truncated, otherwise
-  // it could result in bottom indicator looks thinner than intended in certain
-  // screen densities.
-  // TODO:(crbug.com/383958147): Move bottom indicator and tab bubble to
-  // separate class.
-  bottom_indicator_layer->SetBounds(
-      gfx::Size(bottom_indicator_width, ceil(bottom_indicator_height)));
-
-  // Use the floor value to position vertically to prevent bottom indicator from
-  // getting cut off in certain screen densities.
-  bottom_indicator_layer->SetPosition(
-      gfx::PointF(bottom_indicator_x, floor(bottom_indicator_y)));
-  bottom_indicator_layer->SetBackgroundColor(SkColor4f::FromColor(tint));
+  layer->SetProperties(id, tint, bubble_tint, incognito, foreground,
+                       show_bubble, x, y, width, height, title_start_padding,
+                       title_end_padding, corner_radius, bottom_indicator_width,
+                       bottom_indicator_height, bubble_size,
+                       group_ui_parent_layer_->bounds().height());
 }
 
-void TabStripSceneLayer::CreateGroupTitleBubble(int size,
-                                                int tint,
-                                                int x,
-                                                int y) {
-  group_indicator_bubble_layer_ = cc::slim::SolidColorLayer::Create();
-  group_indicator_bubble_layer_->SetBounds(gfx::Size(size, size));
-  group_indicator_bubble_layer_->SetPosition(gfx::PointF(x, y));
-  group_indicator_bubble_layer_->SetBackgroundColor(SkColor4f::FromColor(tint));
-  group_indicator_bubble_layer_->SetOpacity(1.0f);
-  group_indicator_bubble_layer_->SetIsDrawable(true);
-  group_indicator_bubble_layer_->SetRoundedCorner(
-      gfx::RoundedCornersF(size / 2.0f, size / 2.0f, size / 2.0f, size / 2.0f));
-}
-
-scoped_refptr<TabHandleLayer> TabStripSceneLayer::GetNextLayer(
+scoped_refptr<TabHandleLayer> TabStripSceneLayer::GetNextTabLayer(
     LayerTitleCache* layer_title_cache) {
   if (write_index_ < tab_handle_layers_.size())
     return tab_handle_layers_[write_index_++];
@@ -567,32 +498,19 @@
   return layer_tree;
 }
 
-scoped_refptr<cc::slim::SolidColorLayer>
-TabStripSceneLayer::GetNextGroupTitleLayer() {
+scoped_refptr<GroupIndicatorLayer>
+TabStripSceneLayer::GetNextGroupIndicatorLayer(
+    LayerTitleCache* layer_title_cache) {
   if (group_write_index_ < group_title_layers_.size()) {
-    return group_title_layers_[group_write_index_];
+    return group_title_layers_[group_write_index_++];
   }
 
-  scoped_refptr<cc::slim::SolidColorLayer> layer =
-      cc::slim::SolidColorLayer::Create();
-  layer->SetIsDrawable(true);
-  group_title_layers_.push_back(layer);
-  group_indicator_layer_->AddChild(layer);
-  return layer;
-}
-
-scoped_refptr<cc::slim::SolidColorLayer>
-TabStripSceneLayer::GetNextGroupBottomLayer() {
-  if (group_write_index_ < group_bottom_layers_.size()) {
-    return group_bottom_layers_[group_write_index_];
-  }
-
-  scoped_refptr<cc::slim::SolidColorLayer> layer =
-      cc::slim::SolidColorLayer::Create();
-  layer->SetIsDrawable(true);
-  group_bottom_layers_.push_back(layer);
-  group_indicator_layer_->AddChild(layer);
-  return layer;
+  scoped_refptr<GroupIndicatorLayer> layer_tree =
+      GroupIndicatorLayer::Create(layer_title_cache);
+  group_title_layers_.push_back(layer_tree);
+  group_ui_parent_layer_->AddChild(layer_tree->layer());
+  group_write_index_++;
+  return layer_tree;
 }
 
 bool TabStripSceneLayer::ShouldShowBackground() {
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
index a016b845..38a52e6 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
+++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
@@ -9,7 +9,6 @@
 #include <vector>
 
 #include "base/android/jni_android.h"
-#include "base/android/jni_weak_ref.h"
 #include "base/android/scoped_java_ref.h"
 #include "base/memory/raw_ptr.h"
 #include "cc/input/android/offset_tag_android.h"
@@ -24,6 +23,7 @@
 
 namespace android {
 
+class GroupIndicatorLayer;
 class LayerTitleCache;
 class TabHandleLayer;
 
@@ -154,6 +154,7 @@
       JNIEnv* env,
       const base::android::JavaParamRef<jobject>& jobj,
       jboolean incognito,
+      jboolean foreground,
       jint id,
       jint tint,
       jfloat x,
@@ -174,11 +175,11 @@
   SkColor GetBackgroundColor() override;
 
  private:
-  scoped_refptr<TabHandleLayer> GetNextLayer(
+  scoped_refptr<TabHandleLayer> GetNextTabLayer(
       LayerTitleCache* layer_title_cache);
 
-  scoped_refptr<cc::slim::SolidColorLayer> GetNextGroupTitleLayer();
-  scoped_refptr<cc::slim::SolidColorLayer> GetNextGroupBottomLayer();
+  scoped_refptr<GroupIndicatorLayer> GetNextGroupIndicatorLayer(
+      LayerTitleCache* layer_title_cache);
 
   void UpdateCompositorButton(
       scoped_refptr<cc::slim::UIResourceLayer> button,
@@ -191,14 +192,12 @@
       bool should_apply_hover_highlight,
       float button_alpha);
 
-  void CreateGroupTitleBubble(int bubble_size, int bubble_tint, int x, int y);
-
   typedef std::vector<scoped_refptr<TabHandleLayer>> TabHandleLayerList;
 
   scoped_refptr<cc::slim::SolidColorLayer> tab_strip_layer_;
-  scoped_refptr<cc::slim::SolidColorLayer> group_indicator_bubble_layer_;
+  scoped_refptr<cc::slim::Layer> group_ui_parent_layer_;
   scoped_refptr<cc::slim::Layer> scrollable_strip_layer_;
-  scoped_refptr<cc::slim::Layer> group_indicator_layer_;
+  scoped_refptr<cc::slim::Layer> foreground_layer_;
   scoped_refptr<cc::slim::UIResourceLayer> new_tab_button_;
   scoped_refptr<cc::slim::UIResourceLayer> new_tab_button_background_;
   scoped_refptr<cc::slim::UIResourceLayer> left_fade_;
@@ -216,8 +215,7 @@
   unsigned write_index_ = 0;
   TabHandleLayerList tab_handle_layers_;
   unsigned group_write_index_ = 0;
-  std::vector<scoped_refptr<cc::slim::SolidColorLayer>> group_title_layers_;
-  std::vector<scoped_refptr<cc::slim::SolidColorLayer>> group_bottom_layers_;
+  std::vector<scoped_refptr<GroupIndicatorLayer>> group_title_layers_;
   raw_ptr<SceneLayer> content_tree_;
 };
 
diff --git a/chrome/browser/android/metrics/variations_session.cc b/chrome/browser/android/metrics/variations_session.cc
index 76cfa209..03682d8 100644
--- a/chrome/browser/android/metrics/variations_session.cc
+++ b/chrome/browser/android/metrics/variations_session.cc
@@ -40,14 +40,13 @@
 static std::string JNI_VariationsSession_GetLatestCountry(
     JNIEnv* env,
     const JavaParamRef<jobject>& obj) {
+  std::string latest_country;
+
   variations::VariationsService* variations_service =
       g_browser_process->variations_service();
-  if (!variations_service)
-    return nullptr;
-
-  std::string latest_country = variations_service->GetLatestCountry();
-  if (latest_country.empty())
-    return nullptr;
+  if (variations_service) {
+    latest_country = variations_service->GetLatestCountry();
+  }
 
   return latest_country;
 }
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index ea59d933..97b9b6c5 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -5379,8 +5379,6 @@
 }
 
 IN_PROC_BROWSER_TEST_P(WebViewAccessibilityTest, LoadWebViewAccessibility) {
-  SKIP_FOR_MPARCH();  // TODO(crbug.com/40202416): Enable test for MPArch.
-
   content::ScopedAccessibilityModeOverride mode_override(ui::kAXModeComplete);
   LoadAppWithGuest("web_view/focus_accessibility");
   content::WebContents* web_contents = GetFirstAppWindowWebContents();
@@ -5389,8 +5387,6 @@
 }
 
 IN_PROC_BROWSER_TEST_P(WebViewAccessibilityTest, FocusAccessibility) {
-  SKIP_FOR_MPARCH();  // TODO(crbug.com/40202416): Enable test for MPArch.
-
   content::ScopedAccessibilityModeOverride mode_override(ui::kAXModeComplete);
   LoadAppWithGuest("web_view/focus_accessibility");
   content::WebContents* web_contents = GetFirstAppWindowWebContents();
@@ -5426,8 +5422,6 @@
 // The test was disabled. See crbug.com/1141313.
 IN_PROC_BROWSER_TEST_P(WebViewAccessibilityTest,
                        DISABLED_FocusAccessibilityNestedFrame) {
-  SKIP_FOR_MPARCH();  // TODO(crbug.com/40202416): Enable test for MPArch.
-
   content::ScopedAccessibilityModeOverride mode_override(ui::kAXModeComplete);
   LoadAppWithGuest("web_view/focus_accessibility");
   content::WebContents* web_contents = GetFirstAppWindowWebContents();
@@ -5510,8 +5504,6 @@
 };
 
 IN_PROC_BROWSER_TEST_P(WebViewAccessibilityTest, DISABLED_TouchAccessibility) {
-  SKIP_FOR_MPARCH();  // TODO(crbug.com/40202416): Enable test for MPArch.
-
   content::ScopedAccessibilityModeOverride mode_override(ui::kAXModeComplete);
   LoadAppWithGuest("web_view/touch_accessibility");
   content::WebContents* web_contents = GetFirstAppWindowWebContents();
diff --git a/chrome/browser/ash/bruschetta/bruschetta_network_context.cc b/chrome/browser/ash/bruschetta/bruschetta_network_context.cc
index a865257f..cea9c343 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_network_context.cc
+++ b/chrome/browser/ash/bruschetta/bruschetta_network_context.cc
@@ -262,6 +262,7 @@
     const url::Origin& request_origin,
     std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
         methods_with_options,
+    const std::optional<std::string>& with_lock,
     OnSharedStorageHeaderReceivedCallback callback) {
   std::move(callback).Run();
 }
diff --git a/chrome/browser/ash/bruschetta/bruschetta_network_context.h b/chrome/browser/ash/bruschetta/bruschetta_network_context.h
index 61c71ec..d3b6ce3d 100644
--- a/chrome/browser/ash/bruschetta/bruschetta_network_context.h
+++ b/chrome/browser/ash/bruschetta/bruschetta_network_context.h
@@ -88,6 +88,7 @@
       const url::Origin& request_origin,
       std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
           methods_with_options,
+      const std::optional<std::string>& with_lock,
       OnSharedStorageHeaderReceivedCallback callback) override;
   void Clone(
       mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver>
diff --git a/chrome/browser/ash/crosapi/browser_loader.h b/chrome/browser/ash/crosapi/browser_loader.h
index ee762dd3..32c6398 100644
--- a/chrome/browser/ash/crosapi/browser_loader.h
+++ b/chrome/browser/ash/crosapi/browser_loader.h
@@ -17,7 +17,6 @@
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
 #include "base/version.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 
 namespace component_updater {
 class ComponentManagerAsh;
@@ -27,7 +26,6 @@
 
 class LacrosSelectionLoader;
 class LacrosSelectionLoaderFactory;
-using ash::standalone_browser::LacrosSelection;
 
 // Manages download of the lacros-chrome binary.
 // This class is a part of ash-chrome.
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc
index e9fb80b0..5e532932 100644
--- a/chrome/browser/ash/crosapi/browser_manager.cc
+++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -71,7 +71,6 @@
 #include "chrome/common/chrome_paths.h"
 #include "chromeos/ash/components/browser_context_helper/browser_context_helper.h"
 #include "chromeos/ash/components/standalone_browser/channel_util.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 #include "chromeos/crosapi/cpp/crosapi_constants.h"
 #include "chromeos/crosapi/cpp/lacros_startup_state.h"
 #include "chromeos/crosapi/mojom/crosapi.mojom-shared.h"
diff --git a/chrome/browser/ash/crosapi/browser_manager.h b/chrome/browser/ash/crosapi/browser_manager.h
index 4f67a87..231a238 100644
--- a/chrome/browser/ash/crosapi/browser_manager.h
+++ b/chrome/browser/ash/crosapi/browser_manager.h
@@ -22,7 +22,6 @@
 #include "chrome/browser/ash/crosapi/crosapi_id.h"
 #include "chrome/browser/ui/browser_navigator_params.h"
 #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 #include "components/component_updater/component_updater_service.h"
 #include "components/session_manager/core/session_manager_observer.h"
 #include "components/user_manager/user_manager.h"
@@ -38,7 +37,6 @@
 
 class BrowserLoader;
 
-using ash::standalone_browser::LacrosSelection;
 using component_updater::ComponentUpdateService;
 
 // Manages the lifetime of lacros-chrome, and its loading status. Observes the
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h
index 25bec24..9651c924 100644
--- a/chrome/browser/ash/crosapi/browser_util.h
+++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -5,8 +5,6 @@
 #ifndef CHROME_BROWSER_ASH_CROSAPI_BROWSER_UTIL_H_
 #define CHROME_BROWSER_ASH_CROSAPI_BROWSER_UTIL_H_
 
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
-
 namespace aura {
 class Window;
 }  // namespace aura
@@ -47,10 +45,6 @@
 base::Version GetRootfsLacrosVersionMayBlock(
     const base::FilePath& version_file_path);
 
-// Returns the update channel associated with the given loaded lacros selection.
-version_info::Channel GetLacrosSelectionUpdateChannel(
-    ash::standalone_browser::LacrosSelection selection);
-
 // Returns the currently installed version of lacros-chrome managed by the
 // component updater. Will return an empty / invalid version if no lacros
 // component is found.
diff --git a/chrome/browser/ash/crosapi/crosapi_util.h b/chrome/browser/ash/crosapi/crosapi_util.h
index 3dfa5c1..dcbac07 100644
--- a/chrome/browser/ash/crosapi/crosapi_util.h
+++ b/chrome/browser/ash/crosapi/crosapi_util.h
@@ -14,7 +14,6 @@
 #include "base/files/scoped_file.h"
 #include "base/token.h"
 #include "chrome/browser/ash/crosapi/browser_util.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 #include "chromeos/crosapi/mojom/crosapi.mojom.h"
 #include "components/policy/core/common/cloud/cloud_policy_core.h"
 #include "components/policy/core/common/cloud/component_cloud_policy_service.h"
diff --git a/chrome/browser/ash/lobster/lobster_client_impl.cc b/chrome/browser/ash/lobster/lobster_client_impl.cc
index 0fdc958..1301f8e 100644
--- a/chrome/browser/ash/lobster/lobster_client_impl.cc
+++ b/chrome/browser/ash/lobster/lobster_client_impl.cc
@@ -63,7 +63,3 @@
                                        StatusCallback insert_status_callback) {
   service_->QueueInsertion(image_bytes, std::move(insert_status_callback));
 }
-
-bool LobsterClientImpl::UserHasAccess() {
-  return service_->UserHasAccess();
-}
diff --git a/chrome/browser/ash/lobster/lobster_client_impl.h b/chrome/browser/ash/lobster/lobster_client_impl.h
index dd66092b..544154f8 100644
--- a/chrome/browser/ash/lobster/lobster_client_impl.h
+++ b/chrome/browser/ash/lobster/lobster_client_impl.h
@@ -42,7 +42,6 @@
   void LoadUI(std::optional<std::string> query, ash::LobsterMode mode) override;
   void ShowUI() override;
   void CloseUI() override;
-  bool UserHasAccess() override;
 
  private:
   // Not owned by this class
diff --git a/chrome/browser/ash/lobster/lobster_service.cc b/chrome/browser/ash/lobster/lobster_service.cc
index fff40eb6..3029588a 100644
--- a/chrome/browser/ash/lobster/lobster_service.cc
+++ b/chrome/browser/ash/lobster/lobster_service.cc
@@ -14,19 +14,7 @@
 #include "chrome/browser/ash/lobster/lobster_candidate_id_generator.h"
 #include "chrome/browser/ash/lobster/lobster_feedback.h"
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/signin/identity_manager_factory.h"
 #include "components/manta/snapper_provider.h"
-#include "google_apis/gaia/gaia_auth_util.h"
-#include "google_apis/gaia/gaia_constants.h"
-
-namespace {
-
-constexpr std::string_view kLobsterKey(
-    "\xB3\x3A\x4C\xFC\x84\xA0\x2B\xBE\xAC\x88\x48\x09\xCF\x5E\xD6\xD9\x28\xEC"
-    "\x20\x2A",
-    base::kSHA1Length);
-
-}  // namespace
 
 LobsterService::LobsterService(
     std::unique_ptr<manta::SnapperProvider> snapper_provider,
@@ -92,27 +80,6 @@
   bubble_coordinator_.CloseUI();
 }
 
-bool LobsterService::UserHasAccess() {
-  // Command line looks like:
-  //  out/Default/chrome --user-data-dir=/tmp/tmp123
-  //  --lobster-feature-key="INSERT KEY HERE" --enable-features=Lobster
-  if (base::SHA1HashString(
-          base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
-              ash::switches::kLobsterFeatureKey)) == kLobsterKey) {
-    return true;
-  }
-
-  // Internal Google accounts do not need the key.
-  signin::IdentityManager* identity_manager =
-      IdentityManagerFactory::GetForProfile(profile_);
-
-  return identity_manager != nullptr &&
-         gaia::IsGoogleInternalAccountEmail(
-             identity_manager
-                 ->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
-                 .email);
-}
-
 void LobsterService::OnFocus(int context_id) {
   if (queued_insertion_ == nullptr) {
     return;
diff --git a/chrome/browser/ash/lobster/lobster_service.h b/chrome/browser/ash/lobster/lobster_service.h
index 84b3d0a7..2ff4b0fb 100644
--- a/chrome/browser/ash/lobster/lobster_service.h
+++ b/chrome/browser/ash/lobster/lobster_service.h
@@ -58,7 +58,6 @@
   void ShowUI();
 
   void CloseUI();
-  bool UserHasAccess();
 
   // Relevant input events
   void OnFocus(int context_id) override;
diff --git a/chrome/browser/ash/mall/mall_url.cc b/chrome/browser/ash/mall/mall_url.cc
index d0e3fe70..418bce0 100644
--- a/chrome/browser/ash/mall/mall_url.cc
+++ b/chrome/browser/ash/mall/mall_url.cc
@@ -24,29 +24,32 @@
                    0);
 
 GURL GetMallLaunchUrl(const apps::DeviceInfo& info, std::string_view path) {
+  GURL::Replacements replacements;
+  replacements.SetPathStr(path);
+
+  GURL url = GetMallBaseUrl().ReplaceComponents(replacements);
+  if (!url.is_valid()) {
+    url = GetMallBaseUrl();
+  }
+
+  // Append the parent frame origin for the server to allow iframing for this
+  // origin.
+  constexpr std::string_view kOriginParameter = "origin";
+  url = net::AppendOrReplaceQueryParameter(url, kOriginParameter,
+                                           kChromeUIMallUrl);
+
+  // Append context for localization of app recommendations.
+  constexpr std::string_view kContextParameter = "context";
   apps::proto::ClientContext context;
   *context.mutable_device_context() = info.ToDeviceContext();
   *context.mutable_user_context() = info.ToUserContext();
-
   // Mall experiments may define an Almanac feature flag which we attach as part
   // of the client context, so that it is included in requests to Almanac.
   if (kMallAlmanacFeatureFlag.Get() != 0) {
     context.mutable_user_context()->add_flag_ids(kMallAlmanacFeatureFlag.Get());
   }
-
   std::string encoded_context = base::Base64Encode(context.SerializeAsString());
-
-  constexpr std::string_view kContextParameter = "context";
-
-  GURL::Replacements replacements;
-  replacements.SetPathStr(path);
-
-  GURL url_with_path = GetMallBaseUrl().ReplaceComponents(replacements);
-  if (!url_with_path.is_valid()) {
-    url_with_path = GetMallBaseUrl();
-  }
-
-  return net::AppendOrReplaceQueryParameter(url_with_path, kContextParameter,
+  return net::AppendOrReplaceQueryParameter(url, kContextParameter,
                                             encoded_context);
 }
 
diff --git a/chrome/browser/ash/mall/mall_url_unittest.cc b/chrome/browser/ash/mall/mall_url_unittest.cc
index 0bfe708..956917b0 100644
--- a/chrome/browser/ash/mall/mall_url_unittest.cc
+++ b/chrome/browser/ash/mall/mall_url_unittest.cc
@@ -45,12 +45,14 @@
   ASSERT_EQ(launch_url.host(), GURL(chromeos::kAppMallBaseUrl).host());
 
   std::vector<std::string> query_parts = base::SplitString(
-      launch_url.query(), "=", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+      launch_url.query(), "=&", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
 
-  ASSERT_EQ(query_parts[0], "context");
+  ASSERT_EQ(query_parts[0], "origin");
+  ASSERT_EQ(query_parts[1], "chrome%3A%2F%2Fmall");
+  ASSERT_EQ(query_parts[2], "context");
 
   std::string proto_string;
-  ASSERT_TRUE(base::Base64Decode(net::UnescapePercentEncodedUrl(query_parts[1]),
+  ASSERT_TRUE(base::Base64Decode(net::UnescapePercentEncodedUrl(query_parts[3]),
                                  &proto_string,
                                  base::Base64DecodePolicy::kStrict));
 
@@ -61,14 +63,16 @@
 }
 
 TEST_F(MallUrlTest, GetMallLaunchUrl_BasePath) {
-  EXPECT_THAT(GetMallLaunchUrl(apps::DeviceInfo(), "/").spec(),
-              testing::StartsWith("https://discover.apps.chrome/?context="));
+  EXPECT_THAT(
+      GetMallLaunchUrl(apps::DeviceInfo(), "/").spec(),
+      testing::StartsWith(
+          "https://discover.apps.chrome/?origin=chrome%3A%2F%2Fmall&context="));
 }
 
 TEST_F(MallUrlTest, GetMallLaunchUrl_SimplePath) {
-  EXPECT_THAT(
-      GetMallLaunchUrl(apps::DeviceInfo(), "/apps/").spec(),
-      testing::StartsWith("https://discover.apps.chrome/apps/?context="));
+  EXPECT_THAT(GetMallLaunchUrl(apps::DeviceInfo(), "/apps/").spec(),
+              testing::StartsWith("https://discover.apps.chrome/apps/"
+                                  "?origin=chrome%3A%2F%2Fmall&context="));
 }
 
 TEST_F(MallUrlTest, GetMallLaunchUrl_PathWithQuery) {
@@ -76,19 +80,20 @@
   // query parameters.
   EXPECT_THAT(GetMallLaunchUrl(apps::DeviceInfo(), "/search?q=netflix").spec(),
               testing::StartsWith(
-                  "https://discover.apps.chrome/search%3Fq=netflix?context="));
+                  "https://discover.apps.chrome/"
+                  "search%3Fq=netflix?origin=chrome%3A%2F%2Fmall&context="));
 }
 
 TEST_F(MallUrlTest, GetMallLaunchUrl_RelativePath) {
-  EXPECT_THAT(
-      GetMallLaunchUrl(apps::DeviceInfo(), "../apps/").spec(),
-      testing::StartsWith("https://discover.apps.chrome/apps/?context="));
+  EXPECT_THAT(GetMallLaunchUrl(apps::DeviceInfo(), "../apps/").spec(),
+              testing::StartsWith("https://discover.apps.chrome/apps/"
+                                  "?origin=chrome%3A%2F%2Fmall&context="));
 }
 
 TEST_F(MallUrlTest, GetMallLaunchUrl_RelativePathHost) {
   EXPECT_THAT(GetMallLaunchUrl(apps::DeviceInfo(), "//example.com/").spec(),
-              testing::StartsWith(
-                  "https://discover.apps.chrome//example.com/?context="));
+              testing::StartsWith("https://discover.apps.chrome//example.com/"
+                                  "?origin=chrome%3A%2F%2Fmall&context="));
 }
 
 }  // namespace ash
diff --git a/chrome/browser/ash/policy/handlers/BUILD.gn b/chrome/browser/ash/policy/handlers/BUILD.gn
index e07256f..30c3b27 100644
--- a/chrome/browser/ash/policy/handlers/BUILD.gn
+++ b/chrome/browser/ash/policy/handlers/BUILD.gn
@@ -32,8 +32,6 @@
     "device_wifi_allowed_handler.h",
     "help_me_read_policy_handler.cc",
     "help_me_read_policy_handler.h",
-    "lacros_selection_policy_handler.cc",
-    "lacros_selection_policy_handler.h",
     "lock_to_single_user_manager.cc",
     "lock_to_single_user_manager.h",
     "minimum_version_policy_handler.cc",
diff --git a/chrome/browser/ash/policy/handlers/lacros_selection_policy_handler.cc b/chrome/browser/ash/policy/handlers/lacros_selection_policy_handler.cc
deleted file mode 100644
index b2be39e..0000000
--- a/chrome/browser/ash/policy/handlers/lacros_selection_policy_handler.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ash/policy/handlers/lacros_selection_policy_handler.h"
-
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
-#error This file shall only be used in ash.
-#endif
-
-#include "chrome/common/pref_names.h"
-#include "components/policy/core/browser/policy_error_map.h"
-#include "components/policy/policy_constants.h"
-#include "components/prefs/pref_value_map.h"
-#include "components/strings/grit/components_strings.h"
-
-namespace policy {
-
-LacrosSelectionPolicyHandler::LacrosSelectionPolicyHandler()
-    : TypeCheckingPolicyHandler(key::kLacrosSelection,
-                                base::Value::Type::STRING) {}
-
-bool LacrosSelectionPolicyHandler::CheckPolicySettings(
-    const PolicyMap& policies,
-    PolicyErrorMap* errors) {
-  return GetValue(policies, errors).has_value();
-}
-
-void LacrosSelectionPolicyHandler::ApplyPolicySettings(
-    const PolicyMap& policies,
-    PrefValueMap* prefs) {
-  auto enum_value = GetValue(policies, nullptr);
-  if (enum_value.has_value())
-    prefs->SetInteger(prefs::kLacrosSelection, static_cast<int>(*enum_value));
-}
-
-std::optional<ash::standalone_browser::LacrosSelectionPolicy>
-LacrosSelectionPolicyHandler::GetValue(const PolicyMap& policies,
-                                       PolicyErrorMap* errors) {
-  const base::Value* value;
-  const bool value_found = CheckAndGetValue(policies, errors, &value) && value;
-  if (!value_found)
-    return std::nullopt;
-
-  auto parsed =
-      ash::standalone_browser::ParseLacrosSelectionPolicy(value->GetString());
-  if (!parsed.has_value() && errors) {
-    errors->AddError(policy_name(), IDS_POLICY_INVALID_SELECTION_ERROR,
-                     "LacrosSelection value");
-  }
-  return parsed;
-}
-
-}  // namespace policy
diff --git a/chrome/browser/ash/policy/handlers/lacros_selection_policy_handler.h b/chrome/browser/ash/policy/handlers/lacros_selection_policy_handler.h
deleted file mode 100644
index b6515b18..0000000
--- a/chrome/browser/ash/policy/handlers/lacros_selection_policy_handler.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ASH_POLICY_HANDLERS_LACROS_SELECTION_POLICY_HANDLER_H_
-#define CHROME_BROWSER_ASH_POLICY_HANDLERS_LACROS_SELECTION_POLICY_HANDLER_H_
-
-#include <optional>
-
-#include "build/chromeos_buildflags.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
-#include "components/policy/core/browser/configuration_policy_handler.h"
-
-class PrefValueMap;
-
-namespace policy {
-
-class PolicyMap;
-
-// The handler for LacrosSelection selection policy which maps string-enum
-// policy values to `LacrosSelectionPolicy` enum stored in `PolicyMap`.
-class LacrosSelectionPolicyHandler : public TypeCheckingPolicyHandler {
- public:
-  LacrosSelectionPolicyHandler();
-
-  // ConfigurationPolicyHandler:
-  bool CheckPolicySettings(const PolicyMap& policies,
-                           PolicyErrorMap* errors) override;
-
-  void ApplyPolicySettings(const PolicyMap& policies,
-                           PrefValueMap* prefs) override;
-
- private:
-  std::optional<ash::standalone_browser::LacrosSelectionPolicy> GetValue(
-      const PolicyMap& policies,
-      PolicyErrorMap* errors);
-};
-
-}  // namespace policy
-
-#endif  // CHROME_BROWSER_ASH_POLICY_HANDLERS_LACROS_SELECTION_POLICY_HANDLER_H_
diff --git a/chrome/browser/ash/preferences/preferences.cc b/chrome/browser/ash/preferences/preferences.cc
index fabb45ae..59627d0 100644
--- a/chrome/browser/ash/preferences/preferences.cc
+++ b/chrome/browser/ash/preferences/preferences.cc
@@ -60,7 +60,6 @@
 #include "chromeos/ash/components/peripheral_notification/peripheral_notification_manager.h"
 #include "chromeos/ash/components/settings/cros_settings.h"
 #include "chromeos/ash/components/settings/cros_settings_names.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 #include "chromeos/ash/components/system/statistics_provider.h"
 #include "chromeos/ash/components/timezone/timezone_resolver.h"
 #include "chromeos/components/disks/disks_prefs.h"
@@ -154,10 +153,6 @@
       ::prefs::kSystemTimezoneAutomaticDetectionPolicy,
       enterprise_management::SystemTimezoneProto::USERS_DECIDE);
   registry->RegisterStringPref(::prefs::kMinimumAllowedChromeVersion, "");
-  registry->RegisterIntegerPref(
-      ::prefs::kLacrosSelection,
-      static_cast<int>(
-          ash::standalone_browser::LacrosSelectionPolicy::kUserChoice));
   registry->RegisterBooleanPref(prefs::kDeviceSystemWideTracingEnabled, true);
   registry->RegisterBooleanPref(
       prefs::kLocalStateDevicePeripheralDataAccessEnabled, false);
diff --git a/chrome/browser/ash/system_web_apps/apps/mall_app_integration_browsertest.cc b/chrome/browser/ash/system_web_apps/apps/mall_app_integration_browsertest.cc
index 2358835..2e03570b 100644
--- a/chrome/browser/ash/system_web_apps/apps/mall_app_integration_browsertest.cc
+++ b/chrome/browser/ash/system_web_apps/apps/mall_app_integration_browsertest.cc
@@ -58,8 +58,10 @@
 
   content::WebContents* contents = LaunchApp(ash::SystemWebAppType::MALL);
 
-  EXPECT_THAT(GetMallEmbedUrl(contents),
-              testing::StartsWith("https://discover.apps.chrome/?context="));
+  EXPECT_THAT(
+      GetMallEmbedUrl(contents),
+      testing::StartsWith(
+          "https://discover.apps.chrome/?chrome%3A%2F%2Fmall&context="));
 }
 
 IN_PROC_BROWSER_TEST_P(MallAppIntegrationTest, EmbedMallWithDeepLink) {
@@ -71,9 +73,9 @@
 
   content::WebContents* contents = LaunchApp(std::move(params));
 
-  EXPECT_THAT(
-      GetMallEmbedUrl(contents),
-      testing::StartsWith("https://discover.apps.chrome/apps/list?context="));
+  EXPECT_THAT(GetMallEmbedUrl(contents),
+              testing::StartsWith("https://discover.apps.chrome/apps/"
+                                  "list?chrome%3A%2F%2Fmall&context="));
 }
 
 INSTANTIATE_SYSTEM_WEB_APP_MANAGER_TEST_SUITE_REGULAR_PROFILE_P(
diff --git a/chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h b/chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h
index 5c443e9..3cab7a4e 100644
--- a/chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h
+++ b/chrome/browser/browsing_data/chrome_browsing_data_remover_constants.h
@@ -61,7 +61,8 @@
     DATA_TYPE_SITE_USAGE_DATA | DATA_TYPE_DURABLE_PERMISSION |
     DATA_TYPE_EXTERNAL_PROTOCOL_DATA | DATA_TYPE_ISOLATED_ORIGINS |
     DATA_TYPE_ISOLATED_WEB_APP_COOKIES |
-    content::BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX;
+    content::BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX |
+    content::BrowsingDataRemover::DATA_TYPE_DEVICE_BOUND_SESSIONS;
 
 // Datatypes protected by Important Sites.
 constexpr DataType IMPORTANT_SITES_DATA_TYPES =
diff --git a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingFeatures.java b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingFeatures.java
index ce968517..e84e5e0 100644
--- a/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingFeatures.java
+++ b/chrome/browser/commerce/price_tracking/android/java/src/org/chromium/chrome/browser/price_tracking/PriceTrackingFeatures.java
@@ -25,10 +25,6 @@
     public static final String ALLOW_DISABLE_PRICE_ANNOTATIONS_PARAM =
             "allow_disable_price_annotations";
 
-    @VisibleForTesting
-    public static final String PRICE_DROP_IPH_ENABLED_PARAM = "enable_price_drop_iph";
-
-    private static final String PRICE_DROP_BADGE_ENABLED_PARAM = "enable_price_drop_badge";
     private static final String PRICE_ANNOTATIONS_ENABLED_METRICS_WINDOW_DURATION_PARAM =
             "price_annotations_enabled_metrics_window_duration_ms";
 
@@ -112,28 +108,6 @@
         return isPriceAnnotationsEligible(profile);
     }
 
-    public static boolean isPriceDropIphEnabled(Profile profile) {
-        if (FeatureList.isInitialized()) {
-            return isPriceAnnotationsEligible(profile)
-                    && ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                            ChromeFeatureList.PRICE_ANNOTATIONS,
-                            PRICE_DROP_IPH_ENABLED_PARAM,
-                            false);
-        }
-        return isPriceAnnotationsEligible(profile);
-    }
-
-    public static boolean isPriceDropBadgeEnabled(Profile profile) {
-        if (FeatureList.isInitialized()) {
-            return isPriceAnnotationsEligible(profile)
-                    && ChromeFeatureList.getFieldTrialParamByFeatureAsBoolean(
-                            ChromeFeatureList.PRICE_ANNOTATIONS,
-                            PRICE_DROP_BADGE_ENABLED_PARAM,
-                            false);
-        }
-        return isPriceAnnotationsEligible(profile);
-    }
-
     public static void setPriceAnnotationsEnabledForTesting(Boolean enabled) {
         sPriceAnnotationsEnabledForTesting = enabled;
         ResettersForTesting.register(() -> sPriceAnnotationsEnabledForTesting = null);
diff --git a/chrome/browser/digital_credentials/digital_identity_provider_desktop.cc b/chrome/browser/digital_credentials/digital_identity_provider_desktop.cc
index 5d0c77a..4fd74c2 100644
--- a/chrome/browser/digital_credentials/digital_identity_provider_desktop.cc
+++ b/chrome/browser/digital_credentials/digital_identity_provider_desktop.cc
@@ -10,11 +10,15 @@
 #include "base/functional/overloaded.h"
 #include "base/json/json_writer.h"
 #include "base/values.h"
+#include "chrome/app/vector_icons/vector_icons.h"
 #include "chrome/browser/digital_credentials/digital_identity_low_risk_origins.h"
 #include "chrome/browser/net/system_network_context_manager.h"
+#include "chrome/browser/ui/views/accessibility/theme_tracking_non_accessible_image_view.h"
+#include "chrome/browser/ui/views/chrome_layout_provider.h"
 #include "chrome/browser/ui/views/digital_credentials/digital_identity_bluetooth_manual_dialog_controller.h"
 #include "chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.h"
 #include "chrome/browser/ui/views/digital_credentials/digital_identity_safety_interstitial_controller_desktop.h"
+#include "chrome/grit/browser_resources.h"
 #include "chrome/grit/generated_resources.h"
 #include "components/constrained_window/constrained_window_views.h"
 #include "components/qr_code_generator/bitmap_generator.h"
@@ -31,12 +35,20 @@
 #include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/bubble/bubble_dialog_model_host.h"
 #include "ui/views/controls/image_view.h"
+#include "ui/views/controls/theme_tracking_animated_image_view.h"
+#include "ui/views/layout/box_layout_view.h"
 #include "ui/views/widget/widget.h"
 
 namespace {
 
 // Smaller than DistanceMetric::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH.
-const int kQrCodeSize = 240;
+constexpr int kQrCodeSize = 240;
+
+constexpr int kImageMarginTop = 22;
+constexpr int kImageMarginBottom = 2;
+constexpr int kImageHeight = 112;
+constexpr int kHeaderHeight =
+    kImageHeight + kImageMarginTop + kImageMarginBottom;
 
 using DigitalIdentityInterstitialAbortCallback =
     content::DigitalIdentityProvider::DigitalIdentityInterstitialAbortCallback;
@@ -77,7 +89,7 @@
   image_view->GetViewAccessibility().SetName(
       l10n_util::GetStringUTF16(IDS_WEB_DIGITAL_CREDENTIALS_QR_CODE_ALT_TEXT));
   image_view->SetImageSize(gfx::Size(kQrCodeSize, kQrCodeSize));
-  return std::move(image_view);
+  return image_view;
 }
 
 device::cablev2::CredentialRequestType
@@ -91,6 +103,14 @@
   }
 }
 
+template <typename T>
+void ConfigureHeaderIllustration(T* illustration, gfx::Size header_size) {
+  illustration->SetBorder(views::CreateEmptyBorder(
+      gfx::Insets::TLBR(kImageMarginTop, 0, kImageMarginBottom, 0)));
+  illustration->SetSize(header_size);
+  illustration->SetVerticalAlignment(views::ImageView::Alignment::kLeading);
+}
+
 }  // anonymous namespace
 
 DigitalIdentityProviderDesktop::DigitalIdentityProviderDesktop() = default;
@@ -294,11 +314,65 @@
 }
 
 void DigitalIdentityProviderDesktop::ShowConnectingToPhoneDialog() {
-  // TODO(crbug.com/384423219): implement this method.
+  // Ensure the dialog is created to have access to GetBackgroundColor().
+  EnsureDialogCreated();
+  ShowStepWithIllustration(
+      /*body_text=*/l10n_util::GetStringUTF16(
+          IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTING_TITLE),
+      std::make_unique<views::ThemeTrackingAnimatedImageView>(
+          IDR_WEBAUTHN_HYBRID_CONNECTING_LIGHT,
+          IDR_WEBAUTHN_HYBRID_CONNECTING_DARK,
+          base::BindRepeating(
+              &DigitalIdentityMultiStepDialog::GetBackgroundColor,
+              base::Unretained(dialog_.get()))));
 }
 
 void DigitalIdentityProviderDesktop::ShowContinueStepsOnThePhoneDialog() {
-  // TODO(crbug.com/384423219): implement this method.
+  // Ensure the dialog is created to have access to GetBackgroundColor().
+  EnsureDialogCreated();
+  ShowStepWithIllustration(
+      /*body_text=*/l10n_util::GetStringUTF16(
+          IDS_WEB_DIGITAL_CREDENTIALS_CABLEV2_CONNECTED_TITLE),
+      std::make_unique<ThemeTrackingNonAccessibleImageView>(
+          ui::ImageModel::FromVectorIcon(kPasskeyPhoneIcon),
+          ui::ImageModel::FromVectorIcon(kPasskeyPhoneDarkIcon),
+          base::BindRepeating(
+              &DigitalIdentityMultiStepDialog::GetBackgroundColor,
+              base::Unretained(dialog_.get()))));
+}
+
+template <typename T>
+void DigitalIdentityProviderDesktop::ShowStepWithIllustration(
+    const std::u16string& title_text,
+    std::unique_ptr<T> illustration) {
+  const gfx::Insets& insets =
+      ChromeLayoutProvider::Get()->GetDialogInsetsForContentType(
+          views::DialogContentType::kText, views::DialogContentType::kText);
+  const int available_width =
+      ChromeLayoutProvider::Get()->GetDistanceMetric(
+          views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH) -
+      insets.right() - insets.left();
+  const gfx::Size header_size(available_width, kHeaderHeight);
+  // `illustration` will horizontally center if the width is
+  // larger than the size from the Lottie file, but the height is just used to
+  // truncate the image, so that is disabled with a very large value.
+  illustration->SetPreferredSize(gfx::Size(available_width, 9999));
+  ConfigureHeaderIllustration(illustration.get(), header_size);
+
+  auto container_view =
+      views::Builder<views::BoxLayoutView>()
+          .SetOrientation(views::BoxLayout::Orientation::kVertical)
+          .SetInsideBorderInsets(gfx::Insets())
+          .SetPreferredSize(header_size)
+          .Build();
+  container_view->AddChildView(std::move(illustration));
+
+  EnsureDialogCreated()->TryShow(
+      /*accept_button=*/std::nullopt, base::OnceClosure(),
+      ui::DialogModel::Button::Params(),
+      base::BindOnce(&DigitalIdentityProviderDesktop::OnCanceled,
+                     weak_ptr_factory_.GetWeakPtr()),
+      title_text, /*dialog_body=*/u"", std::move(container_view));
 }
 
 void DigitalIdentityProviderDesktop::OnCableConnectingTimerComplete() {
diff --git a/chrome/browser/digital_credentials/digital_identity_provider_desktop.h b/chrome/browser/digital_credentials/digital_identity_provider_desktop.h
index 08870e9..2b2a52a 100644
--- a/chrome/browser/digital_credentials/digital_identity_provider_desktop.h
+++ b/chrome/browser/digital_credentials/digital_identity_provider_desktop.h
@@ -89,6 +89,10 @@
   // should follow the instruction on the phone.
   void ShowContinueStepsOnThePhoneDialog();
 
+  template <typename T>
+  void ShowStepWithIllustration(const std::u16string& title_text,
+                                std::unique_ptr<T> illustration);
+
   // Called when `cable_connecting_dialog_timer_` completes.
   void OnCableConnectingTimerComplete();
 
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index e0aa05c..10517172 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -5582,16 +5582,6 @@
     "expiry_milestone": 140
   },
   {
-    "name": "lacros-selection",
-    "owners": [ "kimjae@chromium.org", "erikchen@chromium.org", "lacros-team@google.com" ],
-    "expiry_milestone": 140
-  },
-  {
-    "name": "lacros-selection-ignore",
-    "owners": [ "asumaneev@chromium.org", "lacros-team@google.com" ],
-    "expiry_milestone": 140
-  },
-  {
     "name": "lacros-stability",
     "owners": [ "jamescook@chromium.org", "erikchen@chromium.org", "lacros-team@google.com" ],
     // Once Lacros is launched, this flag can be removed. Until then, this
@@ -8136,6 +8126,11 @@
     "expiry_milestone": -1
   },
   {
+    "name": "show-warnings-for-suspicious-notifications",
+    "owners": ["skrakowi@chromium.org", "chrome-counter-abuse-alerts@google.com"],
+    "expiry_milestone": 139
+  },
+  {
     "name" : "side-panel-improved-clobbering",
     "owners": [ "chrome-cros@google.com", "tluk@chromium.org" ],
     "expiry_milestone" : 110
@@ -8663,6 +8658,11 @@
     "expiry_milestone": 150
   },
   {
+    "name": "tabstrip-dedupe",
+    "owners": [ "emshack@chromium.org", "shibalik@chromium.org", "chrome-desktop-ui-sea@google.com" ],
+    "expiry_milestone": 160
+  },
+  {
     "name": "tear-off-web-app-tab-opens-web-app-window",
     "owners": [ "davidbienvenu@chromium.org", "dmurph@chromium.org" ],
     "expiry_milestone": 135
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index df68b1b8..335648a 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -3090,6 +3090,12 @@
     "Settings UI and Page Info Bubble, "
     "default is hidden";
 
+const char kShowWarningsForSuspiciousNotificationsName[] =
+    "Show Warnings for Suspicious Notifications";
+const char kShowWarningsForSuspiciousNotificationsDescription[] =
+    "Enables replacing notification contents with a warning when the on-device "
+    "notification content detection model returns a suspicious verdict.";
+
 const char kPowerBookmarkBackendName[] = "Power bookmark backend";
 const char kPowerBookmarkBackendDescription[] =
     "Enables storing additional metadata to support power bookmark features.";
@@ -5446,6 +5452,11 @@
     "Enables the Tab Declutter feature, which can be found within the Tab "
     "Search bubble.";
 
+const char kTabstripDedupeName[] = "Tab Deduplication";
+const char kTabstripDedupeDescription[] =
+    "Enables the Tab Deduplication feature, which can be found within the Tab "
+    "Search bubble.";
+
 const char kIOSPromoRefreshedPasswordBubbleName[] =
     "Chrome for iOS promo : passwords";
 const char kIOSPromoRefreshedPasswordBubbleDescription[] =
@@ -6966,19 +6977,6 @@
 const char kLacrosStabilityName[] = "Lacros stability";
 const char kLacrosStabilityDescription[] = "Lacros update channel.";
 
-const char kLacrosSelectionName[] = "Lacros selection";
-const char kLacrosSelectionDescription[] =
-    "Choosing between rootfs or stateful Lacros.";
-
-const char kLacrosSelectionRootfsDescription[] = "Rootfs";
-const char kLacrosSelectionStatefulDescription[] = "Stateful";
-
-const char kLacrosSelectionPolicyIgnoreName[] =
-    "Ignore lacros-selection policy";
-const char kLacrosSelectionPolicyIgnoreDescription[] =
-    "Makes the lacros-selection policy have no effect. Instead Lacros "
-    "selection will be controlled by experiment and/or user flags.";
-
 const char kLacrosWaylandLoggingName[] = "Lacros Wayland logging";
 const char kLacrosWaylandLoggingDescription[] =
     "Enables Wayland logging for Lacros. This generates a significant amount "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index a5307092..74b20377 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -1771,6 +1771,9 @@
 extern const char kShowRelatedWebsiteSetsPermissionGrantsName[];
 extern const char kShowRelatedWebsiteSetsPermissionGrantsDescription[];
 
+extern const char kShowWarningsForSuspiciousNotificationsName[];
+extern const char kShowWarningsForSuspiciousNotificationsDescription[];
+
 extern const char kPowerBookmarkBackendName[];
 extern const char kPowerBookmarkBackendDescription[];
 
@@ -3153,6 +3156,9 @@
 extern const char kTabstripDeclutterName[];
 extern const char kTabstripDeclutterDescription[];
 
+extern const char kTabstripDedupeName[];
+extern const char kTabstripDedupeDescription[];
+
 extern const char kIOSPromoRefreshedPasswordBubbleName[];
 extern const char kIOSPromoRefreshedPasswordBubbleDescription[];
 
@@ -4054,14 +4060,6 @@
 extern const char kLacrosStabilityName[];
 extern const char kLacrosStabilityDescription[];
 
-extern const char kLacrosSelectionName[];
-extern const char kLacrosSelectionDescription[];
-extern const char kLacrosSelectionRootfsDescription[];
-extern const char kLacrosSelectionStatefulDescription[];
-
-extern const char kLacrosSelectionPolicyIgnoreName[];
-extern const char kLacrosSelectionPolicyIgnoreDescription[];
-
 extern const char kLacrosWaylandLoggingName[];
 extern const char kLacrosWaylandLoggingDescription[];
 
diff --git a/chrome/browser/glic/glic_focused_tab_manager.cc b/chrome/browser/glic/glic_focused_tab_manager.cc
index 8538e81..48d076e 100644
--- a/chrome/browser/glic/glic_focused_tab_manager.cc
+++ b/chrome/browser/glic/glic_focused_tab_manager.cc
@@ -4,126 +4,137 @@
 
 #include "chrome/browser/glic/glic_focused_tab_manager.h"
 
+#include "base/functional/bind.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_finder.h"
 #include "chrome/browser/ui/browser_list.h"
 
 namespace glic {
 
-constexpr int kMaxActiveWebContents = 50;
+// TODO(wry): Add interactive_ui_tests to check basic functionality.
 
-GlicFocusedTabManager::GlicFocusedTabManager(Profile* profile)
-    : profile_(profile), activated_web_contents_() {
+GlicFocusedTabManager::GlicFocusedTabManager(
+    Profile* profile,
+    GlicWindowController& window_controller)
+    : profile_(profile), window_controller_(window_controller) {
   BrowserList::GetInstance()->AddObserver(this);
-  // Observe existing windows
-  for (Browser* browser : *BrowserList::GetInstance()) {
-    OnBrowserAdded(browser);
-  }
+  window_activation_subscription_ =
+      window_controller.AddWindowActivationChangedCallback(base::BindRepeating(
+          &GlicFocusedTabManager::OnGlicWindowActivationChanged,
+          base::Unretained(this)));
 }
 
 GlicFocusedTabManager::~GlicFocusedTabManager() {
   BrowserList::GetInstance()->RemoveObserver(this);
-  // Stop observing existing windows
-  for (Browser* browser : *BrowserList::GetInstance()) {
-    OnBrowserRemoved(browser);
+}
+
+void GlicFocusedTabManager::OnBrowserSetLastActive(Browser* browser) {
+  // Clear any existing browser callback subscription.
+  browser_subscription_ = {};
+
+  // Subscribe to active tab changes to this browser if it's valid.
+  if (IsValidBrowser(browser)) {
+    browser_subscription_ = browser->RegisterActiveTabDidChange(
+        base::BindRepeating(&GlicFocusedTabManager::OnActiveTabChanged,
+                            base::Unretained(this)));
+  }
+
+  MaybeUpdateFocusedTab();
+}
+
+void GlicFocusedTabManager::OnBrowserNoLongerActive(Browser* browser) {
+  MaybeUpdateFocusedTab();
+}
+
+void GlicFocusedTabManager::OnGlicWindowActivationChanged(bool active) {
+  MaybeUpdateFocusedTab();
+}
+
+void GlicFocusedTabManager::OnActiveTabChanged(
+    BrowserWindowInterface* browser_interface) {
+  MaybeUpdateFocusedTab();
+}
+
+void GlicFocusedTabManager::PrimaryPageChanged(content::Page& page) {
+  // We always want to trigger our notify callback here (even if focused tab
+  // remains the same) so that subscribers can update if they care about primary
+  // page changed events.
+  MaybeUpdateFocusedTab(/*force_notify=*/true);
+}
+
+void GlicFocusedTabManager::MaybeUpdateFocusedTab(bool force_notify) {
+  content::WebContents* const new_focused_web_contents = ComputeFocusedTab();
+  bool focus_changed = new_focused_web_contents != focused_web_contents_.get();
+
+  if (focus_changed) {
+    if (new_focused_web_contents) {
+      focused_web_contents_ = new_focused_web_contents->GetWeakPtr();
+    } else {
+      focused_web_contents_.reset();
+    }
+
+    // This is sufficient for now because there's currently no way for an
+    // invalid focusable to become valid without changing |WebContents|.
+    Observe(new_focused_web_contents);
+  }
+
+  if (focus_changed || force_notify) {
+    NotifyFocusedTabChanged();
   }
 }
 
-void GlicFocusedTabManager::OnBrowserAdded(Browser* browser) {
-  if (browser->profile() == profile_) {
-    browser->tab_strip_model()->AddObserver(this);
-    HandleWebContentsActivated(
-        browser->tab_strip_model()->GetActiveWebContents());
+content::WebContents* GlicFocusedTabManager::ComputeFocusedTab() {
+  if (window_controller_->IsActive()) {
+    Browser* const profile_last_active =
+        chrome::FindLastActiveWithProfile(profile_);
+    return ComputeFocusableTabForBrowser(profile_last_active);
   }
+
+  Browser* const active_browser = BrowserList::GetInstance()->GetLastActive();
+  if (active_browser && active_browser->IsActive()) {
+    return ComputeFocusableTabForBrowser(active_browser);
+  }
+
+  return nullptr;
 }
 
-void GlicFocusedTabManager::OnBrowserRemoved(Browser* browser) {
-  if (browser->profile() == profile_) {
-    browser->tab_strip_model()->RemoveObserver(this);
+content::WebContents* GlicFocusedTabManager::ComputeFocusableTabForBrowser(
+    BrowserWindowInterface* browser_interface) {
+  if (IsValidBrowser(browser_interface)) {
+    content::WebContents* const web_contents =
+        browser_interface->GetActiveTabInterface()
+            ? browser_interface->GetActiveTabInterface()->GetContents()
+            : nullptr;
+    if (IsValidFocusable(web_contents)) {
+      return web_contents;
+    }
   }
+
+  return nullptr;
+}
+
+void GlicFocusedTabManager::NotifyFocusedTabChanged() {
+  // TODO(wry): Debounce here to avoid awkwardness with Mac OS
+  // deactivation/activation handling.
+  focused_callback_list_.Notify(GetWebContentsForFocusedTab());
+}
+
+bool GlicFocusedTabManager::IsValidBrowser(
+    BrowserWindowInterface* browser_interface) {
+  // TODO(wry): Handle browser minimized.
+  return browser_interface && browser_interface->GetProfile() == profile_ &&
+         !browser_interface->GetProfile()->IsOffTheRecord();
 }
 
 bool GlicFocusedTabManager::IsValidFocusable(
     content::WebContents* web_contents) {
-  return web_contents->GetURL().SchemeIsHTTPOrHTTPS() ||
-         web_contents->GetURL().SchemeIsFile();
-}
-
-void GlicFocusedTabManager::HandleWebContentsActivated(
-    content::WebContents* web_contents) {
-  if (!web_contents) {
-    return;
-  }
-  auto it = FindActivatedWebContents(web_contents);
-  if (it == activated_web_contents_.end()) {
-    // Not found, add to front
-    activated_web_contents_.insert(activated_web_contents_.begin(),
-                                   web_contents->GetWeakPtr());
-    if (activated_web_contents_.size() > kMaxActiveWebContents) {
-      activated_web_contents_.pop_back();
-    }
-  } else {
-    // Found, move to front
-    if (it != activated_web_contents_.begin()) {
-      auto value = *it;
-      activated_web_contents_.erase(it);
-      activated_web_contents_.insert(activated_web_contents_.begin(), value);
-    }
-  }
-}
-
-void GlicFocusedTabManager::OnTabStripModelChanged(
-    TabStripModel* tab_strip_model,
-    const TabStripModelChange& change,
-    const TabStripSelectionChange& selection) {
-  if (selection.active_tab_changed()) {
-    HandleWebContentsActivated(selection.new_contents);
-  }
-
-  if (change.type() == TabStripModelChange::kRemoved) {
-    for (const auto& removed_tab : change.GetRemove()->contents) {
-      content::WebContents* removed_contents = removed_tab.contents;
-
-      auto it = std::remove_if(
-          activated_web_contents_.begin(), activated_web_contents_.end(),
-          [removed_contents](
-              const base::WeakPtr<content::WebContents>& weak_ptr) {
-            return weak_ptr.get() == removed_contents;
-          });
-      activated_web_contents_.erase(it, activated_web_contents_.end());
-    }
-  }
-
-  if (change.type() == TabStripModelChange::kReplaced) {
-    auto it = FindActivatedWebContents(change.GetReplace()->old_contents);
-    if (it != activated_web_contents_.end()) {
-      *it = change.GetReplace()->new_contents->GetWeakPtr();
-    }
-  }
-}
-
-std::vector<base::WeakPtr<content::WebContents>>::iterator
-GlicFocusedTabManager::FindActivatedWebContents(
-    content::WebContents* web_contents) {
-  if (!web_contents) {
-    return activated_web_contents_.end();
-  }
-
-  return base::ranges::find_if(
-      activated_web_contents_,
-      [web_contents](const base::WeakPtr<content::WebContents>& weak_ptr) {
-        return weak_ptr.get() == web_contents;
-      });
+  // Changes here may also require new handling of |WebContents| observing.
+  return web_contents;
 }
 
 content::WebContents* GlicFocusedTabManager::GetWebContentsForFocusedTab() {
-  for (base::WeakPtr<content::WebContents> web_contents :
-       activated_web_contents_) {
-    if (web_contents && IsValidFocusable(web_contents.get())) {
-      return web_contents.get();
-    }
-  }
-  return nullptr;
+  return focused_web_contents_.get();
 }
 
 }  // namespace glic
diff --git a/chrome/browser/glic/glic_focused_tab_manager.h b/chrome/browser/glic/glic_focused_tab_manager.h
index 68f611a..f3e5daf 100644
--- a/chrome/browser/glic/glic_focused_tab_manager.h
+++ b/chrome/browser/glic/glic_focused_tab_manager.h
@@ -5,49 +5,99 @@
 #ifndef CHROME_BROWSER_GLIC_GLIC_FOCUSED_TAB_MANAGER_H_
 #define CHROME_BROWSER_GLIC_GLIC_FOCUSED_TAB_MANAGER_H_
 
+#include "base/callback_list.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/ui/browser_list_observer.h"
-#include "chrome/browser/ui/tabs/tab_strip_model_observer.h"
+#include "content/public/browser/web_contents_observer.h"
+#include "glic_window_controller.h"
 
 namespace content {
+class Page;
 class WebContents;
 }  // namespace content
 
+class BrowserWindowInterface;
+
 namespace glic {
 // Responsible for managing which tab is considered "focused" and for accessing
-// its WebContents.
+// its WebContents. This is an implementation detail of GlicKeyedService and
+// others should rely on the interface that GlicKeyedService exposes for
+// observing state changes.
 class GlicFocusedTabManager : public BrowserListObserver,
-                              public TabStripModelObserver {
+                              public content::WebContentsObserver {
  public:
-  explicit GlicFocusedTabManager(Profile* profile);
+  explicit GlicFocusedTabManager(Profile* profile,
+                                 GlicWindowController& window_controller);
   ~GlicFocusedTabManager() override;
 
   GlicFocusedTabManager(const GlicFocusedTabManager&) = delete;
   GlicFocusedTabManager& operator=(const GlicFocusedTabManager&) = delete;
 
+  // Returns the currently focused tab or nullptr if nothing is focused.
   content::WebContents* GetWebContentsForFocusedTab();
 
   // BrowserListObserver
-  void OnBrowserAdded(Browser* browser) override;
-  void OnBrowserRemoved(Browser* browser) override;
+  void OnBrowserSetLastActive(Browser* browser) override;
+  void OnBrowserNoLongerActive(Browser* browser) override;
 
-  // TabStripModelObserver
-  void OnTabStripModelChanged(
-      TabStripModel* tab_strip_model,
-      const TabStripModelChange& change,
-      const TabStripSelectionChange& selection) override;
+  // content::WebContentsObserver
+  void PrimaryPageChanged(content::Page& page) override;
+
+  // Callback for changes to focused tab. The web contents pointer can be null
+  // if no tab is in focus.
+  using FocusedTabChangedCallback =
+      base::RepeatingCallback<void(const content::WebContents*)>;
+  base::CallbackListSubscription AddFocusedTabChangedCallback(
+      FocusedTabChangedCallback callback);
 
  private:
-  bool IsValidFocusable(content::WebContents* web_contents);
-  void HandleWebContentsActivated(content::WebContents* web_contents);
-  std::vector<base::WeakPtr<content::WebContents>>::iterator
-  FindActivatedWebContents(content::WebContents* web_contents);
+  // True if |browser| is valid for Glic focus.
+  bool IsValidBrowser(BrowserWindowInterface* browser_interface);
 
+  // True if |web_contents| is allowed to be focused.
+  bool IsValidFocusable(content::WebContents* web_contents);
+
+  // Updates focused tab if a new one is computed. Notifies if updated or if
+  // |force_notify| is true.
+  void MaybeUpdateFocusedTab(bool force_notify = false);
+
+  // Computes the currently focused tab.
+  content::WebContents* ComputeFocusedTab();
+
+  // Computes the currently focusable tab for a given browser.
+  content::WebContents* ComputeFocusableTabForBrowser(
+      BrowserWindowInterface* browser_interface);
+
+  // Calls all registered focused tab changed callbacks.
+  void NotifyFocusedTabChanged();
+
+  // List of callbacks to be notified when focused tab changed.
+  base::RepeatingCallbackList<void(const content::WebContents*)>
+      focused_callback_list_;
+
+  // The profile for which to manage focused tabs.
   raw_ptr<Profile> profile_;
+
+  // The Glic window controller.
+  raw_ref<GlicWindowController> window_controller_;
+
+  // The currently focused tab (or nullptr if no tab is focused).
   base::WeakPtr<content::WebContents> focused_web_contents_;
-  std::vector<base::WeakPtr<content::WebContents>> activated_web_contents_;
+
+  // Callback subscription for listening to changes to active tab for a browser.
+  base::CallbackListSubscription browser_subscription_;
+
+  // Callback for active tab changes from BrowserWindowInterface.
+  void OnActiveTabChanged(BrowserWindowInterface* browser_interface);
+
+  // Callback subscription for listening to changes to the Glic window
+  // activation changes.
+  base::CallbackListSubscription window_activation_subscription_;
+
+  // Callback for Glic Window activation changes.
+  void OnGlicWindowActivationChanged(bool active);
 };
 
 }  // namespace glic
diff --git a/chrome/browser/glic/glic_keyed_service.cc b/chrome/browser/glic/glic_keyed_service.cc
index a124cd37b..b23ae4c 100644
--- a/chrome/browser/glic/glic_keyed_service.cc
+++ b/chrome/browser/glic/glic_keyed_service.cc
@@ -24,9 +24,12 @@
                                    GlicProfileManager* profile_manager)
     : browser_context_(browser_context),
       window_controller_(Profile::FromBrowserContext(browser_context)),
-      focused_tab_manager_(Profile::FromBrowserContext(browser_context)),
+      focused_tab_manager_(Profile::FromBrowserContext(browser_context),
+                           window_controller_),
       profile_manager_(profile_manager) {}
 
+// TODO(wry): Setup focused tab changed forwarding to external subscribers.
+
 GlicKeyedService::~GlicKeyedService() = default;
 
 void GlicKeyedService::LaunchUI(views::View* glic_button_view) {
@@ -89,8 +92,7 @@
     bool include_inner_text,
     bool include_viewport_screenshot,
     mojom::WebClientHandler::GetContextFromFocusedTabCallback callback) {
-  content::WebContents* web_contents =
-      focused_tab_manager_.GetWebContentsForFocusedTab();
+  content::WebContents* web_contents = GetFocusedTab();
   if (!web_contents) {
     // TODO(crbug.com/379773651): Clean up logspam when it's no longer useful.
     LOG(ERROR) << "GetContextFromFocusedTab: No web contents";
@@ -117,6 +119,10 @@
           std::move(fetcher), std::move(callback)));
 }
 
+content::WebContents* GlicKeyedService::GetFocusedTab() {
+  return focused_tab_manager_.GetWebContentsForFocusedTab();
+}
+
 base::WeakPtr<GlicKeyedService> GlicKeyedService::GetWeakPtr() {
   return weak_ptr_factory_.GetWeakPtr();
 }
diff --git a/chrome/browser/glic/glic_keyed_service.h b/chrome/browser/glic/glic_keyed_service.h
index 1454d6f..92f7c4a 100644
--- a/chrome/browser/glic/glic_keyed_service.h
+++ b/chrome/browser/glic/glic_keyed_service.h
@@ -7,6 +7,7 @@
 
 #include <optional>
 
+#include "base/callback_list.h"
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/glic/glic_focused_tab_manager.h"
 #include "chrome/browser/glic/glic_window_controller.h"
@@ -46,6 +47,24 @@
   std::optional<gfx::Size> ResizePanel(const gfx::Size& size);
   void SetPanelDraggableAreas(const std::vector<gfx::Rect>& draggable_areas);
 
+  // Callback for changes to focused tab. When there is no focused tab,
+  // |WebContents| will be nullptr.
+  using FocusedTabChangedCallback =
+      base::RepeatingCallback<void(const content::WebContents*)>;
+
+  // Registers |callback| to be called whenever the focused tab changes. This
+  // includes when the active/selected tab for the profile changes (including
+  // those resulting from browser/window changes) as well as when the primary
+  // page of the focused tab has changed internally. Subscribers can filter for
+  // specific subsets of changes they care about by holding on to their own
+  // internal state. When the focused tab changes to nothing, this will be
+  // called with nullptr as the supplied WebContents argument.
+  base::CallbackListSubscription AddFocusedTabChangedCallback(
+      FocusedTabChangedCallback callback);
+
+  // Returns the currently focused tab or nullptr if there is none.
+  content::WebContents* GetFocusedTab();
+
   void GetContextFromFocusedTab(
       bool include_inner_text,
       bool include_viewport_screenshot,
diff --git a/chrome/browser/glic/glic_window_controller.cc b/chrome/browser/glic/glic_window_controller.cc
index 4ad9527..85e3429 100644
--- a/chrome/browser/glic/glic_window_controller.cc
+++ b/chrome/browser/glic/glic_window_controller.cc
@@ -17,6 +17,7 @@
 #include "ui/events/event_observer.h"
 #include "ui/views/controls/webview/webview.h"
 #include "ui/views/event_monitor.h"
+#include "ui/views/widget/widget_observer.h"
 
 namespace {
 // Default value for how close the corner of glic has to be from a browser's
@@ -84,6 +85,8 @@
 GlicWindowController::GlicWindowController(Profile* profile)
     : profile_(profile) {}
 
+GlicWindowController::~GlicWindowController() = default;
+
 void GlicWindowController::Show(views::View* glic_button_view) {
   // TODO(crbug.com/379943498): If a glic window already exists, handle showing
   // by bringing to front or activating.
@@ -109,15 +112,24 @@
     padding = GetLayoutConstant(TAB_STRIP_PADDING);
   }
 
-  std::tie(widget_, glic_view_) = glic::GlicView::CreateWidget(
+  widget_ = glic::GlicView::CreateWidget(
       profile_, {top_right_point.x() - kWidgetWidth - padding,
                  top_right_point.y() + padding, kWidgetWidth, kWidgetHeight});
   widget_->AddObserver(this);
+  glic_widget_observer_ =
+      std::make_unique<GlicWidgetObserver>(this, widget_.get());
   widget_->Show();
   window_event_observer_ =
-      std::make_unique<WindowEventObserver>(this, glic_view_);
+      std::make_unique<WindowEventObserver>(this, GetGlicView());
   // Set the draggable area to the top bar of the window, by default.
-  glic_view_->SetDraggableAreas({{0, 0, kWidgetWidth, kWidgetTopBarHeight}});
+  GetGlicView()->SetDraggableAreas({{0, 0, kWidgetWidth, kWidgetTopBarHeight}});
+}
+
+GlicView* GlicWindowController::GetGlicView() {
+  if (!widget_) {
+    return nullptr;
+  }
+  return GlicView::FromWidget(*widget_);
 }
 
 gfx::Point GlicWindowController::GetTopRightPositionForAttachedWindow(
@@ -163,7 +175,7 @@
   }
 
   widget_->SetSize(size);
-  glic_view_->web_view()->SetSize(size);
+  GetGlicView()->web_view()->SetSize(size);
   return true;
 }
 
@@ -177,21 +189,22 @@
 
 void GlicWindowController::SetDraggableAreas(
     const std::vector<gfx::Rect>& draggable_areas) {
-  if (!glic_view_) {
+  GlicView* glic_view = GetGlicView();
+  if (!glic_view) {
     return;
   }
 
-  glic_view_->SetDraggableAreas(draggable_areas);
+  glic_view->SetDraggableAreas(draggable_areas);
 }
 
 void GlicWindowController::Close() {
   if (!widget_) {
     return;
   }
-
   widget_->CloseWithReason(views::Widget::ClosedReason::kCloseButtonClicked);
+  glic_widget_observer_.reset();
+  window_event_observer_.reset();
   widget_.reset();
-  glic_view_ = nullptr;
   NotifyIfPanelStateChanged();
 }
 
@@ -225,16 +238,16 @@
     if (browser->profile()->IsOffTheRecord() ||
         !browser->window()->IsVisible() || window_widget == widget_.get() ||
         browser->GetWebView()->GetBrowserContext() !=
-            glic_view_->web_view()->GetBrowserContext()) {
+            GetGlicView()->web_view()->GetBrowserContext()) {
       continue;
     }
     auto* tab_strip_region_view =
         browser->window()->AsBrowserView()->tab_strip_region_view();
-    if (!tab_strip_region_view || !tab_strip_region_view->glic_button()) {
+    if (!tab_strip_region_view || !tab_strip_region_view->GetGlicButton()) {
       continue;
     }
     gfx::Rect glic_button_rect =
-        tab_strip_region_view->glic_button()->GetBoundsInScreen();
+        tab_strip_region_view->GetGlicButton()->GetBoundsInScreen();
 
     float glic_button_mouse_distance =
         (glic_button_rect.CenterPoint() -
@@ -267,7 +280,7 @@
   gfx::Rect glic_button_rect = browser->window()
                                    ->AsBrowserView()
                                    ->tab_strip_region_view()
-                                   ->glic_button()
+                                   ->GetGlicButton()
                                    ->GetBoundsInScreen();
   gfx::Point top_right = glic_button_rect.top_right();
   int tab_strip_padding = GetLayoutConstant(TAB_STRIP_PADDING);
@@ -335,6 +348,24 @@
   NotifyIfPanelStateChanged();
 }
 
+bool GlicWindowController::IsActive() {
+  return widget_ && widget_->IsActive();
+}
+
+base::CallbackListSubscription
+GlicWindowController::AddWindowActivationChangedCallback(
+    WindowActivationChangedCallback callback) {
+  return window_activation_callback_list_.Add(std::move(callback));
+}
+
+void GlicWindowController::NotifyWindowActivationChanged(bool active) {
+  window_activation_callback_list_.Notify(active);
+}
+
+base::WeakPtr<GlicWindowController> GlicWindowController::GetWeakPtr() {
+  return weak_ptr_factory_.GetWeakPtr();
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 // PinnedTargetWidgetObserver implementations:
 GlicWindowController::PinnedTargetWidgetObserver::PinnedTargetWidgetObserver(
@@ -373,10 +404,27 @@
   SetPinnedTargetWidget(nullptr);
 }
 
-base::WeakPtr<GlicWindowController> GlicWindowController::GetWeakPtr() {
-  return weak_ptr_factory_.GetWeakPtr();
+///////////////////////////////////////////////////////////////////////////////
+// GlicWidgetObserver implementations:
+GlicWindowController::GlicWidgetObserver::GlicWidgetObserver(
+    glic::GlicWindowController* glic_window_controller,
+    views::Widget* widget)
+    : glic_window_controller_(glic_window_controller), widget_(widget) {
+  if (widget) {
+    widget->AddObserver(this);
+  }
 }
 
-GlicWindowController::~GlicWindowController() = default;
+GlicWindowController::GlicWidgetObserver::~GlicWidgetObserver() {
+  if (widget_ && widget_->HasObserver(this)) {
+    widget_->RemoveObserver(this);
+  }
+}
+
+void GlicWindowController::GlicWidgetObserver::OnWidgetActivationChanged(
+    views::Widget* widget,
+    bool active) {
+  glic_window_controller_->NotifyWindowActivationChanged(active);
+}
 
 }  // namespace glic
diff --git a/chrome/browser/glic/glic_window_controller.h b/chrome/browser/glic/glic_window_controller.h
index 2e0785f..47c345f 100644
--- a/chrome/browser/glic/glic_window_controller.h
+++ b/chrome/browser/glic/glic_window_controller.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_GLIC_GLIC_WINDOW_CONTROLLER_H_
 #define CHROME_BROWSER_GLIC_GLIC_WINDOW_CONTROLLER_H_
 
+#include "base/callback_list.h"
 #include "base/memory/weak_ptr.h"
 #include "base/observer_list.h"
 #include "base/observer_list_types.h"
@@ -19,6 +20,7 @@
 }  // namespace gfx
 
 namespace {
+class GlicWidgetObserver;
 class WindowEventObserver;
 }  // namespace
 
@@ -65,6 +67,16 @@
   void AddStateObserver(StateObserver* observer);
   void RemoveStateObserver(StateObserver* observer);
 
+  // Returns whether or not the glic window is currently active.
+  bool IsActive();
+
+  using WindowActivationChangedCallback =
+      base::RepeatingCallback<void(bool active)>;
+
+  // Registers |callback| to be called whenever the window activation changes.
+  base::CallbackListSubscription AddWindowActivationChangedCallback(
+      WindowActivationChangedCallback callback);
+
   // Returns a WeakPtr to this instance. It can be destroyed at any time if the
   // profile is deleted or if the browser shuts down.
   base::WeakPtr<GlicWindowController> GetWeakPtr();
@@ -73,6 +85,7 @@
   void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override;
 
  private:
+  GlicView* GetGlicView();
   // Determines the correct position for the glic window when attached to a
   // browser.
   gfx::Point GetTopRightPositionForAttachedWindow(
@@ -102,10 +115,26 @@
 
    private:
     raw_ptr<glic::GlicWindowController> glic_window_controller_;
-    raw_ptr<glic::GlicView> glic_view_;
     raw_ptr<views::Widget> pinned_target_widget_;
   };
 
+  // Helper class for observing activation events from the widget.
+  class GlicWidgetObserver : public views::WidgetObserver {
+   public:
+    explicit GlicWidgetObserver(
+        glic::GlicWindowController* glic_window_controller,
+        views::Widget* widget);
+    GlicWidgetObserver(const GlicWidgetObserver&) = delete;
+    GlicWidgetObserver& operator=(const GlicWidgetObserver&) = delete;
+    ~GlicWidgetObserver() override;
+
+    void OnWidgetActivationChanged(views::Widget* widget, bool active) override;
+
+   private:
+    raw_ptr<glic::GlicWindowController> glic_window_controller_;
+    raw_ptr<views::Widget> widget_;
+  };
+
   // If the mouse is in snapping distance of a browser's glic button, it snaps
   // glic to the top right of the browser's glic button.
   void HandleBrowserPinning(gfx::Vector2d mouse_location);
@@ -123,6 +152,12 @@
   PinnedTargetWidgetObserver pinned_target_widget_observer_{this};
   base::WeakPtr<Browser> pinned_browser_;
 
+  // Notifies subscribers of a change to the window activation.
+  void NotifyWindowActivationChanged(bool active);
+
+  // List of callbacks to be notified when window activation has changed.
+  base::RepeatingCallbackList<void(bool)> window_activation_callback_list_;
+
   // Empty holder widget to reparent to when unpinned.
   std::unique_ptr<views::Widget> holder_widget_;
 
@@ -130,12 +165,12 @@
   views::UniqueWidgetPtr widget_;
   bool widget_visible_ = false;
 
-  // Owned by widget_.
-  raw_ptr<glic::GlicView> glic_view_ = nullptr;
-
   // Used to monitor key and mouse events from native window.
   std::unique_ptr<WindowEventObserver> window_event_observer_;
 
+  // Used to monitor window activation changes from widget.
+  std::unique_ptr<GlicWidgetObserver> glic_widget_observer_;
+
   // True while RunMoveLoop() has been called on a widget.
   bool in_move_loop_ = false;
 
diff --git a/chrome/browser/glic/launcher/glic_configuration.cc b/chrome/browser/glic/launcher/glic_configuration.cc
index 10b198f..93f03b77 100644
--- a/chrome/browser/glic/launcher/glic_configuration.cc
+++ b/chrome/browser/glic/launcher/glic_configuration.cc
@@ -34,9 +34,6 @@
 // static
 void GlicConfiguration::RegisterPrefs(PrefRegistrySimple* registry) {
   registry->RegisterBooleanPref(prefs::kGlicLauncherEnabled, false);
-  registry->RegisterBooleanPref(prefs::kGlicMicrophoneEnabled, false);
-  registry->RegisterBooleanPref(prefs::kGlicGeolocationEnabled, false);
-  registry->RegisterBooleanPref(prefs::kGlicTabContextEnabled, false);
   registry->RegisterDictionaryPref(
       prefs::kGlicLauncherGlobalHotkey,
       base::Value::Dict()
diff --git a/chrome/browser/history_embeddings/history_embeddings_utils.cc b/chrome/browser/history_embeddings/history_embeddings_utils.cc
index 6bf0aff..3517fff5 100644
--- a/chrome/browser/history_embeddings/history_embeddings_utils.cc
+++ b/chrome/browser/history_embeddings/history_embeddings_utils.cc
@@ -27,11 +27,21 @@
 bool IsEnabledForCountryAndLocale(const base::Feature& launch_feature) {
   // Launch in the US via client-side code, leaving a Finch hook available just
   // in case. Note, the variations service may be nullptr in unit tests.
-  return g_browser_process && g_browser_process->variations_service() &&
-         g_browser_process->variations_service()->GetStoredPermanentCountry() ==
-             "US" &&
-         g_browser_process->GetApplicationLocale() == "en-US" &&
-         base::FeatureList::IsEnabled(launch_feature);
+  if (!g_browser_process || !g_browser_process->variations_service()) {
+    return false;
+  }
+  if (!base::FeatureList::IsEnabled(launch_feature)) {
+    return false;
+  }
+  if (g_browser_process->GetApplicationLocale() != "en-US") {
+    return false;
+  }
+  std::string country_code =
+      g_browser_process->variations_service()->GetStoredPermanentCountry();
+  if (country_code.empty()) {
+    country_code = g_browser_process->variations_service()->GetLatestCountry();
+  }
+  return country_code == "us";
 }
 }  // namespace
 
diff --git a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc
index 221ca5a..09de60b 100644
--- a/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc
+++ b/chrome/browser/ntp_tiles/chrome_most_visited_sites_factory.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/check_deref.h"
-#include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
@@ -24,7 +23,6 @@
 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
 #include "chrome/common/buildflags.h"
 #include "components/history/core/browser/top_sites.h"
-#include "components/image_fetcher/core/features.h"
 #include "components/image_fetcher/core/image_fetcher_impl.h"
 #include "components/ntp_tiles/icon_cacher_impl.h"
 #include "components/ntp_tiles/metrics.h"
@@ -51,10 +49,7 @@
 
   std::unique_ptr<data_decoder::DataDecoder> data_decoder;
 #if BUILDFLAG(IS_ANDROID)
-  if (base::FeatureList::IsEnabled(
-          image_fetcher::features::kBatchImageDecoding)) {
-    data_decoder = std::make_unique<data_decoder::DataDecoder>();
-  }
+  data_decoder = std::make_unique<data_decoder::DataDecoder>();
 #endif
 
   bool is_default_chrome_app_migrated;
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
index 67c481cf..a559272 100644
--- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc
+++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -202,7 +202,6 @@
 #include "chrome/browser/ash/policy/handlers/configuration_policy_handler_ash.h"
 #include "chrome/browser/ash/policy/handlers/contextual_google_integrations_policies_handler.h"
 #include "chrome/browser/ash/policy/handlers/help_me_read_policy_handler.h"
-#include "chrome/browser/ash/policy/handlers/lacros_selection_policy_handler.h"
 #include "chrome/browser/ash/policy/handlers/multi_screen_capture_policy_handler.h"
 #include "chrome/browser/ash/policy/handlers/screen_capture_location_policy_handler.h"
 #include "chrome/browser/ash/policy/reporting/metrics_reporting/metric_reporting_prefs.h"
@@ -3057,7 +3056,6 @@
       SimpleSchemaValidatingPolicyHandler::MANDATORY_ALLOWED));
   handlers->AddHandler(std::make_unique<BooleanDisablingPolicyHandler>(
       key::kNearbyShareAllowed, prefs::kNearbySharingEnabledPrefName));
-  handlers->AddHandler(std::make_unique<LacrosSelectionPolicyHandler>());
   handlers->AddHandler(std::make_unique<BooleanDisablingPolicyHandler>(
       key::kFastPairEnabled, ash::prefs::kFastPairEnabled));
   handlers->AddHandler(std::make_unique<arc::ArcPolicyHandler>());
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc
index f45d3c59..19cc6ca 100644
--- a/chrome/browser/prefs/browser_prefs.cc
+++ b/chrome/browser/prefs/browser_prefs.cc
@@ -1170,6 +1170,7 @@
     "cryptauth.enrollment.user_private_key";
 const char kLacrosLaunchOnLogin[] = "lacros.launch_on_login";
 const char kLacrosLaunchSwitch[] = "lacros_launch_switch";
+const char kLacrosSelection[] = "lacros_selection";
 #endif
 
 // Deprecated 12/2024.
@@ -1289,6 +1290,7 @@
 #if BUILDFLAG(IS_CHROMEOS)
   // Deprecated 12/2024.
   registry->RegisterIntegerPref(kLacrosLaunchSwitch, 0);
+  registry->RegisterIntegerPref(kLacrosSelection, 0);
 #endif
 }
 
@@ -2035,6 +2037,11 @@
   dom_distiller::DistilledPagePrefs::RegisterProfilePrefs(registry);
   DownloadPrefs::RegisterProfilePrefs(registry);
   fingerprinting_protection_filter::prefs::RegisterProfilePrefs(registry);
+#if BUILDFLAG(ENABLE_GLIC)
+  registry->RegisterBooleanPref(prefs::kGlicMicrophoneEnabled, false);
+  registry->RegisterBooleanPref(prefs::kGlicGeolocationEnabled, false);
+  registry->RegisterBooleanPref(prefs::kGlicTabContextEnabled, false);
+#endif
   permissions::PermissionHatsTriggerHelper::RegisterProfilePrefs(registry);
   history_clusters::prefs::RegisterProfilePrefs(registry);
   HostContentSettingsMap::RegisterProfilePrefs(registry);
@@ -2595,6 +2602,7 @@
   // Added 12/2024
 #if BUILDFLAG(IS_CHROMEOS)
   local_state->ClearPref(kLacrosLaunchSwitch);
+  local_state->ClearPref(kLacrosSelection);
 #endif
 
   // Please don't delete the following line. It is used by PRESUBMIT.py.
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 14f63dc..22aa92b1 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -212,7 +212,6 @@
 #include "chrome/browser/signin/chrome_device_id_helper.h"
 #include "chromeos/ash/components/account_manager/account_manager_factory.h"
 #include "chromeos/ash/components/browser_context_helper/browser_context_types.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 #include "components/account_manager_core/chromeos/account_manager.h"
 #include "components/session_manager/core/session_manager.h"
 #include "components/user_manager/user.h"
@@ -654,17 +653,6 @@
       std::move(pref_validation_delegate), GetIOTaskRunner(), key_.get(), path_,
       async_prefs);
   key_->SetPrefs(prefs_.get());
-#if BUILDFLAG(IS_CHROMEOS)
-  // When Chrome crash or gets restarted for other reasons, it loads the policy
-  // immediately. We need to cache the LacrosLaunchSwitch now, as the value is
-  // needed later, while the profile is not fully initialized.
-  if (force_immediate_policy_load &&
-      ash::ProfileHelper::IsPrimaryProfile(this)) {
-    auto& map = profile_policy_connector_->policy_service()->GetPolicies(
-        policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()));
-    ash::standalone_browser::CacheLacrosSelection(map);
-  }
-#endif
 }
 
 void ProfileImpl::DoFinalInit(CreateMode create_mode) {
@@ -1201,13 +1189,6 @@
       OnLocaleReady(create_mode);
       break;
     case CreateMode::kAsynchronous:
-      if (ash::ProfileHelper::IsPrimaryProfile(this)) {
-        auto& map = profile_policy_connector_->policy_service()->GetPolicies(
-            policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME,
-                                    std::string()));
-        ash::standalone_browser::CacheLacrosSelection(map);
-      }
-
       ash::UserSessionManager::GetInstance()->RespectLocalePreferenceWrapper(
           this, base::BindOnce(&ProfileImpl::OnLocaleReady,
                                base::Unretained(this), create_mode));
diff --git a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/player/Colors.java b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/player/Colors.java
index 4e189dac..ab93349 100644
--- a/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/player/Colors.java
+++ b/chrome/browser/readaloud/android/java/src/org/chromium/chrome/browser/readaloud/player/Colors.java
@@ -62,7 +62,7 @@
         bar.setProgressTintList(
                 ColorStateList.valueOf(
                         ColorUtils.inNightMode(context)
-                                ? context.getColor(R.color.baseline_primary_80)
+                                ? SemanticColorUtils.getDefaultIconColorAccent1(context)
                                 : SemanticColorUtils.getDefaultIconColor(context)));
     }
 
diff --git a/chrome/browser/resources/certificate_viewer/modifications_panel.css b/chrome/browser/resources/certificate_viewer/modifications_panel.css
index de9d9d0..3b77fa2 100644
--- a/chrome/browser/resources/certificate_viewer/modifications_panel.css
+++ b/chrome/browser/resources/certificate_viewer/modifications_panel.css
@@ -9,6 +9,7 @@
  * #import=//resources/cr_elements/cr_icons_lit.css.js
  * #import=//resources/cr_elements/cr_shared_style_lit.css.js
  * #import=//resources/cr_elements/md_select_lit.css.js
+ * #import=//resources/cr_elements/cr_shared_vars.css.js
  * #include=cr-icons-lit cr-shared-style-lit cr-hidden-style-lit md-select-lit
  * #css_wrapper_metadata_end */
 
@@ -20,12 +21,13 @@
   width: 150px;
 }
 
-/* TODO(crbug.com/40928765): Try using shared colors from cr_shared_vars.css */
 .horizontal-row {
+  /* Match color in certificate_viewer.css */
   color: #616161;
   display: flex;
   flex-direction: row;
   align-content: flex-start;
+  align-items: baseline;
   padding-top: 10px;
   padding-inline-start: 20px;
   padding-bottom: 10px;
@@ -33,7 +35,7 @@
 
 .error {
   margin: 4px 10px;
-  color: rgb(179, 38, 30);
+  color: var(--cr-fallback-color-error)
 }
 
 .input-with-error {
@@ -44,7 +46,8 @@
 h3 {
   font-size: 100%;
   margin-bottom: 15px;
-  margin-top: 17px;
+  margin-top: 32px;
+  font-weight: normal;
 }
 
 .vertical-box {
diff --git a/chrome/browser/resources/glic/glic_api/glic_api.ts b/chrome/browser/resources/glic/glic_api/glic_api.ts
index 93e92f0..4f62730 100644
--- a/chrome/browser/resources/glic/glic_api/glic_api.ts
+++ b/chrome/browser/resources/glic/glic_api/glic_api.ts
@@ -106,6 +106,24 @@
 
   // Returns the state of the panel.
   getPanelState?(): Observable<PanelState>;
+
+  // Returns the state of the microphone permission.
+  getMicrophonePermissionState?(): Observable<boolean>;
+
+  // Returns the state of the location permission.
+  getLocationPermissionState?(): Observable<boolean>;
+
+  // Returns the state of the tab context permission.
+  getTabContextPermissionState?(): Observable<boolean>;
+
+  // Set the state of the microphone permission in settings.
+  setMicrophonePermissionState(enabled: boolean): Promise<void>;
+
+  // Set the state of the location permission in settings.
+  setLocationPermissionState(enabled: boolean): Promise<void>;
+
+  // Set the state of the tab context permission in settings.
+  setTabContextPermissionState(enabled: boolean): Promise<void>;
 }
 
 // A panel can be in one of these three states.
diff --git a/chrome/browser/resources/glic/glic_api/glic_api_client.ts b/chrome/browser/resources/glic/glic_api/glic_api_client.ts
index 53a2af0a..8a4bd96 100644
--- a/chrome/browser/resources/glic/glic_api/glic_api_client.ts
+++ b/chrome/browser/resources/glic/glic_api/glic_api_client.ts
@@ -42,7 +42,6 @@
   constructor(
       private webClient: GlicWebClient, private host: GlicBrowserHostImpl) {}
 
-
   glicWebClientNotifyPanelOpened(payload: {dockedToWindowId: string|undefined}):
       void {
     if (this.webClient.notifyPanelOpened) {
@@ -57,7 +56,25 @@
   }
 
   glicWebClientPanelStateChanged(payload: {panelState: PanelState}): void {
-    this.host.panelState.assignAndSignal(payload.panelState);
+    this.host.getPanelState().assignAndSignal(payload.panelState);
+  }
+
+  glicWebClientNotifyMicrophonePermissionStateChanged(payload: {
+    enabled: boolean,
+  }) {
+    this.host.getMicrophonePermissionState().assignAndSignal(payload.enabled);
+  }
+
+  glicWebClientNotifyLocationPermissionStateChanged(payload: {
+    enabled: boolean,
+  }) {
+    this.host.getLocationPermissionState().assignAndSignal(payload.enabled);
+  }
+
+  glicWebClientNotifyTabContextPermissionStateChanged(payload: {
+    enabled: boolean,
+  }) {
+    this.host.getTabContextPermissionState().assignAndSignal(payload.enabled);
   }
 }
 
@@ -66,7 +83,10 @@
   private receiver: PostMessageRequestReceiver;
   private handlerFunctionNames: Set<string> = new Set();
   private webClientMessageHandler: WebClientMessageHandler;
-  panelState = new ObservableValue<PanelState>({kind: PanelStateKind.HIDDEN});
+  private panelState = new ObservableValue<PanelState>({ kind: PanelStateKind.HIDDEN });
+  private permissionStateMicrophone = new ObservableValue<boolean>(false);
+  private permissionStateLocation = new ObservableValue<boolean>(false);
+  private permissionStateTabContext = new ObservableValue<boolean>(false);
 
   constructor(private webClient: GlicWebClient, windowProxy: WindowProxy) {
     this.sender = new PostMessageRequestSender(windowProxy, 'chrome://glic');
@@ -145,19 +165,46 @@
     return convertTabContextResultFromPrivate(context.tabContextResult);
   }
 
-  async resizeWindow(width: number, height: number) {
+  resizeWindow(width: number, height: number) {
     return this.sender.requestWithResponse(
         'glicBrowserResizeWindow', {width, height});
   }
 
-  async setWindowDraggableAreas(areas: DraggableArea[]) {
+  setWindowDraggableAreas(areas: DraggableArea[]) {
     return this.sender.requestWithResponse(
         'glicBrowserSetWindowDraggableAreas', {areas});
   }
 
-  getPanelState(): Observable<PanelState> {
+  getPanelState(): ObservableValue<PanelState> {
     return this.panelState;
   }
+
+  getMicrophonePermissionState(): ObservableValue<boolean> {
+    return this.permissionStateMicrophone;
+  }
+
+  getLocationPermissionState(): ObservableValue<boolean> {
+    return this.permissionStateLocation;
+  }
+
+  getTabContextPermissionState(): ObservableValue<boolean> {
+    return this.permissionStateTabContext;
+  }
+
+  setMicrophonePermissionState(enabled: boolean): Promise<void> {
+    return this.sender.requestWithResponse(
+        'glicBrowserSetMicrophonePermissionState', {enabled});
+  }
+
+  setLocationPermissionState(enabled: boolean): Promise<void> {
+    return this.sender.requestWithResponse(
+        'glicBrowserSetLocationPermissionState', {enabled});
+  }
+
+  setTabContextPermissionState(enabled: boolean): Promise<void> {
+    return this.sender.requestWithResponse(
+        'glicBrowserSetTabContextPermissionState', {enabled});
+  }
 }
 
 // Returns a promise which resolves to the `GlicHostRegistry`. This promise
@@ -275,6 +322,7 @@
   getValue(): T {
     return this.value;
   }
+
   subscribe(change: (newValue: T) => void): Subscriber {
     const newSub = new ObservableSubscription(
         change, (sub) => this.subscribers.delete(sub));
diff --git a/chrome/browser/resources/glic/glic_api/request_types.ts b/chrome/browser/resources/glic/glic_api/request_types.ts
index bf58ed5..a978a09 100644
--- a/chrome/browser/resources/glic/glic_api/request_types.ts
+++ b/chrome/browser/resources/glic/glic_api/request_types.ts
@@ -88,6 +88,24 @@
     },
     response: void,
   };
+  glicBrowserSetMicrophonePermissionState: {
+    request: {
+      enabled: boolean,
+    },
+    response: void,
+  };
+  glicBrowserSetLocationPermissionState: {
+    request: {
+      enabled: boolean,
+    },
+    response: void,
+  };
+  glicBrowserSetTabContextPermissionState: {
+    request: {
+      enabled: boolean,
+    },
+    response: void,
+  };
 }
 
 // Types of requests to the GlicWebClient.
@@ -108,6 +126,24 @@
     },
     response: void,
   };
+  glicWebClientNotifyMicrophonePermissionStateChanged: {
+    request: {
+      enabled: boolean,
+    },
+    response: void,
+  };
+  glicWebClientNotifyLocationPermissionStateChanged: {
+    request: {
+      enabled: boolean,
+    },
+    response: void,
+  };
+  glicWebClientNotifyTabContextPermissionStateChanged: {
+    request: {
+      enabled: boolean,
+    },
+    response: void,
+  };
 }
 
 export declare interface WebClientInitialState {
diff --git a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts
index d92fff0..585108b 100644
--- a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts
+++ b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts
@@ -59,6 +59,27 @@
       panelState: panelStateToClient(panelState),
     });
   }
+
+  notifyMicrophonePermissionStateChanged(enabled: boolean): void {
+    this.sender.requestNoResponse(
+        'glicWebClientNotifyMicrophonePermissionStateChanged', {
+          enabled: enabled,
+        });
+  }
+
+  notifyLocationPermissionStateChanged(enabled: boolean): void {
+    this.sender.requestNoResponse(
+        'glicWebClientNotifyLocationPermissionStateChanged', {
+          enabled: enabled,
+        });
+  }
+
+  notifyTabContextPermissionStateChanged(enabled: boolean): void {
+    this.sender.requestNoResponse(
+        'glicWebClientNotifyTabContextPermissionStateChanged', {
+          enabled: enabled,
+        });
+  }
 }
 
 // Handles all requests to the host.
@@ -201,9 +222,21 @@
     };
   }
 
-  async glicBrowserSetWindowDraggableAreas(request: {areas: DraggableArea[]}) {
+  glicBrowserSetWindowDraggableAreas(request: {areas: DraggableArea[]}) {
     this.handler.setPanelDraggableAreas(request.areas);
   }
+
+  glicBrowserSetMicrophonePermissionState(request: {enabled: boolean}) {
+    this.handler.setMicrophonePermissionState(request.enabled);
+  }
+
+  glicBrowserSetLocationPermissionState(request: {enabled: boolean}) {
+    this.handler.setLocationPermissionState(request.enabled);
+  }
+
+  glicBrowserSetTabContextPermissionState(request: {enabled: boolean}) {
+    this.handler.setTabContextPermissionState(request.enabled);
+  }
 }
 
 export class GlicApiHost implements PostMessageRequestHandler {
diff --git a/chrome/browser/resources/glic/main.ts b/chrome/browser/resources/glic/main.ts
index 6746a4b..54f9fb6 100644
--- a/chrome/browser/resources/glic/main.ts
+++ b/chrome/browser/resources/glic/main.ts
@@ -28,7 +28,7 @@
       this.onNewWindowEvent(e as chrome.webviewTag.NewWindowEvent);
     });
     webview.addEventListener('permissionrequest', (e: any) => {
-      if (e.permission === 'media') {
+      if (e.permission === 'media' || e.permission === 'geolocation') {
         e.request.allow();
       }
     });
diff --git a/chrome/browser/resources/settings/ai_page/ai_compare_subpage.html b/chrome/browser/resources/settings/ai_page/ai_compare_subpage.html
index 92991af..de354c5 100644
--- a/chrome/browser/resources/settings/ai_page/ai_compare_subpage.html
+++ b/chrome/browser/resources/settings/ai_page/ai_compare_subpage.html
@@ -7,7 +7,8 @@
 <settings-ai-policy-indicator pref="[[enterprisePref_]]">
 </settings-ai-policy-indicator>
 <cr-link-row label="$i18n{aiCompareLabel}"
-    on-click="onCompareLinkoutClick_" external>
+    on-click="onCompareLinkoutClick_" external
+    disabled="[[isDisabled_(enterprisePref_)]]">
   <div slot="sub-label">
     $i18n{aiCompareSublabel}$i18n{sentenceEnd}
     <a href="[[getLearnMoreUrl_(enterprisePref_)]]"
diff --git a/chrome/browser/resources/settings/ai_page/ai_compare_subpage.ts b/chrome/browser/resources/settings/ai_page/ai_compare_subpage.ts
index 97d0866..eb7eed0 100644
--- a/chrome/browser/resources/settings/ai_page/ai_compare_subpage.ts
+++ b/chrome/browser/resources/settings/ai_page/ai_compare_subpage.ts
@@ -15,6 +15,7 @@
 
 import {getTemplate} from './ai_compare_subpage.html.js';
 import {getAiLearnMoreUrl} from './ai_learn_more_url_util.js';
+import {isFeatureDisabledByPolicy} from './ai_policy_indicator.js';
 import {AiEnterpriseFeaturePrefName, AiPageActions} from './constants.js';
 
 const SettingsAiCompareSubpageElementBase = PrefsMixin(PolymerElement);
@@ -49,6 +50,11 @@
   }
 
   private onCompareLinkoutClick_() {
+    // Ignore click action if the feature is disabled.
+    if (this.isDisabled_()) {
+      return;
+    }
+
     this.recordInteractionMetrics_(
         AiPageCompareInteractions.FEATURE_LINK_CLICKED,
         AiPageActions.COMPARE_FEATURE_LINK_CLICKED);
@@ -72,6 +78,10 @@
         this.enterprisePref_, loadTimeData.getString('compareLearnMoreUrl'),
         loadTimeData.getString('compareLearnMoreManagedUrl'));
   }
+
+  private isDisabled_(): boolean {
+    return isFeatureDisabledByPolicy(this.enterprisePref_);
+  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/settings/ai_page/ai_policy_indicator.ts b/chrome/browser/resources/settings/ai_page/ai_policy_indicator.ts
index 0954649..8f12a77 100644
--- a/chrome/browser/resources/settings/ai_page/ai_policy_indicator.ts
+++ b/chrome/browser/resources/settings/ai_page/ai_policy_indicator.ts
@@ -15,6 +15,12 @@
 import {getTemplate} from './ai_policy_indicator.html.js';
 import {ModelExecutionEnterprisePolicyValue} from './constants.js';
 
+export function isFeatureDisabledByPolicy(
+    enterprisePref: chrome.settingsPrivate.PrefObject|undefined): boolean {
+  return !!enterprisePref &&
+      enterprisePref!.value === ModelExecutionEnterprisePolicyValue.DISABLE;
+}
+
 const SettingsAiPolicyIndicatorBase = PrefControlMixin(PolymerElement);
 
 export class SettingsAiPolicyIndicator extends SettingsAiPolicyIndicatorBase {
@@ -27,8 +33,7 @@
   }
 
   private isFeatureDisabledByPolicy_(): boolean {
-    return !!this.pref &&
-        this.pref!.value === ModelExecutionEnterprisePolicyValue.DISABLE;
+    return isFeatureDisabledByPolicy(this.pref);
   }
 }
 
diff --git a/chrome/browser/resources/settings/lazy_load.ts b/chrome/browser/resources/settings/lazy_load.ts
index 2c2fad8..0d0d70c 100644
--- a/chrome/browser/resources/settings/lazy_load.ts
+++ b/chrome/browser/resources/settings/lazy_load.ts
@@ -111,7 +111,7 @@
 // </if>
 
 export {SettingsAiCompareSubpageElement} from './ai_page/ai_compare_subpage.js';
-export {SettingsAiPolicyIndicator} from './ai_page/ai_policy_indicator.js';
+export {isFeatureDisabledByPolicy, SettingsAiPolicyIndicator} from './ai_page/ai_policy_indicator.js';
 export {SettingsAiTabOrganizationSubpageElement} from './ai_page/ai_tab_organization_subpage.js';
 export {AiEnterpriseFeaturePrefName, AiPageActions, FeatureOptInState, SettingsAiPageFeaturePrefName} from './ai_page/constants.js';
 export {SettingsHistorySearchPageElement} from './ai_page/history_search_page.js';
diff --git a/chrome/browser/resources/settings/privacy_page/fingerprint_progress_arc.html b/chrome/browser/resources/settings/privacy_page/fingerprint_progress_arc.html
index f6555cb6..efd0abe8 100644
--- a/chrome/browser/resources/settings/privacy_page/fingerprint_progress_arc.html
+++ b/chrome/browser/resources/settings/privacy_page/fingerprint_progress_arc.html
@@ -26,9 +26,6 @@
 
     <div id="canvasDiv">
       <canvas id="canvas" height="240" width="460"></canvas>
-      <iron-media-query query="(prefers-color-scheme: dark)"
-          query-matches="{{isDarkModeActive_}}">
-      </iron-media-query>
       <cr-lottie id="scanningAnimation" aria-hidden="true"
           autoplay="[[autoplay]]">
       </cr-lottie>
diff --git a/chrome/browser/resources/settings/privacy_page/fingerprint_progress_arc.ts b/chrome/browser/resources/settings/privacy_page/fingerprint_progress_arc.ts
index 99588ea..d08831f 100644
--- a/chrome/browser/resources/settings/privacy_page/fingerprint_progress_arc.ts
+++ b/chrome/browser/resources/settings/privacy_page/fingerprint_progress_arc.ts
@@ -3,12 +3,12 @@
 // found in the LICENSE file.
 
 import '//resources/cr_elements/cr_icon/cr_icon.js';
-import '//resources/polymer/v3_0/iron-media-query/iron-media-query.js';
 import './fingerprint_icons.html.js';
 import './cr_lottie.js';
 
 import type {CrIconElement} from '//resources/cr_elements/cr_icon/cr_icon.js';
 import {assert} from '//resources/js/assert.js';
+import {EventTracker} from '//resources/js/event_tracker.js';
 import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import type {CrLottieElement} from './cr_lottie.js';
@@ -152,15 +152,6 @@
        * Whether fingerprint enrollment is complete.
        */
       isComplete_: Boolean,
-
-      /**
-       * Whether the fingerprint progress page is being rendered in dark mode.
-       */
-      isDarkModeActive_: {
-        type: Boolean,
-        value: false,
-        observer: 'onDarkModeChanged_',
-      },
     };
   }
 
@@ -168,7 +159,8 @@
   autoplay: boolean;
   private scale_: number;
   private isComplete_: boolean;
-  private isDarkModeActive_: boolean;
+  private isDarkModeActive_: boolean = false;
+  private eventTracker_: EventTracker = new EventTracker();
 
   // Animation ID for the fingerprint progress circle.
   private progressAnimationIntervalId_: number|undefined = undefined;
@@ -182,7 +174,10 @@
   /**
    * Updates the current state to account for whether dark mode is enabled.
    */
-  private onDarkModeChanged_() {
+  private onDarkModeChanged_(e: MediaQueryListEvent) {
+    // Update media query states.
+    this.isDarkModeActive_ = e.matches;
+
     this.clearCanvas_();
     this.drawProgressCircle_(this.progressPercentDrawn_);
     this.updateAnimationAsset_();
@@ -192,11 +187,23 @@
   override connectedCallback() {
     super.connectedCallback();
 
+    // Set media query initial states.
+    const darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)');
+    this.isDarkModeActive_ = darkModeQuery.matches;
+    this.eventTracker_.add(
+        darkModeQuery, 'change',
+        (e: MediaQueryListEvent) => this.onDarkModeChanged_(e));
+
     this.scale_ = this.circleRadius / DEFAULT_PROGRESS_CIRCLE_RADIUS;
     this.updateIconAsset_();
     this.updateImages_();
   }
 
+  override disconnectedCallback() {
+    super.disconnectedCallback();
+    this.eventTracker_.removeAll();
+  }
+
   /**
    * Reset the element to initial state, when the enrollment just starts.
    */
diff --git a/chrome/browser/search_engines/template_url_service_unittest.cc b/chrome/browser/search_engines/template_url_service_unittest.cc
index 87e5b960..3abce08 100644
--- a/chrome/browser/search_engines/template_url_service_unittest.cc
+++ b/chrome/browser/search_engines/template_url_service_unittest.cc
@@ -857,12 +857,10 @@
 
   // Register an extension with unscoped mode allowed.
   model()->AddToUnscopedModeExtensionIds("id");
-  EXPECT_TRUE(model()->IsUnscopedModeExtensionId("id"));
   EXPECT_TRUE(model()->GetUnscopedModeExtensionIds().contains("id"));
 
   // Remove the registered extension.
   model()->RemoveFromUnscopedModeExtensionIdsIfPresent("id");
-  EXPECT_FALSE(model()->IsUnscopedModeExtensionId("id"));
   EXPECT_FALSE(model()->GetUnscopedModeExtensionIds().contains("id"));
 }
 
@@ -877,7 +875,6 @@
   EXPECT_TRUE(extension_with_permission);
   EXPECT_EQ(extension_with_permission,
             model()->GetTemplateURLForKeyword(u"keyword"));
-  EXPECT_TRUE(model()->IsUnscopedModeExtensionId("id"));
   EXPECT_TRUE(model()->GetUnscopedModeExtensionIds().contains("id"));
 
   // Remove the registered extension.
@@ -886,7 +883,6 @@
   const TemplateURL* removed_extension =
       model()->GetTemplateURLForKeyword(u"keyword");
   EXPECT_FALSE(removed_extension);
-  EXPECT_FALSE(model()->IsUnscopedModeExtensionId("id"));
   EXPECT_FALSE(model()->GetUnscopedModeExtensionIds().contains("id"));
 
   // Register an extension again without allowing unscoped mode.
@@ -897,7 +893,6 @@
   EXPECT_TRUE(extension_without_permission);
   EXPECT_EQ(extension_without_permission,
             model()->GetTemplateURLForKeyword(u"keyword"));
-  EXPECT_FALSE(model()->IsUnscopedModeExtensionId("id"));
   EXPECT_FALSE(model()->GetUnscopedModeExtensionIds().contains("id"));
 }
 
diff --git a/chrome/browser/themes/theme_service_unittest.cc b/chrome/browser/themes/theme_service_unittest.cc
index fb21c2ff..4183ee31 100644
--- a/chrome/browser/themes/theme_service_unittest.cc
+++ b/chrome/browser/themes/theme_service_unittest.cc
@@ -652,8 +652,6 @@
       {kColorOmniboxResultsUrl, kColorOmniboxResultsBackgroundHovered},
       {kColorOmniboxResultsUrlSelected, kColorOmniboxResultsBackgroundSelected},
       {kColorOmniboxBubbleOutline, kColorOmniboxResultsBackground},
-      {kColorOmniboxBubbleOutlineExperimentalKeywordMode,
-       kColorOmniboxResultsBackground},
       {kColorOmniboxSecurityChipDefault, kColorToolbarBackgroundSubtleEmphasis},
       {kColorOmniboxSecurityChipDefault,
        kColorToolbarBackgroundSubtleEmphasisHovered},
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd
index c47e2cee..79f84028 100644
--- a/chrome/browser/ui/android/strings/android_chrome_strings.grd
+++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -6406,10 +6406,6 @@
       <message name="IDS_PASSWORD_MANAGER_DROPDOWN_BUTTON_DESCRIPTION" desc="This is a description that will be used for the TalkBack to describe the button with the down arrow that opens a dropdown with a list of items.">
         Select from the dropdown list
       </message>
-      <!-- Price tracking strings -->
-      <message name="IDS_PRICE_DROP_SPOTTED_IPH" desc="This text appears in the IPH when a user opens a new tab page and an item in any of their open tabs has a price drop.">
-        Price drop spotted
-      </message>
       <!-- Partial Custom Tab accessibility -->
       <message name="IDS_ACCESSIBILITY_PARTIAL_CUSTOM_TAB_BOTTOM_SHEET" desc="Content description for partial custom tab of bottom sheet type">
         Bottom sheet
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRICE_DROP_SPOTTED_IPH.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRICE_DROP_SPOTTED_IPH.png.sha1
deleted file mode 100644
index 3b7003c0..0000000
--- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_PRICE_DROP_SPOTTED_IPH.png.sha1
+++ /dev/null
@@ -1 +0,0 @@
-47eedb698c856fe9ea0f17a4642f2cf17f522138
\ No newline at end of file
diff --git a/chrome/browser/ui/ash/web_view/BUILD.gn b/chrome/browser/ui/ash/web_view/BUILD.gn
index 304e0e8..05491b1a 100644
--- a/chrome/browser/ui/ash/web_view/BUILD.gn
+++ b/chrome/browser/ui/ash/web_view/BUILD.gn
@@ -21,6 +21,7 @@
     "//base",
     "//chrome/browser/media/webrtc",
     "//chrome/browser/profiles:profile",
+    "//chrome/browser/ui/ash/new_window:new_window",
     "//content/public/browser",
     "//ui/aura",
     "//ui/base",
diff --git a/chrome/browser/ui/ash/web_view/DEPS b/chrome/browser/ui/ash/web_view/DEPS
index f1f4dbc8..61a7308 100644
--- a/chrome/browser/ui/ash/web_view/DEPS
+++ b/chrome/browser/ui/ash/web_view/DEPS
@@ -12,5 +12,12 @@
   # Whenever possible, avoid adding new //chrome dependencies to this list.
   "+chrome/browser/media/webrtc",
   "+chrome/browser/profiles",
+  "+chrome/browser/ui/ash/new_window",
   "+chrome/test",
 ]
+
+specific_include_rules = {
+  "ash_web_view_impl_browsertest.cc": [
+    "+chrome/browser/ui/browser.h"
+  ]
+}
diff --git a/chrome/browser/ui/ash/web_view/ash_web_view_impl.cc b/chrome/browser/ui/ash/web_view/ash_web_view_impl.cc
index 05fa4a72..44be635 100644
--- a/chrome/browser/ui/ash/web_view/ash_web_view_impl.cc
+++ b/chrome/browser/ui/ash/web_view/ash_web_view_impl.cc
@@ -4,11 +4,13 @@
 
 #include "chrome/browser/ui/ash/web_view/ash_web_view_impl.h"
 
+#include "ash/public/cpp/new_window_delegate.h"
 #include "ash/public/cpp/window_properties.h"
 #include "base/task/sequenced_task_runner.h"
 #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/ash/new_window/chrome_new_window_client.h"
 #include "content/public/browser/focused_node_details.h"
 #include "content/public/browser/host_zoom_map.h"
 #include "content/public/browser/media_session.h"
@@ -145,6 +147,24 @@
       source, params, std::move(navigation_handle_callback));
 }
 
+void AshWebViewImpl::ActivateContents(content::WebContents* contents) {
+  // In cases where the widget is not activatable, an `activation_url` may be
+  // provided to show instead.
+  // This is currently used for Focus Mode YTM for when the user clicks on the
+  // media controls view. Since the media window is a custom hidden window, a
+  // separately provided URL tab (navigating to `activation_url`) is shown when
+  // the hidden media window is activated.
+  if (!GetWidget()->CanActivate() && !params_.activation_url.is_empty()) {
+    ChromeNewWindowClient::Get()->OpenUrl(
+        params_.activation_url,
+        ash::NewWindowDelegate::OpenUrlFrom::kUserInteraction,
+        ash::NewWindowDelegate::Disposition::kSwitchToTab);
+    return;
+  }
+
+  content::WebContentsDelegate::ActivateContents(contents);
+}
+
 void AshWebViewImpl::ResizeDueToAutoResize(content::WebContents* web_contents,
                                            const gfx::Size& new_size) {
   DCHECK_EQ(web_contents_.get(), web_contents);
diff --git a/chrome/browser/ui/ash/web_view/ash_web_view_impl.h b/chrome/browser/ui/ash/web_view/ash_web_view_impl.h
index b078a4a..4fd8dff1 100644
--- a/chrome/browser/ui/ash/web_view/ash_web_view_impl.h
+++ b/chrome/browser/ui/ash/web_view/ash_web_view_impl.h
@@ -66,6 +66,7 @@
       const content::OpenURLParams& params,
       base::OnceCallback<void(content::NavigationHandle&)>
           navigation_handle_callback) override;
+  void ActivateContents(content::WebContents* contents) override;
   void ResizeDueToAutoResize(content::WebContents* web_contents,
                              const gfx::Size& new_size) override;
   bool TakeFocus(content::WebContents* web_contents, bool reverse) override;
diff --git a/chrome/browser/ui/ash/web_view/ash_web_view_impl_browsertest.cc b/chrome/browser/ui/ash/web_view/ash_web_view_impl_browsertest.cc
index d9d93dbdd..3ad692ba 100644
--- a/chrome/browser/ui/ash/web_view/ash_web_view_impl_browsertest.cc
+++ b/chrome/browser/ui/ash/web_view/ash_web_view_impl_browsertest.cc
@@ -12,13 +12,17 @@
 #include "base/run_loop.h"
 #include "base/scoped_observation.h"
 #include "base/strings/stringprintf.h"
+#include "chrome/browser/ui/browser.h"
 #include "chrome/test/base/in_process_browser_test.h"
 #include "content/public/browser/host_zoom_map.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_view_host.h"
 #include "content/public/test/browser_test.h"
+#include "content/public/test/test_navigation_observer.h"
+#include "content/public/test/test_utils.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/views/controls/webview/webview.h"
 #include "ui/views/view.h"
 #include "ui/views/view_observer.h"
 #include "ui/views/widget/widget.h"
@@ -97,12 +101,16 @@
 
 // Helpers ---------------------------------------------------------------------
 
-std::unique_ptr<views::Widget> CreateWidget() {
+std::unique_ptr<views::Widget> CreateWidget(bool activatable = true) {
   auto widget = std::make_unique<views::Widget>();
 
   views::Widget::InitParams params(
       views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
+  params.activatable = activatable
+                           ? views::Widget::InitParams::Activatable::kDefault
+                           : views::Widget::InitParams::Activatable::kNo;
+
   widget->Init(std::move(params));
   return widget;
 }
@@ -310,3 +318,35 @@
   EXPECT_DOUBLE_EQ(
       1.0, content::HostZoomMap::GetZoomLevel(web_view_impl->web_contents()));
 }
+
+// Tests that AshWebViewImpl will open a browser window if the AshWebView is
+// activated (while the widget is not activatable) and provided an
+// `activation_url`.
+IN_PROC_BROWSER_TEST_F(AshWebViewImplBrowserTest, ShouldOpenNewWindow) {
+  auto widget = CreateWidget(/*activatable=*/false);
+  AshWebView::InitParams init_params;
+  const GURL destination_url("https://www.google.com");
+  init_params.activation_url = destination_url;
+
+  AshWebView* web_view =
+      widget->SetContentsView(AshWebViewFactory::Get()->Create(init_params));
+  AshWebViewImpl* web_view_impl = static_cast<AshWebViewImpl*>(web_view);
+
+  web_view->Navigate(CreateDataUrl());
+  EXPECT_DID_STOP_LOADING(web_view);
+
+  // Activate the web contents and wait for the browser tab to load.
+  ASSERT_TRUE(browser());
+  content::TestNavigationObserver navigation_observer(
+      browser()->tab_strip_model()->GetActiveWebContents());
+  navigation_observer.StartWatchingNewWebContents();
+  content::WebContents* web_contents = web_view_impl->web_contents();
+  web_contents->GetDelegate()->ActivateContents(web_contents);
+  navigation_observer.Wait();
+
+  // Verify that the browser was launched with the correct url as the active
+  // tab.
+  EXPECT_EQ(
+      destination_url,
+      browser()->tab_strip_model()->GetActiveWebContents()->GetVisibleURL());
+}
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h
index 90b7f084c..05e0144 100644
--- a/chrome/browser/ui/color/chrome_color_id.h
+++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -317,7 +317,6 @@
   E_CPONLY(kColorOmniboxAnswerIconGM3Background) \
   E_CPONLY(kColorOmniboxAnswerIconGM3Foreground) \
   E_CPONLY(kColorOmniboxBubbleOutline) \
-  E_CPONLY(kColorOmniboxBubbleOutlineExperimentalKeywordMode) \
   E_CPONLY(kColorOmniboxChipInUseActivityIndicatorBackground) \
   E_CPONLY(kColorOmniboxChipInUseActivityIndicatorForeground) \
   E_CPONLY(kColorOmniboxChipBackground) \
diff --git a/chrome/browser/ui/color/omnibox_color_mixer.cc b/chrome/browser/ui/color/omnibox_color_mixer.cc
index e99b516..4150ad6 100644
--- a/chrome/browser/ui/color/omnibox_color_mixer.cc
+++ b/chrome/browser/ui/color/omnibox_color_mixer.cc
@@ -228,8 +228,6 @@
   mixer[kColorOmniboxBubbleOutline] = ui::SelectBasedOnDarkInput(
       kColorToolbarBackgroundSubtleEmphasis, gfx::kGoogleGrey100,
       SkColorSetA(gfx::kGoogleGrey900, 0x24));
-  mixer[kColorOmniboxBubbleOutlineExperimentalKeywordMode] = {
-      kColorOmniboxKeywordSelected};
 
   // Results background, chip, button, and focus colors.
   mixer[kColorOmniboxResultsBackground] =
diff --git a/chrome/browser/ui/lens/lens_overlay_controller.cc b/chrome/browser/ui/lens/lens_overlay_controller.cc
index 83fdc40..6f873ef 100644
--- a/chrome/browser/ui/lens/lens_overlay_controller.cc
+++ b/chrome/browser/ui/lens/lens_overlay_controller.cc
@@ -1615,7 +1615,8 @@
   pdf::PDFDocumentHelper* pdf_helper =
       pdf::PDFDocumentHelper::MaybeGetForWebContents(tab_->GetContents());
   if (!pdf_helper ||
-      lens::features::GetLensOverlayPdfSuggestCharacterTarget() == 0) {
+      lens::features::GetLensOverlayPdfSuggestCharacterTarget() == 0 ||
+      page_count == 0) {
     return;
   }
 
@@ -1623,9 +1624,10 @@
   // pages.
   initialization_data_->pdf_pages_text_.clear();
   pdf_helper->GetPageText(
-      0, base::BindOnce(&LensOverlayController::GetPartialPdfTextCallback,
-                        weak_factory_.GetWeakPtr(), /*page_index=*/0,
-                        page_count, /*total_characters_retrieved=*/0));
+      /*page_index=*/0,
+      base::BindOnce(&LensOverlayController::GetPartialPdfTextCallback,
+                     weak_factory_.GetWeakPtr(), /*page_index=*/0, page_count,
+                     /*total_characters_retrieved=*/0));
 }
 
 void LensOverlayController::GetPartialPdfTextCallback(
diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller.cc b/chrome/browser/ui/lens/lens_overlay_query_controller.cc
index 3a85af5..f4ed705 100644
--- a/chrome/browser/ui/lens/lens_overlay_query_controller.cc
+++ b/chrome/browser/ui/lens/lens_overlay_query_controller.cc
@@ -458,7 +458,7 @@
 
   // If there is a page content request in flight, wait for it to finish before
   // sending the contextual text query.
-  if (page_content_request_in_progress_) {
+  if (ShouldHoldContextualSearchQuery()) {
     pending_contextual_query_callback_ =
         base::BindOnce(&LensOverlayQueryController::SendContextualTextQuery,
                        weak_ptr_factory_.GetWeakPtr(), query_text,
@@ -1790,4 +1790,29 @@
       VitQueryParamValueForMimeType(underlying_content_type_));
   interaction_endpoint_fetcher_ = std::move(endpoint_fetcher);
 }
+
+bool LensOverlayQueryController::ShouldHoldContextualSearchQuery() {
+  // If the page content request has already finished, the query can be sent.
+  if (!page_content_request_in_progress_) {
+    return false;
+  }
+
+  // If the partial page content is empty, the query needs to be held until the
+  // page content upload is finished.
+  if (partial_content_.empty()) {
+    return true;
+  }
+
+  // Get the average number of characters per page.
+  int total_characters = 0;
+  for (const std::u16string& page_text : partial_content_) {
+    total_characters += page_text.size();
+  }
+  const int characters_per_page = total_characters / partial_content_.size();
+
+  // If the average is under the scanned pdf character per page heuristic, the
+  // query needs to wait for the page content upload.
+  return characters_per_page <
+         lens::features::GetScannedPdfCharacterPerPageHeuristic();
+}
 }  // namespace lens
diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller.h b/chrome/browser/ui/lens/lens_overlay_query_controller.h
index 52d17c02..c9b1d561 100644
--- a/chrome/browser/ui/lens/lens_overlay_query_controller.h
+++ b/chrome/browser/ui/lens/lens_overlay_query_controller.h
@@ -503,6 +503,12 @@
   void OnInteractionEndpointFetcherCreated(
       std::unique_ptr<EndpointFetcher> endpoint_fetcher);
 
+  // Returns whether or not the contextual search query should be held until
+  // the full page content upload is finished. This is only true if the page
+  // content upload is in progress and the partial page content upload will not
+  // yield detailed enough results.
+  bool ShouldHoldContextualSearchQuery();
+
   // The request id generator.
   std::unique_ptr<lens::LensOverlayRequestIdGenerator> request_id_generator_;
 
diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc b/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc
index dc45949..dd4b31c7 100644
--- a/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc
+++ b/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc
@@ -117,6 +117,12 @@
 const std::vector<uint8_t> kFakeContentBytes({1, 2, 3, 4});
 const std::vector<uint8_t> kNewFakeContentBytes({5, 6, 7, 8});
 
+const std::vector<std::u16string> kShortPartialContent({u"page 1", u"page 2",
+                                                        u"page 3"});
+const std::vector<std::u16string> kLongPartialContent(
+    {u"this is a page with over 100 characters to ensure that the average "
+     "characters per page is above the heuristic."});
+
 const base::test::FeatureRefAndParams
     kDefaultLensOverlayContextualSearchboxParams =
         base::test::FeatureRefAndParams(
@@ -129,7 +135,8 @@
              {"send-lens-inputs-for-contextual-suggest", "true"},
              {"send-page-url-for-contextualization", "true"},
              {"send-lens-inputs-for-lens-suggest", "true"},
-             {"send-lens-visual-interaction-data-for-lens-suggest", "true"}});
+             {"send-lens-visual-interaction-data-for-lens-suggest", "true"},
+             {"characters-per-page-heuristic", "50"}});
 
 MATCHER_P(EqualsProto, message, "") {
   std::string expected_serialized, actual_serialized;
@@ -1599,7 +1606,7 @@
 }
 
 TEST_F(LensOverlayQueryControllerTest,
-       FetchTextOnlyInteractionWithLargeUpload_HoldsRequest) {
+       SendContextualTextQuery_WithNoPartialUpload_HoldsRequest) {
   InitFeaturesWithClusterInfoOptimization();
   base::test::TestFuture<std::vector<lens::mojom::OverlayObjectPtr>,
                          lens::mojom::TextPtr, bool>
@@ -1641,6 +1648,11 @@
       std::vector<lens::mojom::CenterRotatedBoxPtr>(), kFakeContentBytes,
       lens::MimeType::kPlainText, 0, base::TimeTicks::Now());
   ASSERT_TRUE(full_image_response_future.Wait());
+
+  // Send an empty partial page content request.
+  query_controller.SendPartialPageContentRequest({});
+
+  // Send the contextual text query.
   query_controller.SendContextualTextQuery(
       kTestQueryText, lens::LensOverlaySelectionType::MULTIMODAL_SEARCH,
       additional_search_query_params);
@@ -1657,6 +1669,131 @@
 }
 
 TEST_F(LensOverlayQueryControllerTest,
+       SendContextualTextQuery_WithScannedPdfPartialUpload_HoldsRequest) {
+  InitFeaturesWithClusterInfoOptimization();
+  base::test::TestFuture<std::vector<lens::mojom::OverlayObjectPtr>,
+                         lens::mojom::TextPtr, bool>
+      full_image_response_future;
+  base::test::TestFuture<lens::proto::LensOverlayUrlResponse>
+      url_response_future;
+  base::test::TestFuture<const std::string&> thumbnail_created_future;
+  TestLensOverlayQueryController query_controller(
+      full_image_response_future.GetRepeatingCallback(),
+      url_response_future.GetRepeatingCallback(), GetSuggestInputsCallback(),
+      thumbnail_created_future.GetRepeatingCallback(),
+      fake_variations_client_.get(),
+      IdentityManagerFactory::GetForProfile(profile()), profile(),
+      lens::LensOverlayInvocationSource::kAppMenu,
+      /*use_dark_mode=*/false, GetGen204Controller());
+
+  // Set up the query controller responses.
+  lens::LensOverlayServerClusterInfoResponse fake_cluster_info_response;
+  fake_cluster_info_response.set_server_session_id(kTestServerSessionId);
+  fake_cluster_info_response.set_search_session_id(kTestSearchSessionId);
+  query_controller.set_fake_cluster_info_response(fake_cluster_info_response);
+  lens::LensOverlayObjectsResponse fake_objects_response;
+  fake_objects_response.mutable_cluster_info()->set_server_session_id(
+      kTestServerSessionId);
+  query_controller.set_fake_objects_response(fake_objects_response);
+  lens::LensOverlayInteractionResponse fake_interaction_response;
+  fake_interaction_response.set_encoded_response(kTestSuggestSignals);
+  query_controller.set_fake_interaction_response(fake_interaction_response);
+
+  // Disable the upload progress callback so the test can control when it
+  // completes.
+  query_controller.set_disable_page_upload_response_callback(true);
+
+  SkBitmap bitmap = CreateNonEmptyBitmap(100, 100);
+  std::map<std::string, std::string> additional_search_query_params;
+  query_controller.StartQueryFlow(
+      bitmap, GURL(kTestPageUrl),
+      std::make_optional<std::string>(kTestPageTitle),
+      std::vector<lens::mojom::CenterRotatedBoxPtr>(), kFakeContentBytes,
+      lens::MimeType::kPlainText, 0, base::TimeTicks::Now());
+  ASSERT_TRUE(full_image_response_future.Wait());
+
+  // Send a partial page content request that does not meet the per page
+  // character limit to be considered as a non-scanned pdf. This emulates the
+  // case where the users PDF is scanned and therefore the search query should
+  // be held until the page content upload is finished.
+  query_controller.SendPartialPageContentRequest(kShortPartialContent);
+
+  // Send the contextual text query.
+  query_controller.SendContextualTextQuery(
+      kTestQueryText, lens::LensOverlaySelectionType::MULTIMODAL_SEARCH,
+      additional_search_query_params);
+
+  // Verify the query controller did not issue the search request yet.
+  EXPECT_FALSE(url_response_future.IsReady());
+
+  // Simulate the upload progress callback completing the upload. Verify the
+  // query controller issued the search request after the upload completed.
+  query_controller.RunUploadProgressCallback();
+  ASSERT_TRUE(url_response_future.Wait());
+
+  query_controller.EndQuery();
+}
+
+TEST_F(LensOverlayQueryControllerTest,
+       SendContextualTextQuery_WithFullTextPdfPartialUpload_SendsRequest) {
+  InitFeaturesWithClusterInfoOptimization();
+  base::test::TestFuture<std::vector<lens::mojom::OverlayObjectPtr>,
+                         lens::mojom::TextPtr, bool>
+      full_image_response_future;
+  base::test::TestFuture<lens::proto::LensOverlayUrlResponse>
+      url_response_future;
+  base::test::TestFuture<const std::string&> thumbnail_created_future;
+  TestLensOverlayQueryController query_controller(
+      full_image_response_future.GetRepeatingCallback(),
+      url_response_future.GetRepeatingCallback(), GetSuggestInputsCallback(),
+      thumbnail_created_future.GetRepeatingCallback(),
+      fake_variations_client_.get(),
+      IdentityManagerFactory::GetForProfile(profile()), profile(),
+      lens::LensOverlayInvocationSource::kAppMenu,
+      /*use_dark_mode=*/false, GetGen204Controller());
+
+  // Set up the query controller responses.
+  lens::LensOverlayServerClusterInfoResponse fake_cluster_info_response;
+  fake_cluster_info_response.set_server_session_id(kTestServerSessionId);
+  fake_cluster_info_response.set_search_session_id(kTestSearchSessionId);
+  query_controller.set_fake_cluster_info_response(fake_cluster_info_response);
+  lens::LensOverlayObjectsResponse fake_objects_response;
+  fake_objects_response.mutable_cluster_info()->set_server_session_id(
+      kTestServerSessionId);
+  query_controller.set_fake_objects_response(fake_objects_response);
+  lens::LensOverlayInteractionResponse fake_interaction_response;
+  fake_interaction_response.set_encoded_response(kTestSuggestSignals);
+  query_controller.set_fake_interaction_response(fake_interaction_response);
+
+  // Disable the upload progress callback so the test can control when it
+  // completes.
+  query_controller.set_disable_page_upload_response_callback(true);
+
+  SkBitmap bitmap = CreateNonEmptyBitmap(100, 100);
+  std::map<std::string, std::string> additional_search_query_params;
+  query_controller.StartQueryFlow(
+      bitmap, GURL(kTestPageUrl),
+      std::make_optional<std::string>(kTestPageTitle),
+      std::vector<lens::mojom::CenterRotatedBoxPtr>(), kFakeContentBytes,
+      lens::MimeType::kPlainText, 0, base::TimeTicks::Now());
+  ASSERT_TRUE(full_image_response_future.Wait());
+
+  // Send a partial page content request that does meet the per page
+  // character limit to be considered as a non-scanned pdf.
+  query_controller.SendPartialPageContentRequest(kLongPartialContent);
+
+  // Send the contextual text query.
+  query_controller.SendContextualTextQuery(
+      kTestQueryText, lens::LensOverlaySelectionType::MULTIMODAL_SEARCH,
+      additional_search_query_params);
+
+  // Verify the query controller did issue the search request.
+  ASSERT_TRUE(url_response_future.Wait());
+
+  query_controller.EndQuery();
+}
+
+TEST_F(LensOverlayQueryControllerTest,
        SendPageContentUpdateRequest_IncrementsSequence) {
   InitFeaturesWithClusterInfoOptimization();
   base::test::TestFuture<std::vector<lens::mojom::OverlayObjectPtr>,
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc
index d4dd7d6..f7ba7e23 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc
+++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc
@@ -50,6 +50,7 @@
 #include "ui/base/dragdrop/os_exchange_data.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/models/image_model.h"
+#include "ui/base/models/menu_separator_types.h"
 #include "ui/base/mojom/menu_source_type.mojom-forward.h"
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/theme_provider.h"
@@ -62,6 +63,7 @@
 #include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/controls/button/menu_button.h"
 #include "ui/views/controls/menu/menu_item_view.h"
+#include "ui/views/controls/menu/menu_separator.h"
 #include "ui/views/controls/menu/submenu_view.h"
 #include "ui/views/widget/tooltip_manager.h"
 #include "ui/views/widget/widget.h"
@@ -80,6 +82,10 @@
 // both IE and FF restrict the max width of a menu.
 const int kMaxMenuWidth = 400;
 
+size_t GetSubmenuChildCount(const MenuItemView* menu) {
+  return menu->HasSubmenu() ? menu->GetSubmenu()->children().size() : 0;
+}
+
 ui::ImageModel GetFaviconForNode(BookmarkModel* model,
                                  const BookmarkNode* node) {
   const gfx::Image& image = model->GetFavicon(node);
@@ -240,9 +246,9 @@
   // Assume that the menu will only use mnemonics if there's already a parent
   // menu that uses them.
   menu_uses_mnemonics_ = parent_menu_item_->GetRootMenuItem()->has_mnemonics();
-
   if (ShouldHaveBookmarksTitle()) {
-    BuildBookmarksTitle();
+    const size_t title_index = GetSubmenuChildCount(parent_menu_item_);
+    BuildBookmarksTitle(title_index);
   }
 
   const BookmarkNode* managed_node =
@@ -787,17 +793,30 @@
 void BookmarkMenuDelegate::BuildMenuForFolder(const BookmarkNode* node,
                                               const ui::ImageModel& icon,
                                               MenuItemView* parent_menu) {
-  AddMenuToMaps(
-      parent_menu->AppendSubMenu(GetAndIncrementNextMenuID(),
-                                 MaybeEscapeLabel(node->GetTitle()), icon),
-      node);
+  BuildMenuForFolderAt(node, icon, parent_menu,
+                       GetSubmenuChildCount(parent_menu));
 }
 
-void BookmarkMenuDelegate::BuildMenuForURL(const BookmarkNode* node,
-                                           MenuItemView* parent_menu) {
-  MenuItemView* child_menu_item = parent_menu->AppendMenuItem(
-      GetAndIncrementNextMenuID(), MaybeEscapeLabel(node->GetTitle()),
-      GetFaviconForNode(GetBookmarkModel(), node));
+void BookmarkMenuDelegate::BuildMenuForFolderAt(const BookmarkNode* node,
+                                                const ui::ImageModel& icon,
+                                                MenuItemView* parent_menu,
+                                                size_t index) {
+  AddMenuToMaps(parent_menu->AddMenuItemAt(
+                    index, GetAndIncrementNextMenuID(),
+                    MaybeEscapeLabel(node->GetTitle()), std::u16string(),
+                    std::u16string(), ui::ImageModel(), icon,
+                    MenuItemView::Type::kSubMenu, ui::NORMAL_SEPARATOR),
+                node);
+}
+
+void BookmarkMenuDelegate::BuildMenuForURLAt(const BookmarkNode* node,
+                                             MenuItemView* parent_menu,
+                                             size_t index) {
+  MenuItemView* child_menu_item = parent_menu->AddMenuItemAt(
+      index, GetAndIncrementNextMenuID(), MaybeEscapeLabel(node->GetTitle()),
+      std::u16string(), std::u16string(), ui::ImageModel(),
+      GetFaviconForNode(GetBookmarkModel(), node), MenuItemView::Type::kNormal,
+      ui::NORMAL_SEPARATOR);
   child_menu_item->GetViewAccessibility().SetDescription(
       url_formatter::FormatUrl(
           node->url(), url_formatter::kFormatUrlOmitDefaults,
@@ -805,6 +824,24 @@
   AddMenuToMaps(child_menu_item, node);
 }
 
+void BookmarkMenuDelegate::BuildNodeMenuItem(const BookmarkNode* node,
+                                             MenuItemView* parent_menu) {
+  BuildNodeMenuItemAt(node, parent_menu, GetSubmenuChildCount(parent_menu));
+}
+
+void BookmarkMenuDelegate::BuildNodeMenuItemAt(const BookmarkNode* node,
+                                               MenuItemView* parent_menu,
+                                               size_t index) {
+  if (node->is_url()) {
+    BuildMenuForURLAt(node, parent_menu, index);
+  } else {
+    CHECK(node->is_folder());
+    const ui::ImageModel folder_icon = chrome::GetBookmarkFolderIcon(
+        chrome::BookmarkFolderIconType::kNormal, ui::kColorMenuIcon);
+    BuildMenuForFolderAt(node, folder_icon, parent_menu, index);
+  }
+}
+
 void BookmarkMenuDelegate::BuildMenu(const BookmarkNode* parent,
                                      size_t start_child_index,
                                      MenuItemView* menu) {
@@ -816,13 +853,7 @@
       chrome::BookmarkFolderIconType::kNormal, ui::kColorMenuIcon);
   for (auto i = parent->children().cbegin() + start_child_index;
        i != parent->children().cend(); ++i) {
-    const BookmarkNode* node = i->get();
-    if (node->is_url()) {
-      BuildMenuForURL(node, menu);
-    } else {
-      DCHECK(node->is_folder());
-      BuildMenuForFolder(node, folder_icon, menu);
-    }
+    BuildNodeMenuItem(i->get(), menu);
   }
 }
 
@@ -868,15 +899,14 @@
          !parent_menu_item_->GetSubmenu()->children().empty();
 }
 
-void BookmarkMenuDelegate::BuildBookmarksTitle() {
-  CHECK(parent_menu_item_);
+void BookmarkMenuDelegate::BuildBookmarksTitle(size_t index) {
   CHECK(!bookmarks_title_);
   CHECK(!bookmarks_title_separator_);
-  parent_menu_item_->AppendSeparator();
+  parent_menu_item_->AddSeparatorAt(index);
   bookmarks_title_separator_ =
-      parent_menu_item_->GetSubmenu()->children().back().get();
-  bookmarks_title_ = parent_menu_item_->AppendTitle(
-      l10n_util::GetStringUTF16(IDS_BOOKMARKS_LIST_TITLE));
+      parent_menu_item_->GetSubmenu()->children()[index].get();
+  bookmarks_title_ = parent_menu_item_->AddTitleAt(
+      l10n_util::GetStringUTF16(IDS_BOOKMARKS_LIST_TITLE), index + 1);
 }
 
 void BookmarkMenuDelegate::RemoveBookmarksTitle() {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h
index 04499032f..d1a956cb 100644
--- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h
+++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h
@@ -199,11 +199,24 @@
   void BuildMenuForFolder(const bookmarks::BookmarkNode* node,
                           const ui::ImageModel& icon,
                           views::MenuItemView* parent_menu);
+  void BuildMenuForFolderAt(const bookmarks::BookmarkNode* node,
+                            const ui::ImageModel& icon,
+                            views::MenuItemView* parent_menu,
+                            size_t index);
 
   // Builds a menu item for the provided bookmark url, adding it to
   // `parent_menu`.
-  void BuildMenuForURL(const bookmarks::BookmarkNode* node,
-                       views::MenuItemView* parent_menu);
+  void BuildMenuForURLAt(const bookmarks::BookmarkNode* node,
+                         views::MenuItemView* parent_menu,
+                         size_t index);
+
+  // Build a menu item for the providied bookmark folder or url, adding it to
+  // `parent_menu`.
+  void BuildNodeMenuItem(const bookmarks::BookmarkNode* node,
+                         views::MenuItemView* parent_menu);
+  void BuildNodeMenuItemAt(const bookmarks::BookmarkNode* node,
+                           views::MenuItemView* parent_menu,
+                           size_t index);
 
   // Creates an entry in menu for each child node of |parent| starting at
   // |start_child_index|.
@@ -240,7 +253,7 @@
   // Returns the updated menu if there were changes; otherwise, returns null.
   views::MenuItemView* UpdateBookmarksTitle();
   bool ShouldHaveBookmarksTitle();
-  void BuildBookmarksTitle();
+  void BuildBookmarksTitle(size_t index);
   void RemoveBookmarksTitle();
 
   // Adds or removes the separator of the "other" bookmarks folder as necessary.
diff --git a/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.cc b/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.cc
index be810a3..cb14e5d 100644
--- a/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.cc
+++ b/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.cc
@@ -205,6 +205,15 @@
   }
 }
 
+SkColor DigitalIdentityMultiStepDialog::GetBackgroundColor() {
+  DigitalIdentityMultiStepDialog::Delegate* widget_delegate =
+      GetWidgetDelegate();
+  if (!widget_delegate) {
+    return gfx::kPlaceholderColor;
+  }
+  return widget_delegate->GetBackgroundColor();
+}
+
 DigitalIdentityMultiStepDialog::Delegate*
 DigitalIdentityMultiStepDialog::GetWidgetDelegate() {
   if (!dialog_) {
diff --git a/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.h b/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.h
index dfd256c..4440df1d 100644
--- a/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.h
+++ b/chrome/browser/ui/views/digital_credentials/digital_identity_multi_step_dialog.h
@@ -53,6 +53,8 @@
       const std::u16string& body_text,
       std::unique_ptr<views::View> custom_body_field);
 
+  SkColor GetBackgroundColor();
+
  private:
   // The wrapped views::BubbleDialogDelegate.
   class Delegate : public views::BubbleDialogDelegate {
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view.cc b/chrome/browser/ui/views/frame/tab_strip_region_view.cc
index d284d22..6fe47c0 100644
--- a/chrome/browser/ui/views/frame/tab_strip_region_view.cc
+++ b/chrome/browser/ui/views/frame/tab_strip_region_view.cc
@@ -129,9 +129,6 @@
   std::unique_ptr<TabGlicContainer> tab_glic_container;
   std::unique_ptr<TabStripComboButton> tab_strip_combo_button;
   std::unique_ptr<ProductSpecificationsButton> product_specifications_button;
-#if BUILDFLAG(ENABLE_GLIC)
-  std::unique_ptr<glic::GlicButton> glic_button;
-#endif  // BUILDFLAG(ENABLE_GLIC)
   if (browser &&
       (browser->GetType() == BrowserWindowInterface::Type::TYPE_NORMAL)) {
     if (features::IsTabstripComboButtonEnabled() &&
@@ -165,21 +162,6 @@
       tab_glic_container->SetProperty(
           views::kMarginsKey,
           gfx::Insets::TLBR(0, 0, 0, GetLayoutConstant(TAB_STRIP_PADDING)));
-
-      tab_glic_container_ = AddChildView(std::move(tab_glic_container));
-
-    } else {
-#if BUILDFLAG(ENABLE_GLIC)
-      if (GlicEnabling::IsEnabledByFlags()) {
-        glic_button =
-            std::make_unique<glic::GlicButton>(tab_strip_->controller());
-        glic_button->SetProperty(views::kCrossAxisAlignmentKey,
-                                 views::LayoutAlignment::kCenter);
-        glic_button->SetProperty(
-            views::kMarginsKey,
-            gfx::Insets::TLBR(0, 0, 0, GetLayoutConstant(TAB_STRIP_PADDING)));
-      }
-#endif  // BUILDFLAG(ENABLE_GLIC)
     }
   }
 
@@ -284,12 +266,9 @@
         gfx::Insets::TLBR(0, 0, 0, GetLayoutConstant(TAB_STRIP_PADDING)));
   }
 
-#if BUILDFLAG(ENABLE_GLIC)
-  if (glic_button) {
-    glic_button_ = AddChildView(std::move(glic_button));
+  if (tab_glic_container) {
+    tab_glic_container_ = AddChildView(std::move(tab_glic_container));
   }
-#endif  // BUILDFLAG(ENABLE_GLIC)
-
   UpdateTabStripMargin();
 }
 
@@ -383,6 +362,15 @@
   }
 }
 
+glic::GlicButton* TabStripRegionView::GetGlicButton() {
+  if (tab_glic_container_) {
+#if BUILDFLAG(ENABLE_GLIC)
+    return tab_glic_container_->GetGlicButton();
+#endif  // BUILDFLAG(ENABLE_GLIC)
+  }
+  return nullptr;
+}
+
 TabSearchContainer* TabStripRegionView::GetTabSearchContainer() {
   if (features::IsTabstripComboButtonEnabled()) {
     return tab_strip_combo_button_->tab_search_container();
@@ -417,11 +405,6 @@
   if (tab_glic_container_) {
     children.emplace_back(tab_glic_container_.get());
   }
-#if BUILDFLAG(ENABLE_GLIC)
-  if (glic_button_) {
-    children.emplace_back(glic_button_.get());
-  }
-#endif  // BUILDFLAG(ENABLE_GLIC)
 
   if (reserved_grab_handle_space_) {
     children.emplace_back(reserved_grab_handle_space_.get());
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view.h b/chrome/browser/ui/views/frame/tab_strip_region_view.h
index c2df9e1..41a22a2 100644
--- a/chrome/browser/ui/views/frame/tab_strip_region_view.h
+++ b/chrome/browser/ui/views/frame/tab_strip_region_view.h
@@ -71,7 +71,7 @@
     return product_specifications_button_;
   }
 
-  glic::GlicButton* glic_button() { return glic_button_; }
+  glic::GlicButton* GetGlicButton();
 
   // May be nullptr if combo button is enabled. |Use GetNewTabButton()| to
   // access the new tab button inside the combo button.
@@ -151,7 +151,6 @@
   raw_ptr<TabGlicContainer> tab_glic_container_ = nullptr;
   raw_ptr<TabStripComboButton> tab_strip_combo_button_ = nullptr;
   raw_ptr<ProductSpecificationsButton> product_specifications_button_ = nullptr;
-  raw_ptr<glic::GlicButton> glic_button_ = nullptr;
 
   // On some platforms for Chrome Refresh, the TabSearchButton should be
   // laid out before the TabStrip. Storing this configuration prevents
diff --git a/chrome/browser/ui/views/glic/glic_view.cc b/chrome/browser/ui/views/glic/glic_view.cc
index 711f74a..fad4c5d 100644
--- a/chrome/browser/ui/views/glic/glic_view.cc
+++ b/chrome/browser/ui/views/glic/glic_view.cc
@@ -36,9 +36,8 @@
 GlicView::~GlicView() = default;
 
 // static
-std::pair<views::UniqueWidgetPtr, GlicView*> GlicView::CreateWidget(
-    Profile* profile,
-    const gfx::Rect& initial_bounds) {
+views::UniqueWidgetPtr GlicView::CreateWidget(Profile* profile,
+                                              const gfx::Rect& initial_bounds) {
   views::Widget::InitParams params(
       views::Widget::InitParams::CLIENT_OWNS_WIDGET,
       views::Widget::InitParams::TYPE_WINDOW_FRAMELESS);
@@ -50,11 +49,14 @@
   views::UniqueWidgetPtr widget =
       std::make_unique<views::Widget>(std::move(params));
 
-  auto glic_view = std::make_unique<GlicView>(profile, initial_bounds.size());
-  GlicView* raw_glic_view = glic_view.get();
-  widget->SetContentsView(std::move(glic_view));
+  widget->SetContentsView(
+      std::make_unique<GlicView>(profile, initial_bounds.size()));
 
-  return {std::move(widget), raw_glic_view};
+  return widget;
+}
+
+GlicView* GlicView::FromWidget(views::Widget& widget) {
+  return static_cast<GlicView*>(widget.GetContentsView());
 }
 
 void GlicView::SetDraggableAreas(
diff --git a/chrome/browser/ui/views/glic/glic_view.h b/chrome/browser/ui/views/glic/glic_view.h
index 0b5d9669..2284f05 100644
--- a/chrome/browser/ui/views/glic/glic_view.h
+++ b/chrome/browser/ui/views/glic/glic_view.h
@@ -32,9 +32,11 @@
 
   // Creates a menu widget that contains a `GlicView`, configured with the
   // given `initial_bounds`.
-  static std::pair<views::UniqueWidgetPtr, GlicView*> CreateWidget(
-      Profile* profile,
-      const gfx::Rect& initial_bounds);
+  static views::UniqueWidgetPtr CreateWidget(Profile* profile,
+                                             const gfx::Rect& initial_bounds);
+  // Returns the `GlicView` from the widget returned by
+  // `GlicView::CreateWidget()`.
+  static GlicView* FromWidget(views::Widget& widget);
 
   void SetDraggableAreas(const std::vector<gfx::Rect>& draggable_areas);
 
diff --git a/chrome/browser/ui/views/task_manager_search_bar_view.cc b/chrome/browser/ui/views/task_manager_search_bar_view.cc
index 05787c1e..e1458a0 100644
--- a/chrome/browser/ui/views/task_manager_search_bar_view.cc
+++ b/chrome/browser/ui/views/task_manager_search_bar_view.cc
@@ -25,13 +25,15 @@
 namespace task_manager {
 TaskManagerSearchBarView::TaskManagerSearchBarView(
     const std::u16string& placeholder,
-    const gfx::Insets& margins)
+    const gfx::Insets& margins,
+    Delegate& delegate)
+    : delegate_(delegate)
 #if BUILDFLAG(IS_LINUX)
-    : textfield_placeholder_color_id_(kColorTaskManagerSearchBarPlaceholderText)
+      ,
+      textfield_placeholder_color_id_(kColorTaskManagerSearchBarPlaceholderText)
 #endif
 {
   auto* layout_provider = ChromeLayoutProvider::Get();
-
   auto search_bar_layout = std::make_unique<views::BoxLayout>();
   search_bar_layout->SetOrientation(views::LayoutOrientation::kHorizontal);
   search_bar_layout->set_cross_axis_alignment(views::LayoutAlignment::kCenter);
@@ -78,6 +80,11 @@
 
   AddChildView(std::move(search_icon));
   input_ = AddChildView(std::move(input));
+
+  input_changed_subscription_ =
+      input_->AddTextChangedCallback(base::BindRepeating(
+          &TaskManagerSearchBarView::OnInputChanged, base::Unretained(this)));
+
   if (views::InkDrop::Get(input_)) {
     views::InkDrop::Get(input_)->SetBaseColorCallback(base::BindRepeating(
         [](views::Textfield* host) {
@@ -113,9 +120,20 @@
   }
   return false;
 }
+
 void TaskManagerSearchBarView::Focus() {
   input_->RequestFocus();
 }
+
+void TaskManagerSearchBarView::OnInputChanged() {
+  input_change_notification_timer_.Start(
+      FROM_HERE, kInputChangeCallbackDelay,
+      // `delegate_` is expected to outlive `this`, the timer will either be
+      // triggered when it is alive or canceled.
+      base::BindOnce(&Delegate::SearchBarOnInputChanged,
+                     base::Unretained(delegate_), input_->GetText()));
+}
+
 void TaskManagerSearchBarView::OnClearPressed() {
   input_->SetText(u"");
   clear_->SetVisible(false);
diff --git a/chrome/browser/ui/views/task_manager_search_bar_view.h b/chrome/browser/ui/views/task_manager_search_bar_view.h
index bb0907a..bd96ea6 100644
--- a/chrome/browser/ui/views/task_manager_search_bar_view.h
+++ b/chrome/browser/ui/views/task_manager_search_bar_view.h
@@ -25,15 +25,34 @@
   METADATA_HEADER(TaskManagerSearchBarView, views::View)
 
  public:
+  using OnInputChangedCallback =
+      base::RepeatingCallback<void(const std::u16string&)>;
+
+  class Delegate {
+   public:
+    // Called when text in the textfield changes. Calls are throttled with
+    // a delay of kInputChangeCallbackDelay to avoid excessive triggering.
+    virtual void SearchBarOnInputChanged(const std::u16string& text) = 0;
+
+   protected:
+    virtual ~Delegate() = default;
+  };
+
   DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kInputField);
 
+  // The delay between the textfield text change and triggering
+  // the `OnInputChangedCallback`, used to throttle fast user input.
+  static constexpr base::TimeDelta kInputChangeCallbackDelay =
+      base::Milliseconds(50);
+
   TaskManagerSearchBarView(const std::u16string& placeholder,
-                           const gfx::Insets& margins);
+                           const gfx::Insets& margins,
+                           Delegate& delegate);
   TaskManagerSearchBarView(const TaskManagerSearchBarView&) = delete;
   TaskManagerSearchBarView& operator=(const TaskManagerSearchBarView&) = delete;
   ~TaskManagerSearchBarView() override;
 
-  // views::View
+  // views::View:
   void OnThemeChanged() override;
 
   // views::TextfieldController:
@@ -50,13 +69,19 @@
   void UpdateTextfield();
 
  private:
+  void OnInputChanged();
   void OnClearPressed();
 
+  const raw_ref<Delegate> delegate_;
+
   // Textfield placeholder color.
   std::optional<ui::ColorId> textfield_placeholder_color_id_;
 
   raw_ptr<views::Textfield> input_ = nullptr;
   raw_ptr<views::Button> clear_ = nullptr;
+
+  base::CallbackListSubscription input_changed_subscription_;
+  base::OneShotTimer input_change_notification_timer_;
 };
 }  // namespace task_manager
 
diff --git a/chrome/browser/ui/views/task_manager_search_bar_view_unittest.cc b/chrome/browser/ui/views/task_manager_search_bar_view_unittest.cc
index bb0e716..1963853 100644
--- a/chrome/browser/ui/views/task_manager_search_bar_view_unittest.cc
+++ b/chrome/browser/ui/views/task_manager_search_bar_view_unittest.cc
@@ -23,7 +23,17 @@
 using ::testing::InSequence;
 using ::testing::Mock;
 using ::testing::MockFunction;
+using ::testing::NiceMock;
 
+class MockDelegate : public TaskManagerSearchBarView::Delegate {
+ public:
+  MockDelegate() = default;
+  ~MockDelegate() override = default;
+  MOCK_METHOD(void,
+              SearchBarOnInputChanged,
+              (const std::u16string& text),
+              (override));
+};
 class TaskManagerSearchBarViewTest : public ChromeViewsTestBase {
  public:
   // views::ViewsTestBase:
@@ -44,16 +54,18 @@
  protected:
   views::Widget& widget() { return *widget_; }
   ui::test::EventGenerator& generator() { return *generator_; }
+  MockDelegate& delegate() { return delegate_; }
 
  private:
   std::unique_ptr<views::Widget> widget_;
   std::unique_ptr<ui::test::EventGenerator> generator_;
+  NiceMock<MockDelegate> delegate_;
 };
 
 TEST_F(TaskManagerSearchBarViewTest, SetsFocusOnTextfield) {
   auto* view =
       widget().SetContentsView(std::make_unique<TaskManagerSearchBarView>(
-          u"placeholder", gfx::Insets::TLBR(0, 0, 0, 0)));
+          u"placeholder", gfx::Insets::TLBR(0, 0, 0, 0), delegate()));
   widget().Show();
   view->Focus();
 
@@ -66,7 +78,7 @@
 TEST_F(TaskManagerSearchBarViewTest, KeyPressedFromTextfield) {
   auto* view =
       widget().SetContentsView(std::make_unique<TaskManagerSearchBarView>(
-          u"placeholder", gfx::Insets::TLBR(0, 0, 0, 0)));
+          u"placeholder", gfx::Insets::TLBR(0, 0, 0, 0), delegate()));
   EXPECT_FALSE(view->GetClearButtonVisibleStatusForTesting());
   widget().Show();
   view->Focus();
@@ -77,10 +89,49 @@
   EXPECT_TRUE(view->GetClearButtonVisibleStatusForTesting());
 }
 
+TEST_F(TaskManagerSearchBarViewTest, OnInputChangedIsCalledAfterDelay) {
+  auto view = std::make_unique<TaskManagerSearchBarView>(
+      u"placeholder", gfx::Insets::TLBR(0, 0, 0, 0), delegate());
+
+  MockFunction<void()> check;
+  {
+    InSequence s;
+    EXPECT_CALL(check, Call);
+    EXPECT_CALL(delegate(), SearchBarOnInputChanged(Eq(u"input text")));
+  }
+
+  view->SetInputTextForTesting(u"input text");
+  task_environment()->FastForwardBy(
+      TaskManagerSearchBarView::kInputChangeCallbackDelay / 2);
+  check.Call();
+  task_environment()->FastForwardBy(
+      TaskManagerSearchBarView::kInputChangeCallbackDelay / 2);
+}
+
+TEST_F(TaskManagerSearchBarViewTest, OnInputChangedCallbackIsThrottled) {
+  auto view = std::make_unique<TaskManagerSearchBarView>(
+      u"placeholder", gfx::Insets::TLBR(0, 0, 0, 0), delegate());
+
+  MockFunction<void()> check;
+  {
+    InSequence s;
+    EXPECT_CALL(check, Call);
+    EXPECT_CALL(delegate(), SearchBarOnInputChanged(Eq(u"input text 2")));
+  }
+
+  view->SetInputTextForTesting(u"input text");
+  task_environment()->FastForwardBy(
+      TaskManagerSearchBarView::kInputChangeCallbackDelay / 2);
+  check.Call();
+  view->SetInputTextForTesting(u"input text 2");
+  task_environment()->FastForwardBy(
+      TaskManagerSearchBarView::kInputChangeCallbackDelay);
+}
+
 TEST_F(TaskManagerSearchBarViewTest, ClearButton) {
   auto* view =
       widget().SetContentsView(std::make_unique<TaskManagerSearchBarView>(
-          u"placeholder", gfx::Insets::TLBR(0, 0, 0, 0)));
+          u"placeholder", gfx::Insets::TLBR(0, 0, 0, 0), delegate()));
   widget().Show();
   view->Focus();
 
diff --git a/chrome/browser/ui/views/task_manager_view.cc b/chrome/browser/ui/views/task_manager_view.cc
index 2db68c6b6..ca89034d 100644
--- a/chrome/browser/ui/views/task_manager_view.cc
+++ b/chrome/browser/ui/views/task_manager_view.cc
@@ -406,7 +406,7 @@
   PerformFilter(kTabDefinitions[index].associated_category);
 }
 
-std::unique_ptr<views::View> TaskManagerView::CreateTabbedPane() {
+std::unique_ptr<views::TabbedPaneTabStrip> TaskManagerView::CreateTabbedPane() {
   auto tabs = std::make_unique<views::TabbedPaneTabStrip>(
       views::TabbedPane::Orientation::kHorizontal,
       views::TabbedPane::TabStripStyle::kCompactWithIcon,
@@ -476,7 +476,7 @@
       right_aligned_container->AddChildView(std::move(end_process_btn));
 
   // Compose all parts into header.
-  container->AddChildView(std::move(tabs));
+  tabs_ = container->AddChildView(std::move(tabs));
   container->AddChildView(std::move(empty_view));
   container->AddChildView(std::move(right_aligned_container));
 
@@ -511,7 +511,7 @@
 
   auto search_bar = std::make_unique<TaskManagerSearchBarView>(
       l10n_util::GetStringUTF16(IDS_TASK_MANAGER_SEARCH_PLACEHOLDER),
-      gfx::Insets::VH(0, horizontal_spacing));
+      gfx::Insets::VH(0, horizontal_spacing), *this);
   search_bar_container->AddChildView(std::move(search_bar));
 
   return search_bar_container;
@@ -537,6 +537,10 @@
   return separator;
 }
 
+void TaskManagerView::SearchBarOnInputChanged(const std::u16string& query) {
+  tabs_->SetEnabled(query.empty());
+}
+
 std::unique_ptr<views::ScrollView> TaskManagerView::CreateProcessView(
     std::unique_ptr<views::TableView> tab_table,
     bool table_has_border,
diff --git a/chrome/browser/ui/views/task_manager_view.h b/chrome/browser/ui/views/task_manager_view.h
index d53a2ed..949edcf7 100644
--- a/chrome/browser/ui/views/task_manager_view.h
+++ b/chrome/browser/ui/views/task_manager_view.h
@@ -44,7 +44,8 @@
                         public views::TableGrouper,
                         public views::TableViewObserver,
                         public views::ContextMenuController,
-                        public ui::SimpleMenuModel::Delegate {
+                        public ui::SimpleMenuModel::Delegate,
+                        public TaskManagerSearchBarView::Delegate {
   METADATA_HEADER(TaskManagerView, views::DialogDelegateView)
 
  public:
@@ -108,6 +109,9 @@
   void ExecuteCommand(int id, int event_flags) override;
   void MenuClosed(ui::SimpleMenuModel* source) override;
 
+  // TaskManagerSearchBarView::Delegate:
+  void SearchBarOnInputChanged(const std::u16string& text) override;
+
   views::TableView* tab_table_for_testing() { return tab_table_; }
 
   static TaskManagerView* GetInstanceForTests();
@@ -141,7 +145,7 @@
   void PerformFilter(DisplayCategory category);
 
   // Creates all corresponding subcomponents for the header.
-  std::unique_ptr<views::View> CreateTabbedPane();
+  std::unique_ptr<views::TabbedPaneTabStrip> CreateTabbedPane();
   std::unique_ptr<views::View> CreateSearchBar(
       const ChromeLayoutProvider* provider);
   std::unique_ptr<views::MdTextButton> CreateEndProcessButton(
@@ -187,6 +191,10 @@
   // all possible columns, not necessarily visible.
   std::vector<ui::TableColumn> columns_;
 
+  // The tabs which holds different task categories which is not null if task
+  // manager refresh is enabled.
+  raw_ptr<views::TabbedPaneTabStrip> tabs_ = nullptr;
+
   // This button is not the same as the dialog button. It is only non-null if
   // task manager refresh is enabled.
   raw_ptr<views::MdTextButton> end_process_btn_;
diff --git a/chrome/browser/ui/webui/ash/mako/mako_ui.cc b/chrome/browser/ui/webui/ash/mako/mako_ui.cc
index db2fbd5..79714b1 100644
--- a/chrome/browser/ui/webui/ash/mako/mako_ui.cc
+++ b/chrome/browser/ui/webui/ash/mako/mako_ui.cc
@@ -77,14 +77,12 @@
       ash::features::IsLobsterEnabled()
           ? LobsterServiceProvider::GetForProfile(Profile::FromWebUI(web_ui))
           : nullptr;
-  const bool has_lobster_access =
-      lobster_service != nullptr && lobster_service->UserHasAccess();
   const bool should_use_l10n_strings = input_method::ShouldUseL10nStrings();
 
   auto should_use_resource =
       [&](const webui::ResourcePath& resource_path) -> bool {
     // when lobster access is not granted, lobster resources are not allowed.
-    if (!has_lobster_access &&
+    if (lobster_service == nullptr &&
         base::Contains(kLobsterResourceIds, resource_path.id)) {
       return false;
     }
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 67d2a9a..cbe146a 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
@@ -90,11 +90,8 @@
 }
 
 bool IsLobsterSettingsToggleVisible(Profile* profile) {
-  LobsterService* lobster_service =
-      ash::features::IsLobsterEnabled()
-          ? LobsterServiceProvider::GetForProfile(profile)
-          : nullptr;
-  return lobster_service != nullptr && lobster_service->UserHasAccess();
+  return ash::features::IsLobsterEnabled() &&
+         LobsterServiceProvider::GetForProfile(profile) != nullptr;
 }
 
 base::span<const SearchConcept> GetSearchPageSearchConcepts() {
diff --git a/chrome/browser/ui/webui/certificate_manager/user_cert_sources.cc b/chrome/browser/ui/webui/certificate_manager/user_cert_sources.cc
index 65b2fba..7d9e1360 100644
--- a/chrome/browser/ui/webui/certificate_manager/user_cert_sources.cc
+++ b/chrome/browser/ui/webui/certificate_manager/user_cert_sources.cc
@@ -114,16 +114,21 @@
     }
     if (hash == crypto::SHA256Hash(cert_info.der_cert)) {
       // Found the cert, open cert viewer dialog if able and return.
-      // TODO (crbug.com/40928765): Allow modifying constraints through the
-      // certificate viewer.
       if (base::FeatureList::IsEnabled(
               ::features::kEnableCertManagementUIV2EditCerts)) {
-        ShowCertificateDialog(
-            std::move(web_contents),
-            net::x509_util::CreateCryptoBuffer(cert_info.der_cert),
-            cert_info.cert_metadata,
-            base::BindRepeating(&UpdateCertificateAsync, profile,
-                                user_cert_source));
+        if (IsCACertificateManagementAllowed(*profile->GetPrefs())) {
+          ShowCertificateDialog(
+              std::move(web_contents),
+              net::x509_util::CreateCryptoBuffer(cert_info.der_cert),
+              cert_info.cert_metadata,
+              base::BindRepeating(&UpdateCertificateAsync, profile,
+                                  user_cert_source));
+        } else {
+          ShowCertificateDialog(
+              std::move(web_contents),
+              net::x509_util::CreateCryptoBuffer(cert_info.der_cert),
+              cert_info.cert_metadata, base::NullCallback());
+        }
       } else {
         ShowCertificateDialog(
             std::move(web_contents),
diff --git a/chrome/browser/ui/webui/compose/compose_untrusted_ui.cc b/chrome/browser/ui/webui/compose/compose_untrusted_ui.cc
index 93927f8..eef28f0 100644
--- a/chrome/browser/ui/webui/compose/compose_untrusted_ui.cc
+++ b/chrome/browser/ui/webui/compose/compose_untrusted_ui.cc
@@ -24,7 +24,6 @@
 #include "content/public/browser/web_ui.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "ui/base/l10n/l10n_util.h"
-#include "ui/resources/grit/webui_resources.h"
 #include "ui/webui/color_change_listener/color_change_handler.h"
 
 ComposeUIUntrustedConfig::ComposeUIUntrustedConfig()
diff --git a/chrome/browser/ui/webui/glic/glic.mojom b/chrome/browser/ui/webui/glic/glic.mojom
index ba844a45..a9f39f6e 100644
--- a/chrome/browser/ui/webui/glic/glic.mojom
+++ b/chrome/browser/ui/webui/glic/glic.mojom
@@ -5,10 +5,10 @@
 module glic.mojom;
 
 import "mojo/public/mojom/base/version.mojom";
-import "url/mojom/url.mojom";
-import "url/mojom/origin.mojom";
-import "ui/gfx/geometry/mojom/geometry.mojom";
 import "skia/public/mojom/bitmap.mojom";
+import "ui/gfx/geometry/mojom/geometry.mojom";
+import "url/mojom/origin.mojom";
+import "url/mojom/url.mojom";
 
 // Factory for PageHandler used in chrome://glic.
 interface PageHandlerFactory {
@@ -26,7 +26,7 @@
 enum GetTabContextErrorReason {
   // A valid web contents was not available for the entire duration of context
   // gathering.
- kWebContentsChanged,
+  kWebContentsChanged,
 };
 
 union GetContextResult {
@@ -43,28 +43,45 @@
   // initialize(), indicating that it will support Chrome. `web_client` may
   // be used to communicate with the client.
   WebClientInitialized(pending_remote<WebClient> web_client);
+
   // Returns the Chrome version.
   GetChromeVersion() => (mojo_base.mojom.Version version);
+
   // Creates a new tab. `url` must have a http or https protocol.
   // `tab_data` is null if the tab could not be created, which may happen if the
   // url or window_id is invalid.
   CreateTab(url.mojom.Url url, bool open_in_background, int32? window_id)
-    => (TabData? tab_data);
+      => (TabData? tab_data);
+
   // Closes the Glic panel.
   ClosePanel();
+
   // Returns the context from the currently active tab.
   // `tab_context_result` is null if tab content could not be captured.
   // This may fail if the tab is navigated while collecting data, or closed
   // before data is collected.
-  GetContextFromFocusedTab(bool include_inner_text,
-    bool include_viewport_screenshot) =>
-      (GetContextResult result);
+  GetContextFromFocusedTab(
+      bool include_inner_text, bool include_viewport_screenshot)
+      => (GetContextResult result);
 
   // Set the bounds of the widget hosting the WebUI to the given size.
   ResizeWidget(gfx.mojom.Size size) => (gfx.mojom.Size? actual_size);
+
   // Set the areas of the Glic panel from which it should be draggable. If
   // `draggable_areas` is empty, the panel will use the top bar area by default.
   SetPanelDraggableAreas(array<gfx.mojom.Rect> draggable_areas);
+
+  // Set the state of the Microphone permission pref:
+  // prefs::kGlicMicrophoneEnabled.
+  SetMicrophonePermissionState(bool enabled);
+
+  // Set the state of the Location permission pref:
+  // prefs::kGlicGeolocationEnabled.
+  SetLocationPermissionState(bool enabled);
+
+  // Set the state of the TabContext permission pref:
+  // prefs::kGlicTabContextEnabled.
+  SetTabContextPermissionState(bool enabled);
 };
 
 // State of the glic panel.
@@ -92,12 +109,26 @@
   // `docked_to_window_id` identifies the browser window to which the
   // panel is docked to. It is undefined if it is floating free.
   NotifyPanelOpened(int32? docked_to_window_id);
+
   // The user has closed the web client window. The window may be activated
   // again later. Returns when the web client has stored any needed
   // information and stopped accepting the user's input.
   NotifyPanelClosed() => ();
+
   // Informs the client that the state of the glic panel has changed.
   NotifyPanelStateChange(PanelState panel_state);
+
+  // The Microphone permission has changed either by action within the web
+  // client or by user action in the glic settings.
+  NotifyMicrophonePermissionStateChanged(bool enabled);
+
+  // The Location permission has changed either by action within the web client
+  // or by user action in the glic settings.
+  NotifyLocationPermissionStateChanged(bool enabled);
+
+  // The Tab Context permission has changed either by action within the web
+  // client or by user action in the glic settings.
+  NotifyTabContextPermissionStateChanged(bool enabled);
 };
 
 // Information extracted from a tab.
@@ -144,8 +175,7 @@
 // Annotates an image, providing security relevant information about the origins
 // from which image is composed.
 // TODO(crbug.com/380495633): Finalize and implement image annotations.
-struct ImageOriginAnnotations {
-};
+struct ImageOriginAnnotations {};
 
 // An encoded screenshot image and associated metadata.
 struct Screenshot {
@@ -158,4 +188,4 @@
   string mime_type;
   // Image annotations for this screenshot.
   ImageOriginAnnotations origin_annotations;
-};
\ No newline at end of file
+};
diff --git a/chrome/browser/ui/webui/glic/glic_page_handler.cc b/chrome/browser/ui/webui/glic/glic_page_handler.cc
index f2fccb7d..92fd38e 100644
--- a/chrome/browser/ui/webui/glic/glic_page_handler.cc
+++ b/chrome/browser/ui/webui/glic/glic_page_handler.cc
@@ -10,6 +10,8 @@
 #include "chrome/browser/glic/glic_window_controller.h"
 #include "chrome/browser/ui/browser.h"
 #include "chrome/browser/ui/webui/glic/glic.mojom.h"
+#include "chrome/common/pref_names.h"
+#include "components/prefs/pref_service.h"
 #include "ui/gfx/geometry/mojom/geometry.mojom.h"
 #include "ui/gfx/geometry/size.h"
 
@@ -18,9 +20,12 @@
                              public GlicWindowController::StateObserver {
  public:
   explicit GlicWebClientHandler(
-      GlicKeyedService* glic_service,
+      content::BrowserContext* browser_context,
       mojo::PendingReceiver<glic::mojom::WebClientHandler> receiver)
-      : glic_service_(glic_service), receiver_(this, std::move(receiver)) {}
+      : glic_service_(
+            GlicKeyedServiceFactory::GetGlicKeyedService(browser_context)),
+        pref_service_(Profile::FromBrowserContext(browser_context)->GetPrefs()),
+        receiver_(this, std::move(receiver)) {}
 
   // glic::mojom::WebClientHandler implementation.
   void WebClientInitialized(
@@ -31,6 +36,23 @@
     glic_service_->window_controller().AddStateObserver(this);
     web_client_->NotifyPanelStateChange(
         glic_service_->window_controller().GetPanelState().Clone());
+    // Configure the pref_change_registrar to listen for changes to the prefs
+    pref_change_registrar_.Init(pref_service_);
+    pref_change_registrar_.Add(
+        prefs::kGlicMicrophoneEnabled,
+        base::BindRepeating(&GlicWebClientHandler::OnPrefChanged,
+                            base::Unretained(this)));
+    pref_change_registrar_.Add(
+        prefs::kGlicGeolocationEnabled,
+        base::BindRepeating(&GlicWebClientHandler::OnPrefChanged,
+                            base::Unretained(this)));
+    pref_change_registrar_.Add(
+        prefs::kGlicTabContextEnabled,
+        base::BindRepeating(&GlicWebClientHandler::OnPrefChanged,
+                            base::Unretained(this)));
+
+    // Communicate initial permission values to web client.
+    SendPermissionsToWebClient();
   }
 
   void GetChromeVersion(GetChromeVersionCallback callback) override {
@@ -83,9 +105,48 @@
 
  private:
   void WebClientDisconnected() {
+    pref_change_registrar_.Reset();
     glic_service_->window_controller().RemoveStateObserver(this);
   }
+
+  void SetMicrophonePermissionState(bool enabled) override {
+    pref_service_->SetBoolean(prefs::kGlicMicrophoneEnabled, enabled);
+  }
+
+  void SetLocationPermissionState(bool enabled) override {
+    pref_service_->SetBoolean(prefs::kGlicGeolocationEnabled, enabled);
+  }
+
+  void SetTabContextPermissionState(bool enabled) override {
+    pref_service_->SetBoolean(prefs::kGlicTabContextEnabled, enabled);
+  }
+
+  void OnPrefChanged(const std::string& pref_name) {
+    bool is_enabled = pref_service_->GetBoolean(pref_name);
+    if (pref_name == prefs::kGlicMicrophoneEnabled) {
+      web_client_->NotifyMicrophonePermissionStateChanged(is_enabled);
+    } else if (pref_name == prefs::kGlicGeolocationEnabled) {
+      web_client_->NotifyLocationPermissionStateChanged(is_enabled);
+    } else if (pref_name == prefs::kGlicTabContextEnabled) {
+      web_client_->NotifyTabContextPermissionStateChanged(is_enabled);
+    } else {
+      DCHECK(false) << "Unknown Glic permission pref changed: " << pref_name;
+    }
+  }
+
+ private:
+  void SendPermissionsToWebClient() {
+    web_client_->NotifyMicrophonePermissionStateChanged(
+        pref_service_->GetBoolean(prefs::kGlicMicrophoneEnabled));
+    web_client_->NotifyLocationPermissionStateChanged(
+        pref_service_->GetBoolean(prefs::kGlicGeolocationEnabled));
+    web_client_->NotifyTabContextPermissionStateChanged(
+        pref_service_->GetBoolean(prefs::kGlicTabContextEnabled));
+  }
+
+  PrefChangeRegistrar pref_change_registrar_;
   raw_ptr<GlicKeyedService> glic_service_;
+  raw_ptr<PrefService> pref_service_;
   mojo::Receiver<glic::mojom::WebClientHandler> receiver_;
   mojo::Remote<glic::mojom::WebClient> web_client_;
 };
@@ -101,8 +162,7 @@
     ::mojo::PendingReceiver<glic::mojom::WebClientHandler>
         web_client_receiver) {
   web_client_handler_ = std::make_unique<GlicWebClientHandler>(
-      GlicKeyedServiceFactory::GetGlicKeyedService(browser_context_),
-      std::move(web_client_receiver));
+      browser_context_, std::move(web_client_receiver));
 }
 
 }  // namespace glic
diff --git a/chrome/browser/ui/webui/glic/glic_ui.cc b/chrome/browser/ui/webui/glic/glic_ui.cc
index 0c2476d..5747c200 100644
--- a/chrome/browser/ui/webui/glic/glic_ui.cc
+++ b/chrome/browser/ui/webui/glic/glic_ui.cc
@@ -34,13 +34,21 @@
 }
 
 GlicUI::GlicUI(content::WebUI* web_ui) : ui::MojoWebUIController(web_ui) {
+  content::BrowserContext* browser_context =
+      web_ui->GetWebContents()->GetBrowserContext();
+
   // Set up the chrome://glic source.
   content::WebUIDataSource* source = content::WebUIDataSource::CreateAndAdd(
-      web_ui->GetWebContents()->GetBrowserContext(), chrome::kChromeUIGlicHost);
+      browser_context, chrome::kChromeUIGlicHost);
 
   // Add required resources.
   webui::SetupWebUIDataSource(source, kGlicResources, IDR_GLIC_GLIC_HTML);
 
+  // Register auto-granted permissions.
+  auto* allowlist = WebUIAllowlist::GetOrCreate(browser_context);
+  allowlist->RegisterAutoGrantedPermission(source->GetOrigin(),
+                                           ContentSettingsType::GEOLOCATION);
+
   auto* command_line = base::CommandLine::ForCurrentProcess();
 
   // Set up guest URL via cli flag or default to finch param value.
diff --git a/chrome/browser/ui/webui/location_internals/location_internals_ui.cc b/chrome/browser/ui/webui/location_internals/location_internals_ui.cc
index 4907cbec..c412187c 100644
--- a/chrome/browser/ui/webui/location_internals/location_internals_ui.cc
+++ b/chrome/browser/ui/webui/location_internals/location_internals_ui.cc
@@ -12,7 +12,6 @@
 #include "chrome/grit/location_internals_resources_map.h"
 #include "content/public/browser/web_ui_data_source.h"
 #include "services/network/public/mojom/content_security_policy.mojom.h"
-#include "ui/resources/grit/webui_resources.h"
 
 LocationInternalsUI::LocationInternalsUI(content::WebUI* web_ui)
     : ui::MojoWebUIController(web_ui) {
diff --git a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
index c466d80..fe739cd 100644
--- a/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
+++ b/chrome/browser/ui/webui/net_internals/net_internals_ui.cc
@@ -51,7 +51,6 @@
 #include "services/network/public/mojom/content_security_policy.mojom.h"
 #include "services/network/public/mojom/host_resolver.mojom.h"
 #include "services/network/public/mojom/network_context.mojom.h"
-#include "ui/resources/grit/webui_resources.h"
 #include "url/origin.h"
 #include "url/scheme_host_port.h"
 
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
index c3e0ea7..cee94a2 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_ui.cc
@@ -92,7 +92,6 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/color/color_provider.h"
 #include "ui/native_theme/native_theme.h"
-#include "ui/resources/grit/webui_resources.h"
 #include "ui/webui/color_change_listener/color_change_handler.h"
 #include "ui/webui/webui_allowlist.h"
 #include "url/origin.h"
diff --git a/chrome/browser/ui/webui/new_tab_page_third_party/new_tab_page_third_party_ui.cc b/chrome/browser/ui/webui/new_tab_page_third_party/new_tab_page_third_party_ui.cc
index 6795c7b..b34d37bc 100644
--- a/chrome/browser/ui/webui/new_tab_page_third_party/new_tab_page_third_party_ui.cc
+++ b/chrome/browser/ui/webui/new_tab_page_third_party/new_tab_page_third_party_ui.cc
@@ -38,7 +38,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/color/color_provider.h"
 #include "ui/gfx/color_utils.h"
-#include "ui/resources/grit/webui_resources.h"
 #include "url/url_util.h"
 
 using content::BrowserContext;
diff --git a/chrome/browser/ui/webui/sandbox/sandbox_handler.cc b/chrome/browser/ui/webui/sandbox/sandbox_handler.cc
index 792443e..cbe3f8b 100644
--- a/chrome/browser/ui/webui/sandbox/sandbox_handler.cc
+++ b/chrome/browser/ui/webui/sandbox/sandbox_handler.cc
@@ -93,6 +93,8 @@
       sandbox::policy::features::kWinSboxRestrictCoreSharingOnRenderer));
   features.Append(
       FeatureToValue(sandbox::policy::features::kEnableCsrssLockdown));
+  features.Append(FeatureToValue(
+      sandbox::policy::features::kWinSboxFilterServiceEnvironment));
   return features;
 }
 
diff --git a/chrome/browser/ui/webui/signin/managed_user_profile_notice_ui.cc b/chrome/browser/ui/webui/signin/managed_user_profile_notice_ui.cc
index c26b6d9e..b7895a5 100644
--- a/chrome/browser/ui/webui/signin/managed_user_profile_notice_ui.cc
+++ b/chrome/browser/ui/webui/signin/managed_user_profile_notice_ui.cc
@@ -37,7 +37,6 @@
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/ui_base_features.h"
 #include "ui/base/webui/resource_path.h"
-#include "ui/resources/grit/webui_resources.h"
 #include "ui/strings/grit/ui_strings.h"
 
 ManagedUserProfileNoticeUI::ManagedUserProfileNoticeUI(content::WebUI* web_ui)
diff --git a/chrome/browser/ui/webui/signin/profile_customization_ui.cc b/chrome/browser/ui/webui/signin/profile_customization_ui.cc
index 9d4458e7..eb43287 100644
--- a/chrome/browser/ui/webui/signin/profile_customization_ui.cc
+++ b/chrome/browser/ui/webui/signin/profile_customization_ui.cc
@@ -31,7 +31,6 @@
 #include "ui/base/ui_base_features.h"
 #include "ui/base/webui/resource_path.h"
 #include "ui/base/webui/web_ui_util.h"
-#include "ui/resources/grit/webui_resources.h"
 
 ProfileCustomizationUI::ProfileCustomizationUI(content::WebUI* web_ui)
     : ui::MojoWebUIController(web_ui, /*enable_chrome_send=*/true) {
diff --git a/chrome/browser/ui/webui/signin/signin_reauth_ui.cc b/chrome/browser/ui/webui/signin/signin_reauth_ui.cc
index 1d135f80..9dc067c 100644
--- a/chrome/browser/ui/webui/signin/signin_reauth_ui.cc
+++ b/chrome/browser/ui/webui/signin/signin_reauth_ui.cc
@@ -37,7 +37,6 @@
 #include "ui/base/webui/resource_path.h"
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/gfx/image/image.h"
-#include "ui/resources/grit/webui_resources.h"
 
 namespace {
 
diff --git a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
index f04e0ae..161b240 100644
--- a/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
+++ b/chrome/browser/ui/webui/signin/sync_confirmation_ui.cc
@@ -49,7 +49,6 @@
 #include "ui/base/webui/web_ui_util.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/native_theme/native_theme.h"
-#include "ui/resources/grit/webui_resources.h"
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
 #include "ash/webui/settings/public/constants/routes.mojom.h"
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
index 7a60eacf..c5b90008 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.cc
@@ -911,6 +911,9 @@
 void ChromeAuthenticatorRequestDelegate::OnStartOver() {
   DCHECK(start_over_callback_);
   dialog_model_->generation++;
+  if (g_observer) {
+    g_observer->PreStartOver();
+  }
   start_over_callback_.Run();
 }
 
diff --git a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
index df24e12a..a5a15c6 100644
--- a/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
+++ b/chrome/browser/webauthn/chrome_authenticator_request_delegate.h
@@ -102,6 +102,9 @@
 
     virtual void HintsSet(
         const AuthenticatorRequestClientDelegate::Hints& hints) {}
+
+    // Called right before `start_over_callback_` is invoked.
+    virtual void PreStartOver() {}
   };
 
   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
diff --git a/chrome/browser/webauthn/enclave_authenticator_browsertest.cc b/chrome/browser/webauthn/enclave_authenticator_browsertest.cc
index dd0f1eb..52f44da2b 100644
--- a/chrome/browser/webauthn/enclave_authenticator_browsertest.cc
+++ b/chrome/browser/webauthn/enclave_authenticator_browsertest.cc
@@ -615,6 +615,12 @@
       transports_observed_ = std::nullopt;
     }
 
+    void PreStartOver() override {
+      // Start over creates a new request handler and invokes
+      // OnTransportAvailabilityEnumerated() again.
+      transports_observed_ = std::nullopt;
+    }
+
     void OnDestroy(ChromeAuthenticatorRequestDelegate* delegate) override {
       test_instance_->UpdateRequestDelegate(nullptr);
       destruction_run_loop_->QuitWhenIdle();
@@ -1243,9 +1249,8 @@
 
 #if BUILDFLAG(IS_MAC)
 
-// TODO(crbug.com/383203166): Disabled on Mac for test failures.
 IN_PROC_BROWSER_TEST_F(EnclaveAuthenticatorWithPinBrowserTest,
-                       DISABLED_RegisterICloudDriveEnabled_NoGPMDefault) {
+                       RegisterICloudDriveEnabled_NoGPMDefault) {
   if (__builtin_available(macOS 13.5, *)) {
     // Override iCloud Drive to appear enabled. Because of this GPM should not
     // be the default since none of the other conditions apply.
@@ -2899,15 +2904,8 @@
   EXPECT_EQ(script_result, "\"webauthn: OK\"");
 }
 
-// TODO(crbug.com/383203166): Disabled on Mac for test failures.
-#if BUILDFLAG(IS_MAC)
-#define MAYBE_NotForSameGoogleAccount DISABLED_NotForSameGoogleAccount
-#else
-#define MAYBE_NotForSameGoogleAccount NotForSameGoogleAccount
-#endif
-
 IN_PROC_BROWSER_TEST_F(EnclaveAuthenticatorWithoutPinBrowserTest,
-                       MAYBE_NotForSameGoogleAccount) {
+                       NotForSameGoogleAccount) {
   ASSERT_TRUE(ui_test_utils::NavigateToURL(
       browser(), https_server_.GetURL("accounts.google.com", "/title1.html")));
   EnableUVKeySupport();
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index 509f217..4877441 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1734458182-00f43c5abb15be1f13979c3224986ce4d598783d-c29f06c4a45d01eca24119097916df5f13b682ef.profdata
+chrome-android32-main-1734479922-ff1d053679cb872583c828d372638e001622dd84-e0ce22fbeaee939ba05ec621718e06978cc83609.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 0b99ac8..814f71f2 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1734466479-15885baf4ab41144dfa1f888efc1a60c4a1670c8-873b217c626667c93b3984d8e5b112eabd67a98f.profdata
+chrome-android64-main-1734478304-14f8b971d10c7e51c3bcb151911fa781830844c3-35cdd1d4d337d0d80123a5ebf3adc62f42c02481.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index af0240e..3b3c640 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1734458182-ac4b6c7b3bf9b6dfac9a01c9706d2dd993d812d8-c29f06c4a45d01eca24119097916df5f13b682ef.profdata
+chrome-linux-main-1734479922-08aaacf16f95bf3659bc506582858d4a1a085b9e-e0ce22fbeaee939ba05ec621718e06978cc83609.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 371fb0974..68fa017 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1734465536-3a15132f4c31bee536bd8f633123d45337a99b26-61cd175f0ff07ffdec8c680904680d8f98b92aac.profdata
+chrome-mac-arm-main-1734479922-8c3d07e637d1cd9c1a3b02d21a827a91366a4dff-e0ce22fbeaee939ba05ec621718e06978cc83609.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 72df09f1..b95c353 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1734436763-0edd328847c0406d552fc56ebe92019d1fac4230-350bd3a6bf626f7a1187774fd5cad80e7a73499d.profdata
+chrome-win-arm64-main-1734479922-62bbfa46000e9bc56aef38e369add3e562d97702-e0ce22fbeaee939ba05ec621718e06978cc83609.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 2339409..23b5bd1 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1734447042-a2b2a7db02b089a0b8425312081412707f0d030a-aec661770742e09205cfcdcbf03dbd1ac8cf777b.profdata
+chrome-win32-main-1734458182-8052260335689c799b0e1a2e837d3fa033acc41a-c29f06c4a45d01eca24119097916df5f13b682ef.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 2f90487..d9a495e 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1734436763-0eae6cb40dc27aac8542fec86d50fc538fdb47e1-350bd3a6bf626f7a1187774fd5cad80e7a73499d.profdata
+chrome-win64-main-1734447042-b17281d1bce791bd0bcb4379e4a7c669ee9ed38d-aec661770742e09205cfcdcbf03dbd1ac8cf777b.profdata
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 33e3e4da..3efe4b7 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -76,6 +76,15 @@
 // data in the profile folder on disk but only in memory.
 inline constexpr char kForceEphemeralProfiles[] = "profile.ephemeral_mode";
 
+#if BUILDFLAG(ENABLE_GLIC)
+// Boolean pref that enables or disables microphone access for Glic.
+inline constexpr char kGlicMicrophoneEnabled[] = "glic.microphone_enabled";
+// Boolean pref that enables or disables geolocation access for Glic.
+inline constexpr char kGlicGeolocationEnabled[] = "glic.geolocation_enabled";
+// Boolean pref that enables or disables tab context for Glic.
+inline constexpr char kGlicTabContextEnabled[] = "glic.tab_context_enabled";
+#endif  // BUILDFLAG(ENABLE_GLIC)
+
 // A boolean specifying whether the New Tab page is the home page or not.
 inline constexpr char kHomePageIsNewTabPage[] = "homepage_is_newtabpage";
 
@@ -3948,16 +3957,6 @@
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
-// Enum pref indicating which Lacros browser to launch: rootfs or stateful. It
-// is managed by LacrosSelection policy and can have one of the following
-// values:
-// 0: User choice (default value).
-// 1: Always load rootfs Lacros.
-// 2: Always load stateful Lacros.
-inline constexpr char kLacrosSelection[] = "lacros_selection";
-#endif
-
-#if BUILDFLAG(IS_CHROMEOS_ASH)
 // String enum pref determining what should happen when a user who authenticates
 // via a security token is removing this token. "IGNORE" - nothing happens
 // (default). "LOGOUT" - The user is logged out. "LOCK" - The session is locked.
diff --git a/chrome/services/speech/speech_recognition_recognizer_impl.cc b/chrome/services/speech/speech_recognition_recognizer_impl.cc
index 0385c04..f97a5d3 100644
--- a/chrome/services/speech/speech_recognition_recognizer_impl.cc
+++ b/chrome/services/speech/speech_recognition_recognizer_impl.cc
@@ -498,14 +498,14 @@
     base::UmaHistogramCounts100(kLiveCaptionLanguageCountHistogramName,
                                 config_paths_.size());
   }
-  if (!options_->recognition_context.is_null()) {
+  if (options_->recognition_context.has_value()) {
     auto* context_input =
         config_msg_.mutable_recognition_context()->add_context();
     context_input->set_name(kContextInputName);
-    for (const auto& phrase : options_->recognition_context->phrases) {
+    for (const auto& phrase : options_->recognition_context.value().phrases) {
       auto* p = context_input->mutable_phrases()->add_phrase();
-      p->set_phrase(phrase->phrase);
-      p->set_boost(phrase->boost);
+      p->set_phrase(phrase.phrase);
+      p->set_boost(phrase.boost);
     }
   }
 
diff --git a/chrome/services/speech/speech_recognition_recognizer_impl_unittest.cc b/chrome/services/speech/speech_recognition_recognizer_impl_unittest.cc
index 3a2291fd..f2fa713 100644
--- a/chrome/services/speech/speech_recognition_recognizer_impl_unittest.cc
+++ b/chrome/services/speech/speech_recognition_recognizer_impl_unittest.cc
@@ -51,7 +51,7 @@
   }
 
   media::mojom::SpeechRecognitionOptionsPtr CreateOptions(
-      std::optional<media::mojom::SpeechRecognitionRecognitionContextPtr>
+      std::optional<media::SpeechRecognitionRecognitionContext>
           recognition_context = std::nullopt) {
     media::mojom::SpeechRecognitionOptionsPtr options =
         media::mojom::SpeechRecognitionOptions::New();
@@ -95,15 +95,11 @@
 
 TEST_F(SpeechRecognitionRecognizerImplTest,
        SpeechRecognitionRecognitionContextTest) {
-  auto recognition_context =
-      media::mojom::SpeechRecognitionRecognitionContext::New();
-  std::vector<media::mojom::SpeechRecognitionPhrasePtr> phrases;
-  phrases.push_back(
-      media::mojom::SpeechRecognitionPhrase::New("test-phrase", 2.0));
-  recognition_context->phrases = std::move(phrases);
+  std::vector<media::SpeechRecognitionPhrase> phrases;
+  phrases.push_back(media::SpeechRecognitionPhrase("test phrase", 2.0));
 
-  auto recognizer =
-      CreateRecognizer(CreateOptions(std::move(recognition_context)));
+  auto recognizer = CreateRecognizer(
+      CreateOptions(media::SpeechRecognitionRecognitionContext(phrases)));
   recognizer->SetSodaClientForTesting(
       std::make_unique<NiceMock<::soda::MockSodaClient>>());
   recognizer->OnLanguagePackInstalled(config_paths());
@@ -115,7 +111,7 @@
   EXPECT_EQ("android-speech-api-generic-phrases", context_input.name());
   EXPECT_EQ(1, context_input.phrases().phrase().size());
   auto phrase = context_input.phrases().phrase().Get(0);
-  EXPECT_EQ("test-phrase", phrase.phrase());
+  EXPECT_EQ("test phrase", phrase.phrase());
   EXPECT_EQ(2.0, phrase.boost());
 }
 
diff --git a/chrome/test/data/webui/settings/ai_compare_subpage_test.ts b/chrome/test/data/webui/settings/ai_compare_subpage_test.ts
index e6616c3..c61e2d2 100644
--- a/chrome/test/data/webui/settings/ai_compare_subpage_test.ts
+++ b/chrome/test/data/webui/settings/ai_compare_subpage_test.ts
@@ -28,6 +28,13 @@
     return CrSettingsPrefs.initialized;
   });
 
+  teardown(function() {
+    // Reset pref policy to ALLOW.
+    settingsPrefs.set(
+        `prefs.${AiEnterpriseFeaturePrefName.COMPARE}.value`,
+        ModelExecutionEnterprisePolicyValue.ALLOW);
+  });
+
   function createPage() {
     metricsBrowserProxy = new TestMetricsBrowserProxy();
     MetricsBrowserProxyImpl.setInstance(metricsBrowserProxy);
@@ -61,6 +68,21 @@
     assertEquals(url, loadTimeData.getString('compareDataHomeUrl'));
   });
 
+  test('compareLinkoutDisabled', async function() {
+    settingsPrefs.set(
+        `prefs.${AiEnterpriseFeaturePrefName.COMPARE}.value`,
+        ModelExecutionEnterprisePolicyValue.DISABLE);
+    await createPage();
+
+    const linkout = subpage.shadowRoot!.querySelector('cr-link-row');
+    assertTrue(!!linkout);
+
+    assertTrue(linkout.disabled);
+    linkout.click();
+    assertEquals(
+        0, metricsBrowserProxy.getCallCount('recordAiPageCompareInteractions'));
+  });
+
   test('compareLearnMore', async () => {
     await createPage();
 
diff --git a/chrome/test/data/webui/settings/fingerprint_progress_arc_test.ts b/chrome/test/data/webui/settings/fingerprint_progress_arc_test.ts
index 43a362d..f3f4ca04 100644
--- a/chrome/test/data/webui/settings/fingerprint_progress_arc_test.ts
+++ b/chrome/test/data/webui/settings/fingerprint_progress_arc_test.ts
@@ -12,7 +12,6 @@
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
 
 class FakeMediaQueryList extends EventTarget implements MediaQueryList {
-  private listener_: ((e: MediaQueryListEvent) => any)|null = null;
   private matches_: boolean = false;
   private media_: string;
 
@@ -21,20 +20,12 @@
     this.media_ = media;
   }
 
-  addListener(listener: (e: MediaQueryListEvent) => any) {
-    this.listener_ = listener;
-  }
-
-  removeListener(listener: (e: MediaQueryListEvent) => any) {
-    assertEquals(listener, this.listener_);
-    this.listener_ = null;
-  }
+  addListener() {}
+  removeListener() {}
 
   onchange() {
-    if (this.listener_) {
-      this.listener_(new MediaQueryListEvent(
-          'change', {media: this.media_, matches: this.matches_}));
-    }
+    this.dispatchEvent(new MediaQueryListEvent(
+        'change', {media: this.media_, matches: this.matches_}));
   }
 
   get media(): string {
diff --git a/chrome/updater/policy/service.cc b/chrome/updater/policy/service.cc
index bbdf319..bc300dd9 100644
--- a/chrome/updater/policy/service.cc
+++ b/chrome/updater/policy/service.cc
@@ -215,7 +215,7 @@
     int result,
     scoped_refptr<PolicyManagerInterface> dm_policy_manager) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  VLOG(1) << __func__;
+  VLOG(1) << __func__ << ": " << result;
 
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE, {base::MayBlock(), base::WithBaseSyncPrimitives()},
@@ -239,8 +239,14 @@
     int result,
     std::vector<scoped_refptr<PolicyManagerInterface>> managers) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  policy_managers_ = SortManagers(std::move(managers));
-  VLOG(1) << "Policies after refresh:" << std::endl << GetAllPoliciesAsString();
+  if (result == kErrorOk) {
+    policy_managers_ = SortManagers(std::move(managers));
+    VLOG(1) << "Policies after refresh:" << std::endl
+            << GetAllPoliciesAsString();
+  } else {
+    VLOG(1) << "Failed to refresh policies: " << result;
+  }
+  last_fetch_result_ = result;
   std::move(fetch_policies_callback_).Run(result);
 }
 
diff --git a/chrome/updater/policy/service.h b/chrome/updater/policy/service.h
index 99ce8d3..b76cd33 100644
--- a/chrome/updater/policy/service.h
+++ b/chrome/updater/policy/service.h
@@ -149,6 +149,9 @@
   // Enterprise Core (formerly Chrome Enterprise Cloud Management).
   void IsCloudManaged(base::OnceCallback<void(bool)> callback) const;
 
+  // Returns the last policy fetch result.
+  std::optional<int> LastFetchResult() const { return last_fetch_result_; }
+
  protected:
   virtual ~PolicyService();
 
@@ -187,6 +190,9 @@
   // managers.
   PolicyManagers policy_managers_;
 
+  // Holds the last policy fetch result.
+  std::optional<int> last_fetch_result_;
+
   const scoped_refptr<ExternalConstants> external_constants_;
 
   // Helper function to query the policy from the managed policy providers and
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc
index 965cc99..9c64279 100644
--- a/chrome/updater/test/integration_tests.cc
+++ b/chrome/updater/test/integration_tests.cc
@@ -2240,6 +2240,78 @@
 }
 #endif  // BUILDFLAG(IS_MAC)
 
+TEST_F(IntegrationTestDeviceManagementBase, PolicyFetchFailedNoAppInstall) {
+  ASSERT_NO_FATAL_FAILURE(InstallBrokenEnterpriseCompanionApp());
+  DMPushEnrollmentToken(kEnrollmentToken);
+
+  // Policy fetch errors.
+  ExpectDeviceManagementRegistrationRequest(test_server_.get(),
+                                            kEnrollmentToken, kDMToken);
+  ExpectDeviceManagementPolicyFetchRequest(test_server_.get(), kDMToken,
+                                           OmahaSettingsClientProto());
+  ASSERT_NO_FATAL_FAILURE(Install(/*switches=*/{}));
+
+  // Verify that policy fetch failure blocks the app installation.
+  test_server_->ExpectOnce({}, "", net::HTTP_INTERNAL_SERVER_ERROR);
+#if BUILDFLAG(IS_MAC)
+  // Mac has an out-of-process fallback fetcher.
+  test_server_->ExpectOnce({}, "", net::HTTP_INTERNAL_SERVER_ERROR);
+#endif  // BUILDFLAG(IS_MAC)
+  ExpectAppsUpdateSequence(UpdaterScope::kSystem, test_server_.get(),
+                           /*request_attributes=*/{}, {});
+  ASSERT_NO_FATAL_FAILURE(InstallAppViaService(kApp1.appid));
+  ASSERT_NO_FATAL_FAILURE(ExpectNotRegistered(kApp1.appid));
+  ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
+  ASSERT_NO_FATAL_FAILURE(UninstallBrokenEnterpriseCompanionApp());
+  ASSERT_NO_FATAL_FAILURE(Uninstall());
+}
+
+TEST_F(IntegrationTestDeviceManagementBase, PolicyFetchFailedNoAppUpdate) {
+  ASSERT_NO_FATAL_FAILURE(InstallBrokenEnterpriseCompanionApp());
+
+  ASSERT_NO_FATAL_FAILURE(Install(/*switches=*/{}));
+  ASSERT_NO_FATAL_FAILURE(ExpectInstalled());
+  ASSERT_NO_FATAL_FAILURE(InstallTestApp(kApp1, /*install_v1=*/true));
+  ExpectAppInstalled(kApp1.appid, kApp1.v1);
+
+  // Policy fetch failure should block app update. There's still an update
+  // check request for updater itself.
+  DMPushEnrollmentToken(kEnrollmentToken);
+  ExpectDeviceManagementRegistrationRequest(test_server_.get(),
+                                            kEnrollmentToken, kDMToken);
+  test_server_->ExpectOnce({}, "", net::HTTP_INTERNAL_SERVER_ERROR);
+#if BUILDFLAG(IS_MAC)
+  // Mac has an out-of-process fallback fetcher.
+  test_server_->ExpectOnce({}, "", net::HTTP_INTERNAL_SERVER_ERROR);
+#endif  // BUILDFLAG(IS_MAC)
+  ExpectUpdateCheckRequest(test_server_.get());
+  ASSERT_NO_FATAL_FAILURE(RunWake(0));
+  ASSERT_TRUE(WaitForUpdaterExit());
+  ExpectAppInstalled(kApp1.appid, kApp1.v1);
+
+  // Update should perform normally if subsequent policy fetch succeeds.
+  ASSERT_NO_FATAL_FAILURE(SetLastChecked(base::Time::Now() - base::Hours(9)))
+      << "Failed to set last-checked to force next update check.";
+  ExpectDeviceManagementPolicyFetchRequest(test_server_.get(), kDMToken,
+                                           OmahaSettingsClientProto());
+  ExpectAppsUpdateSequence(
+      UpdaterScope::kSystem, test_server_.get(),
+      /*request_attributes=*/{},
+      {AppUpdateExpectation(
+          kApp1.GetInstallCommandLineArgs(/*install_v1=*/false), kApp1.appid,
+          kApp1.v1, kApp1.v2,
+          /*is_install=*/false,
+          /*should_update=*/true, false, "", "",
+          GetInstallerPath(kApp1.v2_crx))});
+  ASSERT_NO_FATAL_FAILURE(RunWake(0));
+  ASSERT_TRUE(WaitForUpdaterExit());
+
+  ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kApp1.appid, kApp1.v2));
+  ASSERT_NO_FATAL_FAILURE(ExpectUninstallPing(test_server_.get()));
+  ASSERT_NO_FATAL_FAILURE(UninstallBrokenEnterpriseCompanionApp());
+  ASSERT_NO_FATAL_FAILURE(Uninstall());
+}
+
 TEST_P(IntegrationTestDeviceManagement, AppInstall) {
   const base::Version kApp1Version = base::Version("1.0.0.0");
   OmahaSettingsClientProto omaha_settings;
diff --git a/chrome/updater/update_service_impl_impl.cc b/chrome/updater/update_service_impl_impl.cc
index 4b1aefb6..9c028442 100644
--- a/chrome/updater/update_service_impl_impl.cc
+++ b/chrome/updater/update_service_impl_impl.cc
@@ -844,6 +844,13 @@
   VLOG(1) << __func__;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  if (config_->GetPolicyService()->LastFetchResult().value_or(kErrorOk) !=
+      kErrorOk) {
+    VLOG(1) << "Force install apps skipped because of policy refresh error.";
+    base::BindPostTask(main_task_runner_, std::move(callback))
+        .Run(UpdateService::Result::kInstallFailed);
+    return;
+  }
   PolicyStatus<std::vector<std::string>> force_install_apps_status =
       config_->GetPolicyService()->GetForceInstallApps();
   if (!force_install_apps_status) {
@@ -898,6 +905,11 @@
     return;
   }
 
+  if (!IsAppPolicyLoadedOK(app_id)) {
+    HandlePolicyLoadError(app_id, state_update, std::move(callback));
+    return;
+  }
+
   int policy = kPolicyEnabled;
   if (IsUpdateDisabledByPolicy(app_id, priority, false, policy)) {
     HandleUpdateDisabledByPolicy(app_id, policy, false, state_update,
@@ -929,6 +941,11 @@
     return;
   }
 
+  if (!IsAppPolicyLoadedOK(app_id)) {
+    HandlePolicyLoadError(app_id, state_update, std::move(callback));
+    return;
+  }
+
   int policy = kPolicyEnabled;
   if (IsUpdateDisabledByPolicy(app_id, priority, false, policy)) {
     HandleUpdateDisabledByPolicy(app_id, policy, false, state_update,
@@ -952,7 +969,12 @@
   VLOG(1) << __func__;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
-  const auto app_ids = config_->GetUpdaterPersistedData()->GetAppIds();
+  auto app_ids = config_->GetUpdaterPersistedData()->GetAppIds();
+  std::erase_if(app_ids, [this](const std::string& app_id) {
+    return !IsAppPolicyLoadedOK(app_id);
+  });
+  VLOG(1) << "Apps to update: " << base::JoinString(app_ids, ", ");
+
   CHECK(base::Contains(
       app_ids, base::ToLowerASCII(kUpdaterAppId),
       static_cast<std::string (*)(std::string_view)>(&base::ToLowerASCII)));
@@ -987,6 +1009,12 @@
   VLOG(1) << __func__;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  if (!IsAppPolicyLoadedOK(registration.app_id)) {
+    HandlePolicyLoadError(registration.app_id, state_update,
+                          std::move(callback));
+    return;
+  }
+
   int policy = kPolicyEnabled;
   if (IsUpdateDisabledByPolicy(registration.app_id, priority, true, policy)) {
     HandleUpdateDisabledByPolicy(registration.app_id, policy, true,
@@ -1057,6 +1085,11 @@
           << install_args << ": " << install_data << ": " << install_settings;
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
+  if (!IsAppPolicyLoadedOK(app_id)) {
+    HandlePolicyLoadError(app_id, state_update, std::move(callback));
+    return;
+  }
+
   int policy = kPolicyEnabled;
   if (IsUpdateDisabledByPolicy(app_id, Priority::kForeground, true, policy)) {
     HandleUpdateDisabledByPolicy(app_id, policy, true, state_update,
@@ -1225,6 +1258,31 @@
           app_info.brand, std::move(callback)));
 }
 
+bool UpdateServiceImplImpl::IsAppPolicyLoadedOK(
+    const std::string& app_id) const {
+  return IsUpdaterOrCompanionApp(app_id) || app_id == kQualificationAppId ||
+         config_->GetPolicyService()->LastFetchResult().value_or(kErrorOk) ==
+             kErrorOk;
+}
+
+void UpdateServiceImplImpl::HandlePolicyLoadError(
+    const std::string& app_id,
+    base::RepeatingCallback<void(const UpdateState&)> state_update,
+    base::OnceCallback<void(Result)> callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+  VLOG(1) << __func__;
+
+  UpdateState update_state;
+  update_state.app_id = app_id;
+  update_state.state = UpdateService::UpdateState::State::kUpdateError;
+  update_state.error_category = UpdateService::ErrorCategory::kInstaller;
+  update_state.error_code = kErrorPolicyFetchFailed;
+  update_state.extra_code1 = 0;
+  base::BindPostTask(main_task_runner_, state_update).Run(update_state);
+  base::BindPostTask(main_task_runner_, std::move(callback))
+      .Run(UpdateService::Result::kUpdateCheckFailed);
+}
+
 bool UpdateServiceImplImpl::IsUpdateDisabledByPolicy(const std::string& app_id,
                                                      Priority priority,
                                                      bool is_install,
diff --git a/chrome/updater/update_service_impl_impl.h b/chrome/updater/update_service_impl_impl.h
index 581dc9ac..4196952 100644
--- a/chrome/updater/update_service_impl_impl.h
+++ b/chrome/updater/update_service_impl_impl.h
@@ -92,6 +92,12 @@
       base::RepeatingCallback<void(const UpdateState&)> state_update,
       base::OnceCallback<void(Result)> callback);
 
+  bool IsAppPolicyLoadedOK(const std::string& app_id) const;
+  void HandlePolicyLoadError(
+      const std::string& app_id,
+      base::RepeatingCallback<void(const UpdateState&)> state_update,
+      base::OnceCallback<void(Result)> callback);
+
   bool IsUpdateDisabledByPolicy(const std::string& app_id,
                                 Priority priority,
                                 bool is_install,
diff --git a/chromeos/ash/components/BUILD.gn b/chromeos/ash/components/BUILD.gn
index 9af3093f..7453819 100644
--- a/chromeos/ash/components/BUILD.gn
+++ b/chromeos/ash/components/BUILD.gn
@@ -63,7 +63,6 @@
     "//chromeos/ash/components/smbfs:unit_tests",
     "//chromeos/ash/components/sparky:unit_tests",
     "//chromeos/ash/components/specialized_features:unit_tests",
-    "//chromeos/ash/components/standalone_browser:unit_tests",
     "//chromeos/ash/components/string_matching:unit_tests",
     "//chromeos/ash/components/sync_wifi:unit_tests",
     "//chromeos/ash/components/system:unit_tests",
diff --git a/chromeos/ash/components/standalone_browser/BUILD.gn b/chromeos/ash/components/standalone_browser/BUILD.gn
index d637475f..aec8292 100644
--- a/chromeos/ash/components/standalone_browser/BUILD.gn
+++ b/chromeos/ash/components/standalone_browser/BUILD.gn
@@ -13,8 +13,6 @@
   sources = [
     "channel_util.cc",
     "channel_util.h",
-    "lacros_selection.cc",
-    "lacros_selection.h",
     "standalone_browser_features.cc",
     "standalone_browser_features.h",
   ]
@@ -33,25 +31,3 @@
     "//google_apis:google_apis",
   ]
 }
-
-source_set("unit_tests") {
-  testonly = true
-
-  sources = [
-    "channel_util_unittest.cc",
-    "lacros_selection_unittest.cc",
-  ]
-
-  deps = [
-    ":standalone_browser",
-    "//ash/constants:constants",
-    "//base/test:test_support",
-    "//components/account_id",
-    "//components/policy:generated",
-    "//components/policy/core/common",
-    "//components/prefs:test_support",
-    "//components/user_manager:test_support",
-    "//content/test:test_support",
-    "//testing/gtest:gtest",
-  ]
-}
diff --git a/chromeos/ash/components/standalone_browser/DEPS b/chromeos/ash/components/standalone_browser/DEPS
index 6be56c0..654fc91 100644
--- a/chromeos/ash/components/standalone_browser/DEPS
+++ b/chromeos/ash/components/standalone_browser/DEPS
@@ -1,23 +1,6 @@
 specific_include_rules = {
-  "lacros_selection\.cc": [
-    "+components/policy/core/common/policy_map.h",
-    "+components/policy/policy_constants.h",
-    "+components/user_manager/user_manager.h",
-  ],
-  "lacros_selection_unittest\.cc": [
-    "+ash/constants/ash_switches.h",
-    "+components/account_id/account_id.h",
-    "+components/policy/core/common/policy_map.h",
-    "+components/policy/policy_constants.h",
-    "+components/user_manager/fake_user_manager.h",
-    "+components/user_manager/scoped_user_manager.h",
-    "+components/user_manager/user.h",
-  ],
   "channel_util\.cc": [
     "+chromeos/ash/components/channel/channel_info.h",
     "+components/component_updater/component_updater_service.h",
   ],
-  "channel_util_unittest\.cc": [
-    "+chromeos/ash/components/standalone_browser/lacros_selection.h",
-  ],
 }
diff --git a/chromeos/ash/components/standalone_browser/channel_util.cc b/chromeos/ash/components/standalone_browser/channel_util.cc
index a037918..ce84827 100644
--- a/chromeos/ash/components/standalone_browser/channel_util.cc
+++ b/chromeos/ash/components/standalone_browser/channel_util.cc
@@ -13,7 +13,6 @@
 #include "base/logging.h"
 #include "base/version.h"
 #include "chromeos/ash/components/channel/channel_info.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 #include "components/component_updater/component_updater_service.h"
 
 namespace ash::standalone_browser {
@@ -62,23 +61,6 @@
   return GetLacrosComponentInfoForChannel(GetStatefulLacrosChannel());
 }
 
-version_info::Channel GetLacrosSelectionUpdateChannel(
-    standalone_browser::LacrosSelection selection) {
-  switch (selection) {
-    case standalone_browser::LacrosSelection::kRootfs:
-      // For 'rootfs' Lacros use the same channel as ash/OS. Obtained from
-      // the LSB's release track property.
-      return GetChannel();
-    case standalone_browser::LacrosSelection::kStateful:
-      // For 'stateful' Lacros directly check the channel of stateful-lacros
-      // that the user is on.
-      return GetStatefulLacrosChannel();
-    case standalone_browser::LacrosSelection::kDeployedLocally:
-      // For locally deployed Lacros there is no channel so return unknown.
-      return version_info::Channel::UNKNOWN;
-  }
-}
-
 base::Version GetInstalledLacrosComponentVersion(
     const component_updater::ComponentUpdateService* component_update_service) {
   DCHECK(component_update_service);
diff --git a/chromeos/ash/components/standalone_browser/channel_util.h b/chromeos/ash/components/standalone_browser/channel_util.h
index 7403303..77d7783 100644
--- a/chromeos/ash/components/standalone_browser/channel_util.h
+++ b/chromeos/ash/components/standalone_browser/channel_util.h
@@ -17,7 +17,6 @@
 }  // namespace component_updater
 
 namespace ash::standalone_browser {
-enum class LacrosSelection;
 
 // The default update channel to leverage for Lacros when the channel is
 // unknown.
@@ -60,11 +59,6 @@
 COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
 ComponentInfo GetLacrosComponentInfo();
 
-// Returns the update channel associated with the given loaded lacros selection.
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
-version_info::Channel GetLacrosSelectionUpdateChannel(
-    standalone_browser::LacrosSelection selection);
-
 // Returns the currently installed version of lacros-chrome managed by the
 // component updater. Will return an empty / invalid version if no lacros
 // component is found.
diff --git a/chromeos/ash/components/standalone_browser/channel_util_unittest.cc b/chromeos/ash/components/standalone_browser/channel_util_unittest.cc
deleted file mode 100644
index d10d1c0f..0000000
--- a/chromeos/ash/components/standalone_browser/channel_util_unittest.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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 "chromeos/ash/components/standalone_browser/channel_util.h"
-
-#include "base/check_op.h"
-#include "base/command_line.h"
-#include "base/version_info/channel.h"
-#include "chromeos/ash/components/standalone_browser/lacros_selection.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace ash::standalone_browser {
-
-using ChannelUtilTest = testing::Test;
-
-TEST_F(ChannelUtilTest, StatefulLacrosSelectionUpdateChannel) {
-  // Assert that when no Lacros stability switch is specified, we return the
-  // "unknown" channel.
-  ASSERT_EQ(version_info::Channel::UNKNOWN,
-            GetLacrosSelectionUpdateChannel(LacrosSelection::kStateful));
-
-  // Assert that when a Lacros stability switch is specified, we return the
-  // relevant channel name associated to that switch value.
-  base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
-  cmdline->AppendSwitchNative(kLacrosStabilitySwitch,
-                              kLacrosStabilityChannelBeta);
-  ASSERT_EQ(version_info::Channel::BETA,
-            GetLacrosSelectionUpdateChannel(LacrosSelection::kStateful));
-  cmdline->RemoveSwitch(kLacrosStabilitySwitch);
-}
-
-}  // namespace ash::standalone_browser
diff --git a/chromeos/ash/components/standalone_browser/lacros_selection.cc b/chromeos/ash/components/standalone_browser/lacros_selection.cc
deleted file mode 100644
index d7a440a..0000000
--- a/chromeos/ash/components/standalone_browser/lacros_selection.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-// 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 "chromeos/ash/components/standalone_browser/lacros_selection.h"
-
-#include "ash/constants/ash_switches.h"
-#include "base/command_line.h"
-#include "base/containers/fixed_flat_map.h"
-#include "base/containers/flat_map.h"
-#include "base/logging.h"
-#include "base/notreached.h"
-#include "components/policy/core/common/policy_map.h"
-#include "components/policy/policy_constants.h"
-#include "components/user_manager/user_manager.h"
-#include "google_apis/gaia/gaia_auth_util.h"
-
-namespace ash::standalone_browser {
-
-namespace {
-
-// At session start the value for LacrosSelection logic is applied and the
-// result is stored in this variable which is used after that as a cache.
-// TODO(crbug.com/336839132): Move cache related methods to a wrapper class
-// instead of global functions + global variables.
-std::optional<LacrosSelectionPolicy> g_lacros_selection_cache;
-
-// The conversion map for LacrosSelection policy data. The values must match
-// the ones from LacrosSelection.yaml.
-constexpr auto kLacrosSelectionPolicyMap =
-    base::MakeFixedFlatMap<std::string_view, LacrosSelectionPolicy>({
-        {"user_choice", LacrosSelectionPolicy::kUserChoice},
-        {"rootfs", LacrosSelectionPolicy::kRootfs},
-    });
-
-bool IsGoogleInternal(const user_manager::User* user) {
-  if (!user) {
-    return false;
-  }
-
-  const std::string_view email = user->GetAccountId().GetUserEmail();
-  return gaia::IsGoogleInternalAccountEmail(email) ||
-         gaia::IsGoogleRobotAccountEmail(email) ||
-         gaia::ExtractDomainName(gaia::SanitizeEmail(email)) ==
-             "managedchrome.com";
-}
-
-}  // namespace
-
-void CacheLacrosSelection(const policy::PolicyMap& map) {
-  if (g_lacros_selection_cache.has_value()) {
-    // Some browser tests might call this multiple times.
-    LOG(ERROR) << "Trying to cache LacrosSelection and the value was set";
-    return;
-  }
-
-  // Users can set this switch in chrome://flags to disable the effect of the
-  // lacros-selection policy. This should only be allows for googlers.
-  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
-  if (cmdline->HasSwitch(ash::switches::kLacrosSelectionPolicyIgnore) &&
-      IsGoogleInternal(user_manager::UserManager::Get()->GetPrimaryUser())) {
-    LOG(WARNING) << "LacrosSelection policy is ignored due to the ignore flag";
-    return;
-  }
-
-  const base::Value* value =
-      map.GetValue(policy::key::kLacrosSelection, base::Value::Type::STRING);
-  g_lacros_selection_cache = ParseLacrosSelectionPolicy(
-      value ? value->GetString() : std::string_view());
-}
-
-LacrosSelectionPolicy GetCachedLacrosSelectionPolicy() {
-  return g_lacros_selection_cache.value_or(LacrosSelectionPolicy::kUserChoice);
-}
-
-std::optional<LacrosSelection> DetermineLacrosSelection() {
-  switch (GetCachedLacrosSelectionPolicy()) {
-    case LacrosSelectionPolicy::kRootfs:
-      return LacrosSelection::kRootfs;
-    case LacrosSelectionPolicy::kUserChoice:
-      break;
-  }
-
-  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
-
-  if (!cmdline->HasSwitch(kLacrosSelectionSwitch)) {
-    return std::nullopt;
-  }
-
-  auto value = cmdline->GetSwitchValueASCII(kLacrosSelectionSwitch);
-  if (value == kLacrosSelectionRootfs) {
-    return LacrosSelection::kRootfs;
-  }
-  if (value == kLacrosSelectionStateful) {
-    return LacrosSelection::kStateful;
-  }
-
-  return std::nullopt;
-}
-
-std::optional<LacrosSelectionPolicy> ParseLacrosSelectionPolicy(
-    std::string_view value) {
-  auto it = kLacrosSelectionPolicyMap.find(value);
-  if (it != kLacrosSelectionPolicyMap.end()) {
-    return it->second;
-  }
-
-  LOG(ERROR) << "Unknown LacrosSelection policy value is passed: " << value;
-  return std::nullopt;
-}
-
-std::string_view GetLacrosSelectionPolicyName(LacrosSelectionPolicy value) {
-  for (const auto& entry : kLacrosSelectionPolicyMap) {
-    if (entry.second == value) {
-      return entry.first;
-    }
-  }
-
-  NOTREACHED();
-}
-
-void ClearLacrosSelectionCacheForTest() {
-  g_lacros_selection_cache.reset();
-}
-
-}  // namespace ash::standalone_browser
diff --git a/chromeos/ash/components/standalone_browser/lacros_selection.h b/chromeos/ash/components/standalone_browser/lacros_selection.h
deleted file mode 100644
index 6bd11ce..0000000
--- a/chromeos/ash/components/standalone_browser/lacros_selection.h
+++ /dev/null
@@ -1,82 +0,0 @@
-// 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 CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_LACROS_SELECTION_H_
-#define CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_LACROS_SELECTION_H_
-
-#include <optional>
-#include <string_view>
-
-#include "base/component_export.h"
-
-namespace policy {
-class PolicyMap;
-}  // namespace policy
-
-namespace ash::standalone_browser {
-
-// Represents the policy indicating which Lacros browser to launch, named
-// LacrosSelection. The values shall be consistent with the controlling
-// policy. Unlike `LacrosSelection` representing which lacros to select,
-// `LacrosSelectionPolicy` represents how to decide which lacros to select.
-// Stateful option from `LacrosSelection` is omitted due to a breakage risks in
-// case of version skew (e.g. when the latest stateful Lacros available in omaha
-// is older than the rootfs Lacros on the device).
-enum class LacrosSelectionPolicy {
-  // Indicates that the user decides which Lacros browser to launch: rootfs or
-  // stateful.
-  kUserChoice = 0,
-  // Indicates that rootfs Lacros will always be launched.
-  kRootfs = 1,
-};
-
-// Represents the different options available for lacros selection.
-enum class LacrosSelection {
-  kRootfs = 0,
-  kStateful = 1,
-  kDeployedLocally = 2,
-  kMaxValue = kDeployedLocally,
-};
-
-// A command-line switch that can also be set from chrome://flags that chooses
-// which selection of Lacros to use.
-inline constexpr char kLacrosSelectionSwitch[] = "lacros-selection";
-inline constexpr char kLacrosSelectionRootfs[] = "rootfs";
-inline constexpr char kLacrosSelectionStateful[] = "stateful";
-
-// To be called at primary user login, to cache the policy value for
-// LacrosSelection policy. The effective value of the policy does not
-// change for the duration of the user session, so cached value shall be
-// checked.
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
-void CacheLacrosSelection(const policy::PolicyMap& map);
-
-// Returns cached value of LacrosSelection policy. See `CacheLacrosSelection`
-// for details.
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
-LacrosSelectionPolicy GetCachedLacrosSelectionPolicy();
-
-// Returns lacros selection option according to LarcrosSelectionPolicy and
-// lacros-selection flag. Returns nullopt if there is no preference.
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
-std::optional<LacrosSelection> DetermineLacrosSelection();
-
-// Parses the string representation of LacrosSelection policy value into the
-// enum value. Returns nullopt on unknown value.
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
-std::optional<LacrosSelectionPolicy> ParseLacrosSelectionPolicy(
-    std::string_view value);
-
-// Returns the LacrosSelection policy value name from the given value. Returned
-// std::string_view is guaranteed to never be invalidated.
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
-std::string_view GetLacrosSelectionPolicyName(LacrosSelectionPolicy value);
-
-// Clears the cached value for LacrosSelection policy.
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
-void ClearLacrosSelectionCacheForTest();
-
-}  // namespace ash::standalone_browser
-
-#endif  // CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_LACROS_SELECTION_H_
diff --git a/chromeos/ash/components/standalone_browser/lacros_selection_unittest.cc b/chromeos/ash/components/standalone_browser/lacros_selection_unittest.cc
deleted file mode 100644
index ee70ca9a..0000000
--- a/chromeos/ash/components/standalone_browser/lacros_selection_unittest.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-// 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 "chromeos/ash/components/standalone_browser/lacros_selection.h"
-
-#include <memory>
-#include <optional>
-
-#include "ash/constants/ash_switches.h"
-#include "base/test/scoped_command_line.h"
-#include "base/values.h"
-#include "components/account_id/account_id.h"
-#include "components/policy/core/common/policy_map.h"
-#include "components/policy/policy_constants.h"
-#include "components/user_manager/fake_user_manager.h"
-#include "components/user_manager/scoped_user_manager.h"
-#include "components/user_manager/user.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-// This implementation of RAII for LacrosSelection is to make it easy reset
-// the state between runs.
-class ScopedLacrosSelectionCache {
- public:
-  explicit ScopedLacrosSelectionCache(
-      ash::standalone_browser::LacrosSelectionPolicy lacros_selection) {
-    SetLacrosSelection(lacros_selection);
-  }
-  ScopedLacrosSelectionCache(const ScopedLacrosSelectionCache&) = delete;
-  ScopedLacrosSelectionCache& operator=(const ScopedLacrosSelectionCache&) =
-      delete;
-  ~ScopedLacrosSelectionCache() {
-    ash::standalone_browser::ClearLacrosSelectionCacheForTest();
-  }
-
- private:
-  void SetLacrosSelection(
-      ash::standalone_browser::LacrosSelectionPolicy lacros_selection) {
-    policy::PolicyMap policy;
-    policy.Set(policy::key::kLacrosSelection, policy::POLICY_LEVEL_MANDATORY,
-               policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
-               base::Value(GetLacrosSelectionPolicyName(lacros_selection)),
-               /*external_data_fetcher=*/nullptr);
-    ash::standalone_browser::CacheLacrosSelection(policy);
-  }
-};
-
-class LacrosSelectionTest : public testing::Test {
- public:
-  LacrosSelectionTest() = default;
-  ~LacrosSelectionTest() override = default;
-
-  void SetUp() override {
-    fake_user_manager_.Reset(std::make_unique<user_manager::FakeUserManager>());
-  }
-
-  void TearDown() override {
-    fake_user_manager_.Reset();
-  }
-
-  const user_manager::User* AddRegularUser(const std::string& email) {
-    AccountId account_id = AccountId::FromUserEmail(email);
-    const user_manager::User* user = fake_user_manager_->AddUser(account_id);
-    fake_user_manager_->UserLoggedIn(account_id, user->username_hash(),
-                                     /*browser_restart=*/false,
-                                     /*is_child=*/false);
-    return user;
-  }
-
- private:
-  user_manager::TypedScopedUserManager<user_manager::FakeUserManager>
-      fake_user_manager_;
-};
-
-TEST_F(LacrosSelectionTest, LacrosSelection) {
-  // Neither policy nor command line have any preference on Lacros selection.
-  EXPECT_FALSE(ash::standalone_browser::DetermineLacrosSelection());
-
-  {
-    // LacrosSelection policy has precedence over command line.
-    ScopedLacrosSelectionCache cache(
-        ash::standalone_browser::LacrosSelectionPolicy::kRootfs);
-    base::test::ScopedCommandLine cmd_line;
-    cmd_line.GetProcessCommandLine()->AppendSwitchASCII(
-        ash::standalone_browser::kLacrosSelectionSwitch,
-        ash::standalone_browser::kLacrosSelectionStateful);
-    EXPECT_EQ(ash::standalone_browser::DetermineLacrosSelection(),
-              ash::standalone_browser::LacrosSelection::kRootfs);
-  }
-
-  {
-    // LacrosSelection allows command line check, but command line is not set.
-    ScopedLacrosSelectionCache cache(
-        ash::standalone_browser::LacrosSelectionPolicy::kUserChoice);
-    EXPECT_FALSE(ash::standalone_browser::DetermineLacrosSelection());
-  }
-
-  {
-    // LacrosSelection allows command line check.
-    ScopedLacrosSelectionCache cache(
-        ash::standalone_browser::LacrosSelectionPolicy::kUserChoice);
-    base::test::ScopedCommandLine cmd_line;
-    cmd_line.GetProcessCommandLine()->AppendSwitchASCII(
-        ash::standalone_browser::kLacrosSelectionSwitch,
-        ash::standalone_browser::kLacrosSelectionRootfs);
-    EXPECT_EQ(ash::standalone_browser::DetermineLacrosSelection(),
-              ash::standalone_browser::LacrosSelection::kRootfs);
-  }
-
-  {
-    // LacrosSelection allows command line check.
-    ScopedLacrosSelectionCache cache(
-        ash::standalone_browser::LacrosSelectionPolicy::kUserChoice);
-    base::test::ScopedCommandLine cmd_line;
-    cmd_line.GetProcessCommandLine()->AppendSwitchASCII(
-        ash::standalone_browser::kLacrosSelectionSwitch,
-        ash::standalone_browser::kLacrosSelectionStateful);
-    EXPECT_EQ(ash::standalone_browser::DetermineLacrosSelection(),
-              ash::standalone_browser::LacrosSelection::kStateful);
-  }
-}
-
-// LacrosSelection has no effect on non-googlers.
-TEST_F(LacrosSelectionTest, LacrosSelectionPolicyIgnoreNonGoogle) {
-  AddRegularUser("user@random.com");
-
-  base::test::ScopedCommandLine cmd_line;
-  cmd_line.GetProcessCommandLine()->AppendSwitch(
-      ash::switches::kLacrosSelectionPolicyIgnore);
-
-  {
-    ScopedLacrosSelectionCache cache(
-        ash::standalone_browser::LacrosSelectionPolicy::kRootfs);
-    EXPECT_EQ(ash::standalone_browser::GetCachedLacrosSelectionPolicy(),
-              ash::standalone_browser::LacrosSelectionPolicy::kRootfs);
-    EXPECT_EQ(ash::standalone_browser::DetermineLacrosSelection(),
-              ash::standalone_browser::LacrosSelection::kRootfs);
-  }
-}
-
-// LacrosSelection has an effect on googlers.
-TEST_F(LacrosSelectionTest,
-       LacrosSelectionPolicyIgnoreGoogleDisableToUserChoice) {
-  AddRegularUser("user@google.com");
-
-  base::test::ScopedCommandLine cmd_line;
-  cmd_line.GetProcessCommandLine()->AppendSwitch(
-      ash::switches::kLacrosSelectionPolicyIgnore);
-
-  {
-    ScopedLacrosSelectionCache cache(
-        ash::standalone_browser::LacrosSelectionPolicy::kRootfs);
-    EXPECT_EQ(ash::standalone_browser::GetCachedLacrosSelectionPolicy(),
-              ash::standalone_browser::LacrosSelectionPolicy::kUserChoice);
-    EXPECT_FALSE(ash::standalone_browser::DetermineLacrosSelection());
-  }
-}
-
-}  // namespace
diff --git a/chromeos/components/cdm_factory_daemon/content_decryption_module_adapter.cc b/chromeos/components/cdm_factory_daemon/content_decryption_module_adapter.cc
index 71961bd1..b134502f 100644
--- a/chromeos/components/cdm_factory_daemon/content_decryption_module_adapter.cc
+++ b/chromeos/components/cdm_factory_daemon/content_decryption_module_adapter.cc
@@ -356,7 +356,7 @@
         std::vector<uint8_t>(encrypted->data(),
                              encrypted->data() + encrypted->size()),
         nullptr, true,
-        encrypted->has_side_data() ? encrypted->side_data()->secure_handle : 0,
+        encrypted->side_data() ? encrypted->side_data()->secure_handle : 0,
         base::BindOnce(&ContentDecryptionModuleAdapter::OnDecrypt,
                        base::Unretained(this), stream_type, encrypted,
                        std::move(decrypt_cb)));
@@ -380,7 +380,7 @@
       std::vector<uint8_t>(encrypted->data(),
                            encrypted->data() + encrypted->size()),
       decrypt_config->Clone(), stream_type == Decryptor::kVideo,
-      encrypted->has_side_data() ? encrypted->side_data()->secure_handle : 0,
+      encrypted->side_data() ? encrypted->side_data()->secure_handle : 0,
       base::BindOnce(&ContentDecryptionModuleAdapter::OnDecrypt,
                      base::Unretained(this), stream_type, encrypted,
                      std::move(decrypt_cb)));
@@ -524,7 +524,7 @@
 
   // If we decrypted to secure memory, then just send the original buffer back
   // because the result is stored in the secure world.
-  if (encrypted->has_side_data() && encrypted->side_data()->secure_handle) {
+  if (encrypted->side_data() && encrypted->side_data()->secure_handle) {
     std::move(decrypt_cb).Run(media::Decryptor::kSuccess, std::move(encrypted));
     return;
   }
@@ -535,7 +535,7 @@
   decrypted->set_timestamp(encrypted->timestamp());
   decrypted->set_duration(encrypted->duration());
   decrypted->set_is_key_frame(encrypted->is_key_frame());
-  if (encrypted->has_side_data()) {
+  if (encrypted->side_data()) {
     decrypted->set_side_data(encrypted->side_data()->Clone());
   }
 
diff --git a/chromeos/services/assistant/public/shared/BUILD.gn b/chromeos/services/assistant/public/shared/BUILD.gn
index b93a480..468e630b 100644
--- a/chromeos/services/assistant/public/shared/BUILD.gn
+++ b/chromeos/services/assistant/public/shared/BUILD.gn
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 import("//build/config/chrome_build.gni")
+import("//chromeos/ash/components/assistant/assistant.gni")
 
 # C++ headers and sources that can be shared by assistant internal and
 # external directories.
@@ -16,7 +17,7 @@
     "utils.h",
   ]
 
-  if (is_chromeos && is_chrome_branded) {
+  if (enable_cros_libassistant) {
     sources += [ "//chromeos/assistant/internal/constants.cc" ]
   } else {
     sources += [ "constants.cc" ]
@@ -26,7 +27,7 @@
 }
 
 source_set("new_entry_point_constants") {
-  if (is_chromeos && is_chrome_branded) {
+  if (enable_cros_libassistant) {
     deps = [ "//chromeos/assistant/internal:new_entry_point_constants" ]
   } else {
     deps = [ ":new_entry_point_constants_placeholder" ]
diff --git a/clank b/clank
index 773685e..39154b6 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 773685ed2b08bc452886504e9d8efbfb8d7349be
+Subproject commit 39154b6f5dc2836f6dac6e46c711d1c737beb3fd
diff --git a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
index af8b986..32a81893e 100644
--- a/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
+++ b/components/feature_engagement/public/android/java/src/org/chromium/components/feature_engagement/FeatureConstants.java
@@ -105,7 +105,6 @@
     FeatureConstants.VIDEO_TUTORIAL_NTP_SUMMARY_FEATURE,
     FeatureConstants.VIDEO_TUTORIAL_NTP_VOICE_SEARCH_FEATURE,
     FeatureConstants.VIDEO_TUTORIAL_TRY_NOW_FEATURE,
-    FeatureConstants.PRICE_DROP_NTP_FEATURE,
     FeatureConstants.RESTORE_TABS_ON_FRE_FEATURE,
     FeatureConstants.IPH_RTL_GESTURE_NAVIGATION,
     FeatureConstants.TAB_GROUP_CREATION_DIALOG_SYNC_TEXT_FEATURE,
@@ -339,9 +338,6 @@
     /** An IPH feature to inform users about the Webnotes Stylize feature in Sharing Hub. */
     String SHARING_HUB_WEBNOTES_STYLIZE_FEATURE = "IPH_SharingHubWebnotesStylize";
 
-    /** An IPH feature to inform users that a price drop has occurred in any of their open tabs */
-    String PRICE_DROP_NTP_FEATURE = "IPH_PriceDropNTP";
-
     /**
      * An IPH feature to inform users that tabs from another synced device can be restored on FRE.
      */
diff --git a/components/feature_engagement/public/feature_constants.cc b/components/feature_engagement/public/feature_constants.cc
index 7b41f21..d047faa 100644
--- a/components/feature_engagement/public/feature_constants.cc
+++ b/components/feature_engagement/public/feature_constants.cc
@@ -392,9 +392,6 @@
 BASE_FEATURE(kIPHPreviewsOmniboxUIFeature,
              "IPH_PreviewsOmniboxUI",
              base::FEATURE_ENABLED_BY_DEFAULT);
-BASE_FEATURE(kIPHPriceDropNTPFeature,
-             "IPH_PriceDropNTP",
-             base::FEATURE_DISABLED_BY_DEFAULT);
 BASE_FEATURE(kIPHShoppingListMenuItemFeature,
              "IPH_ShoppingListMenuItem",
              base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/components/feature_engagement/public/feature_constants.h b/components/feature_engagement/public/feature_constants.h
index 115c556c..aa3c6e6 100644
--- a/components/feature_engagement/public/feature_constants.h
+++ b/components/feature_engagement/public/feature_constants.h
@@ -165,7 +165,6 @@
 FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHPageInfoStoreInfoFeature);
 FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHPageZoomFeature);
 FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHPreviewsOmniboxUIFeature);
-FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHPriceDropNTPFeature);
 FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHQuietNotificationPromptsFeature);
 FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHReadAloudAppMenuFeature);
 FEATURE_CONSTANTS_DECLARE_FEATURE(kIPHReadAloudExpandedPlayerFeature);
diff --git a/components/feature_engagement/public/feature_list.cc b/components/feature_engagement/public/feature_list.cc
index e25cb77..394eebe 100644
--- a/components/feature_engagement/public/feature_list.cc
+++ b/components/feature_engagement/public/feature_list.cc
@@ -70,7 +70,6 @@
     &kIPHPageInfoStoreInfoFeature,
     &kIPHPageZoomFeature,
     &kIPHPreviewsOmniboxUIFeature,
-    &kIPHPriceDropNTPFeature,
     &kIPHReadAloudAppMenuFeature,
     &kIPHReadAloudExpandedPlayerFeature,
     &kIPHReadLaterContextMenuFeature,
diff --git a/components/feature_engagement/public/feature_list.h b/components/feature_engagement/public/feature_list.h
index 58b4463..9612118d 100644
--- a/components/feature_engagement/public/feature_list.h
+++ b/components/feature_engagement/public/feature_list.h
@@ -126,7 +126,6 @@
 DEFINE_VARIATION_PARAM(kIPHPageInfoStoreInfoFeature, "IPH_PageInfoStoreInfo");
 DEFINE_VARIATION_PARAM(kIPHPageZoomFeature, "IPH_PageZoom");
 DEFINE_VARIATION_PARAM(kIPHPreviewsOmniboxUIFeature, "IPH_PreviewsOmniboxUI");
-DEFINE_VARIATION_PARAM(kIPHPriceDropNTPFeature, "IPH_PriceDropNTP");
 DEFINE_VARIATION_PARAM(kIPHReadAloudAppMenuFeature,
                        "IPH_ReadAloudAppMenuFeature");
 DEFINE_VARIATION_PARAM(kIPHReadAloudExpandedPlayerFeature,
@@ -560,7 +559,6 @@
         VARIATION_ENTRY(kIPHPageInfoStoreInfoFeature),
         VARIATION_ENTRY(kIPHPageZoomFeature),
         VARIATION_ENTRY(kIPHPreviewsOmniboxUIFeature),
-        VARIATION_ENTRY(kIPHPriceDropNTPFeature),
         VARIATION_ENTRY(kIPHReadAloudAppMenuFeature),
         VARIATION_ENTRY(kIPHReadAloudExpandedPlayerFeature),
         VARIATION_ENTRY(kIPHReadLaterContextMenuFeature),
diff --git a/components/image_fetcher/core/BUILD.gn b/components/image_fetcher/core/BUILD.gn
index 50b317d..6ce8d33 100644
--- a/components/image_fetcher/core/BUILD.gn
+++ b/components/image_fetcher/core/BUILD.gn
@@ -10,8 +10,6 @@
   sources = [
     "cached_image_fetcher.cc",
     "cached_image_fetcher.h",
-    "features.cc",
-    "features.h",
     "image_data_fetcher.cc",
     "image_data_fetcher.h",
     "image_decoder.h",
diff --git a/components/image_fetcher/core/features.cc b/components/image_fetcher/core/features.cc
deleted file mode 100644
index 6e0a767..0000000
--- a/components/image_fetcher/core/features.cc
+++ /dev/null
@@ -1,18 +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 "components/image_fetcher/core/features.h"
-
-namespace image_fetcher {
-namespace features {
-
-#if BUILDFLAG(IS_ANDROID)
-// Enables batching decoding of related images in a single process.
-BASE_FEATURE(kBatchImageDecoding,
-             "BatchImageDecoding",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-#endif
-
-}  // namespace features
-}  // namespace image_fetcher
diff --git a/components/image_fetcher/core/features.h b/components/image_fetcher/core/features.h
deleted file mode 100644
index 13a60039..0000000
--- a/components/image_fetcher/core/features.h
+++ /dev/null
@@ -1,21 +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 COMPONENTS_IMAGE_FETCHER_CORE_FEATURES_H_
-#define COMPONENTS_IMAGE_FETCHER_CORE_FEATURES_H_
-
-#include "base/feature_list.h"
-#include "build/build_config.h"
-
-namespace image_fetcher {
-namespace features {
-
-#if BUILDFLAG(IS_ANDROID)
-BASE_DECLARE_FEATURE(kBatchImageDecoding);
-#endif
-
-}  // namespace features
-}  // namespace image_fetcher
-
-#endif  // COMPONENTS_IMAGE_FETCHER_CORE_FEATURES_H_
diff --git a/components/image_fetcher/image_fetcher_bridge.cc b/components/image_fetcher/image_fetcher_bridge.cc
index 5722ab0..f73966f4 100644
--- a/components/image_fetcher/image_fetcher_bridge.cc
+++ b/components/image_fetcher/image_fetcher_bridge.cc
@@ -11,13 +11,11 @@
 #include "base/android/callback_android.h"
 #include "base/android/jni_array.h"
 #include "base/android/jni_string.h"
-#include "base/feature_list.h"
 #include "base/files/file_path.h"
 #include "base/functional/bind.h"
 #include "base/no_destructor.h"
 #include "components/embedder_support/android/simple_factory_key/simple_factory_key_handle.h"
 #include "components/image_fetcher/core/cache/image_cache.h"
-#include "components/image_fetcher/core/features.h"
 #include "components/image_fetcher/core/image_fetcher.h"
 #include "components/image_fetcher/core/image_fetcher_metrics_reporter.h"
 #include "components/image_fetcher/core/image_fetcher_service.h"
@@ -108,8 +106,7 @@
     params.set_hold_for_expiration_interval(
         base::Minutes(j_expiration_interval_mins));
   }
-  if (base::FeatureList::IsEnabled(features::kBatchImageDecoding))
-    params.set_data_decoder(GetDataDecoder());
+  params.set_data_decoder(GetDataDecoder());
 
   // We can skip transcoding here because this method is used in java as
   // ImageFetcher.fetchGif, which decodes the data in a Java-only library.
@@ -148,8 +145,7 @@
     params.set_hold_for_expiration_interval(
         base::Minutes(j_expiration_interval_mins));
   }
-  if (base::FeatureList::IsEnabled(features::kBatchImageDecoding))
-    params.set_data_decoder(GetDataDecoder());
+  params.set_data_decoder(GetDataDecoder());
 
   SimpleFactoryKey* key =
       simple_factory_key::SimpleFactoryKeyFromJavaHandle(j_simple_factory_key);
diff --git a/components/lens/lens_features.cc b/components/lens/lens_features.cc
index eb1e2cce..df9de28 100644
--- a/components/lens/lens_features.cc
+++ b/components/lens/lens_features.cc
@@ -317,6 +317,9 @@
 constexpr base::FeatureParam<bool> kUseWebpageInteractionType{
     &kLensOverlayContextualSearchbox, "use-webpage-interaction-type", false};
 
+constexpr base::FeatureParam<int> kScannedPdfCharacterPerPageHeuristic{
+    &kLensOverlayContextualSearchbox, "characters-per-page-heuristic", 200};
+
 constexpr base::FeatureParam<std::string> kTranslateEndpointUrl{
     &kLensOverlayTranslateLanguages, "translate-endpoint-url",
     "https://translate-pa.googleapis.com/v1/supportedLanguages"};
@@ -546,6 +549,10 @@
   return kUseWebpageInteractionType.Get();
 }
 
+int GetScannedPdfCharacterPerPageHeuristic() {
+  return kScannedPdfCharacterPerPageHeuristic.Get();
+}
+
 bool UsePdfsAsContext() {
   return kUsePdfsAsContext.Get();
 }
diff --git a/components/lens/lens_features.h b/components/lens/lens_features.h
index a7b2e81..6ec3dae9 100644
--- a/components/lens/lens_features.h
+++ b/components/lens/lens_features.h
@@ -331,6 +331,12 @@
 COMPONENT_EXPORT(LENS_FEATURES)
 extern bool UseWebpageInteractionType();
 
+// Returns the number of characters that should be present per page if the PDF
+// is not scanned. This value is compared to the average number of characters
+// per page to determine if the PDF is scanned.
+COMPONENT_EXPORT(LENS_FEATURES)
+extern int GetScannedPdfCharacterPerPageHeuristic();
+
 // Returns whether to include PDFs from the underlying page in the request to be
 // used as page context.
 COMPONENT_EXPORT(LENS_FEATURES)
diff --git a/components/lookalikes/core/lookalike_url_util.h b/components/lookalikes/core/lookalike_url_util.h
index 1034489..478a4ec8 100644
--- a/components/lookalikes/core/lookalike_url_util.h
+++ b/components/lookalikes/core/lookalike_url_util.h
@@ -130,8 +130,12 @@
   // Skeletons of top bucket domains. This is the top 500 or 1000 most popular
   // domains (though, there can be fewer than 500 or 1000 skeletons in this
   // array).
-  // This field is not a raw_ptr<> because it was filtered by the rewriter for:
-  // #global-scope
+  // This field is not a raw_ptr<> because it only ever points to statically-
+  // allocated memory which is never freed, so it cannot dangle.
+  // Spanification note: unlike the raw_spans below, the pointed-to arrays
+  // are defined in generated files, so their size isn't exposed in the header.
+  // To get compile-time safety guarantees, the header itself would have to be
+  // generated as well.
   RAW_PTR_EXCLUSION const char* const* edit_distance_skeletons;
   // Number of skeletons in `edit_distance_skeletons`.
   size_t num_edit_distance_skeletons;
diff --git a/components/omnibox/browser/document_provider.cc b/components/omnibox/browser/document_provider.cc
index 2416e2d..2ef6ed1 100644
--- a/components/omnibox/browser/document_provider.cc
+++ b/components/omnibox/browser/document_provider.cc
@@ -69,7 +69,7 @@
 // numeric values should never be reused.
 //
 // Keep up to date with DocumentProviderAllowedReason in
-// //tools/metrics/histograms/enums.xml.
+// //tools/metrics/histograms/metadata/omnibox/enums.xml.
 enum class DocumentProviderAllowedReason : int {
   kAllowed = 0,
   kUnknown = 1,
@@ -84,7 +84,8 @@
   kInputOnFocusOrEmpty = 10,
   kInputTooShort = 11,
   kInputLooksLikeUrl = 12,
-  kMaxValue = kInputLooksLikeUrl
+  kNotEnterpriseEligible = 13,
+  kMaxValue = kNotEnterpriseEligible
 };
 
 void LogOmniboxDocumentRequest(RemoteRequestEvent request_event) {
@@ -361,7 +362,7 @@
     return false;
   }
 
-  // Must be logged in.
+  // Must be authenticated.
   const bool is_authenticated =
       base::FeatureList::IsEnabled(
           omnibox::kDocumentProviderPrimaryAccountRequirement)
@@ -373,6 +374,26 @@
     return false;
   }
 
+  // Must be enterprise eligibile (if the feature is enabled).
+  bool is_enterprise_eligible = true;
+  if (base::FeatureList::IsEnabled(
+          omnibox::kDocumentProviderEnterpriseEligibility)) {
+    const auto& entrprise_account_state =
+        client_->GetDocumentSuggestionsService()
+            ->account_is_subject_to_enterprise_policies();
+    is_enterprise_eligible =
+        base::FeatureList::IsEnabled(
+            omnibox::kDocumentProviderEnterpriseEligibilityWhenUnknown)
+            ? entrprise_account_state != signin::Tribool::kFalse
+            : entrprise_account_state == signin::Tribool::kTrue;
+  }
+  if (!is_enterprise_eligible) {
+    base::UmaHistogramEnumeration(
+        "Omnibox.DocumentSuggest.ProviderAllowed",
+        DocumentProviderAllowedReason::kNotEnterpriseEligible);
+    return false;
+  }
+
   // Sync must be enabled and active.
   if (!base::FeatureList::IsEnabled(
           omnibox::kDocumentProviderNoSyncRequirement) &&
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc
index d764adb5..0f401cbe 100644
--- a/components/omnibox/common/omnibox_features.cc
+++ b/components/omnibox/common/omnibox_features.cc
@@ -177,13 +177,27 @@
              "OmniboxDocumentProvider",
              enable_if(!IS_ANDROID && !IS_IOS));
 
-// If enabled, checks whether the primary account is available, i.e., the user
-// is signed into Chrome, rarther than checking if any signed in account is
-// available in the cookie jar.
+// If enabled, the authentication requirement for Drive suggestions is based on
+// whether the primary account is available, i.e., the user is signed into
+// Chrome, rarther than checking if any signed in account is available in the
+// cookie jar.
 BASE_FEATURE(kDocumentProviderPrimaryAccountRequirement,
              "OmniboxDocumentProviderPrimaryAccountRequirement",
              DISABLED);
 
+// If enabled, the primary account must be subject to enterprise policies in
+// order to receive Drive suggestions.
+BASE_FEATURE(kDocumentProviderEnterpriseEligibility,
+             "OmniboxDocumentProviderEnterpriseEligibility",
+             DISABLED);
+
+// If enabled, the enterprise eligibility requirement for Drive suggestions
+// is considered met even when the account capability is unknown. Has no effect
+// if kDocumentProviderEnterpriseEligibility is disabled.
+BASE_FEATURE(kDocumentProviderEnterpriseEligibilityWhenUnknown,
+             "OmniboxDocumentProviderEnterpriseEligibilityWhenUnknown",
+             DISABLED);
+
 // If enabled, the requirement to be in an active Sync state is removed and
 // Drive suggestions are available to all clients who meet the other
 // requirements.
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h
index 0d7b6b6d..8c3a222e 100644
--- a/components/omnibox/common/omnibox_features.h
+++ b/components/omnibox/common/omnibox_features.h
@@ -13,7 +13,6 @@
 // Please do not add more features to this "big blob" list.
 // Instead, use the categorized and alphabetized lists below this "big blob".
 // You can create a new category if none of the existing ones fit.
-BASE_DECLARE_FEATURE(kExperimentalKeywordMode);
 BASE_DECLARE_FEATURE(kImageSearchSuggestionThumbnail);
 BASE_DECLARE_FEATURE(kOmniboxRemoveSuggestionsFromClipboard);
 
@@ -65,6 +64,8 @@
 // Document provider and domain suggestions
 BASE_DECLARE_FEATURE(kDocumentProvider);
 BASE_DECLARE_FEATURE(kDocumentProviderPrimaryAccountRequirement);
+BASE_DECLARE_FEATURE(kDocumentProviderEnterpriseEligibility);
+BASE_DECLARE_FEATURE(kDocumentProviderEnterpriseEligibilityWhenUnknown);
 BASE_DECLARE_FEATURE(kDocumentProviderNoSyncRequirement);
 BASE_DECLARE_FEATURE(kDomainSuggestions);
 
diff --git a/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc b/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc
index a704ab6..2758de3 100644
--- a/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc
+++ b/components/optimization_guide/core/model_execution/on_device_model_service_controller_unittest.cc
@@ -415,7 +415,7 @@
   const std::string expected_response = "Input: execute:foo\n";
   EXPECT_EQ(*response_.value(), expected_response);
   EXPECT_TRUE(*response_.provided_by_on_device());
-  EXPECT_THAT(response_.partials(), IsEmpty());
+  EXPECT_THAT(response_.partials(), ElementsAre(expected_response));
   EXPECT_TRUE(response_.log_entry());
   auto logged_on_device_model_execution_info =
       response_.log_entry()
@@ -1584,21 +1584,27 @@
   ASSERT_TRUE(response_.GetFinalStatus());
   // Make sure T&S logged.
   ASSERT_TRUE(response_.log_entry());
-  EXPECT_THAT(response_.logged_executions(),
-              ElementsAre(testing::_,  // Base Model Execution
-                          ResultOf("check text", &GetCheckText,
-                                   "request_check: unsafe_url"),
-                          ResultOf("check text", &GetCheckText,
-                                   "raw_output_check: unsafe_output")));
+  EXPECT_THAT(
+      response_.logged_executions(),
+      ElementsAre(
+          testing::_,  // Base Model Execution
+          ResultOf("check text", &GetCheckText, "request_check: unsafe_url"),
+          ResultOf("check text", &GetCheckText,  // partial check
+                   "raw_output_check: unsafe_output"),
+          ResultOf("check text", &GetCheckText,  // complete check
+                   "raw_output_check: unsafe_output")));
   ASSERT_TRUE(response_.model_execution_info());
-  EXPECT_THAT(response_.model_execution_info()
-                  ->on_device_model_execution_info()
-                  .execution_infos(),
-              ElementsAre(testing::_,  // Base Model Execution
-                          ResultOf("check text", &GetCheckText,
-                                   "request_check: unsafe_url"),
-                          ResultOf("check text", &GetCheckText,
-                                   "raw_output_check: unsafe_output")));
+  EXPECT_THAT(
+      response_.model_execution_info()
+          ->on_device_model_execution_info()
+          .execution_infos(),
+      ElementsAre(
+          testing::_,  // Base Model Execution
+          ResultOf("check text", &GetCheckText, "request_check: unsafe_url"),
+          ResultOf("check text", &GetCheckText,  // partial check
+                   "raw_output_check: unsafe_output"),
+          ResultOf("check text", &GetCheckText,  // complete check
+                   "raw_output_check: unsafe_output")));
 }
 
 TEST_F(OnDeviceModelServiceControllerTest, ModelExecutionNoMinContext) {
@@ -3014,7 +3020,7 @@
   const std::string expected_response =
       "Input: execute:foo\nTopK: 4, Temp: 1.5\n";
   EXPECT_EQ(*response_.value(), expected_response);
-  EXPECT_THAT(response_.partials(), IsEmpty());
+  EXPECT_THAT(response_.partials(), ElementsAre(expected_response));
 }
 
 TEST_F(OnDeviceModelServiceControllerTest, UsesSessionTopKAndTemperature) {
@@ -3044,7 +3050,7 @@
   const std::string expected_response =
       "Input: execute:foo\nTopK: 3, Temp: 2\n";
   EXPECT_EQ(*response_.value(), expected_response);
-  EXPECT_THAT(response_.partials(), IsEmpty());
+  EXPECT_THAT(response_.partials(), ElementsAre(expected_response));
 }
 
 // Validate that a missing partial output config suppresses partial output.
@@ -3071,7 +3077,11 @@
   const std::vector<std::string> expected_responses = {
       "token1 token2 token3 token4"};
   EXPECT_EQ(*response_.value(), expected_responses.back());
-  EXPECT_THAT(response_.partials(), IsEmpty());
+  const std::vector<std::string> partial_expected_responses = {
+      "token1", "token1 token2", "token1 token2 token3",
+      "token1 token2 token3 token4"};
+  EXPECT_THAT(response_.partials(),
+              ElementsAreArray(partial_expected_responses));
 }
 
 // Validate that token interval 1 evaluates all partial output.
diff --git a/components/optimization_guide/core/model_execution/safety_config.cc b/components/optimization_guide/core/model_execution/safety_config.cc
index e332b09..6eb5355 100644
--- a/components/optimization_guide/core/model_execution/safety_config.cc
+++ b/components/optimization_guide/core/model_execution/safety_config.cc
@@ -104,7 +104,10 @@
     return true;
   }
   if (!proto_->has_partial_output_checks()) {
-    return false;
+    // TODO(crbug.com/379429927): Temporary fix before rolling out the partial
+    // output checks. Change the return value to false after fully landing the
+    // new configs.
+    return true;
   }
   if (num_output_tokens < proto_->partial_output_checks().minimum_tokens()) {
     return false;
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal
index e70be79..f922d0d 160000
--- a/components/optimization_guide/internal
+++ b/components/optimization_guide/internal
@@ -1 +1 @@
-Subproject commit e70be79b11bd34dc7e788c4debc9329eb2edc4cd
+Subproject commit f922d0d5ccb76da8ca58e7feeac432cd43b0d214
diff --git a/components/page_load_metrics/browser/observers/use_counter/webdx_feature_maps.cc b/components/page_load_metrics/browser/observers/use_counter/webdx_feature_maps.cc
index ede35bf..d8a915f 100644
--- a/components/page_load_metrics/browser/observers/use_counter/webdx_feature_maps.cc
+++ b/components/page_load_metrics/browser/observers/use_counter/webdx_feature_maps.cc
@@ -185,6 +185,8 @@
            WebDXFeature::kClipboardCustomFormat},
           {WebFeature::kClipboardCustomFormatWrite,
            WebDXFeature::kClipboardCustomFormat},
+          {WebFeature::kClipboardSvgRead, WebDXFeature::kClipboardSvg},
+          {WebFeature::kClipboardSvgWrite, WebDXFeature::kClipboardSvg},
           {WebFeature::kV8AbortController_Constructor, WebDXFeature::kAborting},
           {WebFeature::kV8AbortSignal_Abort_Method, WebDXFeature::kAborting},
           {WebFeature::kAbortSignalTimeout, WebDXFeature::kAborting},
diff --git a/components/performance_manager/BUILD.gn b/components/performance_manager/BUILD.gn
index ed6fa3b..481addb 100644
--- a/components/performance_manager/BUILD.gn
+++ b/components/performance_manager/BUILD.gn
@@ -178,8 +178,6 @@
     "public/performance_manager.h",
     "public/performance_manager_main_thread_mechanism.h",
     "public/performance_manager_main_thread_observer.h",
-    "public/performance_manager_owned.h",
-    "public/performance_manager_registered.h",
     "public/power/battery_level_provider_creator.h",
     "public/render_frame_host_proxy.h",
     "public/render_process_host_id.h",
diff --git a/components/performance_manager/graph/graph_registered_unittest.cc b/components/performance_manager/graph/graph_registered_unittest.cc
index 2cdc198..951a5aa8 100644
--- a/components/performance_manager/graph/graph_registered_unittest.cc
+++ b/components/performance_manager/graph/graph_registered_unittest.cc
@@ -172,57 +172,4 @@
   TearDownAndDestroyGraph();
 }
 
-namespace {
-
-// This class is non-sensically both a GraphRegistered object and a
-// PerformanceManagerRegistered object. This is done to ensure that the
-// implementations use the appropriately typed "TypeId" functions, as there are
-// now two of them available!
-class Baz : public GraphRegisteredImpl<Baz>,
-            public PerformanceManagerRegisteredImpl<Baz> {
- public:
-  Baz() = default;
-  ~Baz() override = default;
-};
-
-using GraphAndPerformanceManagerRegisteredTest = PerformanceManagerTestHarness;
-
-}  // namespace
-
-TEST_F(GraphAndPerformanceManagerRegisteredTest, GraphAndPMRegistered) {
-  // Each TypeId should be backed by a distinct "TypeId" implementation and
-  // value.
-  const uintptr_t kGraphId = GraphRegisteredImpl<Baz>::TypeId();
-  const uintptr_t kPMId = PerformanceManagerRegisteredImpl<Baz>::TypeId();
-  ASSERT_NE(kGraphId, kPMId);
-
-  // Create a stand-alone graph that is bound to this sequence so we can test
-  // both the PM and a graph on the same sequence.
-  std::unique_ptr<GraphImpl> graph(new GraphImpl());
-  graph->SetUp();
-
-  PerformanceManagerRegistryImpl* registry =
-      PerformanceManagerRegistryImpl::GetInstance();
-
-  Baz baz;
-  graph->RegisterObject(&baz);
-  registry->RegisterObject(&baz);
-
-  EXPECT_EQ(&baz, graph->GetRegisteredObject(kGraphId));
-  EXPECT_EQ(&baz, registry->GetRegisteredObject(kPMId));
-  EXPECT_EQ(nullptr, graph->GetRegisteredObject(kPMId));
-  EXPECT_EQ(nullptr, registry->GetRegisteredObject(kGraphId));
-
-  // This directly tests that the templated helper function uses the correct
-  // instance of TypeId.
-  EXPECT_EQ(&baz, graph->GetRegisteredObjectAs<Baz>());
-  EXPECT_EQ(&baz, PerformanceManager::GetRegisteredObjectAs<Baz>());
-
-  graph->UnregisterObject(&baz);
-  registry->UnregisterObject(&baz);
-
-  graph->TearDown();
-  graph.reset();
-}
-
-}  // namespace performance_manager
\ No newline at end of file
+}  // namespace performance_manager
diff --git a/components/performance_manager/performance_manager.cc b/components/performance_manager/performance_manager.cc
index 6581b6b..0e52fcf 100644
--- a/components/performance_manager/performance_manager.cc
+++ b/components/performance_manager/performance_manager.cc
@@ -16,7 +16,6 @@
 #include "components/performance_manager/performance_manager_impl.h"
 #include "components/performance_manager/performance_manager_registry_impl.h"
 #include "components/performance_manager/performance_manager_tab_helper.h"
-#include "components/performance_manager/public/performance_manager_owned.h"
 #include "components/performance_manager/resource_attribution/query_scheduler.h"
 #include "content/public/browser/browser_child_process_host.h"
 #include "content/public/browser/child_process_data.h"
@@ -195,40 +194,6 @@
 }
 
 // static
-void PerformanceManager::PassToPM(
-    std::unique_ptr<PerformanceManagerOwned> pm_owned) {
-  return PerformanceManagerRegistryImpl::GetInstance()->PassToPM(
-      std::move(pm_owned));
-}
-
-// static
-std::unique_ptr<PerformanceManagerOwned> PerformanceManager::TakeFromPM(
-    PerformanceManagerOwned* pm_owned) {
-  return PerformanceManagerRegistryImpl::GetInstance()->TakeFromPM(pm_owned);
-}
-
-// static
-void PerformanceManager::RegisterObject(
-    PerformanceManagerRegistered* pm_object) {
-  return PerformanceManagerRegistryImpl::GetInstance()->RegisterObject(
-      pm_object);
-}
-
-// static
-void PerformanceManager::UnregisterObject(
-    PerformanceManagerRegistered* pm_object) {
-  return PerformanceManagerRegistryImpl::GetInstance()->UnregisterObject(
-      pm_object);
-}
-
-// static
-PerformanceManagerRegistered* PerformanceManager::GetRegisteredObject(
-    uintptr_t type_id) {
-  return PerformanceManagerRegistryImpl::GetInstance()->GetRegisteredObject(
-      type_id);
-}
-
-// static
 scoped_refptr<base::SequencedTaskRunner> PerformanceManager::GetTaskRunner() {
   return PerformanceManagerImpl::GetTaskRunner();
 }
diff --git a/components/performance_manager/performance_manager_registry_impl.cc b/components/performance_manager/performance_manager_registry_impl.cc
index 3fcb910..c55ff85 100644
--- a/components/performance_manager/performance_manager_registry_impl.cc
+++ b/components/performance_manager/performance_manager_registry_impl.cc
@@ -16,7 +16,6 @@
 #include "components/performance_manager/public/performance_manager.h"
 #include "components/performance_manager/public/performance_manager_main_thread_mechanism.h"
 #include "components/performance_manager/public/performance_manager_main_thread_observer.h"
-#include "components/performance_manager/public/performance_manager_owned.h"
 #include "components/performance_manager/render_process_user_data.h"
 #include "components/performance_manager/service_worker_context_adapter.h"
 #include "components/performance_manager/worker_watcher.h"
@@ -51,8 +50,6 @@
   DCHECK(!g_instance);
   DCHECK(web_contents_.empty());
   DCHECK(render_process_hosts_.empty());
-  DCHECK(pm_owned_.empty());
-  DCHECK(pm_registered_.empty());
   // TODO(crbug.com/40131811): |observers_| and |mechanisms_| should also be
   // empty by now!
 }
@@ -92,36 +89,6 @@
   return mechanisms_.HasObserver(mechanism);
 }
 
-void PerformanceManagerRegistryImpl::PassToPM(
-    std::unique_ptr<PerformanceManagerOwned> pm_owned) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  pm_owned_.PassObject(std::move(pm_owned));
-}
-
-std::unique_ptr<PerformanceManagerOwned>
-PerformanceManagerRegistryImpl::TakeFromPM(PerformanceManagerOwned* pm_owned) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return pm_owned_.TakeObject(pm_owned);
-}
-
-void PerformanceManagerRegistryImpl::RegisterObject(
-    PerformanceManagerRegistered* pm_object) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  pm_registered_.RegisterObject(pm_object);
-}
-
-void PerformanceManagerRegistryImpl::UnregisterObject(
-    PerformanceManagerRegistered* pm_object) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  pm_registered_.UnregisterObject(pm_object);
-}
-
-PerformanceManagerRegistered*
-PerformanceManagerRegistryImpl::GetRegisteredObject(uintptr_t type_id) {
-  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  return pm_registered_.GetRegisteredObject(type_id);
-}
-
 Binders& PerformanceManagerRegistryImpl::GetBinders() {
   return binders_;
 }
@@ -276,12 +243,6 @@
   // Release the browser and utility process nodes.
   browser_child_process_watcher_.TearDown();
 
-  // Tear down PM owned objects. This lets them clear up object registrations,
-  // observers, mechanisms, etc.
-  pm_owned_.ReleaseObjects();
-
-  DCHECK(pm_owned_.empty());
-  DCHECK(pm_registered_.empty());
   // TODO(crbug.com/40131811): |observers_| and |mechanisms_| should also be
   // empty by now!
 }
diff --git a/components/performance_manager/performance_manager_registry_impl.h b/components/performance_manager/performance_manager_registry_impl.h
index 3ffab7f..a4a5d82 100644
--- a/components/performance_manager/performance_manager_registry_impl.h
+++ b/components/performance_manager/performance_manager_registry_impl.h
@@ -15,13 +15,9 @@
 #include "components/performance_manager/browser_child_process_watcher.h"
 #include "components/performance_manager/embedder/binders.h"
 #include "components/performance_manager/embedder/performance_manager_registry.h"
-#include "components/performance_manager/owned_objects.h"
 #include "components/performance_manager/performance_manager_tab_helper.h"
 #include "components/performance_manager/process_node_source.h"
 #include "components/performance_manager/public/browser_child_process_host_id.h"
-#include "components/performance_manager/public/performance_manager_owned.h"
-#include "components/performance_manager/public/performance_manager_registered.h"
-#include "components/performance_manager/registered_objects.h"
 #include "components/performance_manager/render_process_user_data.h"
 #include "components/performance_manager/tab_helper_frame_node_source.h"
 #include "content/public/browser/render_process_host_creation_observer.h"
@@ -69,18 +65,6 @@
   void RemoveMechanism(PerformanceManagerMainThreadMechanism* mechanism);
   bool HasMechanism(PerformanceManagerMainThreadMechanism* mechanism);
 
-  // PM owned objects. Forwarded to from the public PerformanceManager
-  // interface. See performance_manager.h for details.
-  void PassToPM(std::unique_ptr<PerformanceManagerOwned> pm_owned);
-  std::unique_ptr<PerformanceManagerOwned> TakeFromPM(
-      PerformanceManagerOwned* pm_owned);
-
-  // PM registered objects. Forwarded to from the public PerformanceManager
-  // interface. See performance_manager.h for details.
-  void RegisterObject(PerformanceManagerRegistered* pm_object);
-  void UnregisterObject(PerformanceManagerRegistered* object);
-  PerformanceManagerRegistered* GetRegisteredObject(uintptr_t type_id);
-
   // PerformanceManagerRegistry:
   Binders& GetBinders() override;
   void CreatePageNodeForWebContents(
@@ -123,16 +107,6 @@
   // on the UI thread.
   WorkerNodeImpl* FindWorkerNodeForToken(const blink::WorkerToken& token);
 
-  size_t GetOwnedCountForTesting() const {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    return pm_owned_.size();
-  }
-
-  size_t GetRegisteredCountForTesting() const {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-    return pm_registered_.size();
-  }
-
   // Returns the WorkerWatcher for `browser_context`, or nullptr if there is
   // none. Tests can call methods on the WorkerWatcher to simulate workers.
   WorkerWatcher* GetWorkerWatcherForTesting(
@@ -184,17 +158,6 @@
       GUARDED_BY_CONTEXT(sequence_checker_);
   base::ObserverList<PerformanceManagerMainThreadMechanism> mechanisms_
       GUARDED_BY_CONTEXT(sequence_checker_);
-
-  // Objects owned by the PM.
-  OwnedObjects<PerformanceManagerOwned,
-               /* CallbackArgType = */ void,
-               &PerformanceManagerOwned::OnPassedToPM,
-               &PerformanceManagerOwned::OnTakenFromPM>
-      pm_owned_ GUARDED_BY_CONTEXT(sequence_checker_);
-
-  // Storage for PerformanceManagerRegistered objects.
-  RegisteredObjects<PerformanceManagerRegistered> pm_registered_
-      GUARDED_BY_CONTEXT(sequence_checker_);
 };
 
 }  // namespace performance_manager
diff --git a/components/performance_manager/performance_manager_registry_impl_unittest.cc b/components/performance_manager/performance_manager_registry_impl_unittest.cc
index 0c9b39be..ec261c0 100644
--- a/components/performance_manager/performance_manager_registry_impl_unittest.cc
+++ b/components/performance_manager/performance_manager_registry_impl_unittest.cc
@@ -9,8 +9,6 @@
 #include "components/performance_manager/graph/process_node_impl.h"
 #include "components/performance_manager/public/performance_manager_main_thread_mechanism.h"
 #include "components/performance_manager/public/performance_manager_main_thread_observer.h"
-#include "components/performance_manager/public/performance_manager_owned.h"
-#include "components/performance_manager/public/performance_manager_registered.h"
 #include "components/performance_manager/test_support/performance_manager_test_harness.h"
 #include "components/performance_manager/test_support/run_in_graph.h"
 #include "components/performance_manager/test_support/test_browser_child_process.h"
@@ -139,121 +137,6 @@
   registry->RemoveMechanism(&mechanism2);
 }
 
-namespace {
-
-class LenientOwned : public PerformanceManagerOwned {
- public:
-  LenientOwned() = default;
-  ~LenientOwned() override { OnDestructor(); }
-
-  LenientOwned(const LenientOwned&) = delete;
-  LenientOwned& operator=(const LenientOwned) = delete;
-
-  // PerformanceManagerOwned implementation:
-  MOCK_METHOD(void, OnPassedToPM, (), (override));
-  MOCK_METHOD(void, OnTakenFromPM, (), (override));
-  MOCK_METHOD(void, OnDestructor, ());
-};
-
-using Owned = testing::StrictMock<LenientOwned>;
-
-}  // namespace
-
-TEST_F(PerformanceManagerRegistryImplTest, PerformanceManagerOwned) {
-  PerformanceManagerRegistryImpl* registry =
-      PerformanceManagerRegistryImpl::GetInstance();
-
-  std::unique_ptr<Owned> owned1 = std::make_unique<Owned>();
-  std::unique_ptr<Owned> owned2 = std::make_unique<Owned>();
-  auto* raw1 = owned1.get();
-  auto* raw2 = owned2.get();
-
-  // Pass both objects to the PM.
-  EXPECT_EQ(0u, registry->GetOwnedCountForTesting());
-  EXPECT_CALL(*raw1, OnPassedToPM());
-  PerformanceManager::PassToPM(std::move(owned1));
-  EXPECT_EQ(1u, registry->GetOwnedCountForTesting());
-  EXPECT_CALL(*raw2, OnPassedToPM());
-  PerformanceManager::PassToPM(std::move(owned2));
-  EXPECT_EQ(2u, registry->GetOwnedCountForTesting());
-
-  // Take one back.
-  EXPECT_CALL(*raw1, OnTakenFromPM());
-  owned1 = PerformanceManager::TakeFromPMAs<Owned>(raw1);
-  EXPECT_EQ(1u, registry->GetOwnedCountForTesting());
-
-  // Destroy that object and expect its destructor to have been invoked.
-  EXPECT_CALL(*raw1, OnDestructor());
-  owned1.reset();
-  raw1 = nullptr;
-
-  // Tear down the PM and expect the other object to die with it.
-  EXPECT_CALL(*raw2, OnTakenFromPM());
-  EXPECT_CALL(*raw2, OnDestructor());
-  TearDownNow();
-}
-
-namespace {
-
-class Foo : public PerformanceManagerRegisteredImpl<Foo> {
- public:
-  Foo() = default;
-  ~Foo() override = default;
-};
-
-class Bar : public PerformanceManagerRegisteredImpl<Bar> {
- public:
-  Bar() = default;
-  ~Bar() override = default;
-};
-
-}  // namespace
-
-TEST_F(PerformanceManagerRegistryImplTest, RegistrationWorks) {
-  // The bulk of the tests for the registry are done in the RegisteredObjects
-  // templated base class. This simply checks the additional functionality
-  // endowed by the PM wrapper.
-
-  PerformanceManagerRegistryImpl* registry =
-      PerformanceManagerRegistryImpl::GetInstance();
-
-  // This ensures that the templated distinct TypeId generation works.
-  ASSERT_NE(Foo::TypeId(), Bar::TypeId());
-
-  EXPECT_EQ(0u, registry->GetRegisteredCountForTesting());
-  EXPECT_FALSE(PerformanceManager::GetRegisteredObjectAs<Foo>());
-  EXPECT_FALSE(PerformanceManager::GetRegisteredObjectAs<Bar>());
-
-  // Insertion works.
-  Foo foo;
-  Bar bar;
-  PerformanceManager::RegisterObject(&foo);
-  EXPECT_EQ(1u, registry->GetRegisteredCountForTesting());
-  PerformanceManager::RegisterObject(&bar);
-  EXPECT_EQ(2u, registry->GetRegisteredCountForTesting());
-  EXPECT_EQ(&foo, PerformanceManager::GetRegisteredObjectAs<Foo>());
-  EXPECT_EQ(&bar, PerformanceManager::GetRegisteredObjectAs<Bar>());
-
-  // Check the various helper functions.
-  EXPECT_EQ(&foo, Foo::GetFromPM());
-  EXPECT_EQ(&bar, Bar::GetFromPM());
-  EXPECT_TRUE(foo.IsRegisteredInPM());
-  EXPECT_TRUE(bar.IsRegisteredInPM());
-  EXPECT_FALSE(Foo::NothingRegisteredInPM());
-  EXPECT_FALSE(Bar::NothingRegisteredInPM());
-  PerformanceManager::UnregisterObject(&bar);
-  EXPECT_EQ(1u, registry->GetRegisteredCountForTesting());
-  EXPECT_EQ(&foo, Foo::GetFromPM());
-  EXPECT_FALSE(Bar::GetFromPM());
-  EXPECT_TRUE(foo.IsRegisteredInPM());
-  EXPECT_FALSE(bar.IsRegisteredInPM());
-  EXPECT_FALSE(Foo::NothingRegisteredInPM());
-  EXPECT_TRUE(Bar::NothingRegisteredInPM());
-
-  PerformanceManager::UnregisterObject(&foo);
-  EXPECT_EQ(0u, registry->GetRegisteredCountForTesting());
-}
-
 // Tests that accessors for browser and utility ProcessNodes work. Renderer
 // ProcessNodes are handled by RenderProcessUserData.
 
diff --git a/components/performance_manager/public/performance_manager.h b/components/performance_manager/public/performance_manager.h
index 74d00d9..89c0cb2 100644
--- a/components/performance_manager/public/performance_manager.h
+++ b/components/performance_manager/public/performance_manager.h
@@ -32,13 +32,8 @@
 class ProcessNode;
 class PerformanceManagerMainThreadMechanism;
 class PerformanceManagerMainThreadObserver;
-class PerformanceManagerOwned;
-class PerformanceManagerRegistered;
 class WorkerNode;
 
-template <typename DerivedType>
-class PerformanceManagerRegisteredImpl;
-
 // The performance manager is a rendezvous point for communicating with the
 // performance manager graph on its dedicated sequence.
 class PerformanceManager {
@@ -154,48 +149,6 @@
   static void RemoveMechanism(PerformanceManagerMainThreadMechanism* mechanism);
   static bool HasMechanism(PerformanceManagerMainThreadMechanism* mechanism);
 
-  // For convenience, allows you to pass ownership of an object that lives on
-  // the main thread to the performance manager. Useful for attaching observers
-  // or mechanisms that will live with the PM until it dies. If you can name the
-  // object you can also take it back via "TakeFromPM". The objects will be
-  // torn down gracefully (and their "OnTakenFromPM" functions invoked) as the
-  // PM itself is torn down.
-  static void PassToPM(std::unique_ptr<PerformanceManagerOwned> pm_owned);
-  static std::unique_ptr<PerformanceManagerOwned> TakeFromPM(
-      PerformanceManagerOwned* pm_owned);
-
-  // A TakeFromPM helper for taking back the ownership of a
-  // PerformanceManagerOwned object via its DerivedType.
-  template <typename DerivedType>
-  static std::unique_ptr<DerivedType> TakeFromPMAs(DerivedType* pm_owned) {
-    return base::WrapUnique(
-        static_cast<DerivedType*>(TakeFromPM(pm_owned).release()));
-  }
-
-  // Registers an object with the PM. It is expected that no more than one
-  // object of a given type is registered at a given moment, and that all
-  // registered objects are unregistered before PM tear-down. This allows the
-  // PM to act as a rendez-vous point for objects that live on the main thread.
-  // Combined with PerformanceManagerOwned this offers an alternative to
-  // using singletons, and brings clear ownerships and lifetime semantics.
-  static void RegisterObject(PerformanceManagerRegistered* pm_object);
-
-  // Unregisters the provided |object|, which must previously have been
-  // registered with "RegisterObject". It is expected that all registered
-  // objects are unregistered before graph tear-down.
-  static void UnregisterObject(PerformanceManagerRegistered* object);
-
-  // Returns the registered object of the given type, nullptr if none has been
-  // registered.
-  template <typename DerivedType>
-  static DerivedType* GetRegisteredObjectAs() {
-    // Be sure to access the TypeId provided by PerformanceManagerRegisteredImpl
-    // in case this class has other TypeId implementations.
-    PerformanceManagerRegistered* object = GetRegisteredObject(
-        PerformanceManagerRegisteredImpl<DerivedType>::TypeId());
-    return static_cast<DerivedType*>(object);
-  }
-
   // Returns the performance manager graph task runner. This is safe to call
   // from any thread at any time between the creation of the thread pool and its
   // destruction.
@@ -212,10 +165,6 @@
 
  protected:
   PerformanceManager();
-
-  // Retrieves the object with the given |type_id|, returning nullptr if none
-  // exists. Clients must use the GetRegisteredObjectAs wrapper instead.
-  static PerformanceManagerRegistered* GetRegisteredObject(uintptr_t type_id);
 };
 
 }  // namespace performance_manager
diff --git a/components/performance_manager/public/performance_manager_owned.h b/components/performance_manager/public/performance_manager_owned.h
deleted file mode 100644
index 5a76bd2..0000000
--- a/components/performance_manager/public/performance_manager_owned.h
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_OWNED_H_
-#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_OWNED_H_
-
-namespace performance_manager {
-
-// Helper class for passing ownership of objects to the PerformanceManager.
-// The object is expected to live on the main thread.
-class PerformanceManagerOwned {
- public:
-  virtual ~PerformanceManagerOwned() = default;
-
-  PerformanceManagerOwned(const PerformanceManagerOwned&) = delete;
-  PerformanceManagerOwned& operator=(const PerformanceManagerOwned&) = delete;
-
-  // Called when the object is passed into the PerformanceManager.
-  virtual void OnPassedToPM() = 0;
-
-  // Called when the object is removed from the PerformanceManager, either via
-  // an explicit call to TakeFromPM, or prior to the PerformanceManager being
-  // destroyed.
-  virtual void OnTakenFromPM() = 0;
-
- protected:
-  PerformanceManagerOwned() = default;
-};
-
-// A default implementation of PerformanceManagerOwned.
-class PerformanceManagerOwnedDefaultImpl : public PerformanceManagerOwned {
- public:
-  ~PerformanceManagerOwnedDefaultImpl() override = default;
-
-  PerformanceManagerOwnedDefaultImpl(
-      const PerformanceManagerOwnedDefaultImpl&) = delete;
-  PerformanceManagerOwnedDefaultImpl& operator=(
-      const PerformanceManagerOwnedDefaultImpl*) = delete;
-
-  // PerformanceManagerOwned implementation:
-  void OnPassedToPM() override {}
-  void OnTakenFromPM() override {}
-
- protected:
-  PerformanceManagerOwnedDefaultImpl() = default;
-};
-
-}  // namespace performance_manager
-
-#endif  // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_OWNED_H_
diff --git a/components/performance_manager/public/performance_manager_registered.h b/components/performance_manager/public/performance_manager_registered.h
deleted file mode 100644
index 66d9d935..0000000
--- a/components/performance_manager/public/performance_manager_registered.h
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_REGISTERED_H_
-#define COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_REGISTERED_H_
-
-#include "components/performance_manager/public/performance_manager.h"
-
-namespace performance_manager {
-
-// This provides functionality that allows an instance of a PM-associated
-// object to be looked up by type, allowing the PM to act as a rendezvous
-// point for main thread objects. It enforces singleton semantics, so there may
-// be no more than one instance of an object of a given type registered with the
-// PM at the same time. All registration and unregistration must happen on the
-// main thread. It is illegal to register more than one object of the same class
-// at a time, and all registered objects must be unregistered prior to PM tear-
-// down.
-
-template <typename SelfType>
-class PerformanceManagerRegisteredImpl;
-
-// Interface that PerformanceManager registered objects must implement. Should
-// only be implemented via PerformanceManagerRegisteredImpl.
-class PerformanceManagerRegistered {
- public:
-  PerformanceManagerRegistered(const PerformanceManagerRegistered&) = delete;
-  PerformanceManagerRegistered& operator=(const PerformanceManagerRegistered&) =
-      delete;
-  virtual ~PerformanceManagerRegistered() = default;
-
-  // Returns the unique type of the object. Implemented by
-  // PerformanceManagerRegisteredImpl.
-  virtual uintptr_t GetTypeId() const = 0;
-
- protected:
-  template <typename SelfType>
-  friend class PerformanceManagerRegisteredImpl;
-
-  PerformanceManagerRegistered() = default;
-};
-
-// Fully implements PerformanceManagerRegistered. Clients should derive from
-// this class.
-template <typename SelfType>
-class PerformanceManagerRegisteredImpl : public PerformanceManagerRegistered {
- public:
-  PerformanceManagerRegisteredImpl() = default;
-  ~PerformanceManagerRegisteredImpl() override = default;
-
-  // The static TypeId associated with this class.
-  static uintptr_t TypeId() {
-    // The pointer to this object acts as a unique key that identifies the type
-    // at runtime. Note that the address of this should be taken only from a
-    // single library, as a different address will be returned from each library
-    // into which a given data type is linked. Note that if base/type_id ever
-    // becomes a thing, this should use that!
-    static constexpr int kTypeId = 0;
-    return reinterpret_cast<uintptr_t>(&kTypeId);
-  }
-
-  // PerformanceManagerRegistered implementation:
-  uintptr_t GetTypeId() const override { return TypeId(); }
-
-  // Helper function for looking up the registered object of this type from the
-  // PM. Syntactic sugar for "PerformanceManager::GetRegisteredObjectAs".
-  static SelfType* GetFromPM() {
-    return PerformanceManager::GetRegisteredObjectAs<SelfType>();
-  }
-
-  // Returns true if this object is the registered object in the PM, false
-  // otherwise. Useful for DCHECKing contract conditions.
-  bool IsRegisteredInPM() const { return GetFromPM() == this; }
-
-  // Returns true if no object of this type is registered in the PM, false
-  // otherwise. Useful for DCHECKing contract conditions.
-  static bool NothingRegisteredInPM() { return GetFromPM() == nullptr; }
-};
-
-}  // namespace performance_manager
-
-#endif  // COMPONENTS_PERFORMANCE_MANAGER_PUBLIC_PERFORMANCE_MANAGER_REGISTERED_H_
\ No newline at end of file
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/LacrosSelection.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/LacrosSelection.yaml
index c1318d3..e1b8a957 100644
--- a/components/policy/resources/templates/policy_definitions/Miscellaneous/LacrosSelection.yaml
+++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/LacrosSelection.yaml
@@ -50,6 +50,7 @@
   - rootfs
   type: string
 supported_on:
-- chrome_os:112-
+- chrome_os:112-130
 tags: []
 type: string-enum
+deprecated: true
diff --git a/components/policy/test/data/pref_mapping/LacrosSelection.json b/components/policy/test/data/pref_mapping/LacrosSelection.json
deleted file mode 100644
index fb03859d..0000000
--- a/components/policy/test/data/pref_mapping/LacrosSelection.json
+++ /dev/null
@@ -1,41 +0,0 @@
-[
-  {
-    "can_be_recommended": false,
-    "os": [
-      "chromeos_ash"
-    ],
-    "policy_pref_mapping_tests": [
-      {
-        "policies": {},
-        "prefs": {
-          "lacros_selection": {
-            "location": "local_state",
-            "value": 1
-          }
-        }
-      },
-      {
-        "policies": {
-          "LacrosSelection": "user_choice"
-        },
-        "prefs": {
-          "lacros_selection": {
-            "location": "local_state",
-            "value": 0
-          }
-        }
-      },
-      {
-        "policies": {
-          "LacrosSelection": "rootfs"
-        },
-        "prefs": {
-          "lacros_selection": {
-            "location": "local_state",
-            "value": 1
-          }
-        }
-      }
-    ]
-  }
-]
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc
index 4851820..e9ca75d4 100644
--- a/components/search_engines/template_url_service.cc
+++ b/components/search_engines/template_url_service.cc
@@ -2397,11 +2397,6 @@
   return unscoped_mode_extension_ids_;
 }
 
-bool TemplateURLService::IsUnscopedModeExtensionId(
-    const std::string& extension_id) {
-  return unscoped_mode_extension_ids_.contains(extension_id);
-}
-
 void TemplateURLService::UpdateTemplateURLVisitTime(TemplateURL* url) {
   TemplateURLData data(url->data());
   data.last_visited = clock_->Now();
diff --git a/components/search_engines/template_url_service.h b/components/search_engines/template_url_service.h
index e0e4341e..d141704 100644
--- a/components/search_engines/template_url_service.h
+++ b/components/search_engines/template_url_service.h
@@ -300,9 +300,6 @@
   // It's OK to return a copy since we expect this set to be very small.
   std::set<std::string> GetUnscopedModeExtensionIds() const;
 
-  // Returns whether `unscoped_mode_extension_ids_` contains `extension_id`.
-  bool IsUnscopedModeExtensionId(const std::string& extension_id);
-
   // Returns the set of URLs describing the keywords. The elements are owned
   // by TemplateURLService and should not be deleted.
   TemplateURLVector GetTemplateURLs();
diff --git a/content/app/BUILD.gn b/content/app/BUILD.gn
index 464e72b..1e4b691 100644
--- a/content/app/BUILD.gn
+++ b/content/app/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//build/config/chrome_build.gni")
-import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/features.gni")
 import("//ppapi/buildflags/buildflags.gni")
 import("//third_party/tflite/features.gni")
@@ -90,12 +89,6 @@
            "//third_party/tflite:buildflags",
            "//tools/v8_context_snapshot:buildflags",
          ]
-  if (is_chromeos_lacros) {
-    deps += [
-      "//chromeos/startup",
-      "//chromeos/startup:constants",
-    ]
-  }
   if (build_tflite_with_xnnpack) {
     deps += [ "//third_party/cpuinfo" ]
   }
diff --git a/content/app/content_main.cc b/content/app/content_main.cc
index 919bd47f..6cb1ea6 100644
--- a/content/app/content_main.cc
+++ b/content/app/content_main.cc
@@ -34,7 +34,6 @@
 #include "base/trace_event/trace_config.h"
 #include "base/trace_event/trace_log.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "components/tracing/common/trace_to_console.h"
 #include "components/tracing/common/tracing_switches.h"
 #include "content/app/content_main_runner_impl.h"
@@ -200,11 +199,6 @@
     ContentMainParams params,
     ContentMainRunner* content_main_runner) {
   base::FeatureList::FailOnFeatureAccessWithoutFeatureList();
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  // Lacros is launched with inherited priority. Revert to normal priority
-  // before spawning more processes.
-  base::PlatformThread::SetCurrentThreadType(base::ThreadType::kDefault);
-#endif
   int exit_code = -1;
 #if BUILDFLAG(IS_MAC)
   base::apple::ScopedNSAutoreleasePool autorelease_pool;
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index 09d35ecd..8c20f5066 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -55,7 +55,6 @@
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "components/discardable_memory/service/discardable_shared_memory_manager.h"
 #include "components/download/public/common/download_task_runner.h"
 #include "components/power_monitor/make_power_monitor_device_source.h"
@@ -162,11 +161,6 @@
 #include "third_party/boringssl/src/include/openssl/crypto.h"
 #include "third_party/webrtc_overrides/init_webrtc.h"  // nogncheck
 
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "chromeos/startup/browser_init_params.h"
-#include "chromeos/startup/startup_switches.h"
-#endif
-
 #if BUILDFLAG(ENABLE_PPAPI)
 #include "content/common/pepper_plugin_list.h"
 #include "content/public/common/content_plugin_info.h"
@@ -340,10 +334,6 @@
       switches::kRegisterPepperPlugins,
       switches::kV,
       switches::kVModule,
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-      switches::kCrosWidevineBundledDir,
-      switches::kCrosWidevineComponentUpdatedHintFile,
-#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
   };
   cmd_line->CopySwitchesFrom(*base::CommandLine::ForCurrentProcess(),
                              kForwardSwitches);
@@ -357,11 +347,6 @@
   additional_remapped_fds->Share(
       GetSandboxFD(), SandboxHostLinux::GetInstance()->GetChildSocket());
 
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  GetContentClient()->browser()->GetAdditionalMappedFilesForZygote(
-      cmd_line, additional_remapped_fds.get());
-#endif
-
   return ZygoteHostImpl::GetInstance()->LaunchZygote(
       cmd_line, control_fd, additional_remapped_fds->GetMapping());
 }
@@ -535,13 +520,12 @@
 
 bool ShouldAllowSystemTracingConsumer() {
 // System tracing consumer support is currently only supported on ChromeOS.
-// TODO(crbug.com/40167100): Also enable for Lacros-Chrome.
 #if BUILDFLAG(IS_CHROMEOS)
   // The consumer should only be enabled when the delegate allows it.
   return GetContentClient()->browser()->IsSystemWideTracingEnabled();
-#else   // BUILDFLAG(IS_CHROMEOS_ASH)
+#else
   return false;
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
+#endif  // BUILDFLAG(IS_CHROMEOS)
 }
 
 void CreateChildThreadPool(const std::string& process_type) {
diff --git a/content/app/initialize_mojo_core.cc b/content/app/initialize_mojo_core.cc
index 2473048c..1691abe 100644
--- a/content/app/initialize_mojo_core.cc
+++ b/content/app/initialize_mojo_core.cc
@@ -35,17 +35,10 @@
   const auto& command_line = *base::CommandLine::ForCurrentProcess();
   const bool is_browser = !command_line.HasSwitch(switches::kProcessType);
   if (is_browser) {
-    // On Lacros, Chrome is not always the broker, because ash-chrome is.
-    // Otherwise, look at the command line flag to decide whether it is
-    // a broker.
+    // Look at the command line flag to decide whether it is a broker.
     config.is_broker_process =
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-        false
-#else
         !command_line.HasSwitch(switches::kDisableMojoBroker) &&
-        !mojo::PlatformChannel::CommandLineHasPassedEndpoint(command_line)
-#endif
-        ;
+        !mojo::PlatformChannel::CommandLineHasPassedEndpoint(command_line);
     if (!config.is_broker_process)
       config.force_direct_shared_memory_allocation = true;
   } else {
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn
index 184507a..16a57714 100644
--- a/content/browser/BUILD.gn
+++ b/content/browser/BUILD.gn
@@ -791,8 +791,8 @@
     "cookie_deprecation_label/cookie_deprecation_label_manager_impl.h",
     "cookie_insight_list/cookie_insight_list.cc",
     "cookie_insight_list/cookie_insight_list.h",
-    "cookie_insight_list/cookie_insight_list_handler.cc",
-    "cookie_insight_list/cookie_insight_list_handler.h",
+    "cookie_insight_list/cookie_insight_list_handler_impl.cc",
+    "cookie_insight_list/cookie_insight_list_handler_impl.h",
     "cookie_insight_list/cookie_readiness_list/cookie_readiness_list_parser.cc",
     "cookie_insight_list/cookie_readiness_list/cookie_readiness_list_parser.h",
     "cookie_store/cookie_change_subscription.cc",
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
index a93b608..3e17f2d 100644
--- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
+++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -3321,10 +3321,6 @@
   RunHtmlTest(FILE_PATH_LITERAL("option-in-datalist.html"));
 }
 
-IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityOptionLabel) {
-  RunAriaTest(FILE_PATH_LITERAL("option-label.html"));
-}
-
 IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityOutput) {
   RunHtmlTest(FILE_PATH_LITERAL("output.html"));
 }
diff --git a/content/browser/browsing_data/browsing_data_remover_impl.cc b/content/browser/browsing_data/browsing_data_remover_impl.cc
index 53402fa..793faa0 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl.cc
+++ b/content/browser/browsing_data/browsing_data_remover_impl.cc
@@ -496,6 +496,10 @@
     storage_partition_remove_mask |=
         StoragePartition::REMOVE_DATA_MASK_SHARED_STORAGE;
   }
+  if (remove_mask & DATA_TYPE_DEVICE_BOUND_SESSIONS) {
+    storage_partition_remove_mask |=
+        StoragePartition::REMOVE_DATA_MASK_DEVICE_BOUND_SESSIONS;
+  }
 
   if (storage_partition_remove_mask) {
     // If cookies are supposed to be conditionally deleted from the storage
diff --git a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
index 9da038f..7061e2a 100644
--- a/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
+++ b/content/browser/browsing_data/browsing_data_remover_impl_unittest.cc
@@ -1428,6 +1428,15 @@
             StoragePartition::REMOVE_DATA_MASK_PRIVATE_AGGREGATION_INTERNAL);
 }
 
+TEST_F(BrowsingDataRemoverImplTest, RemoveDeviceBoundSessions) {
+  BlockUntilBrowsingDataRemoved(
+      base::Time(), base::Time::Max(),
+      BrowsingDataRemover::DATA_TYPE_DEVICE_BOUND_SESSIONS, false);
+  StoragePartitionRemovalData removal_data = GetStoragePartitionRemovalData();
+  EXPECT_EQ(removal_data.remove_mask,
+            StoragePartition::REMOVE_DATA_MASK_DEVICE_BOUND_SESSIONS);
+}
+
 class MultipleTasksObserver {
  public:
   // A simple implementation of BrowsingDataRemover::Observer.
diff --git a/content/browser/browsing_data/clear_site_data_handler_browsertest.cc b/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
index fc3ecef..8bfb32c 100644
--- a/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
+++ b/content/browser/browsing_data/clear_site_data_handler_browsertest.cc
@@ -133,7 +133,8 @@
     if (cookies) {
       uint64_t data_type_mask =
           BrowsingDataRemover::DATA_TYPE_COOKIES |
-          BrowsingDataRemover::DATA_TYPE_AVOID_CLOSING_CONNECTIONS;
+          BrowsingDataRemover::DATA_TYPE_AVOID_CLOSING_CONNECTIONS |
+          BrowsingDataRemover::DATA_TYPE_DEVICE_BOUND_SESSIONS;
       net::CookiePartitionKey::AncestorChainBit ancestor_chain_bit =
           net::CookiePartitionKey::BoolToAncestorChainBit(
               partition_key_cross_site);
@@ -152,7 +153,8 @@
     if (storage || cache) {
       uint64_t data_type_mask =
           (storage ? BrowsingDataRemover::DATA_TYPE_DOM_STORAGE |
-                         BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX
+                         BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX |
+                         BrowsingDataRemover::DATA_TYPE_DEVICE_BOUND_SESSIONS
                    : 0) |
           (cache ? BrowsingDataRemover::DATA_TYPE_CACHE : 0);
       data_type_mask &=
diff --git a/content/browser/browsing_data/clear_site_data_utils.cc b/content/browser/browsing_data/clear_site_data_utils.cc
index 74a481ab..6c228c8 100644
--- a/content/browser/browsing_data/clear_site_data_utils.cc
+++ b/content/browser/browsing_data/clear_site_data_utils.cc
@@ -99,7 +99,9 @@
       }
 
       pending_task_count_++;
-      uint64_t remove_mask = BrowsingDataRemover::DATA_TYPE_COOKIES;
+      uint64_t remove_mask =
+          BrowsingDataRemover::DATA_TYPE_COOKIES |
+          BrowsingDataRemover::DATA_TYPE_DEVICE_BOUND_SESSIONS;
       if (avoid_closing_connections_) {
         remove_mask |= BrowsingDataRemover::DATA_TYPE_AVOID_CLOSING_CONNECTIONS;
       }
@@ -130,6 +132,7 @@
     if (clear_site_data_types_.Has(ClearSiteDataType::kStorage)) {
       remove_mask |= BrowsingDataRemover::DATA_TYPE_DOM_STORAGE;
       remove_mask |= BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX;
+      remove_mask |= BrowsingDataRemover::DATA_TYPE_DEVICE_BOUND_SESSIONS;
       // Internal data should not be removed by site-initiated deletions.
       remove_mask &= ~BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX_INTERNAL;
     }
diff --git a/content/browser/cookie_insight_list/cookie_insight_list.cc b/content/browser/cookie_insight_list/cookie_insight_list.cc
index 598c3561..3812fc1a 100644
--- a/content/browser/cookie_insight_list/cookie_insight_list.cc
+++ b/content/browser/cookie_insight_list/cookie_insight_list.cc
@@ -10,6 +10,7 @@
 #include <utility>
 
 #include "base/check.h"
+#include "content/public/browser/cookie_insight_list_data.h"
 
 namespace content {
 
@@ -28,9 +29,9 @@
 bool CookieInsightList::operator==(content::CookieInsightList const&) const =
     default;
 
-std::optional<CookieInsightList::CookieIssueInsight>
-CookieInsightList::GetInsight(std::string_view cookie_domain,
-                              const net::CookieInclusionStatus& status) const {
+std::optional<CookieIssueInsight> CookieInsightList::GetInsight(
+    std::string_view cookie_domain,
+    const net::CookieInclusionStatus& status) const {
   // If a cookie domain has an entry in the GitHub, we opt to use
   // kGitHubResource and populate entry_url. Otherwise, we check
   // if a cookie domain has a Heuristics or Grace Period exception
@@ -38,16 +39,14 @@
   if (it == readiness_list_map_.end()) {
     switch (status.exemption_reason()) {
       case net::CookieInclusionStatus::ExemptionReason::k3PCDMetadata:
-        return CookieIssueInsight{CookieInsightList::InsightType::kGracePeriod,
-                                  {}};
+        return CookieIssueInsight{InsightType::kGracePeriod, {}};
       case net::CookieInclusionStatus::ExemptionReason::k3PCDHeuristics:
-        return CookieIssueInsight{CookieInsightList::InsightType::kHeuristics,
-                                  {}};
+        return CookieIssueInsight{InsightType::kHeuristics, {}};
       default:
         return std::nullopt;
     }
   }
-  return CookieIssueInsight{CookieInsightList::InsightType::kGitHubResource,
+  return CookieIssueInsight{InsightType::kGitHubResource,
                             {it->second.entry_url}};
 }
 
diff --git a/content/browser/cookie_insight_list/cookie_insight_list.h b/content/browser/cookie_insight_list/cookie_insight_list.h
index 290b6f6..79d75d4 100644
--- a/content/browser/cookie_insight_list/cookie_insight_list.h
+++ b/content/browser/cookie_insight_list/cookie_insight_list.h
@@ -11,6 +11,7 @@
 
 #include "base/containers/flat_map.h"
 #include "content/common/content_export.h"
+#include "content/public/browser/cookie_insight_list_data.h"
 #include "net/cookies/cookie_inclusion_status.h"
 
 namespace content {
@@ -27,38 +28,6 @@
 
   bool operator==(content::CookieInsightList const&) const;
 
-  // Contains information about a domain's third-party cookie use status
-  // retrieved from the third-party cookie migration readiness list:
-  // https://github.com/privacysandbox/privacy-sandbox-dev-support/blob/main/3pc-migration-readiness.md
-  //
-  // Defined as a struct for ease of extensibility in the future.
-  struct DomainInfo {
-    // Link to table entry in third-party cookie migration readiness list
-    std::string entry_url;
-
-    bool operator==(const DomainInfo&) const = default;
-  };
-
-  enum class InsightType {
-    // Cookie domain has an entry in third-party cookie migration readiness
-    // list:
-    // https://github.com/privacysandbox/privacy-sandbox-dev-support/blob/main/3pc-migration-readiness.md
-    kGitHubResource,
-    // Cookie is exempted due to a grace period:
-    // https://developers.google.com/privacy-sandbox/cookies/temporary-exceptions/grace-period
-    kGracePeriod,
-    // Cookie is exempted due a heuristics-based exemptiuon:
-    // https://developers.google.com/privacy-sandbox/cookies/temporary-exceptions/heuristics-based-exception
-    kHeuristics
-  };
-  struct CookieIssueInsight {
-    InsightType type;
-    // Link to table entry in third-party cookie migration readiness list
-    DomainInfo domain_info;
-
-    bool operator==(const CookieIssueInsight&) const = default;
-  };
-
   // Maps cookie domains as strings to DomainInfo.
   using ReadinessListMap = base::flat_map<std::string, DomainInfo>;
 
diff --git a/content/browser/cookie_insight_list/cookie_insight_list_handler.h b/content/browser/cookie_insight_list/cookie_insight_list_handler.h
deleted file mode 100644
index 8bf40a5..0000000
--- a/content/browser/cookie_insight_list/cookie_insight_list_handler.h
+++ /dev/null
@@ -1,55 +0,0 @@
-// 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 CONTENT_BROWSER_COOKIE_INSIGHT_LIST_COOKIE_INSIGHT_LIST_HANDLER_H_
-#define CONTENT_BROWSER_COOKIE_INSIGHT_LIST_COOKIE_INSIGHT_LIST_HANDLER_H_
-
-#include <optional>
-
-#include "base/no_destructor.h"
-#include "base/sequence_checker.h"
-#include "content/browser/cookie_insight_list/cookie_insight_list.h"
-#include "content/common/content_export.h"
-#include "net/cookies/cookie_inclusion_status.h"
-
-namespace content {
-
-// Singleton class that stores a CookieInsightList, which can be queried to
-// provide third-party cookie migration insights about a cookie.
-class CONTENT_EXPORT CookieInsightListHandler final {
- public:
-  CookieInsightListHandler(const CookieInsightListHandler&) = delete;
-  CookieInsightListHandler& operator=(const CookieInsightListHandler&) = delete;
-  CookieInsightListHandler(const CookieInsightListHandler&&) = delete;
-  CookieInsightListHandler& operator=(const CookieInsightListHandler&&) =
-      delete;
-
-  ~CookieInsightListHandler();
-
-  static CookieInsightListHandler& GetInstance();  // Singleton
-
-  // Sets the handler's CookieInsightList.
-  void set_insight_list(std::string_view json_content);
-
-  // Returns a CookieIssueInsight based on the data in the handler's
-  // CookieInsightList.
-  //
-  // Returns nullopt if no CookieIssueInsight could be retrieved.
-  std::optional<CookieInsightList::CookieIssueInsight> GetInsight(
-      std::string_view cookie_domain,
-      const net::CookieInclusionStatus& status) const;
-
- private:
-  CookieInsightListHandler();
-
-  friend class base::NoDestructor<CookieInsightListHandler>;
-
-  SEQUENCE_CHECKER(sequence_checker_);
-
-  CookieInsightList insight_list_ GUARDED_BY_CONTEXT(sequence_checker_);
-};
-
-}  // namespace content
-
-#endif  // CONTENT_BROWSER_COOKIE_INSIGHT_LIST_COOKIE_INSIGHT_LIST_HANDLER_H_
diff --git a/content/browser/cookie_insight_list/cookie_insight_list_handler.cc b/content/browser/cookie_insight_list/cookie_insight_list_handler_impl.cc
similarity index 66%
rename from content/browser/cookie_insight_list/cookie_insight_list_handler.cc
rename to content/browser/cookie_insight_list/cookie_insight_list_handler_impl.cc
index 7fc7514..ce347ca4 100644
--- a/content/browser/cookie_insight_list/cookie_insight_list_handler.cc
+++ b/content/browser/cookie_insight_list/cookie_insight_list_handler_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 "content/browser/cookie_insight_list/cookie_insight_list_handler.h"
+#include "content/browser/cookie_insight_list/cookie_insight_list_handler_impl.h"
 
 #include <optional>
 #include <string_view>
@@ -10,27 +10,29 @@
 
 #include "content/browser/cookie_insight_list/cookie_insight_list.h"
 #include "content/browser/cookie_insight_list/cookie_readiness_list/cookie_readiness_list_parser.h"
+#include "content/public/browser/cookie_insight_list_data.h"
+#include "content/public/browser/cookie_insight_list_handler.h"
 
 namespace content {
 
-CookieInsightListHandler::CookieInsightListHandler() = default;
+CookieInsightListHandlerImpl::CookieInsightListHandlerImpl() = default;
 //  Since CookieInsightListHandler is a singleton,
 //  the destructor will never run.
-CookieInsightListHandler::~CookieInsightListHandler() = default;
+CookieInsightListHandlerImpl::~CookieInsightListHandlerImpl() = default;
 
 CookieInsightListHandler& CookieInsightListHandler::GetInstance() {
-  static base::NoDestructor<CookieInsightListHandler> instance;
+  static base::NoDestructor<CookieInsightListHandlerImpl> instance;
   return *instance.get();
 }
 
-void CookieInsightListHandler::set_insight_list(std::string_view json_content) {
+void CookieInsightListHandlerImpl::set_insight_list(
+    std::string_view json_content) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   insight_list_ =
       std::move(CookieReadinessListParser::ParseReadinessList(json_content));
 }
 
-std::optional<CookieInsightList::CookieIssueInsight>
-CookieInsightListHandler::GetInsight(
+std::optional<CookieIssueInsight> CookieInsightListHandlerImpl::GetInsight(
     std::string_view cookie_domain,
     const net::CookieInclusionStatus& status) const {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
diff --git a/content/browser/cookie_insight_list/cookie_insight_list_handler_impl.h b/content/browser/cookie_insight_list/cookie_insight_list_handler_impl.h
new file mode 100644
index 0000000..7b4ec44
--- /dev/null
+++ b/content/browser/cookie_insight_list/cookie_insight_list_handler_impl.h
@@ -0,0 +1,53 @@
+// 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 CONTENT_BROWSER_COOKIE_INSIGHT_LIST_COOKIE_INSIGHT_LIST_HANDLER_IMPL_H_
+#define CONTENT_BROWSER_COOKIE_INSIGHT_LIST_COOKIE_INSIGHT_LIST_HANDLER_IMPL_H_
+
+#include <optional>
+
+#include "base/no_destructor.h"
+#include "base/sequence_checker.h"
+#include "content/browser/cookie_insight_list/cookie_insight_list.h"
+#include "content/common/content_export.h"
+#include "content/public/browser/cookie_insight_list_data.h"
+#include "content/public/browser/cookie_insight_list_handler.h"
+#include "net/cookies/cookie_inclusion_status.h"
+
+namespace content {
+
+// Singleton class that stores a CookieInsightList, which can be queried to
+// provide third-party cookie migration insights about a cookie.
+class CONTENT_EXPORT CookieInsightListHandlerImpl
+    : public CookieInsightListHandler {
+ public:
+  CookieInsightListHandlerImpl(const CookieInsightListHandlerImpl&) = delete;
+  CookieInsightListHandlerImpl& operator=(const CookieInsightListHandlerImpl&) =
+      delete;
+  CookieInsightListHandlerImpl(const CookieInsightListHandlerImpl&&) = delete;
+  CookieInsightListHandlerImpl& operator=(
+      const CookieInsightListHandlerImpl&&) = delete;
+  ~CookieInsightListHandlerImpl() override;
+
+  static CookieInsightListHandlerImpl& GetInstance();
+
+  // CoookieInsightListHandler:
+  void set_insight_list(std::string_view json_content) override;
+  std::optional<CookieIssueInsight> GetInsight(
+      std::string_view cookie_domain,
+      const net::CookieInclusionStatus& status) const override;
+
+ private:
+  CookieInsightListHandlerImpl();
+
+  friend class base::NoDestructor<CookieInsightListHandlerImpl>;
+
+  SEQUENCE_CHECKER(sequence_checker_);
+
+  CookieInsightList insight_list_ GUARDED_BY_CONTEXT(sequence_checker_);
+};
+
+}  // namespace content
+
+#endif  // CONTENT_BROWSER_COOKIE_INSIGHT_LIST_COOKIE_INSIGHT_LIST_HANDLER_IMPL_H_
diff --git a/content/browser/cookie_insight_list/cookie_insight_list_handler_unittest.cc b/content/browser/cookie_insight_list/cookie_insight_list_handler_impl_unittest.cc
similarity index 64%
rename from content/browser/cookie_insight_list/cookie_insight_list_handler_unittest.cc
rename to content/browser/cookie_insight_list/cookie_insight_list_handler_impl_unittest.cc
index a467a72..506e9b9 100644
--- a/content/browser/cookie_insight_list/cookie_insight_list_handler_unittest.cc
+++ b/content/browser/cookie_insight_list/cookie_insight_list_handler_impl_unittest.cc
@@ -2,13 +2,13 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "content/browser/cookie_insight_list/cookie_insight_list_handler.h"
+#include "content/browser/cookie_insight_list/cookie_insight_list_handler_impl.h"
 
 #include <optional>
 #include <string>
 
-#include "content/browser/cookie_insight_list/cookie_insight_list.h"
-#include "net/cookies/cookie_inclusion_status.h"
+#include "content/public/browser/cookie_insight_list_data.h"
+#include "content/public/browser/cookie_insight_list_handler.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -16,16 +16,16 @@
 
 using testing::Optional;
 
-class CookieInsightListHandlerTest : public ::testing::Test {
+class CookieInsightListHandlerImplTest : public ::testing::Test {
  public:
-  CookieInsightListHandlerTest() = default;
+  CookieInsightListHandlerImplTest() = default;
 
   void SetUp() override {
     CookieInsightListHandler::GetInstance().set_insight_list("");
   }
 };
 
-TEST_F(CookieInsightListHandlerTest, GetInsight_GitHubResource_ListUpdate) {
+TEST_F(CookieInsightListHandlerImplTest, GetInsight_GitHubResource_ListUpdate) {
   const std::string json_content = R"({"entries": [
     {
       "domains": [
@@ -38,9 +38,8 @@
 
   EXPECT_THAT(
       CookieInsightListHandler::GetInstance().GetInsight("example.com", {}),
-      Optional(CookieInsightList::CookieIssueInsight{
-          CookieInsightList::InsightType::kGitHubResource,
-          CookieInsightList::DomainInfo{"url"}}));
+      Optional(
+          CookieIssueInsight{InsightType::kGitHubResource, DomainInfo{"url"}}));
 
   const std::string new_json_content = R"({"entries": [
     {
@@ -54,9 +53,8 @@
 
   EXPECT_THAT(
       CookieInsightListHandler::GetInstance().GetInsight("example.com", {}),
-      Optional(CookieInsightList::CookieIssueInsight{
-          CookieInsightList::InsightType::kGitHubResource,
-          CookieInsightList::DomainInfo{"newUrl"}}));
+      Optional(CookieIssueInsight{InsightType::kGitHubResource,
+                                  DomainInfo{"newUrl"}}));
 }
 
 }  // namespace content
diff --git a/content/browser/cookie_insight_list/cookie_insight_list_unittest.cc b/content/browser/cookie_insight_list/cookie_insight_list_unittest.cc
index 2d62186..714c64e 100644
--- a/content/browser/cookie_insight_list/cookie_insight_list_unittest.cc
+++ b/content/browser/cookie_insight_list/cookie_insight_list_unittest.cc
@@ -7,6 +7,7 @@
 #include <optional>
 #include <string>
 
+#include "content/public/browser/cookie_insight_list_data.h"
 #include "net/cookies/cookie_inclusion_status.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -21,14 +22,13 @@
 }
 
 TEST(CookieInsightListTest, GetInsight_GitHubResource) {
-  base::flat_map<std::string, CookieInsightList::DomainInfo> domain_map = {
+  base::flat_map<std::string, DomainInfo> domain_map = {
       {"example.com", {"url"}}};
 
   EXPECT_THAT(
       CookieInsightList(domain_map).GetInsight("example.com", /*status=*/{}),
-      Optional(CookieInsightList::CookieIssueInsight{
-          CookieInsightList::InsightType::kGitHubResource,
-          CookieInsightList::DomainInfo{"url"}}));
+      Optional(
+          CookieIssueInsight{InsightType::kGitHubResource, DomainInfo{"url"}}));
 }
 
 TEST(CookieInsightListTest, GetInsight_Heuristics) {
@@ -37,8 +37,7 @@
       net::CookieInclusionStatus::ExemptionReason::k3PCDHeuristics);
 
   EXPECT_THAT(CookieInsightList().GetInsight("unknown", status),
-              Optional(CookieInsightList::CookieIssueInsight{
-                  CookieInsightList::InsightType::kHeuristics, {}}));
+              Optional(CookieIssueInsight{InsightType::kHeuristics, {}}));
 }
 
 TEST(CookieInsightListTest, GetInsight_GracePeriod) {
@@ -47,8 +46,7 @@
       net::CookieInclusionStatus::ExemptionReason::k3PCDMetadata);
 
   EXPECT_THAT(CookieInsightList().GetInsight("unknown", status),
-              Optional(CookieInsightList::CookieIssueInsight{
-                  CookieInsightList::InsightType::kGracePeriod, {}}));
+              Optional(CookieIssueInsight{InsightType::kGracePeriod, {}}));
 }
 
 }  // namespace content
diff --git a/content/browser/cookie_insight_list/cookie_readiness_list/cookie_readiness_list_parser.cc b/content/browser/cookie_insight_list/cookie_readiness_list/cookie_readiness_list_parser.cc
index 94a59d9..df9f272 100644
--- a/content/browser/cookie_insight_list/cookie_readiness_list/cookie_readiness_list_parser.cc
+++ b/content/browser/cookie_insight_list/cookie_readiness_list/cookie_readiness_list_parser.cc
@@ -13,7 +13,7 @@
 
 #include "base/json/json_reader.h"
 #include "base/values.h"
-#include "content/browser/cookie_insight_list/cookie_insight_list.h"
+#include "content/public/browser/cookie_insight_list_data.h"
 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
 #include "url/gurl.h"
 
@@ -27,8 +27,8 @@
 // Creates a map of cookie domains to DomainInfo.
 //
 // Returns an empty map if any entry is misconfigured.
-base::flat_map<std::string, CookieInsightList::DomainInfo>
-GenerateReadinessListMap(std::string_view json_content) {
+base::flat_map<std::string, DomainInfo> GenerateReadinessListMap(
+    std::string_view json_content) {
   std::optional<base::Value> json =
       base::JSONReader::Read(json_content, base::JSON_ALLOW_TRAILING_COMMAS);
   if (!json.has_value()) {
@@ -51,8 +51,7 @@
   }
 
   std::set<std::string> added_domains;
-  std::vector<std::pair<std::string, CookieInsightList::DomainInfo>>
-      domain_map_entries;
+  std::vector<std::pair<std::string, DomainInfo>> domain_map_entries;
   for (const auto& entry : *entry_list) {
     const base::Value::Dict* entry_dict = entry.GetIfDict();
     if (!entry_dict) {
@@ -71,7 +70,7 @@
       return {};
     }
 
-    CookieInsightList::DomainInfo info;
+    DomainInfo info;
     info.entry_url = *entry_url;
 
     for (const auto& domain : *domain_list) {
@@ -93,8 +92,7 @@
       domain_map_entries.emplace_back(*domain_string, info);
     }
   }
-  return base::flat_map<std::string, CookieInsightList::DomainInfo>(
-      domain_map_entries);
+  return base::flat_map<std::string, DomainInfo>(domain_map_entries);
 }
 }  // namespace
 
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc
index 07dc4f4..57ca949 100644
--- a/content/browser/devtools/devtools_instrumentation.cc
+++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -12,8 +12,6 @@
 #include "components/download/public/common/download_create_info.h"
 #include "components/download/public/common/download_item.h"
 #include "components/download/public/common/download_url_parameters.h"
-#include "content/browser/cookie_insight_list/cookie_insight_list.h"
-#include "content/browser/cookie_insight_list/cookie_insight_list_handler.h"
 #include "content/browser/devtools/browser_devtools_agent_host.h"
 #include "content/browser/devtools/dedicated_worker_devtools_agent_host.h"
 #include "content/browser/devtools/devtools_issue_storage.h"
@@ -48,6 +46,8 @@
 #include "content/browser/web_contents/web_contents_impl.h"
 #include "content/browser/web_package/signed_exchange_envelope.h"
 #include "content/public/browser/browser_context.h"
+#include "content/public/browser/cookie_insight_list_data.h"
+#include "content/public/browser/cookie_insight_list_handler.h"
 #include "devtools_agent_host_impl.h"
 #include "devtools_instrumentation.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -1923,23 +1923,23 @@
 std::unique_ptr<protocol::Audits::CookieIssueInsight> BuildCookieIssueInsight(
     std::string_view cookie_domain,
     const net::CookieInclusionStatus& status) {
-  std::optional<CookieInsightList::CookieIssueInsight> insight =
+  std::optional<CookieIssueInsight> insight =
       CookieInsightListHandler::GetInstance().GetInsight(cookie_domain, status);
   if (!insight.has_value()) {
     return nullptr;
   }
 
   switch (insight->type) {
-    case CookieInsightList::InsightType::kGitHubResource:
+    case InsightType::kGitHubResource:
       return protocol::Audits::CookieIssueInsight::Create()
           .SetType(protocol::Audits::InsightTypeEnum::GitHubResource)
           .SetTableEntryUrl(insight->domain_info.entry_url)
           .Build();
-    case CookieInsightList::InsightType::kGracePeriod:
+    case InsightType::kGracePeriod:
       return protocol::Audits::CookieIssueInsight::Create()
           .SetType(protocol::Audits::InsightTypeEnum::GracePeriod)
           .Build();
-    case CookieInsightList::InsightType::kHeuristics:
+    case InsightType::kHeuristics:
       return protocol::Audits::CookieIssueInsight::Create()
           .SetType(protocol::Audits::InsightTypeEnum::Heuristics)
           .Build();
diff --git a/content/browser/interest_group/ad_auction_service_impl_unittest.cc b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
index b0163af..04c35e39 100644
--- a/content/browser/interest_group/ad_auction_service_impl_unittest.cc
+++ b/content/browser/interest_group/ad_auction_service_impl_unittest.cc
@@ -17421,6 +17421,176 @@
 }
 
 TEST_P(AdAuctionServiceImplBAndAKAnonEnabledTest,
+       WinnerAndGhostWinnerWithNonKAnonPrivateAggregation) {
+  OverridePrivateAggregationManagerForTesting();
+  ProvideKeys();
+  NavigateAndCommit(kUrlA);
+
+  blink::InterestGroup interest_group1 =
+      blink::TestInterestGroupBuilder(kOriginA, "cars")
+          .SetAds({{{GURL("https://c.test/ad.html"), /*metadata=*/std::nullopt,
+                     /*size_group=*/std::nullopt,
+                     /*buyer_reporting_id=*/std::nullopt,
+                     /*buyer_and_seller_reporting_id=*/std::nullopt,
+                     /*selectable_buyer_and_seller_reporting_ids=*/std::nullopt,
+                     "1234"}}})
+          .SetBiddingUrl(kBiddingLogicUrlA)
+          .Build();
+  manager_->JoinInterestGroup(interest_group1,
+                              GURL("https://a.test/example.html"));
+  blink::InterestGroup interest_group2 =
+      blink::TestInterestGroupBuilder(kOriginA, "bikes")
+          .SetAds({{{GURL("https://c.test/ad2.html"), /*metadata=*/std::nullopt,
+                     /*size_group=*/std::nullopt,
+                     /*buyer_reporting_id=*/std::nullopt,
+                     /*buyer_and_seller_reporting_id=*/std::nullopt,
+                     /*selectable_buyer_and_seller_reporting_ids=*/std::nullopt,
+                     "5678"}}})
+          .SetBiddingUrl(kBiddingLogicUrlA)
+          .Build();
+  manager_->JoinInterestGroup(interest_group2,
+                              GURL("https://a.test/example.html"));
+  task_environment()->FastForwardBy(base::Seconds(1));
+
+  std::optional<AdAuctionDataAndId> auction_data =
+      GetAdAuctionDataAndFlushForFrame(kOriginA);
+  EXPECT_TRUE(auction_data.has_value());
+
+  AdAuctionPageData* page_data = PageUserData<AdAuctionPageData>::GetForPage(
+      static_cast<RenderFrameHostImpl*>(main_rfh())->GetPage());
+  ASSERT_TRUE(page_data);
+  ASSERT_TRUE(auction_data->request_id);
+  AdAuctionRequestContext* request_context =
+      page_data->GetContextForAdAuctionRequest(*auction_data->request_id);
+
+  ASSERT_EQ(request_context->group_names.begin()->second.size(), 2u);
+  int win_idx =
+      request_context->group_names.begin()->second[0] == "bikes" ? 0 : 1;
+  base::Value response_value = base::Value(
+      base::Value::Dict()
+          .Set("adRenderURL", interest_group1.ads.value()[0].render_url())
+          .Set("interestGroupName", "cars")
+          .Set("interestGroupOwner", kOriginA.Serialize())
+          .Set("biddingGroups",
+               base::Value(base::Value::Dict().Set(
+                   "https://a.test/",
+                   base::Value(base::Value::List().Append(0).Append(1)))))
+          .Set("kAnonWinnerJoinCandidates",
+               base::Value(
+                   base::Value::Dict()
+                       .Set("adRenderURLHash",
+                            AsBlobValue(HashedKAnonKeyForAdBid(
+                                interest_group1,
+                                interest_group1.ads.value()[0].render_url())))
+                       .Set("reportingIdHash",
+                            AsBlobValue(HashedKAnonKeyForAdNameReporting(
+                                interest_group1, interest_group1.ads.value()[0],
+                                /*selected_buyer_and_seller_reporting_id=*/
+                                std::nullopt)))))
+          .Set(
+              "kAnonGhostWinners",
+              base::Value(base::Value::List().Append(base::Value(
+                  base::Value::Dict()
+                      .Set(
+                          "kAnonJoinCandidates",
+                          base::Value(
+                              base::Value::Dict()
+                                  .Set("adRenderURLHash",
+                                       AsBlobValue(HashedKAnonKeyForAdBid(
+                                           interest_group2,
+                                           interest_group2.ads.value()[0]
+                                               .render_url())))
+                                  .Set(
+                                      "reportingIdHash",
+                                      AsBlobValue(
+                                          HashedKAnonKeyForAdNameReporting(
+                                              interest_group2,
+                                              interest_group2.ads.value()[0],
+                                              /*selected_buyer_and_seller_reporting_id=*/
+                                              std::nullopt)))))
+                      .Set("interestGroupIndex", base::Value(win_idx))
+                      .Set("owner", base::Value("https://a.test/"))
+                      .Set("ghostWinnerPrivateAggregationSignals",
+                           base::Value::Dict()
+                               .Set("bucket", base::Value(std::vector<uint8_t>{
+                                                  0x04, 0x01}))
+                               .Set("value", base::Value(4))))))));
+  std::string unframed_response;
+  ASSERT_TRUE(compression::GzipCompress(
+      auction_worklet::test::ToCborVector(response_value), &unframed_response));
+
+  uint32_t request_size = unframed_response.size();
+  std::string response = {0x02, static_cast<char>(request_size >> 24),
+                          static_cast<char>(request_size >> 16),
+                          static_cast<char>(request_size >> 8),
+                          static_cast<char>(request_size >> 0)};
+  response += unframed_response;
+
+  std::string encrypted_response =
+      quiche::ObliviousHttpResponse::CreateServerObliviousResponse(
+          response, request_context->context,
+          kBiddingAndAuctionEncryptionResponseMediaType)
+          ->EncapsulateAndSerialize();
+
+  page_data->AddAuctionResultWitnessForOrigin(
+      kOriginA, crypto::SHA256HashString(encrypted_response));
+
+  base::RunLoop run_loop;
+  if (GetParam() == KAnonState::kEnforceOnDeviceEnforceOnServer) {
+    EXPECT_CALL(mock_private_aggregation_cb_, Run)
+        .WillOnce(testing::Invoke(
+            [&](PrivateAggregationHost::ReportRequestGenerator generator,
+                std::vector<
+                    blink::mojom::AggregatableReportHistogramContribution>
+                    contributions,
+                PrivateAggregationBudgetKey budget_key,
+                PrivateAggregationHost::NullReportBehavior
+                    null_report_behavior) {
+              AggregatableReportRequest request =
+                  std::move(generator).Run(contributions);
+              EXPECT_THAT(
+                  request.payload_contents().contributions,
+                  testing::UnorderedElementsAre(
+                      blink::mojom::AggregatableReportHistogramContribution(
+                          /*bucket=*/absl::MakeUint128(0, 1025), /*value=*/4,
+                          /*filtering_id=*/std::nullopt)));
+              EXPECT_EQ(request.shared_info().reporting_origin, kOriginA);
+              run_loop.Quit();
+            }));
+  }
+
+  blink::AuctionConfig auction_config;
+  auction_config.seller = kOriginA;
+  auction_config.non_shared_params.interest_group_buyers = {kOriginA};
+  auction_config.server_response.emplace();
+  auction_config.server_response->request_id = *auction_data->request_id;
+  std::optional<GURL> result = RunAdAuctionWithPromiseAndFlushForFrame(
+      auction_config,
+      base::BindLambdaForTesting(
+          [&](mojo::Remote<blink::mojom::AbortableAdAuction>& runner) {
+            runner->ResolvedAuctionAdResponsePromise(
+                blink::mojom::AuctionAdConfigAuctionId::NewMainAuction(0),
+                mojo_base::BigBuffer(base::as_byte_span(encrypted_response)));
+          }),
+      main_rfh());
+
+  ASSERT_TRUE(result);
+  InvokeCallbackForURN(*result);
+  switch (GetParam()) {
+    case KAnonState::kNoEnforcement:
+    case KAnonState::kSimulateOnDeviceNoneOnServer:
+    case KAnonState::kEnforceOnDeviceNoneOnServer:
+    case KAnonState::kNoneOnDeviceEnforceOnServer:
+    case KAnonState::kSimulateOnDeviceEnforceOnServer:
+      EXPECT_FALSE(run_loop.AnyQuitCalled());
+      break;
+    case KAnonState::kEnforceOnDeviceEnforceOnServer:
+      run_loop.Run();
+      break;
+  }
+}
+
+TEST_P(AdAuctionServiceImplBAndAKAnonEnabledTest,
        WinnerAndGhostWinnerWithAdComponents) {
   ProvideKeys();
   NavigateAndCommit(kUrlA);
diff --git a/content/browser/interest_group/bidding_and_auction_response.cc b/content/browser/interest_group/bidding_and_auction_response.cc
index 127916b..0e989ef1 100644
--- a/content/browser/interest_group/bidding_and_auction_response.cc
+++ b/content/browser/interest_group/bidding_and_auction_response.cc
@@ -447,6 +447,37 @@
   result.interest_group =
       blink::InterestGroupKey(owner, names[*maybe_group_idx]);
 
+  base::Value* ghost_winner_private_aggregation_signals_value =
+      k_anon_ghost_winner->Find("ghostWinnerPrivateAggregationSignals");
+  if (ghost_winner_private_aggregation_signals_value) {
+    base::Value::Dict* ghost_winner_private_aggregation_signals =
+        ghost_winner_private_aggregation_signals_value->GetIfDict();
+    if (!ghost_winner_private_aggregation_signals) {
+      return std::nullopt;
+    }
+    // `ghostWinnerPrivateAggregationSignals` will only have reject reason
+    // contributions, which the server will guarantee.
+    const std::vector<uint8_t>* bucket =
+        ghost_winner_private_aggregation_signals->FindBlob("bucket");
+    std::optional<int> value =
+        ghost_winner_private_aggregation_signals->FindInt("value");
+    if (!bucket || bucket->size() > 16 || !value.has_value()) {
+      return std::nullopt;
+    }
+    // Server already filtered out not needed contributions based on final
+    // auction result.
+    result.non_kanon_private_aggregation_request =
+        auction_worklet::mojom::PrivateAggregationRequest::New(
+            auction_worklet::mojom::AggregatableReportContribution::
+                NewHistogramContribution(
+                    blink::mojom::AggregatableReportHistogramContribution::New(
+                        /*bucket=*/U128FromBigEndian(*bucket),
+                        /*value=*/*value,
+                        /*filtering_id=*/std::nullopt)),
+            blink::mojom::AggregationServiceMode::kDefault,
+            blink::mojom::DebugModeDetails::New());
+  }
+
   base::Value* ghost_winner_for_top_level_auction_value =
       k_anon_ghost_winner->Find("ghostWinnerForTopLevelAuction");
   if (ghost_winner_for_top_level_auction_value) {
diff --git a/content/browser/interest_group/bidding_and_auction_response.h b/content/browser/interest_group/bidding_and_auction_response.h
index 58d06b0..f1424b5 100644
--- a/content/browser/interest_group/bidding_and_auction_response.h
+++ b/content/browser/interest_group/bidding_and_auction_response.h
@@ -70,6 +70,10 @@
 
     KAnonJoinCandidate candidate;
     blink::InterestGroupKey interest_group;
+    // `non_kanon_private_aggregation_request` will only have reject reason
+    // contributions, which the server will guarantee.
+    auction_worklet::mojom::PrivateAggregationRequestPtr
+        non_kanon_private_aggregation_request;
     std::optional<GhostWinnerForTopLevelAuction> ghost_winner;
   };
 
diff --git a/content/browser/interest_group/bidding_and_auction_response_unittest.cc b/content/browser/interest_group/bidding_and_auction_response_unittest.cc
index 838ac559..2ebbc03 100644
--- a/content/browser/interest_group/bidding_and_auction_response_unittest.cc
+++ b/content/browser/interest_group/bidding_and_auction_response_unittest.cc
@@ -5,6 +5,7 @@
 #include "content/browser/interest_group/bidding_and_auction_response.h"
 
 #include <optional>
+#include <sstream>
 #include <string>
 #include <vector>
 
@@ -28,6 +29,22 @@
 std::string ToString(const blink::InterestGroupKey& key) {
   return "(" + key.owner.Serialize() + ", " + key.name + ")";
 }
+
+std::string ToString(
+    const auction_worklet::mojom::PrivateAggregationRequestPtr& request) {
+  if (!request) {
+    return "null";
+  }
+  const blink::mojom::AggregatableReportHistogramContributionPtr& contribution =
+      request->contribution->get_histogram_contribution();
+  std::stringstream ss;
+  ss << "{bucket: ";
+  ss << contribution->bucket;
+  ss << ", value: ";
+  ss << contribution->value;
+  ss << "}";
+  return ss.str();
+}
 }  // namespace
 
 std::ostream& operator<<(
@@ -82,6 +99,8 @@
   os << "KAnonGhostWinner(";
   os << "candidate: " << testing::PrintToString(winner.candidate) << ", ";
   os << "interest_group: " << ToString(winner.interest_group) << ", ";
+  os << "non_kanon_private_aggregation_request: "
+     << ToString(winner.non_kanon_private_aggregation_request) << ", ";
   os << "ghost_winner: " << testing::PrintToString(winner.ghost_winner) << ")";
   return os;
 }
@@ -425,7 +444,13 @@
           testing::Field(
               "interest_group",
               &BiddingAndAuctionResponse::KAnonGhostWinner::interest_group,
-              testing::Eq(other.get().interest_group))};
+              testing::Eq(other.get().interest_group)),
+          testing::Field(
+              "non_kanon_private_aggregation_request",
+              &BiddingAndAuctionResponse::KAnonGhostWinner::
+                  non_kanon_private_aggregation_request,
+              testing::Eq(std::ref(
+                  other.get().non_kanon_private_aggregation_request)))};
   if (other.get().ghost_winner.has_value()) {
     matchers.push_back(testing::Field(
         "ghost_winner",
@@ -1657,6 +1682,86 @@
           CreateMinimalkAnonGhostWinnersServerResponse(),
       },
       {
+          // Private aggregation not a dict
+          base::Value(CreateValidResponseDict().Set(
+              "kAnonGhostWinners",
+              base::Value(base::Value::List().Append(
+                  kValidMinimalkAnonGhostWinnersDict.Clone().Set(
+                      "ghostWinnerPrivateAggregationSignals",
+                      base::Value(1)))))),
+          CreateExpectedValidResponse(),
+      },
+      {
+          // Private aggregation bad type for bucket
+          base::Value(CreateValidResponseDict().Set(
+              "kAnonGhostWinners",
+              base::Value(base::Value::List().Append(
+                  kValidMinimalkAnonGhostWinnersDict.Clone().Set(
+                      "ghostWinnerPrivateAggregationSignals",
+                      base::Value(base::Value::Dict()
+                                      .Set("bucket", base::Value(1))
+                                      .Set("value", base::Value(1)))))))),
+          CreateExpectedValidResponse(),
+      },
+      {
+          // Private aggregation bucket too big (17 bytes > 16)
+          base::Value(CreateValidResponseDict().Set(
+              "kAnonGhostWinners",
+              base::Value(base::Value::List().Append(
+                  kValidMinimalkAnonGhostWinnersDict.Clone().Set(
+                      "ghostWinnerPrivateAggregationSignals",
+                      base::Value(
+                          base::Value::Dict()
+                              .Set("bucket",
+                                   base::Value(std::vector<uint8_t>{
+                                       0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
+                                       0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
+                                       0x0e, 0x0f, 0x10}))
+                              .Set("value", base::Value(4)))))))),
+          CreateExpectedValidResponse(),
+      },
+      {
+          // Private aggregation bad type for value
+          base::Value(CreateValidResponseDict().Set(
+              "kAnonGhostWinners",
+              base::Value(base::Value::List().Append(
+                  kValidMinimalkAnonGhostWinnersDict.Clone().Set(
+                      "ghostWinnerPrivateAggregationSignals",
+                      base::Value(
+                          base::Value::Dict()
+                              .Set("bucket", base::Value(std::vector<uint8_t>{
+                                                 0x00, 0x01}))
+                              .Set("value", base::Value(std::vector<uint8_t>{
+                                                0x00, 0x01})))))))),
+          CreateExpectedValidResponse(),
+      },
+      {// Valid private aggregation
+       base::Value(CreateValidResponseDict().Set(
+           "kAnonGhostWinners",
+           base::Value(base::Value::List().Append(
+               kValidMinimalkAnonGhostWinnersDict.Clone().Set(
+                   "ghostWinnerPrivateAggregationSignals",
+                   base::Value(
+                       base::Value::Dict()
+                           .Set("bucket",
+                                base::Value(std::vector<uint8_t>{0x04, 0x01}))
+                           .Set("value", base::Value(2)))))))),
+       [&]() {
+         auto response = CreateMinimalkAnonGhostWinnersServerResponse();
+         response.k_anon_ghost_winner->non_kanon_private_aggregation_request =
+             auction_worklet::mojom::PrivateAggregationRequest::New(
+                 auction_worklet::mojom::AggregatableReportContribution::
+                     NewHistogramContribution(
+                         blink::mojom::AggregatableReportHistogramContribution::
+                             New(
+                                 /*bucket=*/1025,
+                                 /*value=*/2,
+                                 /*filtering_id=*/std::nullopt)),
+                 blink::mojom::AggregationServiceMode::kDefault,
+                 blink::mojom::DebugModeDetails::New());
+         return response;
+       }()},
+      {
           // Bad ghost_winner type
           base::Value(CreateValidResponseDict().Set(
               "kAnonGhostWinners",
diff --git a/content/browser/interest_group/interest_group_auction.cc b/content/browser/interest_group/interest_group_auction.cc
index ab8d5a8..5da9d6f 100644
--- a/content/browser/interest_group/interest_group_auction.cc
+++ b/content/browser/interest_group/interest_group_auction.cc
@@ -1907,6 +1907,8 @@
           server_filtered_pagg_requests_reserved,
       std::map<std::string, PrivateAggregationRequests>
           server_filtered_pagg_requests_non_reserved,
+      auction_worklet::mojom::PrivateAggregationRequestPtr
+          non_kanon_private_aggregation_request,
       std::map<BiddingAndAuctionResponse::DebugReportKey, std::optional<GURL>>
           component_win_debugging_only_reports,
       std::map<url::Origin, std::vector<GURL>>
@@ -2007,6 +2009,10 @@
         std::move(server_filtered_pagg_requests_reserved);
     bid_state->server_filtered_pagg_requests_non_reserved =
         std::move(server_filtered_pagg_requests_non_reserved);
+    if (non_kanon_private_aggregation_request) {
+      bid_state->non_kanon_private_aggregation_requests.emplace_back(
+          std::move(non_kanon_private_aggregation_request));
+    }
 
     // 4. forDebuggingOnly reports.
     for (auto& [debug_key, maybeReportUrl] :
@@ -6579,6 +6585,7 @@
       std::move(saved_response_->component_win_pagg_requests),
       std::move(saved_response_->server_filtered_pagg_requests_reserved),
       std::move(saved_response_->server_filtered_pagg_requests_non_reserved),
+      /*non_kanon_private_aggregation_request=*/{},
       std::move(saved_response_->component_win_debugging_only_reports),
       std::move(saved_response_->server_filtered_debugging_only_reports));
 }
@@ -6616,8 +6623,14 @@
       /*ad_descriptor=*/
       blink::AdDescriptor(
           saved_response_->k_anon_ghost_winner->ghost_winner->ad_render_url),
-      /*ad_component_descriptors=*/std::move(ghost_ad_components), {}, {}, {},
-      {}, {});
+      /*ad_component_descriptors=*/std::move(ghost_ad_components),
+      /*component_win_pagg_requests=*/{},
+      /*server_filtered_pagg_requests_reserved=*/{},
+      /*server_filtered_pagg_requests_non_reserved=*/{},
+      std::move(saved_response_->k_anon_ghost_winner
+                    ->non_kanon_private_aggregation_request),
+      /*component_win_debugging_only_reports=*/{},
+      /*server_filtered_debugging_only_reports=*/{});
 }
 
 void InterestGroupAuction::OnDirectFromSellerSignalHeaderAdSlotResolved(
diff --git a/content/browser/media/session/audio_focus_delegate_android.cc b/content/browser/media/session/audio_focus_delegate_android.cc
index e9013d1..d86750b 100644
--- a/content/browser/media/session/audio_focus_delegate_android.cc
+++ b/content/browser/media/session/audio_focus_delegate_android.cc
@@ -111,12 +111,6 @@
   media_session_->StopDucking();
 }
 
-void AudioFocusDelegateAndroid::RecordSessionDuck(
-    JNIEnv*,
-    const JavaParamRef<jobject>&) {
-  media_session_->RecordSessionDuck();
-}
-
 void AudioFocusDelegateAndroid::OnAudioStateChanged(bool is_audible) {
   if (!is_deferred_gain_pending_ || !is_audible) {
     return;
diff --git a/content/browser/media/session/audio_focus_delegate_android.h b/content/browser/media/session/audio_focus_delegate_android.h
index 3c502e0..7192536 100644
--- a/content/browser/media/session/audio_focus_delegate_android.h
+++ b/content/browser/media/session/audio_focus_delegate_android.h
@@ -59,11 +59,6 @@
   // Called by Java through JNI.
   void OnStopDucking(JNIEnv* env, jobject obj);
 
-  // Record when the Android system requests the MediaSession to duck.
-  // Called by Java through JNI.
-  void RecordSessionDuck(JNIEnv* env,
-                         const base::android::JavaParamRef<jobject>& obj);
-
   // This is not used by this delegate.
   void MediaSessionInfoChanged(
       const media_session::mojom::MediaSessionInfoPtr&) override {}
diff --git a/content/browser/media/session/media_session_impl.cc b/content/browser/media/session/media_session_impl.cc
index 897773e6..1c01c088 100644
--- a/content/browser/media/session/media_session_impl.cc
+++ b/content/browser/media/session/media_session_impl.cc
@@ -70,9 +70,6 @@
 
 using media_session::mojom::AudioFocusType;
 
-using MediaSessionSuspendedSource =
-    MediaSessionUmaHelper::MediaSessionSuspendedSource;
-
 const char kMediaSessionDataName[] = "MediaSessionDataName";
 
 class MediaSessionData : public base::SupportsUserData::Data {
@@ -571,11 +568,6 @@
   RebuildAndNotifyMediaPositionChanged();
 }
 
-void MediaSessionImpl::RecordSessionDuck() {
-  uma_helper_.RecordSessionSuspended(
-      MediaSessionSuspendedSource::kSystemTransientDuck);
-}
-
 void MediaSessionImpl::OnPlayerPaused(MediaSessionPlayerObserver* observer,
                                       int player_id) {
   // If a playback is completed, BrowserMediaPlayerManager will call
@@ -943,29 +935,6 @@
   if (audio_focus_state_ != State::ACTIVE)
     return;
 
-  switch (suspend_type) {
-    case SuspendType::kUI:
-      uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::kUI);
-      break;
-    case SuspendType::kSystem:
-      switch (new_state) {
-        case State::SUSPENDED:
-          uma_helper_.RecordSessionSuspended(
-              MediaSessionSuspendedSource::kSystemTransient);
-          break;
-        case State::INACTIVE:
-          uma_helper_.RecordSessionSuspended(
-              MediaSessionSuspendedSource::kSystemPermanent);
-          break;
-        case State::ACTIVE:
-          NOTREACHED();
-      }
-      break;
-    case SuspendType::kContent:
-      uma_helper_.RecordSessionSuspended(MediaSessionSuspendedSource::kCONTENT);
-      break;
-  }
-
   SetAudioFocusState(new_state);
   suspend_type_ = suspend_type;
 
diff --git a/content/browser/media/session/media_session_impl.h b/content/browser/media/session/media_session_impl.h
index 5d44bb3..c31165a 100644
--- a/content/browser/media/session/media_session_impl.h
+++ b/content/browser/media/session/media_session_impl.h
@@ -114,9 +114,6 @@
   // these were the last players in the session.
   CONTENT_EXPORT void RemovePlayers(MediaSessionPlayerObserver* observer);
 
-  // Record that the session was ducked.
-  void RecordSessionDuck();
-
   // Called when a player is paused in the content.
   // If the paused player is the last player, we suspend the MediaSession.
   // Otherwise, the paused player will be removed from the MediaSession.
diff --git a/content/browser/media/session/media_session_impl_browsertest.cc b/content/browser/media/session/media_session_impl_browsertest.cc
index d09f5c28..ec4cf51 100644
--- a/content/browser/media/session/media_session_impl_browsertest.cc
+++ b/content/browser/media/session/media_session_impl_browsertest.cc
@@ -2113,135 +2113,6 @@
 }
 
 IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
-                       UMA_Suspended_SystemTransient) {
-  auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
-      media::MediaContentType::kPersistent);
-  base::HistogramTester tester;
-
-  StartNewPlayer(player_observer.get());
-  ResolveAudioFocusSuccess();
-  SystemSuspend(true);
-
-  std::unique_ptr<base::HistogramSamples> samples(
-      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
-  EXPECT_EQ(1, samples->TotalCount());
-  EXPECT_EQ(1, samples->GetCount(0));  // System Transient
-  EXPECT_EQ(0, samples->GetCount(1));  // System Permanent
-  EXPECT_EQ(0, samples->GetCount(2));  // UI
-}
-
-IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
-                       UMA_Suspended_SystemPermantent) {
-  auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
-      media::MediaContentType::kPersistent);
-  base::HistogramTester tester;
-
-  StartNewPlayer(player_observer.get());
-  ResolveAudioFocusSuccess();
-  SystemSuspend(false);
-
-  std::unique_ptr<base::HistogramSamples> samples(
-      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
-  EXPECT_EQ(1, samples->TotalCount());
-  EXPECT_EQ(0, samples->GetCount(0));  // System Transient
-  EXPECT_EQ(1, samples->GetCount(1));  // System Permanent
-  EXPECT_EQ(0, samples->GetCount(2));  // UI
-}
-
-IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, UMA_Suspended_UI) {
-  auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
-      media::MediaContentType::kPersistent);
-
-  base::HistogramTester tester;
-
-  StartNewPlayer(player_observer.get());
-  ResolveAudioFocusSuccess();
-  UISuspend();
-
-  std::unique_ptr<base::HistogramSamples> samples(
-      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
-  EXPECT_EQ(1, samples->TotalCount());
-  EXPECT_EQ(0, samples->GetCount(0));  // System Transient
-  EXPECT_EQ(0, samples->GetCount(1));  // System Permanent
-  EXPECT_EQ(1, samples->GetCount(2));  // UI
-}
-
-IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
-                       UMA_Suspended_Multiple) {
-  auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
-      media::MediaContentType::kPersistent);
-  base::HistogramTester tester;
-
-  StartNewPlayer(player_observer.get());
-  ResolveAudioFocusSuccess();
-
-  UISuspend();
-  UIResume();
-  ResolveAudioFocusSuccess();
-
-  SystemSuspend(true);
-  SystemResume();
-
-  UISuspend();
-  UIResume();
-  ResolveAudioFocusSuccess();
-
-  SystemSuspend(false);
-
-  std::unique_ptr<base::HistogramSamples> samples(
-      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
-  EXPECT_EQ(4, samples->TotalCount());
-  EXPECT_EQ(1, samples->GetCount(0));  // System Transient
-  EXPECT_EQ(1, samples->GetCount(1));  // System Permanent
-  EXPECT_EQ(2, samples->GetCount(2));  // UI
-}
-
-IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
-                       UMA_Suspended_Crossing) {
-  auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
-      media::MediaContentType::kPersistent);
-  base::HistogramTester tester;
-
-  StartNewPlayer(player_observer.get());
-  ResolveAudioFocusSuccess();
-
-  UISuspend();
-  SystemSuspend(true);
-  SystemSuspend(false);
-  UIResume();
-  ResolveAudioFocusSuccess();
-
-  SystemSuspend(true);
-  SystemSuspend(true);
-  SystemSuspend(false);
-  SystemResume();
-
-  std::unique_ptr<base::HistogramSamples> samples(
-      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
-  EXPECT_EQ(2, samples->TotalCount());
-  EXPECT_EQ(1, samples->GetCount(0));  // System Transient
-  EXPECT_EQ(0, samples->GetCount(1));  // System Permanent
-  EXPECT_EQ(1, samples->GetCount(2));  // UI
-}
-
-IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest, UMA_Suspended_Stop) {
-  auto player_observer = std::make_unique<MockMediaSessionPlayerObserver>(
-      media::MediaContentType::kPersistent);
-  base::HistogramTester tester;
-
-  StartNewPlayer(player_observer.get());
-  ResolveAudioFocusSuccess();
-  media_session_->Stop(MediaSession::SuspendType::kUI);
-
-  std::unique_ptr<base::HistogramSamples> samples(
-      tester.GetHistogramSamplesSinceCreation("Media.Session.Suspended"));
-  EXPECT_EQ(1, samples->TotalCount());
-  EXPECT_EQ(0, samples->GetCount(0));  // System Transient
-  EXPECT_EQ(0, samples->GetCount(1));  // System Permanent
-  EXPECT_EQ(1, samples->GetCount(2));  // UI
-}
-
-IN_PROC_BROWSER_TEST_P(MediaSessionImplParamBrowserTest,
                        UMA_ActiveTime_NoActivation) {
   base::HistogramTester tester;
 
diff --git a/content/browser/media/session/media_session_uma_helper.cc b/content/browser/media/session/media_session_uma_helper.cc
index 4b5ce9dd..56d0046 100644
--- a/content/browser/media/session/media_session_uma_helper.cc
+++ b/content/browser/media/session/media_session_uma_helper.cc
@@ -21,11 +21,6 @@
 MediaSessionUmaHelper::~MediaSessionUmaHelper()
 {}
 
-void MediaSessionUmaHelper::RecordSessionSuspended(
-    MediaSessionSuspendedSource source) const {
-  UMA_HISTOGRAM_ENUMERATION("Media.Session.Suspended", source);
-}
-
 void MediaSessionUmaHelper::RecordEnterPictureInPicture(
     EnterPictureInPictureType type) const {
   base::UmaHistogramEnumeration("Media.Session.EnterPictureInPicture", type);
diff --git a/content/browser/media/session/media_session_uma_helper.h b/content/browser/media/session/media_session_uma_helper.h
index 719be17..3b4da99 100644
--- a/content/browser/media/session/media_session_uma_helper.h
+++ b/content/browser/media/session/media_session_uma_helper.h
@@ -18,17 +18,6 @@
 
 class CONTENT_EXPORT MediaSessionUmaHelper {
  public:
-  // This is used for UMA histogram (Media.Session.Suspended). New values should
-  // be appended only and must be added before |Count|.
-  enum class MediaSessionSuspendedSource {
-    kSystemTransient = 0,
-    kSystemPermanent = 1,
-    kUI = 2,
-    kCONTENT = 3,
-    kSystemTransientDuck = 4,
-    kMaxValue = kSystemTransientDuck,
-  };
-
   // These values are persisted to logs. Entries should not be renumbered and
   // numeric values should never be reused.
   enum class EnterPictureInPictureType {
@@ -50,8 +39,6 @@
   MediaSessionUmaHelper();
   ~MediaSessionUmaHelper();
 
-  void RecordSessionSuspended(MediaSessionSuspendedSource source) const;
-
   void RecordEnterPictureInPicture(EnterPictureInPictureType type) const;
 
   void OnSessionActive();
diff --git a/content/browser/media/session/media_session_uma_helper_unittest.cc b/content/browser/media/session/media_session_uma_helper_unittest.cc
index 88467858..2f39cee 100644
--- a/content/browser/media/session/media_session_uma_helper_unittest.cc
+++ b/content/browser/media/session/media_session_uma_helper_unittest.cc
@@ -11,9 +11,6 @@
 
 namespace content {
 
-using MediaSessionSuspendedSource =
-    MediaSessionUmaHelper::MediaSessionSuspendedSource;
-
 namespace {
 
 class MediaSessionUmaHelperTest : public testing::Test {
@@ -52,67 +49,11 @@
 
   {
     std::unique_ptr<base::HistogramSamples> samples(
-        GetHistogramSamplesSinceTestStart("Media.Session.Suspended"));
-    EXPECT_EQ(0, samples->TotalCount());
-  }
-
-  {
-    std::unique_ptr<base::HistogramSamples> samples(
         GetHistogramSamplesSinceTestStart("Media.Session.ActiveTime"));
     EXPECT_EQ(0, samples->TotalCount());
   }
 }
 
-TEST_F(MediaSessionUmaHelperTest, SuspendRegisterImmediately) {
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kSystemTransient);
-
-  std::unique_ptr<base::HistogramSamples> samples(
-      GetHistogramSamplesSinceTestStart("Media.Session.Suspended"));
-  EXPECT_EQ(1, samples->TotalCount());
-  EXPECT_EQ(1, samples->GetCount(0)); // System Transient
-  EXPECT_EQ(0, samples->GetCount(1)); // System Permanent
-  EXPECT_EQ(0, samples->GetCount(2)); // UI
-}
-
-TEST_F(MediaSessionUmaHelperTest, MultipleSuspend) {
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kSystemTransient);
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kSystemPermanent);
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kUI);
-
-  std::unique_ptr<base::HistogramSamples> samples(
-      GetHistogramSamplesSinceTestStart("Media.Session.Suspended"));
-  EXPECT_EQ(3, samples->TotalCount());
-  EXPECT_EQ(1, samples->GetCount(0)); // System Transient
-  EXPECT_EQ(1, samples->GetCount(1)); // System Permanent
-  EXPECT_EQ(1, samples->GetCount(2)); // UI
-}
-
-TEST_F(MediaSessionUmaHelperTest, MultipleSuspendSame) {
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kSystemPermanent);
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kSystemTransient);
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kUI);
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kSystemTransient);
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kSystemPermanent);
-  media_session_uma_helper().RecordSessionSuspended(
-      MediaSessionSuspendedSource::kUI);
-
-  std::unique_ptr<base::HistogramSamples> samples(
-      GetHistogramSamplesSinceTestStart("Media.Session.Suspended"));
-  EXPECT_EQ(6, samples->TotalCount());
-  EXPECT_EQ(2, samples->GetCount(0)); // System Transient
-  EXPECT_EQ(2, samples->GetCount(1)); // System Permanent
-  EXPECT_EQ(2, samples->GetCount(2)); // UI
-}
-
 TEST_F(MediaSessionUmaHelperTest, ActivationNotTerminatedDoesNotCommit) {
   media_session_uma_helper().OnSessionActive();
   clock()->Advance(base::Milliseconds(1000));
diff --git a/content/browser/network_service_client.cc b/content/browser/network_service_client.cc
index 3445add..905f262a 100644
--- a/content/browser/network_service_client.cc
+++ b/content/browser/network_service_client.cc
@@ -337,6 +337,7 @@
     const url::Origin& request_origin,
     std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
         methods_with_options,
+    const std::optional<std::string>& with_lock,
     OnSharedStorageHeaderReceivedCallback callback) {
   std::move(callback).Run();
 }
diff --git a/content/browser/network_service_client.h b/content/browser/network_service_client.h
index 805a5d5..96c9e2f 100644
--- a/content/browser/network_service_client.h
+++ b/content/browser/network_service_client.h
@@ -130,6 +130,7 @@
       const url::Origin& request_origin,
       std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
           methods_with_options,
+      const std::optional<std::string>& with_lock,
       OnSharedStorageHeaderReceivedCallback callback) override;
   void Clone(
       mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver>
diff --git a/content/browser/shared_storage/shared_storage_header_observer.cc b/content/browser/shared_storage/shared_storage_header_observer.cc
index 8b2cb6ac..e81cd22 100644
--- a/content/browser/shared_storage/shared_storage_header_observer.cc
+++ b/content/browser/shared_storage/shared_storage_header_observer.cc
@@ -86,6 +86,7 @@
     ContextType context_type,
     NavigationOrDocumentHandle* navigation_or_document_handle,
     std::vector<MethodWithOptionsPtr> methods_with_options,
+    const std::optional<std::string>& with_lock,
     base::OnceClosure callback,
     mojo::ReportBadMessageCallback bad_message_callback,
     bool can_defer) {
@@ -179,19 +180,20 @@
                 [](base::WeakPtr<SharedStorageHeaderObserver> header_observer,
                    const url::Origin& request_origin, ContextType context_type,
                    std::vector<MethodWithOptionsPtr> methods_with_options,
+                   const std::optional<std::string>& with_lock,
                    mojo::ReportBadMessageCallback bad_message_callback,
                    NavigationOrDocumentHandle* navigation_or_document_handle) {
                   if (header_observer) {
                     header_observer->HeaderReceived(
                         request_origin, context_type,
                         navigation_or_document_handle,
-                        std::move(methods_with_options), base::DoNothing(),
-                        std::move(bad_message_callback),
+                        std::move(methods_with_options), with_lock,
+                        base::DoNothing(), std::move(bad_message_callback),
                         /*can_defer=*/false);
                   }
                 },
                 weak_ptr_factory_.GetWeakPtr(), request_origin, context_type,
-                std::move(methods_with_options),
+                std::move(methods_with_options), with_lock,
                 std::move(bad_message_callback));
         static_cast<RenderFrameHostImpl*>(rfh)
             ->AddDeferredSharedStorageHeaderCallback(std::move(defer_callback));
@@ -252,11 +254,11 @@
   storage_partition_->GetSharedStorageRuntimeManager()
       ->lock_manager()
       .SharedStorageBatchUpdate(
-          std::move(methods_with_options), /*with_lock=*/std::nullopt,
-          request_origin, AccessScope::kHeader, main_frame_id,
+          std::move(methods_with_options), with_lock, request_origin,
+          AccessScope::kHeader, main_frame_id,
           base::BindOnce(&SharedStorageHeaderObserver::OnBatchUpdateFinished,
                          weak_ptr_factory_.GetWeakPtr(), request_origin,
-                         std::move(cloned_methods_with_options)));
+                         std::move(cloned_methods_with_options), with_lock));
 
   OnHeaderProcessed(request_origin);
   std::move(callback).Run();
diff --git a/content/browser/shared_storage/shared_storage_header_observer.h b/content/browser/shared_storage/shared_storage_header_observer.h
index 24f095a..6b9181e 100644
--- a/content/browser/shared_storage/shared_storage_header_observer.h
+++ b/content/browser/shared_storage/shared_storage_header_observer.h
@@ -96,6 +96,7 @@
                       ContextType context_type,
                       NavigationOrDocumentHandle* navigation_or_document_handle,
                       std::vector<MethodWithOptionsPtr> methods_with_options,
+                      const std::optional<std::string>& with_lock,
                       base::OnceClosure callback,
                       mojo::ReportBadMessageCallback bad_message_callback,
                       bool can_defer);
@@ -106,6 +107,7 @@
   virtual void OnBatchUpdateFinished(
       const url::Origin& request_origin,
       std::vector<MethodWithOptionsPtr> methods_with_options,
+      const std::optional<std::string>& with_lock,
       const std::string& error_message) {}
 
  private:
diff --git a/content/browser/shared_storage/shared_storage_header_observer_unittest.cc b/content/browser/shared_storage/shared_storage_header_observer_unittest.cc
index d19a750..c5b8510b 100644
--- a/content/browser/shared_storage/shared_storage_header_observer_unittest.cc
+++ b/content/browser/shared_storage/shared_storage_header_observer_unittest.cc
@@ -412,9 +412,9 @@
         .get();
   }
 
-  void RunHeaderReceived(
-      const url::Origin& request_origin,
-      std::vector<MethodWithOptionsPtr> methods_with_options) {
+  void RunHeaderReceived(const url::Origin& request_origin,
+                         std::vector<MethodWithOptionsPtr> methods_with_options,
+                         const std::optional<std::string>& with_lock) {
     base::RunLoop loop;
     base::OnceCallback<void(std::string_view error)> bad_message_callback =
         base::BindLambdaForTesting([&](std::string_view error) {
@@ -425,8 +425,8 @@
         GetNavigationOrDocumentHandle(request_origin);
     observer_->HeaderReceived(
         request_origin, GetContextType(), navigation_or_document_handle,
-        std::move(methods_with_options), loop.QuitClosure(),
-        std::move(bad_message_callback),
+        CloneSharedStorageMethods(methods_with_options), with_lock,
+        loop.QuitClosure(), std::move(bad_message_callback),
         /*can_defer=*/true);
     loop.Run();
 
@@ -585,7 +585,8 @@
 
   // No operations are invoked because we've simulated shared storage being
   // disabled in user preferences.
-  RunHeaderReceived(kOrigin1, CloneSharedStorageMethods(methods_with_options));
+  RunHeaderReceived(kOrigin1, CloneSharedStorageMethods(methods_with_options),
+                    /*with_lock=*/std::nullopt);
   EXPECT_TRUE(observer_->header_results().empty());
   EXPECT_TRUE(observer_->operations().empty());
   EXPECT_EQ(Length(kOrigin1), 0);
@@ -614,7 +615,8 @@
 
   methods_with_options.push_back(MojomAppendMethod(key, /*value=*/u"a"));
 
-  RunHeaderReceived(kOrigin1, CloneSharedStorageMethods(methods_with_options));
+  RunHeaderReceived(kOrigin1, CloneSharedStorageMethods(methods_with_options),
+                    /*with_lock=*/std::nullopt);
 
   if (!ExpectSuccess()) {
     EXPECT_TRUE(observer_->header_results().empty());
@@ -632,6 +634,7 @@
   EXPECT_EQ(observer_->operations()[0],
             OperationAndResult(kOrigin1,
                                CloneSharedStorageMethods(methods_with_options),
+                               /*with_lock=*/std::nullopt,
                                /*success=*/false));
 
   EXPECT_EQ(GetExistingValue(kOrigin1, base::UTF16ToUTF8(key)),
@@ -658,7 +661,8 @@
                                                 /*ignore_if_present=*/false));
   methods_with_options.push_back(MojomDeleteMethod(/*key=*/u"key2"));
 
-  RunHeaderReceived(kOrigin1, CloneSharedStorageMethods(methods_with_options));
+  RunHeaderReceived(kOrigin1, CloneSharedStorageMethods(methods_with_options),
+                    /*with_lock=*/std::nullopt);
 
   if (!ExpectSuccess()) {
     EXPECT_TRUE(observer_->header_results().empty());
@@ -674,6 +678,7 @@
   EXPECT_EQ(observer_->operations()[0],
             OperationAndResult(kOrigin1,
                                CloneSharedStorageMethods(methods_with_options),
+                               /*with_lock=*/std::nullopt,
                                /*success=*/true));
 
   EXPECT_EQ(GetExistingValue(kOrigin1, "key1"), "value1value1");
@@ -699,13 +704,16 @@
   std::vector<MethodWithOptionsPtr> methods_with_options3;
   methods_with_options3.push_back(MojomDeleteMethod(/*key=*/u"a"));
 
-  RunHeaderReceived(kOrigin1, CloneSharedStorageMethods(methods_with_options1));
+  RunHeaderReceived(kOrigin1, CloneSharedStorageMethods(methods_with_options1),
+                    /*with_lock=*/"lock1");
 
   if (!ExpectSuccess()) {
     RunHeaderReceived(kOrigin2,
-                      CloneSharedStorageMethods(methods_with_options2));
+                      CloneSharedStorageMethods(methods_with_options2),
+                      /*with_lock=*/std::nullopt);
     RunHeaderReceived(kOrigin3,
-                      CloneSharedStorageMethods(methods_with_options3));
+                      CloneSharedStorageMethods(methods_with_options3),
+                      /*with_lock=*/std::nullopt);
     EXPECT_TRUE(observer_->header_results().empty());
     EXPECT_TRUE(observer_->operations().empty());
     EXPECT_EQ(Length(kOrigin1), 0);
@@ -717,11 +725,13 @@
   ASSERT_EQ(observer_->header_results().size(), 1u);
   EXPECT_EQ(observer_->header_results().back(), kOrigin1);
 
-  RunHeaderReceived(kOrigin2, CloneSharedStorageMethods(methods_with_options2));
+  RunHeaderReceived(kOrigin2, CloneSharedStorageMethods(methods_with_options2),
+                    /*with_lock=*/std::nullopt);
   ASSERT_EQ(observer_->header_results().size(), 2u);
   EXPECT_EQ(observer_->header_results().back(), kOrigin2);
 
-  RunHeaderReceived(kOrigin3, CloneSharedStorageMethods(methods_with_options3));
+  RunHeaderReceived(kOrigin3, CloneSharedStorageMethods(methods_with_options3),
+                    /*with_lock=*/std::nullopt);
   ASSERT_EQ(observer_->header_results().size(), 3u);
   EXPECT_EQ(observer_->header_results().back(), kOrigin3);
 
@@ -729,14 +739,17 @@
   EXPECT_EQ(observer_->operations()[0],
             OperationAndResult(kOrigin1,
                                CloneSharedStorageMethods(methods_with_options1),
+                               /*with_lock=*/"lock1",
                                /*success=*/true));
   EXPECT_EQ(observer_->operations()[1],
             OperationAndResult(kOrigin2,
                                CloneSharedStorageMethods(methods_with_options2),
+                               /*with_lock=*/std::nullopt,
                                /*success=*/true));
   EXPECT_EQ(observer_->operations()[2],
             OperationAndResult(kOrigin3,
                                CloneSharedStorageMethods(methods_with_options3),
+                               /*with_lock=*/std::nullopt,
                                /*success=*/true));
 
   // Operations on different origins don't affect each other.
diff --git a/content/browser/speech/soda_speech_recognition_engine_impl.cc b/content/browser/speech/soda_speech_recognition_engine_impl.cc
index a756cb0..9daa4b1 100644
--- a/content/browser/speech/soda_speech_recognition_engine_impl.cc
+++ b/content/browser/speech/soda_speech_recognition_engine_impl.cc
@@ -79,6 +79,7 @@
       media::mojom::RecognizerClientType::kLiveCaption;
   options->skip_continuously_empty_audio = true;
   options->language = config_.language;
+  options->recognition_context = config_.recognition_context;
 
   speech_recognition_context_->BindRecognizer(
       speech_recognition_recognizer_.BindNewPipeAndPassReceiver(),
diff --git a/content/browser/speech/speech_recognition_dispatcher_host.cc b/content/browser/speech/speech_recognition_dispatcher_host.cc
index 8846fae..cbf3ad58 100644
--- a/content/browser/speech/speech_recognition_dispatcher_host.cc
+++ b/content/browser/speech/speech_recognition_dispatcher_host.cc
@@ -202,6 +202,7 @@
   config.interim_results = params->interim_results;
   config.on_device = params->on_device;
   config.allow_cloud_fallback = params->allow_cloud_fallback;
+  config.recognition_context = params->recognition_context;
 
   for (media::mojom::SpeechRecognitionGrammarPtr& grammar_ptr :
        params->grammars) {
diff --git a/content/browser/speech/speech_recognition_manager_impl.cc b/content/browser/speech/speech_recognition_manager_impl.cc
index 30c96ef7..fd8d623 100644
--- a/content/browser/speech/speech_recognition_manager_impl.cc
+++ b/content/browser/speech/speech_recognition_manager_impl.cc
@@ -274,6 +274,7 @@
     options->recognizer_client_type =
         media::mojom::RecognizerClientType::kLiveCaption;
     options->skip_continuously_empty_audio = true;
+    options->recognition_context = config.recognition_context;
 
     speech_recognition_context_->BindWebSpeechRecognizer(
         std::move(session_receiver), std::move(client_remote),
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc
index 07c4665..3bbefc88 100644
--- a/content/browser/storage_partition_impl.cc
+++ b/content/browser/storage_partition_impl.cc
@@ -2342,6 +2342,7 @@
     const url::Origin& request_origin,
     std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
         methods_with_options,
+    const std::optional<std::string>& with_lock,
     OnSharedStorageHeaderReceivedCallback callback) {
   if (!shared_storage_header_observer_) {
     std::move(callback).Run();
@@ -2361,7 +2362,7 @@
 
   shared_storage_header_observer_->HeaderReceived(
       request_origin, url_loader_network_observers_.current_context().type(),
-      navigation_or_document, std::move(methods_with_options),
+      navigation_or_document, std::move(methods_with_options), with_lock,
       std::move(callback), mojo::GetBadMessageCallback(), /*can_defer=*/true);
 }
 
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h
index 554eb78..333adb7 100644
--- a/content/browser/storage_partition_impl.h
+++ b/content/browser/storage_partition_impl.h
@@ -398,6 +398,7 @@
       const url::Origin& request_origin,
       std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
           methods_with_options,
+      const std::optional<std::string>& with_lock,
       OnSharedStorageHeaderReceivedCallback callback) override;
 
   SharedStorageHeaderObserver* shared_storage_header_observer() {
diff --git a/content/browser/utility_sandbox_delegate_win.cc b/content/browser/utility_sandbox_delegate_win.cc
index b43619f1..82057aefb 100644
--- a/content/browser/utility_sandbox_delegate_win.cc
+++ b/content/browser/utility_sandbox_delegate_win.cc
@@ -354,6 +354,9 @@
     if (result != sandbox::SBOX_ALL_OK) {
       return false;
     }
+
+    config->SetFilterEnvironment(base::FeatureList::IsEnabled(
+        sandbox::policy::features::kWinSboxFilterServiceEnvironment));
   }
 
   if (sandbox_type_ == sandbox::mojom::Sandbox::kService) {
diff --git a/content/child/browser_exposed_child_interfaces.cc b/content/child/browser_exposed_child_interfaces.cc
index 2d0a668..f4e3c43 100644
--- a/content/child/browser_exposed_child_interfaces.cc
+++ b/content/child/browser_exposed_child_interfaces.cc
@@ -26,15 +26,11 @@
       base::BindRepeating(&tracing::TracedProcess::OnTracedProcessRequest),
       base::SequencedTaskRunner::GetCurrentDefault());
 
-  // TODO(crbug.com/40946277): Investiagte the reason why the mojo connection
-  // is often created and closed for the same render process on lacros-chrome.
-#if !BUILDFLAG(IS_CHROMEOS_LACROS)
   if (!in_browser_process) {
     binders->Add<mojom::SyntheticTrialConfiguration>(
         base::BindRepeating(&ChildProcessSyntheticTrialSyncer::Create),
         base::SequencedTaskRunner::GetCurrentDefault());
   }
-#endif  // !BUILDFLAG(IS_CHROMEOS_LACROS)
 
   GetContentClient()->ExposeInterfacesToBrowser(io_task_runner, binders);
 }
diff --git a/content/child/child_thread_impl.cc b/content/child/child_thread_impl.cc
index 91470e82..9e3b754 100644
--- a/content/child/child_thread_impl.cc
+++ b/content/child/child_thread_impl.cc
@@ -428,7 +428,7 @@
     content::SetPseudonymizationSalt(salt);
   }
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   void ReinitializeLogging(mojom::LoggingSettingsPtr settings) override {
     logging::LoggingSettings logging_settings;
     logging_settings.logging_dest = settings->logging_dest;
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc
index 341947d..c4acaa4 100644
--- a/content/child/runtime_features.cc
+++ b/content/child/runtime_features.cc
@@ -16,7 +16,6 @@
 #include "base/strings/string_number_conversions.h"
 #include "base/strings/string_util.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "cc/base/features.h"
 #include "components/attribution_reporting/features.h"
 #include "content/common/content_navigation_policy.h"
@@ -74,7 +73,7 @@
   WebRuntimeFeatures::EnableCompositedSelectionUpdate(true);
 #endif
 
-#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_APPLE)
   const bool enable_canvas_2d_image_chromium =
       command_line.HasSwitch(
           blink::switches::kEnableGpuMemoryBufferCompositorResources) &&
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn
index d8243ca3..059a2c0b 100644
--- a/content/common/BUILD.gn
+++ b/content/common/BUILD.gn
@@ -220,7 +220,6 @@
     "//base",
     "//base/allocator:buildflags",
     "//build:branding_buildflags",
-    "//build:chromeos_buildflags",
     "//build/util:chromium_git_revision",
     "//components/discardable_memory/common",
     "//components/input",
@@ -374,7 +373,7 @@
     deps += [ "//ppapi/proxy:ipc_sources" ]
   }
 
-  if (!is_chromeos_ash) {
+  if (!is_chromeos) {
     sources -= [ "cursors/webcursor_ash.cc" ]
   }
 
diff --git a/content/common/child_process.mojom b/content/common/child_process.mojom
index 75a9fcb9..588ec149 100644
--- a/content/common/child_process.mojom
+++ b/content/common/child_process.mojom
@@ -13,7 +13,7 @@
 
 // Information about how logging should be configured.
 // Corresponds to logging::LoggingSettings.
-[EnableIf=is_chromeos_ash]
+[EnableIf=is_chromeos]
 struct LoggingSettings {
   uint32 logging_dest;
   handle<platform> log_file_descriptor;
@@ -108,7 +108,7 @@
   // Reinitializes the child process's logging with the given settings. This
   // is needed on Chrome OS, which switches to a log file in the user's home
   // directory once they log in.
-  [EnableIf=is_chromeos_ash]
+  [EnableIf=is_chromeos]
   ReinitializeLogging(LoggingSettings settings);
 
   // Notifies a child process of current memory pressure level.
diff --git a/content/common/cursors/webcursor.h b/content/common/cursors/webcursor.h
index 43f9606..a828403 100644
--- a/content/common/cursors/webcursor.h
+++ b/content/common/cursors/webcursor.h
@@ -57,7 +57,7 @@
   display::Display::Rotation rotation_ = display::Display::ROTATE_0;
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   // This matches ozone drm_util.cc's kDefaultCursorWidth/Height.
   static constexpr int kDefaultMaxSize = 64;
   gfx::Size maximum_cursor_size_ = {kDefaultMaxSize, kDefaultMaxSize};
diff --git a/content/common/cursors/webcursor_aura.cc b/content/common/cursors/webcursor_aura.cc
index 72e9496..6acba87e 100644
--- a/content/common/cursors/webcursor_aura.cc
+++ b/content/common/cursors/webcursor_aura.cc
@@ -19,19 +19,9 @@
     if (!custom_cursor_) {
       SkBitmap bitmap = cursor_.custom_bitmap();
       gfx::Point hotspot = cursor_.custom_hotspot();
-
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-      // In lacros, cursor should not be scaled to device scale
-      // factor because device scale factor is not always integer
-      // which could cause rounding errors. We should keep the
-      // image scale factor and handle the actual scaling in ash.
-      // Cursor rotation is also handled in ash.
-      float cursor_image_scale = cursor_.image_scale_factor();
-#else
       float cursor_image_scale = device_scale_factor_;
       wm::ScaleAndRotateCursorBitmapAndHotpoint(GetCursorScaleFactor(&bitmap),
                                                 rotation_, &bitmap, &hotspot);
-#endif
       custom_cursor_ = ui::Cursor::NewCustom(
           std::move(bitmap), std::move(hotspot), cursor_image_scale);
       custom_cursor_->SetPlatformCursor(
@@ -45,7 +35,7 @@
   return cursor_.type();
 }
 
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
+#if !BUILDFLAG(IS_CHROMEOS)
 // Ash has its own UpdateDisplayInfoForWindow that takes rotation into account.
 void WebCursor::UpdateDisplayInfoForWindow(aura::Window* window) {
   float preferred_scale = display::Screen::GetScreen()
diff --git a/content/common/cursors/webcursor_unittest.cc b/content/common/cursors/webcursor_unittest.cc
index 688eb1c..392a555 100644
--- a/content/common/cursors/webcursor_unittest.cc
+++ b/content/common/cursors/webcursor_unittest.cc
@@ -9,7 +9,6 @@
 #include <optional>
 
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "content/public/test/test_renderer_host.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
@@ -63,22 +62,16 @@
   // on aura platform.
   EXPECT_FALSE(webcursor.has_custom_cursor_for_test());
   gfx::NativeCursor native_cursor = webcursor.GetNativeCursor();
-
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  // Cursor is not scaled to device scale factor in lacros.
-  EXPECT_EQ(gfx::Point(10, 20), native_cursor.custom_hotspot());
-#else
   EXPECT_EQ(gfx::Point(5, 10), native_cursor.custom_hotspot());
-#endif
-
   EXPECT_TRUE(webcursor.has_custom_cursor_for_test());
+
   // Test if the rotating custom cursor works correctly.
   display::Display display(/*id=*/1);
   display.set_panel_rotation(display::Display::ROTATE_90);
   TestScreen screen(display);
   webcursor.UpdateDisplayInfoForWindow(nullptr);
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   EXPECT_FALSE(webcursor.has_custom_cursor_for_test());
 #else
   EXPECT_TRUE(webcursor.has_custom_cursor_for_test());
@@ -87,11 +80,7 @@
   native_cursor = webcursor.GetNativeCursor();
   EXPECT_TRUE(webcursor.has_custom_cursor_for_test());
 
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  // In lacros rotation and scale is handled by ash. So the cursor
-  // is not rotated or scaled.
-  EXPECT_EQ(gfx::Point(10, 20), native_cursor.custom_hotspot());
-#elif BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   // Hotspot should be scaled & rotated. We're using the icon created for 2.0,
   // on the display with dsf=1.0, so the hotspot should be
   // ((32 - 20) / 2, 10 / 2) = (6, 5).
@@ -118,18 +107,13 @@
   TestScreen screen(display);
   webcursor.UpdateDisplayInfoForWindow(nullptr);
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   // In Ash, the size of the cursor is capped at 64px unless the hardware
   // advertises support for bigger cursors.
   const gfx::Size kDefaultMaxSize = gfx::Size(64, 64);
   EXPECT_EQ(gfx::SkISizeToSize(
                 webcursor.GetNativeCursor().custom_bitmap().dimensions()),
             kDefaultMaxSize);
-#elif BUILDFLAG(IS_CHROMEOS_LACROS)
-  // Bitmap doesn't get scaled to device scale factor in lacros.
-  EXPECT_EQ(gfx::SkISizeToSize(
-                webcursor.GetNativeCursor().custom_bitmap().dimensions()),
-            gfx::Size(128, 128));
 #else
   EXPECT_EQ(
       gfx::SkISizeToSize(
@@ -137,14 +121,9 @@
       gfx::ScaleToFlooredSize(gfx::Size(128, 128), kDeviceScale / kImageScale));
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_LACROS)
-  // The scale factor of the cursor image should match the image scale.
-  EXPECT_EQ(webcursor.GetNativeCursor().image_scale_factor(), kImageScale);
-#else
   // The scale factor of the cursor image should match the device scale factor,
   // regardless of the cursor size.
   EXPECT_EQ(webcursor.GetNativeCursor().image_scale_factor(), kDeviceScale);
-#endif
 }
 #endif  // defined(USE_AURA)
 
diff --git a/content/common/features.cc b/content/common/features.cc
index a3ebebb..eb55d647 100644
--- a/content/common/features.cc
+++ b/content/common/features.cc
@@ -81,7 +81,7 @@
 // enabled.
 BASE_FEATURE(kCanvas2DImageChromium,
              "Canvas2DImageChromium",
-#if BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_APPLE)
              base::FEATURE_ENABLED_BY_DEFAULT
 #else
              base::FEATURE_DISABLED_BY_DEFAULT
@@ -435,7 +435,7 @@
 #endif
 
 // Allows swipe left/right from touchpad change browser navigation. Currently
-// only enabled by default on CrOS, LaCrOS and Windows.
+// only enabled by default on CrOS and Windows.
 BASE_FEATURE(kTouchpadOverscrollHistoryNavigation,
              "TouchpadOverscrollHistoryNavigation",
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_WIN)
diff --git a/content/common/gpu_pre_sandbox_hook_linux.cc b/content/common/gpu_pre_sandbox_hook_linux.cc
index d2b5ece..1e0cd98 100644
--- a/content/common/gpu_pre_sandbox_hook_linux.cc
+++ b/content/common/gpu_pre_sandbox_hook_linux.cc
@@ -29,7 +29,6 @@
 #include "base/strings/stringprintf.h"
 #include "build/build_config.h"
 #include "build/buildflag.h"
-#include "build/chromeos_buildflags.h"
 #include "content/public/common/content_switches.h"
 #include "media/gpu/buildflags.h"
 #include "sandbox/linux/bpf_dsl/policy.h"
@@ -54,9 +53,6 @@
 namespace {
 
 inline bool IsChromeOS() {
-  // TODO(b/206464999): for now, we're making the LaCrOS and Ash GPU sandboxes
-  // behave similarly. However, the LaCrOS GPU sandbox could probably be made
-  // tighter.
 #if BUILDFLAG(IS_CHROMEOS)
   return true;
 #else
diff --git a/content/common/profiling_utils.cc b/content/common/profiling_utils.cc
index 9ff52b4b..417a848 100644
--- a/content/common/profiling_utils.cc
+++ b/content/common/profiling_utils.cc
@@ -40,14 +40,6 @@
 #if BUILDFLAG(IS_ANDROID)
   base::PathService::Get(base::DIR_TEMP, &path);
   path = path.Append("pgo_profiles/");
-  // Lacros is similar to Android that it's running on a device that is not
-  // the host machine and environment variables aren't well supported.
-  // But Lacros also need to pass in the path so it is the same path as
-  // isolate test output folder on bots.
-#elif BUILDFLAG(IS_CHROMEOS_LACROS)
-  path = base::CommandLine::ForCurrentProcess()
-             ->GetSwitchValuePath(switches::kLLVMProfileFile)
-             .DirName();
 #else
   std::string prof_template;
   std::unique_ptr<base::Environment> env(base::Environment::Create());
diff --git a/content/common/user_agent_unittest.cc b/content/common/user_agent_unittest.cc
index 68154fbc..f6222dd 100644
--- a/content/common/user_agent_unittest.cc
+++ b/content/common/user_agent_unittest.cc
@@ -5,7 +5,6 @@
 #include "content/public/common/user_agent.h"
 
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace content {
@@ -21,6 +20,7 @@
 }  // namespace
 
 TEST(UserAgentStringTest, BuildOSCpuInfoFromOSVersionAndCpuType) {
+  // clang-format off
   const BuildOSCpuInfoTestCases test_cases[] = {
 #if BUILDFLAG(IS_WIN)
     // On Windows, it's possible to have an empty string for CPU type.
@@ -74,7 +74,7 @@
         /*cpu_type=*/"CPU TYPE",
         /*expected_os_cpu_info=*/"CPU TYPE Mac OS X VERSION",
     },
-#elif BUILDFLAG(IS_CHROMEOS_ASH)
+#elif BUILDFLAG(IS_CHROMEOS)
     {
         /*os_version=*/"4537.56.0",
         /*cpu_type=*/"armv7l",
@@ -118,6 +118,7 @@
     },
 #endif
   };
+  // clang-format on
 
   for (const auto& test_case : test_cases) {
     const std::string os_cpu_info = BuildOSCpuInfoFromOSVersionAndCpuType(
diff --git a/content/gpu/BUILD.gn b/content/gpu/BUILD.gn
index 098082510..f9b0c04 100644
--- a/content/gpu/BUILD.gn
+++ b/content/gpu/BUILD.gn
@@ -3,7 +3,6 @@
 # found in the LICENSE file.
 
 import("//build/config/cast.gni")
-import("//build/config/chromeos/ui_mode.gni")
 import("//build/config/ui.gni")
 import("//gpu/vulkan/features.gni")
 import("//media/media_options.gni")
@@ -48,7 +47,6 @@
   deps = [
     "//base",
     "//build:branding_buildflags",
-    "//build:chromeos_buildflags",
     "//components/viz/service",
     "//content:export",
     "//content/child",
@@ -85,14 +83,14 @@
     "//ui/latency/ipc",
   ]
 
-  if (!is_chromeos_ash || !is_chrome_branded) {
+  if (!is_chromeos || !is_chrome_branded) {
     deps += [
       "//services/shape_detection:lib",
       "//services/shape_detection/public/mojom",
     ]
   }
 
-  if (is_chromeos_ash) {
+  if (is_chromeos) {
     deps += [
       "//components/services/font/public/cpp",
       "//components/services/font/public/mojom",
diff --git a/content/gpu/gpu_child_thread.cc b/content/gpu/gpu_child_thread.cc
index 4f676c0..4bd385f 100644
--- a/content/gpu/gpu_child_thread.cc
+++ b/content/gpu/gpu_child_thread.cc
@@ -21,7 +21,6 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/threading/thread_checker.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "content/child/child_process.h"
 #include "content/common/process_visibility_tracker.h"
 #include "content/gpu/browser_exposed_gpu_interfaces.h"
@@ -51,7 +50,7 @@
 #include "media/mojo/clients/mojo_android_overlay.h"
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
 #include "components/services/font/public/cpp/font_loader.h"  // nogncheck
 #include "components/services/font/public/mojom/font_service.mojom.h"  // nogncheck
 #include "third_party/skia/include/core/SkRefCnt.h"
@@ -161,7 +160,7 @@
   }
 #endif
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   if (!in_process_gpu()) {
     mojo::PendingRemote<font_service::mojom::FontService> font_service;
     BindHostReceiver(font_service.InitWithNewPipeAndPassReceiver());
diff --git a/content/gpu/gpu_child_thread_receiver_bindings.cc b/content/gpu/gpu_child_thread_receiver_bindings.cc
index ec164289..223e2c1 100644
--- a/content/gpu/gpu_child_thread_receiver_bindings.cc
+++ b/content/gpu/gpu_child_thread_receiver_bindings.cc
@@ -8,10 +8,9 @@
 
 #include "base/no_destructor.h"
 #include "build/branding_buildflags.h"
-#include "build/chromeos_buildflags.h"
 #include "media/mojo/buildflags.h"
 
-#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) || !BUILDFLAG(IS_CHROMEOS_ASH)
+#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) || !BUILDFLAG(IS_CHROMEOS)
 #include "services/shape_detection/public/mojom/shape_detection_service.mojom.h"  // nogncheck
 #include "services/shape_detection/shape_detection_service.h"  // nogncheck
 #endif
@@ -37,7 +36,7 @@
     return;
   }
 
-#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) || !BUILDFLAG(IS_CHROMEOS_ASH)
+#if !BUILDFLAG(GOOGLE_CHROME_BRANDING) || !BUILDFLAG(IS_CHROMEOS)
   if (auto shape_detection_receiver =
           receiver.As<shape_detection::mojom::ShapeDetectionService>()) {
     static base::NoDestructor<shape_detection::ShapeDetectionService> service{
diff --git a/content/gpu/gpu_main.cc b/content/gpu/gpu_main.cc
index 400c0d3..47e3435 100644
--- a/content/gpu/gpu_main.cc
+++ b/content/gpu/gpu_main.cc
@@ -32,7 +32,6 @@
 #include "base/timer/hi_res_timer_manager.h"
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
-#include "build/chromeos_buildflags.h"
 #include "components/viz/service/main/viz_main_impl.h"
 #include "content/child/child_process.h"
 #include "content/common/content_constants_internal.h"
@@ -371,7 +370,7 @@
   // message from the browser (through mojom::VizMain::CreateGpuService()).
   const bool init_success = gpu_init->InitializeAndStartSandbox(
       const_cast<base::CommandLine*>(&command_line), gpu_preferences);
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS)
   LOG(WARNING) << "gpu initialization completed init_success:" << init_success;
 #endif
   const bool dead_on_arrival = !init_success;
@@ -503,7 +502,7 @@
 
 #if BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX)
   // Video decoding of many video streams can use thousands of FDs as well as
-  // Exo clients like Lacros.
+  // Exo clients.
   // See https://crbug.com/1417237
   const auto current_max_fds =
       base::saturated_cast<unsigned int>(base::GetMaxFds());
diff --git a/content/public/android/java/src/org/chromium/content/browser/AudioFocusDelegate.java b/content/public/android/java/src/org/chromium/content/browser/AudioFocusDelegate.java
index 8901f7a9..a524ceb 100644
--- a/content/public/android/java/src/org/chromium/content/browser/AudioFocusDelegate.java
+++ b/content/public/android/java/src/org/chromium/content/browser/AudioFocusDelegate.java
@@ -145,9 +145,6 @@
             case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                 mIsDucking = true;
                 AudioFocusDelegateJni.get()
-                        .recordSessionDuck(
-                                mNativeAudioFocusDelegateAndroid, AudioFocusDelegate.this);
-                AudioFocusDelegateJni.get()
                         .onStartDucking(mNativeAudioFocusDelegateAndroid, AudioFocusDelegate.this);
                 break;
             case AudioManager.AUDIOFOCUS_LOSS:
@@ -170,7 +167,5 @@
         void onStartDucking(long nativeAudioFocusDelegateAndroid, AudioFocusDelegate caller);
 
         void onStopDucking(long nativeAudioFocusDelegateAndroid, AudioFocusDelegate caller);
-
-        void recordSessionDuck(long nativeAudioFocusDelegateAndroid, AudioFocusDelegate caller);
     }
 }
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn
index edd136c..1c1d5900 100644
--- a/content/public/browser/BUILD.gn
+++ b/content/public/browser/BUILD.gn
@@ -127,6 +127,8 @@
     "cookie_access_details.cc",
     "cookie_access_details.h",
     "cookie_deprecation_label_manager.h",
+    "cookie_insight_list_data.h",
+    "cookie_insight_list_handler.h",
     "cookie_store_factory.h",
     "cors_origin_pattern_setter.cc",
     "cors_origin_pattern_setter.h",
diff --git a/content/public/browser/browsing_data_remover.h b/content/public/browser/browsing_data_remover.h
index 7b18975..4ebf90b 100644
--- a/content/public/browser/browsing_data_remover.h
+++ b/content/public/browser/browsing_data_remover.h
@@ -151,9 +151,13 @@
   static constexpr DataType DATA_TYPE_RELATED_WEBSITE_SETS_PERMISSIONS = 1
                                                                          << 24;
 
+  // Device bound sessions
+  // (https://github.com/WICG/dbsc/blob/main/README.md)
+  static constexpr DataType DATA_TYPE_DEVICE_BOUND_SESSIONS = 1 << 25;
+
   // Embedders can add more datatypes beyond this point.
   static constexpr DataType DATA_TYPE_CONTENT_END =
-      DATA_TYPE_RELATED_WEBSITE_SETS_PERMISSIONS;
+      DATA_TYPE_DEVICE_BOUND_SESSIONS;
 
   // All data stored by the Attribution Reporting API.
   static constexpr DataType DATA_TYPE_ATTRIBUTION_REPORTING =
@@ -178,7 +182,8 @@
   static constexpr DataType DATA_TYPE_ON_STORAGE_PARTITION =
       DATA_TYPE_DOM_STORAGE | DATA_TYPE_COOKIES |
       DATA_TYPE_AVOID_CLOSING_CONNECTIONS | DATA_TYPE_CACHE |
-      DATA_TYPE_APP_CACHE_DEPRECATED | DATA_TYPE_PRIVACY_SANDBOX;
+      DATA_TYPE_APP_CACHE_DEPRECATED | DATA_TYPE_PRIVACY_SANDBOX |
+      DATA_TYPE_DEVICE_BOUND_SESSIONS;
 
   using OriginType = uint64_t;
   // Web storage origins that StoragePartition recognizes as NOT protected
diff --git a/content/public/browser/cookie_insight_list_data.h b/content/public/browser/cookie_insight_list_data.h
new file mode 100644
index 0000000..53762fd7
--- /dev/null
+++ b/content/public/browser/cookie_insight_list_data.h
@@ -0,0 +1,51 @@
+// 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 CONTENT_PUBLIC_BROWSER_COOKIE_INSIGHT_LIST_DATA_H_
+#define CONTENT_PUBLIC_BROWSER_COOKIE_INSIGHT_LIST_DATA_H_
+
+#include <string>
+
+namespace content {
+
+// Contains information about a domain's third-party cookie use status.
+struct DomainInfo {
+  // Link to table entry in third-party cookie migration readiness list.
+  //
+  // TODO(crbug.com/384720467): Use GURL for entry_url instead of string.
+  std::string entry_url;
+
+  bool operator==(const DomainInfo&) const = default;
+};
+
+// Represents the category of insight that a reported cookie issue
+// falls under.
+enum class InsightType {
+  // Cookie domain has an entry in third-party cookie migration readiness
+  // list:
+  // https://github.com/privacysandbox/privacy-sandbox-dev-support/blob/main/3pc-migration-readiness.md
+  kGitHubResource,
+  // Cookie is exempted due to a grace period:
+  // https://developers.google.com/privacy-sandbox/cookies/temporary-exceptions/grace-period
+  kGracePeriod,
+  // Cookie is exempted due a heuristics-based exemptiuon:
+  // https://developers.google.com/privacy-sandbox/cookies/temporary-exceptions/heuristics-based-exception
+  kHeuristics
+};
+
+// Contains information about a reported cookie issue, categorizing the issue
+// and providing information about the cookie's domain's third-party cookie use
+// status.
+struct CookieIssueInsight {
+  // The insight type.
+  InsightType type;
+  // Information about the cookie's domain.
+  DomainInfo domain_info;
+
+  bool operator==(const CookieIssueInsight&) const = default;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_BROWSER_COOKIE_INSIGHT_LIST_DATA_H_
diff --git a/content/public/browser/cookie_insight_list_handler.h b/content/public/browser/cookie_insight_list_handler.h
new file mode 100644
index 0000000..ac6fef7
--- /dev/null
+++ b/content/public/browser/cookie_insight_list_handler.h
@@ -0,0 +1,39 @@
+// 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 CONTENT_PUBLIC_BROWSER_COOKIE_INSIGHT_LIST_HANDLER_H_
+#define CONTENT_PUBLIC_BROWSER_COOKIE_INSIGHT_LIST_HANDLER_H_
+
+#include <optional>
+
+#include "content/common/content_export.h"
+#include "content/public/browser/cookie_insight_list_data.h"
+#include "net/cookies/cookie_inclusion_status.h"
+
+namespace content {
+
+// The CookieInsightListHandler class allows an embedder to provide
+// a readiness list input from custom sources.
+class CONTENT_EXPORT CookieInsightListHandler {
+ public:
+  virtual ~CookieInsightListHandler() = default;
+
+  // Returns the singleton instance.
+  static CookieInsightListHandler& GetInstance();
+
+  // Sets the handler's CookieInsightList.
+  virtual void set_insight_list(std::string_view json_content) = 0;
+
+  // Returns a CookieIssueInsight based on the data in the handler's
+  // CookieInsightList.
+  //
+  // Returns nullopt if no CookieIssueInsight could be retrieved.
+  virtual std::optional<CookieIssueInsight> GetInsight(
+      std::string_view cookie_domain,
+      const net::CookieInclusionStatus& status) const = 0;
+};
+
+}  // namespace content
+
+#endif  // CONTENT_PUBLIC_BROWSER_COOKIE_INSIGHT_LIST_HANDLER_H_
diff --git a/content/public/browser/dips_delegate.h b/content/public/browser/dips_delegate.h
index 59df937f5..627ea355 100644
--- a/content/public/browser/dips_delegate.h
+++ b/content/public/browser/dips_delegate.h
@@ -34,7 +34,8 @@
       content::BrowsingDataRemover::DATA_TYPE_PRIVACY_SANDBOX |
       content::BrowsingDataRemover::DATA_TYPE_CACHE |
       content::BrowsingDataRemover::DATA_TYPE_DOWNLOADS |
-      content::BrowsingDataRemover::DATA_TYPE_RELATED_WEBSITE_SETS_PERMISSIONS;
+      content::BrowsingDataRemover::DATA_TYPE_RELATED_WEBSITE_SETS_PERMISSIONS |
+      content::BrowsingDataRemover::DATA_TYPE_DEVICE_BOUND_SESSIONS;
 
   virtual ~DipsDelegate();
 
diff --git a/content/public/browser/speech_recognition_session_config.h b/content/public/browser/speech_recognition_session_config.h
index 64aec3b..c9e7661 100644
--- a/content/public/browser/speech_recognition_session_config.h
+++ b/content/public/browser/speech_recognition_session_config.h
@@ -14,6 +14,7 @@
 #include "content/common/content_export.h"
 #include "content/public/browser/speech_recognition_session_context.h"
 #include "content/public/browser/speech_recognition_session_preamble.h"
+#include "media/mojo/mojom/speech_recognition.mojom.h"
 #include "media/mojo/mojom/speech_recognition_grammar.mojom.h"
 #include "services/network/public/cpp/shared_url_loader_factory.h"
 #include "url/origin.h"
@@ -30,6 +31,7 @@
 
   std::string language;
   std::vector<media::mojom::SpeechRecognitionGrammar> grammars;
+  std::optional<media::SpeechRecognitionRecognitionContext> recognition_context;
   url::Origin origin;
   bool filter_profanities;
   bool continuous;
diff --git a/content/public/test/accessibility_notification_waiter.cc b/content/public/test/accessibility_notification_waiter.cc
index 8534c3c..5f885a0 100644
--- a/content/public/test/accessibility_notification_waiter.cc
+++ b/content/public/test/accessibility_notification_waiter.cc
@@ -89,14 +89,17 @@
     frame_count_++;
     ListenToFrame(node->current_frame_host());
   }
-  BrowserPluginGuestManager* guest_manager =
-      web_contents_impl->GetBrowserContext()->GetGuestManager();
-  if (guest_manager) {
-    guest_manager->ForEachGuest(web_contents_impl,
-                                [&](WebContents* web_contents) {
-                                  ListenToAllFrames(web_contents);
-                                  return true;
-                                });
+
+  if (!base::FeatureList::IsEnabled(features::kGuestViewMPArch)) {
+    BrowserPluginGuestManager* guest_manager =
+        web_contents_impl->GetBrowserContext()->GetGuestManager();
+    if (guest_manager) {
+      guest_manager->ForEachGuest(web_contents_impl,
+                                  [&](WebContents* web_contents) {
+                                    ListenToAllFrames(web_contents);
+                                    return true;
+                                  });
+    }
   }
 }
 
diff --git a/content/public/test/shared_storage_test_utils.cc b/content/public/test/shared_storage_test_utils.cc
index af52284..099c205 100644
--- a/content/public/test/shared_storage_test_utils.cc
+++ b/content/public/test/shared_storage_test_utils.cc
@@ -174,9 +174,11 @@
 SharedStorageWriteOperationAndResult::SharedStorageWriteOperationAndResult(
     const url::Origin& request_origin,
     std::vector<MethodWithOptionsPtr> methods_with_options,
+    const std::optional<std::string>& with_lock,
     bool success)
     : request_origin(request_origin),
       methods_with_options(std::move(methods_with_options)),
+      with_lock(with_lock),
       success(success) {}
 
 SharedStorageWriteOperationAndResult::SharedStorageWriteOperationAndResult(
@@ -228,6 +230,11 @@
     }
   }
 
+  const std::optional<std::string>& with_lock = op.with_lock;
+  if (with_lock) {
+    os << "; WithLock (batch): " << with_lock.value();
+  }
+
   os << "; Result: " << (op.success ? "Success" : "Failure");
 
   return os;
@@ -236,8 +243,10 @@
 SharedStorageWriteOperationAndResult HeaderOperationSuccess(
     const url::Origin& request_origin,
     std::vector<MethodWithOptionsPtr> methods_with_options) {
-  return SharedStorageWriteOperationAndResult(
-      request_origin, std::move(methods_with_options), /*success=*/true);
+  return SharedStorageWriteOperationAndResult(request_origin,
+                                              std::move(methods_with_options),
+                                              /*with_lock=*/std::nullopt,
+                                              /*success=*/true);
 }
 
 PrivateAggregationHost::PipeResult
diff --git a/content/public/test/shared_storage_test_utils.h b/content/public/test/shared_storage_test_utils.h
index 31b7de5..388928c 100644
--- a/content/public/test/shared_storage_test_utils.h
+++ b/content/public/test/shared_storage_test_utils.h
@@ -76,12 +76,13 @@
 RenderFrameHost* CreateFencedFrame(RenderFrameHost* root,
                                    const FencedFrameNavigationTarget& target);
 
-// Bundles the request (`request_origin` and `with_lock`) with the result
-// `success`.
+// Bundles the request (`request_origin`, `methods_with_options`, and
+// `with_lock`) with the result `success`.
 struct SharedStorageWriteOperationAndResult {
   SharedStorageWriteOperationAndResult(
       const url::Origin& request_origin,
       std::vector<MethodWithOptionsPtr> methods_with_options,
+      const std::optional<std::string>& with_lock,
       bool success);
 
   SharedStorageWriteOperationAndResult(
@@ -102,6 +103,7 @@
 
   url::Origin request_origin;
   std::vector<MethodWithOptionsPtr> methods_with_options;
+  std::optional<std::string> with_lock;
   bool success;
 };
 
diff --git a/content/public/test/test_shared_storage_header_observer.cc b/content/public/test/test_shared_storage_header_observer.cc
index 943c3662..c89bb08 100644
--- a/content/public/test/test_shared_storage_header_observer.cc
+++ b/content/public/test/test_shared_storage_header_observer.cc
@@ -45,10 +45,11 @@
 void TestSharedStorageHeaderObserver::OnBatchUpdateFinished(
     const url::Origin& request_origin,
     std::vector<MethodWithOptionsPtr> methods_with_options,
+    const std::optional<std::string>& with_lock,
     const std::string& error_message) {
   bool success = error_message.empty();
   operations_.emplace_back(request_origin, std::move(methods_with_options),
-                           success);
+                           with_lock, success);
 
   if (loop_ && loop_->running() && operations_.size() >= expected_total_) {
     loop_->Quit();
diff --git a/content/public/test/test_shared_storage_header_observer.h b/content/public/test/test_shared_storage_header_observer.h
index c3221fb..02a084a9 100644
--- a/content/public/test/test_shared_storage_header_observer.h
+++ b/content/public/test/test_shared_storage_header_observer.h
@@ -52,6 +52,7 @@
   void OnBatchUpdateFinished(
       const url::Origin& request_origin,
       std::vector<MethodWithOptionsPtr> methods_with_options,
+      const std::optional<std::string>& with_lock,
       const std::string& error_message) override;
 
   std::unique_ptr<base::RunLoop> loop_;
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn
index 99b4112..a54bb552 100644
--- a/content/test/BUILD.gn
+++ b/content/test/BUILD.gn
@@ -2537,7 +2537,7 @@
     "../browser/content_index/content_index_database_unittest.cc",
     "../browser/content_index/content_index_service_impl_unittest.cc",
     "../browser/cookie_deprecation_label/cookie_deprecation_label_manager_impl_unittest.cc",
-    "../browser/cookie_insight_list/cookie_insight_list_handler_unittest.cc",
+    "../browser/cookie_insight_list/cookie_insight_list_handler_impl_unittest.cc",
     "../browser/cookie_insight_list/cookie_insight_list_unittest.cc",
     "../browser/cookie_insight_list/cookie_readiness_list/cookie_readiness_list_parser_unittest.cc",
     "../browser/cookie_store/cookie_store_manager_unittest.cc",
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist
index 3a0ed91f..3fb9429 100644
--- a/content/test/content_test_bundle_data.filelist
+++ b/content/test/content_test_bundle_data.filelist
@@ -1875,9 +1875,6 @@
 data/accessibility/aria/label-with-selected-option.html
 data/accessibility/aria/missing-relation-targets-added-later-expected-blink.txt
 data/accessibility/aria/missing-relation-targets-added-later.html
-data/accessibility/aria/option-label-expected-blink.txt
-data/accessibility/aria/option-label-expected-mac.txt
-data/accessibility/aria/option-label.html
 data/accessibility/aria/presentational-expected-android-assist-data.txt
 data/accessibility/aria/presentational-expected-android-external.txt
 data/accessibility/aria/presentational-expected-android.txt
diff --git a/content/test/data/accessibility/aria/aria-combobox-expected-mac.txt b/content/test/data/accessibility/aria/aria-combobox-expected-mac.txt
index 6c9ac94..c7ab0e8 100644
--- a/content/test/data/accessibility/aria/aria-combobox-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-combobox-expected-mac.txt
@@ -3,8 +3,8 @@
 ++++AXStaticText AXValue='State'
 ++AXComboBox AXAutocompleteValue='list' AXLinkedUIElements=[:5] AXTitle='State'
 ++AXList
-++++AXMenuItem AXValue='Alabama'
-++++AXMenuItem AXFocused=1 AXValue='Alaska'
+++++AXStaticText AXValue='Alabama'
+++++AXStaticText AXFocused=1 AXValue='Alaska'
 ++AXComboBox AXLinkedUIElements=[:9]
 ++AXTable
 ++++AXRow AXTitle='Grid row'
diff --git a/content/test/data/accessibility/aria/aria-combobox-uneditable-expected-mac.txt b/content/test/data/accessibility/aria/aria-combobox-uneditable-expected-mac.txt
index e0589b0..182b8b9 100644
--- a/content/test/data/accessibility/aria/aria-combobox-uneditable-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-combobox-uneditable-expected-mac.txt
@@ -4,6 +4,6 @@
 ++AXComboBox AXLinkedUIElements=[:6] AXTitle='Choose a fruit, with text content' AXValue='Apple'
 ++++AXStaticText AXValue='Apple'
 ++AXList
-++++AXMenuItem AXValue='Apple'
-++++AXMenuItem AXValue='Banana'
-++++AXMenuItem AXValue='Cherry'
+++++AXStaticText AXValue='Apple'
+++++AXStaticText AXValue='Banana'
+++++AXStaticText AXValue='Cherry'
diff --git a/content/test/data/accessibility/aria/aria-listbox-activedescendant-expected-mac.txt b/content/test/data/accessibility/aria/aria-listbox-activedescendant-expected-mac.txt
index a2ac0fb..b32eb01a 100644
--- a/content/test/data/accessibility/aria/aria-listbox-activedescendant-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-listbox-activedescendant-expected-mac.txt
@@ -1,14 +1,14 @@
 AXWebArea AXSelected=0
 ++AXList AXOrientation='AXVerticalOrientation' AXSelected=0 AXSelectedChildren=[] AXVisibleChildren=[:3, :4, :5]
-++++AXMenuItem AXSelected=0 AXValue='1'
-++++AXMenuItem AXSelected=0 AXValue='2'
-++++AXMenuItem AXSelected=0 AXValue='3'
+++++AXStaticText AXSelected=0 AXValue='1'
+++++AXStaticText AXSelected=0 AXValue='2'
+++++AXStaticText AXSelected=0 AXValue='3'
 ++AXGroup AXSelected=0
 === Start Continuation ===
 AXWebArea AXSelected=0
 ++AXList AXOrientation='AXVerticalOrientation' AXSelected=0 AXSelectedChildren=[:5] AXVisibleChildren=[:3, :4, :5]
-++++AXMenuItem AXSelected=0 AXValue='1'
-++++AXMenuItem AXSelected=0 AXValue='2'
-++++AXMenuItem AXSelected=1 AXValue='3'
+++++AXStaticText AXSelected=0 AXValue='1'
+++++AXStaticText AXSelected=0 AXValue='2'
+++++AXStaticText AXSelected=1 AXValue='3'
 ++AXGroup AXSelected=0
 ++++AXStaticText AXSelected=0 AXValue='focused'
diff --git a/content/test/data/accessibility/aria/aria-listbox-aria-selected-expected-mac.txt b/content/test/data/accessibility/aria/aria-listbox-aria-selected-expected-mac.txt
index 5339fe5..403f631 100644
--- a/content/test/data/accessibility/aria/aria-listbox-aria-selected-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-listbox-aria-selected-expected-mac.txt
@@ -1,7 +1,7 @@
 AXWebArea AXSelected=0
 ++AXList AXOrientation='AXVerticalOrientation' AXSelected=0 AXSelectedChildren=[:6, :7] AXVisibleChildren=[:3, :4, :5, :6, :7]
-++++AXMenuItem AXSelected=0 AXValue='Item 1 not selected'
-++++AXMenuItem AXSelected=0 AXValue='Item 2 not selected'
-++++AXMenuItem AXSelected=0 AXValue='Item 3 not selected'
-++++AXMenuItem AXSelected=1 AXValue='Item 4 selected'
-++++AXMenuItem AXSelected=1 AXValue='Item 5 selected'
+++++AXStaticText AXSelected=0 AXValue='Item 1 not selected'
+++++AXStaticText AXSelected=0 AXValue='Item 2 not selected'
+++++AXStaticText AXSelected=0 AXValue='Item 3 not selected'
+++++AXStaticText AXSelected=1 AXValue='Item 4 selected'
+++++AXStaticText AXSelected=1 AXValue='Item 5 selected'
diff --git a/content/test/data/accessibility/aria/aria-listbox-childfocus-expected-mac.txt b/content/test/data/accessibility/aria/aria-listbox-childfocus-expected-mac.txt
index 7c51f1c5..051d125 100644
--- a/content/test/data/accessibility/aria/aria-listbox-childfocus-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-listbox-childfocus-expected-mac.txt
@@ -1,5 +1,5 @@
 AXWebArea
 ++AXList AXOrientation='AXVerticalOrientation' AXSelectedChildren=[:4] AXVisibleChildren=[:3, :4, :5]
-++++AXMenuItem AXValue='1'
-++++AXMenuItem AXValue='2'
-++++AXMenuItem AXValue='3'
+++++AXStaticText AXValue='1'
+++++AXStaticText AXValue='2'
+++++AXStaticText AXValue='3'
diff --git a/content/test/data/accessibility/aria/aria-listbox-disabled-expected-mac.txt b/content/test/data/accessibility/aria/aria-listbox-disabled-expected-mac.txt
index 7f38166..4575ac4 100644
--- a/content/test/data/accessibility/aria/aria-listbox-disabled-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-listbox-disabled-expected-mac.txt
@@ -2,9 +2,9 @@
 ++AXHeading AXTitle='Start of test: striped should have selected state' AXValue=1
 ++++AXStaticText AXValue='Start of test: striped should have selected state'
 ++AXList
-++++AXMenuItem AXValue='Orange'
-++++AXMenuItem AXValue='Striped'
-++++AXMenuItem AXValue='Calico'
-++++AXMenuItem AXValue='Black'
+++++AXStaticText AXValue='Orange'
+++++AXStaticText AXValue='Striped'
+++++AXStaticText AXValue='Calico'
+++++AXStaticText AXValue='Black'
 ++AXGroup
 ++++AXStaticText AXValue='End of test'
diff --git a/content/test/data/accessibility/aria/aria-listbox-expected-mac.txt b/content/test/data/accessibility/aria/aria-listbox-expected-mac.txt
index ef6e82da..b3ff257 100644
--- a/content/test/data/accessibility/aria/aria-listbox-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-listbox-expected-mac.txt
@@ -1,7 +1,7 @@
 AXWebArea AXRoleDescription='HTML content'
 ++AXList AXRoleDescription='list box'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='Item 1'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='Item 2'
+++++AXStaticText AXRoleDescription='text' AXValue='Item 1'
+++++AXStaticText AXRoleDescription='text' AXValue='Item 2'
 ++++AXSplitter AXRoleDescription='splitter'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='Second group item 1'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='Second group item 2'
+++++AXStaticText AXRoleDescription='text' AXValue='Second group item 1'
+++++AXStaticText AXRoleDescription='text' AXValue='Second group item 2'
diff --git a/content/test/data/accessibility/aria/aria-multiselectable-expected-mac.txt b/content/test/data/accessibility/aria/aria-multiselectable-expected-mac.txt
index 25b74c4..758ef98 100644
--- a/content/test/data/accessibility/aria/aria-multiselectable-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-multiselectable-expected-mac.txt
@@ -1,11 +1,11 @@
 AXWebArea
 ++AXList AXDescription='My Listbox'
-++++AXMenuItem AXValue='Example 1 not selected'
-++++AXMenuItem AXValue='Example 2 not selected'
-++++AXMenuItem AXValue='Example 3 not selected'
-++++AXMenuItem AXValue='Example 4 not selected'
+++++AXStaticText AXValue='Example 1 not selected'
+++++AXStaticText AXValue='Example 2 not selected'
+++++AXStaticText AXValue='Example 3 not selected'
+++++AXStaticText AXValue='Example 4 not selected'
 ++AXList AXDescription='My Listbox'
-++++AXMenuItem AXValue='Example 1 not selected'
-++++AXMenuItem AXValue='Example 2 selected'
-++++AXMenuItem AXValue='Example 3 not selected'
-++++AXMenuItem AXValue='Example 4 selected'
+++++AXStaticText AXValue='Example 1 not selected'
+++++AXStaticText AXValue='Example 2 selected'
+++++AXStaticText AXValue='Example 3 not selected'
+++++AXStaticText AXValue='Example 4 selected'
diff --git a/content/test/data/accessibility/aria/aria-option-complex-children-expected-mac.txt b/content/test/data/accessibility/aria/aria-option-complex-children-expected-mac.txt
index 727c2f05..4a995666d 100644
--- a/content/test/data/accessibility/aria/aria-option-complex-children-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-option-complex-children-expected-mac.txt
@@ -1,11 +1,11 @@
 AXWebArea AXRoleDescription='HTML content'
 ++AXList AXRoleDescription='list box'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='label-WAI-ARIA 1.1'
+++++AXStaticText AXRoleDescription='text' AXValue='href-WAI-ARIA 1.1link-https://www.w3.org/TR/wai-aria-practices-1.1/Close'
 ++++++AXLink AXDescription='href-WAI-ARIA 1.1' AXHelp='title-WAI-ARIA 1.1' AXRoleDescription='link'
 ++++++++AXStaticText AXRoleDescription='text' AXValue='href-WAI-ARIA 1.1'
 ++++++AXGroup AXHelp='title-https://www.w3.org/TR/wai-aria-practices-1.1/' AXRoleDescription='group'
 ++++++++AXStaticText AXRoleDescription='text' AXValue='link-https://www.w3.org/TR/wai-aria-practices-1.1/'
 ++++++AXButton AXRoleDescription='button' AXTitle='Close'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='1234567'
+++++AXStaticText AXRoleDescription='text' AXValue='href-WAI-ARIA 1.1 Close'
 ++++++AXStaticText AXRoleDescription='text' AXValue='href-WAI-ARIA 1.1 '
 ++++++AXButton AXRoleDescription='button' AXTitle='Close'
diff --git a/content/test/data/accessibility/aria/aria-option-expected-mac.txt b/content/test/data/accessibility/aria/aria-option-expected-mac.txt
index bd5c892..04d3f5c 100644
--- a/content/test/data/accessibility/aria/aria-option-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-option-expected-mac.txt
@@ -1,16 +1,16 @@
 AXWebArea AXRoleDescription='HTML content'
 ++AXList AXRoleDescription='list box'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='option 1'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='label 2'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='caterpillar'
+++++AXStaticText AXRoleDescription='text' AXValue='option 1'
+++++AXStaticText AXRoleDescription='text' AXValue='label 2'
+++++AXStaticText AXRoleDescription='text' AXValue='caterpillar'
 ++++++AXStaticText AXRoleDescription='text' AXValue='cat'
 ++++++AXGroup AXSubrole=AXStrongStyleGroup AXRoleDescription='strong'
 ++++++++AXStaticText AXRoleDescription='text' AXValue='erpillar'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='catfish'
+++++AXStaticText AXRoleDescription='text' AXValue='catfish'
 ++++++AXStaticText AXRoleDescription='text' AXValue='cat'
 ++++++AXGroup AXSubrole=AXEmphasisStyleGroup AXRoleDescription='emphasis'
 ++++++++AXStaticText AXRoleDescription='text' AXValue='fish'
-++++AXMenuItem AXRoleDescription='menu item' AXValue='medusa'
+++++AXStaticText AXRoleDescription='text' AXValue='jellyfish'
 ++++++AXGroup AXSubrole=AXEmphasisStyleGroup AXRoleDescription='emphasis'
 ++++++++AXStaticText AXRoleDescription='text' AXValue='jelly'
 ++++++AXStaticText AXRoleDescription='text' AXValue='fish'
diff --git a/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt b/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt
index b48e1a6..aa72e7c 100644
--- a/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-posinset-expected-mac.txt
@@ -4,11 +4,11 @@
 ++AXGroup AXSubrole=AXDocumentArticle AXRoleDescription='article'
 ++++AXStaticText AXRoleDescription='text' AXValue='This is an ARIA article 2.'
 ++AXList AXARIASetSize=2 AXRoleDescription='list box'
-++++AXMenuItem AXARIAPosInSet=1 AXARIASetSize=2 AXRoleDescription='menu item' AXValue='Item 1'
-++++AXMenuItem AXARIAPosInSet=2 AXARIASetSize=2 AXRoleDescription='menu item' AXValue='Item 2'
+++++AXStaticText AXARIAPosInSet=1 AXARIASetSize=2 AXRoleDescription='text' AXValue='Item 1'
+++++AXStaticText AXARIAPosInSet=2 AXARIASetSize=2 AXRoleDescription='text' AXValue='Item 2'
 ++AXList AXARIASetSize=2 AXRoleDescription='list box'
-++++AXMenuItem AXARIAPosInSet=1 AXARIASetSize=2 AXRoleDescription='menu item' AXValue='Item 1'
-++++AXMenuItem AXARIAPosInSet=2 AXARIASetSize=2 AXRoleDescription='menu item' AXValue='Item 2'
+++++AXStaticText AXARIAPosInSet=1 AXARIASetSize=2 AXRoleDescription='text' AXValue='Item 1'
+++++AXStaticText AXARIAPosInSet=2 AXARIASetSize=2 AXRoleDescription='text' AXValue='Item 2'
 ++AXGroup AXRoleDescription='group'
 ++++AXRadioButton AXARIAPosInSet=3 AXARIASetSize=4 AXRoleDescription='radio button' AXValue=0
 ++++AXStaticText AXRoleDescription='text' AXValue='1'
diff --git a/content/test/data/accessibility/aria/aria-selected-expected-mac.txt b/content/test/data/accessibility/aria/aria-selected-expected-mac.txt
index edefe73..cf071e1 100644
--- a/content/test/data/accessibility/aria/aria-selected-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-selected-expected-mac.txt
@@ -1,4 +1,4 @@
 AXWebArea AXSelected=0
 ++AXList AXSelected=0 AXSelectedChildren=[:3]
-++++AXMenuItem AXSelected=1 AXValue='1'
-++++AXMenuItem AXSelected=0 AXValue='2'
+++++AXStaticText AXSelected=1 AXValue='1'
+++++AXStaticText AXSelected=0 AXValue='2'
diff --git a/content/test/data/accessibility/aria/aria-setsize-expected-mac.txt b/content/test/data/accessibility/aria/aria-setsize-expected-mac.txt
index add8e27..ecc664c 100644
--- a/content/test/data/accessibility/aria/aria-setsize-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria-setsize-expected-mac.txt
@@ -1,12 +1,12 @@
 AXWebArea AXRoleDescription='HTML content'
 ++AXList AXARIASetSize=4 AXRoleDescription='list box'
-++++AXMenuItem AXARIAPosInSet=1 AXARIASetSize=4 AXRoleDescription='menu item' AXValue='Item 1'
-++++AXMenuItem AXARIAPosInSet=2 AXARIASetSize=4 AXRoleDescription='menu item' AXValue='Item 2'
-++++AXMenuItem AXARIAPosInSet=3 AXARIASetSize=4 AXRoleDescription='menu item' AXValue='Item 3'
-++++AXMenuItem AXARIAPosInSet=4 AXARIASetSize=4 AXRoleDescription='menu item' AXValue='Item 4'
+++++AXStaticText AXARIAPosInSet=1 AXARIASetSize=4 AXRoleDescription='text' AXValue='Item 1'
+++++AXStaticText AXARIAPosInSet=2 AXARIASetSize=4 AXRoleDescription='text' AXValue='Item 2'
+++++AXStaticText AXARIAPosInSet=3 AXARIASetSize=4 AXRoleDescription='text' AXValue='Item 3'
+++++AXStaticText AXARIAPosInSet=4 AXARIASetSize=4 AXRoleDescription='text' AXValue='Item 4'
 ++AXList AXARIASetSize=5 AXRoleDescription='list box'
-++++AXMenuItem AXARIAPosInSet=1 AXARIASetSize=5 AXRoleDescription='menu item' AXValue='Item 1'
-++++AXMenuItem AXARIAPosInSet=2 AXARIASetSize=5 AXRoleDescription='menu item' AXValue='Item 2'
-++++AXMenuItem AXARIAPosInSet=3 AXARIASetSize=5 AXRoleDescription='menu item' AXValue='Item 3'
-++++AXMenuItem AXARIAPosInSet=4 AXARIASetSize=5 AXRoleDescription='menu item' AXValue='Item 4'
-++++AXMenuItem AXARIAPosInSet=5 AXARIASetSize=5 AXRoleDescription='menu item' AXValue='Item 5'
+++++AXStaticText AXARIAPosInSet=1 AXARIASetSize=5 AXRoleDescription='text' AXValue='Item 1'
+++++AXStaticText AXARIAPosInSet=2 AXARIASetSize=5 AXRoleDescription='text' AXValue='Item 2'
+++++AXStaticText AXARIAPosInSet=3 AXARIASetSize=5 AXRoleDescription='text' AXValue='Item 3'
+++++AXStaticText AXARIAPosInSet=4 AXARIASetSize=5 AXRoleDescription='text' AXValue='Item 4'
+++++AXStaticText AXARIAPosInSet=5 AXARIASetSize=5 AXRoleDescription='text' AXValue='Item 5'
diff --git a/content/test/data/accessibility/aria/aria1.1-combobox-expected-mac.txt b/content/test/data/accessibility/aria/aria1.1-combobox-expected-mac.txt
index 409f810..96f8201 100644
--- a/content/test/data/accessibility/aria/aria1.1-combobox-expected-mac.txt
+++ b/content/test/data/accessibility/aria/aria1.1-combobox-expected-mac.txt
@@ -4,10 +4,10 @@
 ++AXComboBox AXTitle='State'
 ++++AXTextField AXLinkedUIElements=[:6]
 ++AXList
-++++AXMenuItem AXValue='Alabama'
-++++AXMenuItem AXFocused=1 AXValue='Alaska'
+++++AXStaticText AXValue='Alabama'
+++++AXStaticText AXFocused=1 AXValue='Alaska'
 ++AXComboBox AXTitle='State'
 ++++AXTextField AXLinkedUIElements=[:11]
 ++AXList
-++++AXMenuItem AXValue='Alabama'
-++++AXMenuItem AXValue='Alaska'
+++++AXStaticText AXValue='Alabama'
+++++AXStaticText AXValue='Alaska'
diff --git a/content/test/data/accessibility/aria/option-label-expected-blink.txt b/content/test/data/accessibility/aria/option-label-expected-blink.txt
deleted file mode 100644
index 815b0d8..0000000
--- a/content/test/data/accessibility/aria/option-label-expected-blink.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-rootWebArea
-++genericContainer ignored
-++++genericContainer ignored
-++++++listBox
-++++++++listBoxOption name='A B' selected=false
-++++++++++staticText name='A'
-++++++++++++inlineTextBox name='A'
-++++++++++genericContainer
-++++++++++++staticText name='B'
-++++++++++++++inlineTextBox name='B'
-++++++listBox
-++++++++listBoxOption name='Other' selected=false
-++++++++++staticText name='C'
-++++++++++++inlineTextBox name='C'
-++++++++++genericContainer
-++++++++++++staticText name='D'
-++++++++++++++inlineTextBox name='D'
-++++++listBox
-++++++++listBoxOption name='E F' selected=false
-++++++++++genericContainer
-++++++++++++staticText name='E'
-++++++++++++++inlineTextBox name='E'
-++++++++++genericContainer
-++++++++++++staticText name='F'
-++++++++++++++inlineTextBox name='F'
\ No newline at end of file
diff --git a/content/test/data/accessibility/aria/option-label-expected-mac.txt b/content/test/data/accessibility/aria/option-label-expected-mac.txt
deleted file mode 100644
index 08b8ca8..0000000
--- a/content/test/data/accessibility/aria/option-label-expected-mac.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-AXWebArea
-++AXList
-++++AXMenuItem AXValue='A B'
-++++++AXStaticText AXValue='A'
-++++++AXGroup
-++++++++AXStaticText AXValue='B'
-++AXList
-++++AXMenuItem AXValue='Other'
-++++++AXStaticText AXValue='C'
-++++++AXGroup
-++++++++AXStaticText AXValue='D'
-++AXList
-++++AXMenuItem AXValue='E F'
-++++++AXGroup
-++++++++AXStaticText AXValue='E'
-++++++AXGroup
-++++++++AXStaticText AXValue='F'
diff --git a/content/test/data/accessibility/aria/option-label.html b/content/test/data/accessibility/aria/option-label.html
deleted file mode 100644
index 45a783d..0000000
--- a/content/test/data/accessibility/aria/option-label.html
+++ /dev/null
@@ -1,3 +0,0 @@
-<div role="listbox"><div role="option">A<div>B</div></div></div>
-<div role="listbox"><div role="option" aria-label="Other">C<div>D</div></div></div>
-<div role="listbox"><div role="option" aria-labelledby="id1 id2"><div id="id1">E</div><div id="id2">F</div></div></div>
\ No newline at end of file
diff --git a/content/test/data/accessibility/event/aria-activedescendant-element-tree-changes-expected-mac.txt b/content/test/data/accessibility/event/aria-activedescendant-element-tree-changes-expected-mac.txt
index 663efbe..64f6fa8 100644
--- a/content/test/data/accessibility/event/aria-activedescendant-element-tree-changes-expected-mac.txt
+++ b/content/test/data/accessibility/event/aria-activedescendant-element-tree-changes-expected-mac.txt
@@ -1,12 +1,12 @@
-AXFocusedUIElementChanged on AXMenuItem AXValue='Otter'
+AXFocusedUIElementChanged on AXStaticText AXValue='Otter'
 AXSelectedChildrenChanged on AXList AXDescription='list'
 === Start Continuation ===
 AXFocusedUIElementChanged on AXTextField AXTitle='Mammal'
 === Start Continuation ===
-AXFocusedUIElementChanged on AXMenuItem AXValue='Ocelot'
+AXFocusedUIElementChanged on AXStaticText AXValue='Ocelot'
 AXSelectedChildrenChanged on AXList AXDescription='list'
 === Start Continuation ===
 AXFocusedUIElementChanged on AXTextField AXTitle='Mammal'
 === Start Continuation ===
-AXFocusedUIElementChanged on AXMenuItem AXValue='Opossum'
+AXFocusedUIElementChanged on AXStaticText AXValue='Opossum'
 AXSelectedChildrenChanged on AXList AXDescription='list'
diff --git a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-mac.txt b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-mac.txt
index 9633e7f1..bfe44ed 100644
--- a/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-mac.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-delay-show-list-expected-mac.txt
@@ -1,3 +1,3 @@
-AXFocusedUIElementChanged on AXMenuItem AXValue='Apple'
+AXFocusedUIElementChanged on AXStaticText AXValue='Apple'
 AXSelectedChildrenChanged on AXComboBox AXAutocompleteValue='list'
 AXSelectedChildrenChanged on AXList
diff --git a/content/test/data/accessibility/event/aria-combo-box-expand-expected-mac.txt b/content/test/data/accessibility/event/aria-combo-box-expand-expected-mac.txt
index 1cba862..f33ca00 100644
--- a/content/test/data/accessibility/event/aria-combo-box-expand-expected-mac.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-expand-expected-mac.txt
@@ -4,6 +4,6 @@
 === Start Continuation ===
 AXExpandedChanged on AXComboBox AXAutocompleteValue='list'
 === Start Continuation ===
-AXFocusedUIElementChanged on AXMenuItem AXValue='Apple'
+AXFocusedUIElementChanged on AXStaticText AXValue='Apple'
 AXSelectedChildrenChanged on AXComboBox AXAutocompleteValue='list'
 AXSelectedChildrenChanged on AXList
diff --git a/content/test/data/accessibility/event/aria-combo-box-next-expected-mac.txt b/content/test/data/accessibility/event/aria-combo-box-next-expected-mac.txt
index aaeb9af2..d14a5aa 100644
--- a/content/test/data/accessibility/event/aria-combo-box-next-expected-mac.txt
+++ b/content/test/data/accessibility/event/aria-combo-box-next-expected-mac.txt
@@ -1,7 +1,7 @@
-AXFocusedUIElementChanged on AXMenuItem AXValue='Orange'
+AXFocusedUIElementChanged on AXStaticText AXValue='Orange'
 AXSelectedChildrenChanged on AXComboBox AXAutocompleteValue='list'
 AXSelectedChildrenChanged on AXList
 === Start Continuation ===
-AXFocusedUIElementChanged on AXMenuItem AXValue='Banana'
+AXFocusedUIElementChanged on AXStaticText AXValue='Banana'
 AXSelectedChildrenChanged on AXComboBox AXAutocompleteValue='list'
 AXSelectedChildrenChanged on AXList
diff --git a/content/test/data/accessibility/event/focus-listbox-expected-mac.txt b/content/test/data/accessibility/event/focus-listbox-expected-mac.txt
index 9022caa..ee89e02 100644
--- a/content/test/data/accessibility/event/focus-listbox-expected-mac.txt
+++ b/content/test/data/accessibility/event/focus-listbox-expected-mac.txt
@@ -1,2 +1,2 @@
-AXFocusedUIElementChanged on AXMenuItem AXValue='%C3%A7'
+AXFocusedUIElementChanged on AXStaticText AXValue='%C3%A7'
 AXSelectedChildrenChanged on AXList
diff --git a/content/test/data/accessibility/event/focus-listbox-multiselect-expected-mac.txt b/content/test/data/accessibility/event/focus-listbox-multiselect-expected-mac.txt
index 55568f2..5e3711b 100644
--- a/content/test/data/accessibility/event/focus-listbox-multiselect-expected-mac.txt
+++ b/content/test/data/accessibility/event/focus-listbox-multiselect-expected-mac.txt
@@ -1,2 +1,2 @@
-AXFocusedUIElementChanged on AXMenuItem AXValue='c selected'
+AXFocusedUIElementChanged on AXStaticText AXValue='c selected'
 AXSelectedChildrenChanged on AXList
diff --git a/content/test/data/accessibility/event/listbox-next-expected-mac.txt b/content/test/data/accessibility/event/listbox-next-expected-mac.txt
index 5cf2f742..f1cfbb6 100644
--- a/content/test/data/accessibility/event/listbox-next-expected-mac.txt
+++ b/content/test/data/accessibility/event/listbox-next-expected-mac.txt
@@ -1,2 +1,2 @@
-AXFocusedUIElementChanged on AXMenuItem AXValue='Orange'
+AXFocusedUIElementChanged on AXStaticText AXValue='Orange'
 AXSelectedChildrenChanged on AXList
diff --git a/content/test/data/accessibility/html/button-with-listbox-popup-expected-mac.txt b/content/test/data/accessibility/html/button-with-listbox-popup-expected-mac.txt
index 826358c..f0996f5 100644
--- a/content/test/data/accessibility/html/button-with-listbox-popup-expected-mac.txt
+++ b/content/test/data/accessibility/html/button-with-listbox-popup-expected-mac.txt
@@ -4,6 +4,6 @@
 ++++++AXStaticText AXValue='Choose one:'
 ++++AXPopUpButton AXTitle='Choose one: Foo'
 ++++AXList AXTitle='Choose one:'
-++++++AXMenuItem AXValue='Baz'
-++++++AXMenuItem AXValue='Bar'
-++++++AXMenuItem AXValue='Foo'
+++++++AXStaticText AXValue='Baz'
+++++++AXStaticText AXValue='Bar'
+++++++AXStaticText AXValue='Foo'
diff --git a/content/test/data/accessibility/html/custom-select-expected-mac.txt b/content/test/data/accessibility/html/custom-select-expected-mac.txt
index 8d13f52..e512239 100644
--- a/content/test/data/accessibility/html/custom-select-expected-mac.txt
+++ b/content/test/data/accessibility/html/custom-select-expected-mac.txt
@@ -1,7 +1,7 @@
 AXWebArea AXRoleDescription='HTML content'
 ++AXGroup AXRoleDescription='group'
 ++++AXPopUpButton AXDescription='Currency for purchase' AXRoleDescription='pop up button' AXValue='USD United States Dollar $'
-++++++AXMenuItem AXRoleDescription='menu item' AXValue='USD United States Dollar'
+++++++AXMenuItem AXRoleDescription='menu item' AXValue='USDUnited States Dollar'
 ++++++++AXGroup AXRoleDescription='group'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXGroup AXRoleDescription='group'
diff --git a/content/test/data/accessibility/html/custom-select-open-expected-mac.txt b/content/test/data/accessibility/html/custom-select-open-expected-mac.txt
index 53c7141b..fe251a64 100644
--- a/content/test/data/accessibility/html/custom-select-open-expected-mac.txt
+++ b/content/test/data/accessibility/html/custom-select-open-expected-mac.txt
@@ -2,27 +2,27 @@
 ++AXGroup AXRoleDescription='group'
 ++++AXPopUpButton AXDescription='Currency for purchase' AXRoleDescription='pop up button' AXValue='USD United States Dollar $'
 ++++++AXMenu AXRoleDescription='menu'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='EUR Euro'
+++++++++AXMenuItem AXRoleDescription='menu item' AXValue='EUREuro'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='EUR'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='Euro'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='GBP Great British Pound'
+++++++++AXMenuItem AXRoleDescription='menu item' AXValue='GBPGreat British Pound'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='GBP'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='Great British Pound'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='USD United States Dollar'
+++++++++AXMenuItem AXRoleDescription='menu item' AXValue='USDUnited States Dollar'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='USD'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='United States Dollar'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='JPY Japanese Yen'
+++++++++AXMenuItem AXRoleDescription='menu item' AXValue='JPYJapanese Yen'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='JPY'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='Japanese Yen'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='BTC Bitcoin'
+++++++++AXMenuItem AXRoleDescription='menu item' AXValue='BTCBitcoin'
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXStaticText AXRoleDescription='text' AXValue='BTC'
 ++++++++++AXGroup AXRoleDescription='group'
diff --git a/content/test/data/accessibility/html/input-time-with-popup-open-expected-mac.txt b/content/test/data/accessibility/html/input-time-with-popup-open-expected-mac.txt
index 2926514..7c04e41 100644
--- a/content/test/data/accessibility/html/input-time-with-popup-open-expected-mac.txt
+++ b/content/test/data/accessibility/html/input-time-with-popup-open-expected-mac.txt
@@ -18,151 +18,151 @@
 ++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++AXGroup AXRoleDescription='group'
 ++++++++++++++AXList AXDescription='Hours' AXRoleDescription='list box'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='01'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='02'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='03'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='04'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='05'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='06'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='07'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='08'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='09'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='10'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='11'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='12'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='01'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='02'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='03'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='04'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='05'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='06'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='07'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='08'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='09'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='10'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='11'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='12'
 ++++++++++++++AXList AXDescription='Minutes' AXRoleDescription='list box'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='01'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='02'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='03'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='04'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='05'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='06'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='07'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='08'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='09'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='10'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='11'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='12'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='13'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='14'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='15'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='16'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='17'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='18'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='19'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='20'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='21'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='22'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='23'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='24'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='25'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='26'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='27'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='28'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='29'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='30'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='31'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='32'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='33'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='34'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='35'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='36'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='37'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='38'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='39'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='40'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='41'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='42'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='43'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='44'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='45'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='46'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='47'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='48'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='49'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='50'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='51'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='52'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='53'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='54'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='55'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='56'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='57'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='58'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='59'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='00'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='01'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='02'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='03'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='04'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='05'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='06'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='07'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='08'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='09'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='10'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='11'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='12'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='13'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='14'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='15'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='16'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='17'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='18'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='19'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='20'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='21'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='22'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='23'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='24'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='25'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='26'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='27'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='28'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='29'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='30'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='31'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='32'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='33'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='34'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='35'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='36'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='37'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='38'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='39'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='40'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='41'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='42'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='43'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='44'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='45'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='46'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='47'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='48'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='49'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='50'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='51'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='52'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='53'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='54'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='55'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='56'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='57'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='58'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='59'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='00'
 ++++++++++++++AXList AXDescription='Seconds' AXRoleDescription='list box'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='01'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='02'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='03'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='04'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='05'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='06'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='07'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='08'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='09'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='10'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='11'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='12'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='13'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='14'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='15'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='16'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='17'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='18'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='19'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='20'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='21'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='22'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='23'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='24'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='25'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='26'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='27'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='28'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='29'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='30'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='31'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='32'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='33'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='34'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='35'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='36'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='37'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='38'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='39'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='40'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='41'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='42'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='43'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='44'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='45'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='46'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='47'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='48'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='49'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='50'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='51'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='52'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='53'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='54'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='55'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='56'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='57'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='58'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='59'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='00'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='01'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='02'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='03'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='04'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='05'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='06'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='07'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='08'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='09'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='10'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='11'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='12'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='13'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='14'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='15'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='16'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='17'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='18'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='19'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='20'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='21'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='22'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='23'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='24'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='25'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='26'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='27'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='28'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='29'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='30'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='31'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='32'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='33'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='34'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='35'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='36'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='37'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='38'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='39'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='40'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='41'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='42'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='43'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='44'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='45'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='46'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='47'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='48'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='49'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='50'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='51'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='52'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='53'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='54'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='55'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='56'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='57'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='58'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='59'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='00'
 ++++++++++++++AXList AXDescription='Milliseconds' AXRoleDescription='list box'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='100'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='200'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='300'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='400'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='500'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='600'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='700'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='800'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='922'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='000'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='100'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='200'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='300'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='400'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='500'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='600'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='700'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='800'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='922'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='000'
 ++++++++++++++AXList AXDescription='AM/PM' AXRoleDescription='list box'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='PM'
-++++++++++++++++AXMenuItem AXRoleDescription='menu item' AXValue='AM'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='PM'
+++++++++++++++++AXStaticText AXRoleDescription='text' AXValue='AM'
\ No newline at end of file
diff --git a/content/test/data/accessibility/html/interactive-controls-with-labels-expected-mac.txt b/content/test/data/accessibility/html/interactive-controls-with-labels-expected-mac.txt
index 517b611..5f1945b5 100644
--- a/content/test/data/accessibility/html/interactive-controls-with-labels-expected-mac.txt
+++ b/content/test/data/accessibility/html/interactive-controls-with-labels-expected-mac.txt
@@ -13,22 +13,22 @@
 ++AXButton AXTitle='Test label'
 ++AXComboBox AXDescription='aria label'
 ++AXList
-++++AXMenuItem AXValue='Option 1'
-++++AXMenuItem AXValue='Option 2'
+++++AXStaticText AXValue='Option 1'
+++++AXStaticText AXValue='Option 2'
 ++AXComboBox AXTitle='Test label'
 ++AXList
-++++AXMenuItem AXValue='Option 3'
-++++AXMenuItem AXValue='Option 4'
+++++AXStaticText AXValue='Option 3'
+++++AXStaticText AXValue='Option 4'
 ++AXComboBox AXDescription='aria label' AXValue='Combobox'
 ++++AXStaticText AXValue='Combobox'
 ++AXList
-++++AXMenuItem AXValue='Option 5'
-++++AXMenuItem AXValue='Option 6'
+++++AXStaticText AXValue='Option 5'
+++++AXStaticText AXValue='Option 6'
 ++AXComboBox AXTitle='Test label' AXValue='Combobox with aria-labelledby'
 ++++AXStaticText AXValue='Combobox with aria-labelledby'
 ++AXList
-++++AXMenuItem AXValue='Option 7'
-++++AXMenuItem AXValue='Option 8'
+++++AXStaticText AXValue='Option 7'
+++++AXStaticText AXValue='Option 8'
 ++AXTimeField AXDescription='aria label' AXValue='12:05'
 ++++AXGroup
 ++++++AXGroup
diff --git a/content/test/data/accessibility/html/optgroup-expected-mac.txt b/content/test/data/accessibility/html/optgroup-expected-mac.txt
index 35036cf..82fd967 100644
--- a/content/test/data/accessibility/html/optgroup-expected-mac.txt
+++ b/content/test/data/accessibility/html/optgroup-expected-mac.txt
@@ -2,14 +2,14 @@
 ++AXGroup AXRoleDescription='group'
 ++++AXList AXRoleDescription='list box'
 ++++++AXGroup AXSubrole=AXApplicationGroup AXDescription='Enabled' AXRoleDescription='group'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='One'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='Two'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='Three'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='Four'
+++++++++AXStaticText AXRoleDescription='text' AXValue='One'
+++++++++AXStaticText AXRoleDescription='text' AXValue='Two'
+++++++++AXStaticText AXRoleDescription='text' AXValue='Three'
+++++++++AXStaticText AXRoleDescription='text' AXValue='Four'
 ++++++AXGroup AXSubrole=AXApplicationGroup AXDescription='Disabled' AXRoleDescription='group'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='One'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='Two'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='Three'
-++++++++AXMenuItem AXRoleDescription='menu item' AXValue='Four'
+++++++++AXStaticText AXRoleDescription='text' AXValue='One'
+++++++++AXStaticText AXRoleDescription='text' AXValue='Two'
+++++++++AXStaticText AXRoleDescription='text' AXValue='Three'
+++++++++AXStaticText AXRoleDescription='text' AXValue='Four'
 ++++AXPopUpButton AXRoleDescription='pop up button' AXValue='Random Transformer'
 ++++++AXMenuItem AXRoleDescription='menu item' AXValue='Random Transformer'
diff --git a/content/test/data/accessibility/html/select-expected-mac.txt b/content/test/data/accessibility/html/select-expected-mac.txt
index 285a9b2..3b41687 100644
--- a/content/test/data/accessibility/html/select-expected-mac.txt
+++ b/content/test/data/accessibility/html/select-expected-mac.txt
@@ -7,10 +7,10 @@
 ++++AXPopUpButton AXRoleDescription='pop up button' AXValue='Option 1'
 ++++++AXMenuItem AXRoleDescription='menu item' AXValue='Option 1'
 ++++AXList AXRoleDescription='list box'
-++++++AXMenuItem AXRoleDescription='menu item' AXValue='Option 1 not selected'
-++++++AXMenuItem AXRoleDescription='menu item' AXValue='Option 2 not selected'
-++++++AXMenuItem AXRoleDescription='menu item' AXValue='Option 3 not selected'
+++++++AXStaticText AXRoleDescription='text' AXValue='Option 1 not selected'
+++++++AXStaticText AXRoleDescription='text' AXValue='Option 2 not selected'
+++++++AXStaticText AXRoleDescription='text' AXValue='Option 3 not selected'
 ++++AXList AXRoleDescription='list box'
-++++++AXMenuItem AXRoleDescription='menu item' AXValue='Option 1'
-++++++AXMenuItem AXRoleDescription='menu item' AXValue='Option 2'
-++++++AXMenuItem AXRoleDescription='menu item' AXValue='Option 3'
+++++++AXStaticText AXRoleDescription='text' AXValue='Option 1'
+++++++AXStaticText AXRoleDescription='text' AXValue='Option 2'
+++++++AXStaticText AXRoleDescription='text' AXValue='Option 3'
diff --git a/docs/website b/docs/website
index 31a2f43..24d837ac 160000
--- a/docs/website
+++ b/docs/website
@@ -1 +1 @@
-Subproject commit 31a2f432dc14e60054e2a361f4fa16ffff65e01b
+Subproject commit 24d837acc5671ab1bffac9b8a49de5847c0025a6
diff --git a/infra/inclusive_language_presubmit_exempt_dirs.txt b/infra/inclusive_language_presubmit_exempt_dirs.txt
index 6da3f2fd..21c6ed44 100644
--- a/infra/inclusive_language_presubmit_exempt_dirs.txt
+++ b/infra/inclusive_language_presubmit_exempt_dirs.txt
@@ -650,11 +650,11 @@
 third_party/rust/chromium_crates_io/vendor/byteorder-1.5.0/.github/workflows 5 1
 third_party/rust/chromium_crates_io/vendor/bytes-1.9.0/.github/workflows 3 1
 third_party/rust/chromium_crates_io/vendor/cfg-if-1.0.0/.github/workflows 4 1
-third_party/rust/chromium_crates_io/vendor/clap-4.5.21 2 1
-third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src 4 2
-third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src 1 1
-third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder 10 3
-third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser 1 1
+third_party/rust/chromium_crates_io/vendor/clap-4.5.23 2 1
+third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src 4 2
+third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src 1 1
+third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder 10 3
+third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser 1 1
 third_party/rust/chromium_crates_io/vendor/codespan-reporting-0.11.1 2 1
 third_party/rust/chromium_crates_io/vendor/codespan-reporting-0.11.1/examples 1 1
 third_party/rust/chromium_crates_io/vendor/crc32fast-1.4.2/.github/workflows 2 1
diff --git a/internal b/internal
index 988e04e..7b05527 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit 988e04e61c5fc061c4443c7b9a0c3ffa8e3bb0d8
+Subproject commit 7b0552739dbba05794c3ffa8f35aa0eccc8400f4
diff --git a/ios_internal b/ios_internal
index 178cb6b..ea8b061 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 178cb6bc81569dcbfdcdb991ea73a8c35944a104
+Subproject commit ea8b061b465214cc89a4d539ac35c26f01670698
diff --git a/media/base/decoder_buffer.cc b/media/base/decoder_buffer.cc
index 6bb85333..847de1c 100644
--- a/media/base/decoder_buffer.cc
+++ b/media/base/decoder_buffer.cc
@@ -158,7 +158,7 @@
 
 DecoderBufferSideData& DecoderBuffer::WritableSideData() {
   DCHECK(!end_of_stream());
-  if (!has_side_data()) {
+  if (!side_data()) {
     side_data_ = std::make_unique<DecoderBufferSideData>();
   }
   return *side_data_;
@@ -176,12 +176,8 @@
     return false;
   }
 
-  if (has_side_data() != buffer.has_side_data()) {
-    return false;
-  }
-
   // Note: We use `side_data_` directly to avoid DCHECKs for EOS buffers.
-  if (has_side_data() && !side_data_->Matches(*buffer.side_data_)) {
+  if (side_data_ && !side_data_->Matches(*buffer.side_data_)) {
     return false;
   }
 
@@ -239,8 +235,8 @@
     << " encrypted=" << (decrypt_config_ != nullptr);
 
   if (verbose) {
-    s << " has_side_data=" << has_side_data();
-    if (has_side_data()) {
+    s << " side_data=" << !!side_data();
+    if (side_data()) {
       s << " discard_padding (us)=("
         << side_data_->discard_padding.first.InMicroseconds() << ", "
         << side_data_->discard_padding.second.InMicroseconds() << ")";
@@ -270,7 +266,7 @@
   memory_usage += size();
 
   // Side data and decrypt config would not change after construction.
-  if (has_side_data()) {
+  if (side_data()) {
     memory_usage += sizeof(decltype(side_data_->spatial_layers)::value_type) *
                     side_data_->spatial_layers.capacity();
     memory_usage += side_data_->alpha_data.size();
diff --git a/media/base/decoder_buffer.h b/media/base/decoder_buffer.h
index e759124..64c50df 100644
--- a/media/base/decoder_buffer.h
+++ b/media/base/decoder_buffer.h
@@ -246,8 +246,6 @@
     is_key_frame_ = is_key_frame;
   }
 
-  bool has_side_data() const { return !!side_data_; }
-
   // Returns DecoderBufferSideData associated with `this`. Check if `side_data_`
   // exists using `has_side_data()` before calling this function.
   const DecoderBufferSideData* side_data() const {
diff --git a/media/base/decoder_buffer_unittest.cc b/media/base/decoder_buffer_unittest.cc
index a263b39..a74dad5a 100644
--- a/media/base/decoder_buffer_unittest.cc
+++ b/media/base/decoder_buffer_unittest.cc
@@ -256,7 +256,7 @@
 
 TEST(DecoderBufferTest, SideData) {
   scoped_refptr<DecoderBuffer> buffer(new DecoderBuffer(0));
-  EXPECT_FALSE(buffer->has_side_data());
+  EXPECT_FALSE(buffer->side_data());
 
   constexpr uint64_t kSecureHandle = 42;
   const std::vector<uint32_t> kSpatialLayers = {1, 2, 3};
@@ -266,7 +266,7 @@
   buffer->WritableSideData().spatial_layers = kSpatialLayers;
   buffer->WritableSideData().alpha_data =
       base::HeapArray<uint8_t>::CopiedFrom(kAlphaData);
-  EXPECT_TRUE(buffer->has_side_data());
+  EXPECT_TRUE(buffer->side_data());
   EXPECT_EQ(buffer->side_data()->secure_handle, kSecureHandle);
   EXPECT_EQ(buffer->side_data()->spatial_layers, kSpatialLayers);
   EXPECT_EQ(buffer->side_data()->alpha_data.as_span(), base::span(kAlphaData));
@@ -281,7 +281,7 @@
             cloned_side_data->alpha_data.as_span());
 
   buffer->set_side_data(nullptr);
-  EXPECT_FALSE(buffer->has_side_data());
+  EXPECT_FALSE(buffer->side_data());
 }
 
 TEST(DecoderBufferTest, IsEncrypted) {
diff --git a/media/cast/openscreen/remoting_proto_utils.cc b/media/cast/openscreen/remoting_proto_utils.cc
index 095ccbe0..a86aab7 100644
--- a/media/cast/openscreen/remoting_proto_utils.cc
+++ b/media/cast/openscreen/remoting_proto_utils.cc
@@ -92,7 +92,7 @@
   buffer_message->set_back_discard_usec(
       decoder_buffer.discard_padding().second.InMicroseconds());
 
-  if (decoder_buffer.has_side_data() &&
+  if (decoder_buffer.side_data() &&
       !decoder_buffer.side_data()->alpha_data.empty()) {
     buffer_message->set_side_data(
         decoder_buffer.side_data()->alpha_data.data(),
diff --git a/media/cast/openscreen/remoting_proto_utils_unittest.cc b/media/cast/openscreen/remoting_proto_utils_unittest.cc
index 1403ca15..b689513 100644
--- a/media/cast/openscreen/remoting_proto_utils_unittest.cc
+++ b/media/cast/openscreen/remoting_proto_utils_unittest.cc
@@ -84,7 +84,7 @@
   ASSERT_TRUE(output_buffer->is_key_frame());
   ASSERT_EQ(output_buffer->timestamp(), pts);
   EXPECT_EQ(base::span(*output_buffer), base::span(buffer));
-  ASSERT_TRUE(output_buffer->has_side_data());
+  ASSERT_TRUE(output_buffer->side_data());
   EXPECT_EQ(output_buffer->side_data()->alpha_data.as_span(),
             base::span(side_buffer));
 }
diff --git a/media/cdm/cbcs_decryptor.cc b/media/cdm/cbcs_decryptor.cc
index a7e5575..206b3e6 100644
--- a/media/cdm/cbcs_decryptor.cc
+++ b/media/cdm/cbcs_decryptor.cc
@@ -148,7 +148,7 @@
   buffer->set_timestamp(input.timestamp());
   buffer->set_duration(input.duration());
   buffer->set_is_key_frame(input.is_key_frame());
-  if (input.has_side_data()) {
+  if (input.side_data()) {
     buffer->set_side_data(input.side_data()->Clone());
   }
 
diff --git a/media/cdm/cbcs_decryptor_unittest.cc b/media/cdm/cbcs_decryptor_unittest.cc
index e9403d5..9287206c 100644
--- a/media/cdm/cbcs_decryptor_unittest.cc
+++ b/media/cdm/cbcs_decryptor_unittest.cc
@@ -147,7 +147,7 @@
   EXPECT_EQ(encrypted_buffer->end_of_stream(),
             decrypted_buffer->end_of_stream());
   EXPECT_EQ(encrypted_buffer->is_key_frame(), decrypted_buffer->is_key_frame());
-  EXPECT_TRUE(decrypted_buffer->has_side_data());
+  EXPECT_TRUE(decrypted_buffer->side_data());
   EXPECT_TRUE(
       encrypted_buffer->side_data()->Matches(*decrypted_buffer->side_data()));
 }
diff --git a/media/cdm/cenc_decryptor.cc b/media/cdm/cenc_decryptor.cc
index 3f2e28a8..ff103d2 100644
--- a/media/cdm/cenc_decryptor.cc
+++ b/media/cdm/cenc_decryptor.cc
@@ -62,7 +62,7 @@
   output->set_timestamp(input.timestamp());
   output->set_duration(input.duration());
   output->set_is_key_frame(input.is_key_frame());
-  if (input.has_side_data()) {
+  if (input.side_data()) {
     output->set_side_data(input.side_data()->Clone());
   }
 }
diff --git a/media/cdm/cenc_decryptor_unittest.cc b/media/cdm/cenc_decryptor_unittest.cc
index 409c312..277ebb3 100644
--- a/media/cdm/cenc_decryptor_unittest.cc
+++ b/media/cdm/cenc_decryptor_unittest.cc
@@ -108,7 +108,7 @@
   EXPECT_EQ(encrypted_buffer->end_of_stream(),
             decrypted_buffer->end_of_stream());
   EXPECT_EQ(encrypted_buffer->is_key_frame(), decrypted_buffer->is_key_frame());
-  EXPECT_TRUE(decrypted_buffer->has_side_data());
+  EXPECT_TRUE(decrypted_buffer->side_data());
   EXPECT_TRUE(
       encrypted_buffer->side_data()->Matches(*decrypted_buffer->side_data()));
 }
diff --git a/media/filters/vpx_video_decoder.cc b/media/filters/vpx_video_decoder.cc
index 068f8ed..fc89212 100644
--- a/media/filters/vpx_video_decoder.cc
+++ b/media/filters/vpx_video_decoder.cc
@@ -420,7 +420,7 @@
     const struct vpx_image** vpx_image_alpha,
     const DecoderBuffer* buffer) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  if (!vpx_codec_alpha_ || !buffer->has_side_data() ||
+  if (!vpx_codec_alpha_ || !buffer->side_data() ||
       buffer->side_data()->alpha_data.size() < 8) {
     return kAlphaPlaneProcessed;
   }
diff --git a/media/gpu/av1_decoder.cc b/media/gpu/av1_decoder.cc
index 862fb948..61b901ed 100644
--- a/media/gpu/av1_decoder.cc
+++ b/media/gpu/av1_decoder.cc
@@ -216,8 +216,7 @@
     decrypt_config_ = decoder_buffer.decrypt_config()->Clone();
   else
     decrypt_config_.reset();
-  if (decoder_buffer.has_side_data() &&
-      decoder_buffer.side_data()->secure_handle) {
+  if (decoder_buffer.side_data() && decoder_buffer.side_data()->secure_handle) {
     secure_handle_ = decoder_buffer.side_data()->secure_handle;
   } else {
     secure_handle_ = 0;
diff --git a/media/gpu/chromeos/decoder_buffer_transcryptor.cc b/media/gpu/chromeos/decoder_buffer_transcryptor.cc
index c095864..d44866e 100644
--- a/media/gpu/chromeos/decoder_buffer_transcryptor.cc
+++ b/media/gpu/chromeos/decoder_buffer_transcryptor.cc
@@ -144,7 +144,7 @@
     current_transcrypt_task_->buffer->set_duration(superframe->duration());
     current_transcrypt_task_->buffer->set_is_key_frame(
         superframe->is_key_frame());
-    if (superframe->has_side_data()) {
+    if (superframe->side_data()) {
       current_transcrypt_task_->buffer->set_side_data(
           superframe->side_data()->Clone());
     }
@@ -182,8 +182,7 @@
   }
 
   // If we've already attached a secure buffer, don't do it again.
-  if (!curr_buffer->has_side_data() ||
-      !curr_buffer->side_data()->secure_handle) {
+  if (!curr_buffer->side_data() || !curr_buffer->side_data()->secure_handle) {
     auto status =
         decoder_->AttachSecureBuffer(current_transcrypt_task_->buffer);
     if (status == CroStatus::Codes::kSecureBufferPoolEmpty) {
@@ -196,8 +195,7 @@
       return;
     }
 
-    if (curr_buffer->has_side_data() &&
-        curr_buffer->side_data()->secure_handle) {
+    if (curr_buffer->side_data() && curr_buffer->side_data()->secure_handle) {
       // Wrap the callback so we can release the secure buffer when decoding is
       // done.
       current_transcrypt_task_->decode_done_cb =
diff --git a/media/gpu/h264_decoder.cc b/media/gpu/h264_decoder.cc
index 8a6d19e..1cab0e1 100644
--- a/media/gpu/h264_decoder.cc
+++ b/media/gpu/h264_decoder.cc
@@ -1478,8 +1478,7 @@
     parser_.SetStream(ptr, size);
     current_decrypt_config_ = nullptr;
   }
-  if (decoder_buffer.has_side_data() &&
-      decoder_buffer.side_data()->secure_handle) {
+  if (decoder_buffer.side_data() && decoder_buffer.side_data()->secure_handle) {
     secure_handle_ = decoder_buffer.side_data()->secure_handle;
   } else {
     secure_handle_ = 0;
diff --git a/media/gpu/h265_decoder.cc b/media/gpu/h265_decoder.cc
index 69c5b6c..b00ed916 100644
--- a/media/gpu/h265_decoder.cc
+++ b/media/gpu/h265_decoder.cc
@@ -168,8 +168,7 @@
     parser_.SetStream(ptr, size);
     current_decrypt_config_ = nullptr;
   }
-  if (decoder_buffer.has_side_data() &&
-      decoder_buffer.side_data()->secure_handle) {
+  if (decoder_buffer.side_data() && decoder_buffer.side_data()->secure_handle) {
     secure_handle_ = decoder_buffer.side_data()->secure_handle;
   } else {
     secure_handle_ = 0;
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
index 0300561..312f2ddc 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decode_accelerator.cc
@@ -78,7 +78,7 @@
 bool IsVp9KSVCStream(uint32_t input_format_fourcc,
                      const DecoderBuffer& decoder_buffer) {
   return input_format_fourcc == V4L2_PIX_FMT_VP9 &&
-         decoder_buffer.has_side_data() &&
+         decoder_buffer.side_data() &&
          !decoder_buffer.side_data()->spatial_layers.empty();
 }
 
diff --git a/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc b/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
index f80022e..00878c2b 100644
--- a/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
+++ b/media/gpu/v4l2/legacy/v4l2_video_decoder_backend_stateful.cc
@@ -35,7 +35,7 @@
 bool IsVp9KSVCStream(VideoCodecProfile profile,
                      const DecoderBuffer& decoder_buffer) {
   return VideoCodecProfileToVideoCodec(profile) == VideoCodec::kVP9 &&
-         decoder_buffer.has_side_data() &&
+         decoder_buffer.side_data() &&
          !decoder_buffer.side_data()->spatial_layers.empty();
 }
 
diff --git a/media/gpu/v4l2/v4l2_vp9_helpers.cc b/media/gpu/v4l2/v4l2_vp9_helpers.cc
index 9b0c3ec..a8e49406 100644
--- a/media/gpu/v4l2/v4l2_vp9_helpers.cc
+++ b/media/gpu/v4l2/v4l2_vp9_helpers.cc
@@ -103,7 +103,7 @@
 }  // namespace
 
 bool AppendVP9SuperFrameIndex(scoped_refptr<DecoderBuffer>& buffer) {
-  DCHECK(buffer->has_side_data());
+  DCHECK(buffer->side_data());
   std::vector<uint32_t> frame_sizes = buffer->side_data()->spatial_layers;
   DCHECK(!frame_sizes.empty());
 
diff --git a/media/gpu/vp9_decoder.cc b/media/gpu/vp9_decoder.cc
index f69e89ca..e94b692 100644
--- a/media/gpu/vp9_decoder.cc
+++ b/media/gpu/vp9_decoder.cc
@@ -23,7 +23,7 @@
                               std::vector<uint32_t>& frame_sizes) {
   frame_sizes.clear();
 
-  if (!decoder_buffer.has_side_data() ||
+  if (!decoder_buffer.side_data() ||
       decoder_buffer.side_data()->spatial_layers.empty()) {
     return true;
   }
@@ -134,8 +134,7 @@
     SetError();
     return;
   }
-  if (decoder_buffer.has_side_data() &&
-      decoder_buffer.side_data()->secure_handle) {
+  if (decoder_buffer.side_data() && decoder_buffer.side_data()->secure_handle) {
     secure_handle_ = decoder_buffer.side_data()->secure_handle;
   } else {
     secure_handle_ = 0;
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc
index b572eeb2..f855b2e 100644
--- a/media/gpu/windows/d3d11_video_decoder.cc
+++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -500,7 +500,7 @@
   }
 
   const bool is_spatial_layer_buffer =
-      !buffer->end_of_stream() && buffer->has_side_data() &&
+      !buffer->end_of_stream() && buffer->side_data() &&
       !buffer->side_data()->spatial_layers.empty();
 
   input_buffer_queue_.push_back(
diff --git a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
index aaaf4d6..00d43c74 100644
--- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
+++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -2071,21 +2071,18 @@
     hr = PerformD3DScaling(input_texture.Get(), frame->visible_rect());
     RETURN_ON_HR_FAILURE(hr, "Failed to perform D3D video processing", hr);
     sample_texture = scaled_d3d11_texture_;
+  } else if (frame->HasSharedImage()) {
+    // The texture is already a copied version so we can directly use it.
+    sample_texture = input_texture;
   } else {
     // Even though no scaling is needed we still need to copy the texture to
     // avoid concurrent usage causing glitches (https://crbug.com/1462315). This
     // is preferred over holding a keyed mutex for the duration of the encode
     // operation since that can take a significant amount of time and mutex
     // acquisitions (necessary even for read-only operations) are blocking.
-    ComD3D11Device texture_device;
-    input_texture->GetDevice(&texture_device);
-    if (texture_device == dxgi_device_manager_->GetDevice()) {
-      sample_texture = input_texture;
-    } else {
       hr = PerformD3DCopy(input_texture.Get(), frame->visible_rect());
       RETURN_ON_HR_FAILURE(hr, "Failed to perform D3D texture copy", hr);
       sample_texture = copied_d3d11_texture_;
-    }
   }
 
   ComMFMediaBuffer input_buffer;
@@ -2540,9 +2537,7 @@
   video_context_->VideoProcessorSetOutputColorSpace(video_processor_.Get(),
                                                     &output_d3d11_color_space);
 
-  ComD3D11Device texture_device;
-  input_texture->GetDevice(&texture_device);
-  if (texture_device != dxgi_device_manager_->GetDevice()) {
+  {
     std::optional<gpu::DXGIScopedReleaseKeyedMutex> release_keyed_mutex;
     ComDXGIKeyedMutex keyed_mutex;
     hr = input_texture->QueryInterface(IID_PPV_ARGS(&keyed_mutex));
diff --git a/media/mojo/clients/mojo_stable_video_decoder_unittest.cc b/media/mojo/clients/mojo_stable_video_decoder_unittest.cc
index 6f421cb..562682b8a 100644
--- a/media/mojo/clients/mojo_stable_video_decoder_unittest.cc
+++ b/media/mojo/clients/mojo_stable_video_decoder_unittest.cc
@@ -855,7 +855,7 @@
     EXPECT_EQ(decoder_buffer_to_send->is_key_frame(), kIsKeyFrame);
     ASSERT_EQ(decoder_buffer_to_send->size(), std::size(kEncodedData));
     EXPECT_EQ(base::span(*decoder_buffer_to_send), base::span(kEncodedData));
-    ASSERT_TRUE(decoder_buffer_to_send->has_side_data());
+    ASSERT_TRUE(decoder_buffer_to_send->side_data());
     EXPECT_EQ(decoder_buffer_to_send->side_data()->secure_handle,
               kSecureHandle);
   }
diff --git a/media/mojo/common/media_type_converters.cc b/media/mojo/common/media_type_converters.cc
index 60a94b1e..9321f16e 100644
--- a/media/mojo/common/media_type_converters.cc
+++ b/media/mojo/common/media_type_converters.cc
@@ -124,7 +124,7 @@
   data_buffer->duration = input.duration();
   data_buffer->is_key_frame = input.is_key_frame();
   data_buffer->data_size = base::checked_cast<uint32_t>(input.size());
-  if (input.has_side_data()) {
+  if (input.side_data()) {
     data_buffer->side_data =
         media::mojom::DecoderBufferSideData::From(*input.side_data());
   }
diff --git a/media/mojo/common/media_type_converters_unittest.cc b/media/mojo/common/media_type_converters_unittest.cc
index b0bb0bfb..63d09729 100644
--- a/media/mojo/common/media_type_converters_unittest.cc
+++ b/media/mojo/common/media_type_converters_unittest.cc
@@ -91,7 +91,7 @@
   // Note: We intentionally do not serialize the data section of the
   // DecoderBuffer; no need to check the data here.
   EXPECT_EQ(kDataSize, result->size());
-  EXPECT_TRUE(result->has_side_data());
+  EXPECT_TRUE(result->side_data());
   EXPECT_TRUE(buffer->side_data()->Matches(*result->side_data()));
   EXPECT_EQ(buffer->timestamp(), result->timestamp());
   EXPECT_EQ(buffer->duration(), result->duration());
diff --git a/media/mojo/mojom/BUILD.gn b/media/mojo/mojom/BUILD.gn
index 99c3fe02..5ed07ef 100644
--- a/media/mojo/mojom/BUILD.gn
+++ b/media/mojo/mojom/BUILD.gn
@@ -846,6 +846,7 @@
   public_deps = [
     ":audio_data",
     ":speech_recognition_audio_forwarder",
+    ":speech_recognition_recognition_context",
     ":web_speech_recognition",
     "//mojo/public/mojom/base",
     "//sandbox/policy/mojom",
@@ -853,6 +854,30 @@
   ]
 }
 
+mojom("speech_recognition_recognition_context") {
+  generate_java = true
+  sources = [ "speech_recognition_recognition_context.mojom" ]
+  cpp_typemaps = [
+    {
+      types = [
+        {
+          mojom = "media.mojom.SpeechRecognitionRecognitionContext"
+          cpp = "::media::SpeechRecognitionRecognitionContext"
+        },
+      ]
+      traits_headers = [
+        "speech_recognition_recognition_context.h",
+        "speech_recognition_recognition_context_mojom_traits.h",
+      ]
+      traits_sources = [
+        "speech_recognition_recognition_context.cc",
+        "speech_recognition_recognition_context_mojom_traits.cc",
+      ]
+      traits_public_deps = [ "//base" ]
+    },
+  ]
+}
+
 source_set("shared_mojom_traits") {
   sources = [
     "audio_processing_mojom_traits.cc",
@@ -897,6 +922,7 @@
     "audio_decoder_config_mojom_traits_unittest.cc",
     "audio_processing_mojom_traits_unittest.cc",
     "cdm_key_information_mojom_traits_unittest.cc",
+    "speech_recognition_recognition_context_mojom_traits_unittest.cc",
     "video_decoder_config_mojom_traits_unittest.cc",
     "video_encode_accelerator_mojom_traits_unittest.cc",
     "video_frame_metadata_mojom_traits_unittest.cc",
@@ -909,6 +935,7 @@
 
   deps = [
     ":speech_recognition",
+    ":speech_recognition_recognition_context",
     "//base",
     "//base/test:test_support",
     "//media:test_support",
@@ -927,13 +954,13 @@
     "speech_recognition_error.mojom",
     "speech_recognition_error_code.mojom",
     "speech_recognition_grammar.mojom",
-    "speech_recognition_recognition_context.mojom",
     "speech_recognition_result.mojom",
     "speech_recognizer.mojom",
   ]
 
   deps = [
     ":speech_recognition_audio_forwarder",
+    ":speech_recognition_recognition_context",
     "//mojo/public/mojom/base",
     "//url/mojom:url_mojom_gurl",
   ]
diff --git a/media/mojo/mojom/speech_recognition_recognition_context.cc b/media/mojo/mojom/speech_recognition_recognition_context.cc
new file mode 100644
index 0000000..761d1e7
--- /dev/null
+++ b/media/mojo/mojom/speech_recognition_recognition_context.cc
@@ -0,0 +1,37 @@
+// 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 "media/mojo/mojom/speech_recognition_recognition_context.h"
+
+namespace media {
+
+SpeechRecognitionPhrase::SpeechRecognitionPhrase() = default;
+SpeechRecognitionPhrase::SpeechRecognitionPhrase(const std::string phrase,
+                                                 float boost)
+    : phrase(std::move(phrase)), boost(boost) {}
+SpeechRecognitionPhrase::SpeechRecognitionPhrase(
+    const SpeechRecognitionPhrase&) = default;
+SpeechRecognitionPhrase::~SpeechRecognitionPhrase() = default;
+
+bool SpeechRecognitionPhrase::operator==(
+    const SpeechRecognitionPhrase& rhs) const {
+  return phrase == rhs.phrase && boost == rhs.boost;
+}
+
+SpeechRecognitionRecognitionContext::SpeechRecognitionRecognitionContext() =
+    default;
+SpeechRecognitionRecognitionContext::SpeechRecognitionRecognitionContext(
+    const std::vector<SpeechRecognitionPhrase> phrases)
+    : phrases(std::move(phrases)) {}
+SpeechRecognitionRecognitionContext::SpeechRecognitionRecognitionContext(
+    const SpeechRecognitionRecognitionContext&) = default;
+SpeechRecognitionRecognitionContext::~SpeechRecognitionRecognitionContext() =
+    default;
+
+bool SpeechRecognitionRecognitionContext::operator==(
+    const SpeechRecognitionRecognitionContext& rhs) const {
+  return phrases == rhs.phrases;
+}
+
+}  // namespace media
diff --git a/media/mojo/mojom/speech_recognition_recognition_context.h b/media/mojo/mojom/speech_recognition_recognition_context.h
new file mode 100644
index 0000000..69cf3b37
--- /dev/null
+++ b/media/mojo/mojom/speech_recognition_recognition_context.h
@@ -0,0 +1,50 @@
+// 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 MEDIA_MOJO_MOJOM_SPEECH_RECOGNITION_RECOGNITION_CONTEXT_H_
+#define MEDIA_MOJO_MOJOM_SPEECH_RECOGNITION_RECOGNITION_CONTEXT_H_
+
+#include <string>
+#include <vector>
+
+namespace media {
+
+// Definition of the phrase for speech recognition biasing.
+struct SpeechRecognitionPhrase {
+  SpeechRecognitionPhrase();
+  SpeechRecognitionPhrase(const std::string phrase, float boost);
+  SpeechRecognitionPhrase(const SpeechRecognitionPhrase&);
+  ~SpeechRecognitionPhrase();
+
+  bool operator==(const SpeechRecognitionPhrase& rhs) const;
+
+  // Text to be boosted for speech recognition biasing.
+  std::string phrase;
+
+  // Represents approximately the natural log of the number of times more likely
+  // you think this phrase is than what the recognizer knows. A reasonable boost
+  // value should be inside the range [0, 10], with a default value of 1. A
+  // boost value of 0 means the phrase is not boosted at all, and a higher boost
+  // value means the phrase is more likely to appear.
+  float boost = 0;
+};
+
+// A collection of recognition context for speech recognition biasing.
+struct SpeechRecognitionRecognitionContext {
+  SpeechRecognitionRecognitionContext();
+  SpeechRecognitionRecognitionContext(
+      const std::vector<SpeechRecognitionPhrase> phrases);
+  SpeechRecognitionRecognitionContext(
+      const SpeechRecognitionRecognitionContext&);
+  ~SpeechRecognitionRecognitionContext();
+
+  bool operator==(const SpeechRecognitionRecognitionContext& rhs) const;
+
+  // A list of speech recognition phrases to be plugged into the model.
+  std::vector<SpeechRecognitionPhrase> phrases;
+};
+
+}  // namespace media
+
+#endif  // MEDIA_MOJO_MOJOM_SPEECH_RECOGNITION_RECOGNITION_CONTEXT_H_
diff --git a/media/mojo/mojom/speech_recognition_recognition_context_mojom_traits.cc b/media/mojo/mojom/speech_recognition_recognition_context_mojom_traits.cc
new file mode 100644
index 0000000..3fd992bf
--- /dev/null
+++ b/media/mojo/mojom/speech_recognition_recognition_context_mojom_traits.cc
@@ -0,0 +1,42 @@
+// 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 "media/mojo/mojom/speech_recognition_recognition_context_mojom_traits.h"
+
+namespace mojo {
+
+bool StructTraits<media::mojom::SpeechRecognitionPhraseDataView,
+                  media::SpeechRecognitionPhrase>::
+    Read(media::mojom::SpeechRecognitionPhraseDataView data,
+         media::SpeechRecognitionPhrase* out) {
+  std::string phrase;
+
+  if (!data.ReadPhrase(&phrase) || phrase.empty()) {
+    return false;
+  }
+
+  if (data.boost() < 0 || data.boost() > 10) {
+    return false;
+  }
+
+  out->phrase = std::move(phrase);
+  out->boost = data.boost();
+  return true;
+}
+
+bool StructTraits<media::mojom::SpeechRecognitionRecognitionContextDataView,
+                  media::SpeechRecognitionRecognitionContext>::
+    Read(media::mojom::SpeechRecognitionRecognitionContextDataView data,
+         media::SpeechRecognitionRecognitionContext* out) {
+  std::vector<media::SpeechRecognitionPhrase> phrases;
+
+  if (!data.ReadPhrases(&phrases) || phrases.empty()) {
+    return false;
+  }
+
+  out->phrases = std::move(phrases);
+  return true;
+}
+
+}  // namespace mojo
diff --git a/media/mojo/mojom/speech_recognition_recognition_context_mojom_traits.h b/media/mojo/mojom/speech_recognition_recognition_context_mojom_traits.h
new file mode 100644
index 0000000..2cf12e49c
--- /dev/null
+++ b/media/mojo/mojom/speech_recognition_recognition_context_mojom_traits.h
@@ -0,0 +1,45 @@
+// 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 MEDIA_MOJO_MOJOM_SPEECH_RECOGNITION_RECOGNITION_CONTEXT_MOJOM_TRAITS_H_
+#define MEDIA_MOJO_MOJOM_SPEECH_RECOGNITION_RECOGNITION_CONTEXT_MOJOM_TRAITS_H_
+
+#include "media/mojo/mojom/speech_recognition_recognition_context.h"
+#include "media/mojo/mojom/speech_recognition_recognition_context.mojom.h"
+
+namespace mojo {
+
+template <>
+class StructTraits<media::mojom::SpeechRecognitionPhraseDataView,
+                   media::SpeechRecognitionPhrase> {
+ public:
+  static const std::string& phrase(const media::SpeechRecognitionPhrase& r) {
+    return r.phrase;
+  }
+
+  static float boost(const media::SpeechRecognitionPhrase& r) {
+    return r.boost;
+  }
+
+  static bool Read(media::mojom::SpeechRecognitionPhraseDataView data,
+                   media::SpeechRecognitionPhrase* out);
+};
+
+template <>
+class StructTraits<media::mojom::SpeechRecognitionRecognitionContextDataView,
+                   media::SpeechRecognitionRecognitionContext> {
+ public:
+  static const std::vector<media::SpeechRecognitionPhrase>& phrases(
+      const media::SpeechRecognitionRecognitionContext& r) {
+    return r.phrases;
+  }
+
+  static bool Read(
+      media::mojom::SpeechRecognitionRecognitionContextDataView data,
+      media::SpeechRecognitionRecognitionContext* out);
+};
+
+}  // namespace mojo
+
+#endif  // MEDIA_MOJO_MOJOM_SPEECH_RECOGNITION_RECOGNITION_CONTEXT_MOJOM_TRAITS_H_
diff --git a/media/mojo/mojom/speech_recognition_recognition_context_mojom_traits_unittest.cc b/media/mojo/mojom/speech_recognition_recognition_context_mojom_traits_unittest.cc
new file mode 100644
index 0000000..7359212f
--- /dev/null
+++ b/media/mojo/mojom/speech_recognition_recognition_context_mojom_traits_unittest.cc
@@ -0,0 +1,69 @@
+// 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 "media/mojo/mojom/speech_recognition_recognition_context_mojom_traits.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace media {
+
+TEST(SpeechRecognitionPhraseStructTraitsTest, ValidPhrase) {
+  media::SpeechRecognitionPhrase phrase("test phrase", 1.0);
+  std::vector<uint8_t> data =
+      media::mojom::SpeechRecognitionPhrase::Serialize(&phrase);
+  media::SpeechRecognitionPhrase output;
+  EXPECT_TRUE(media::mojom::SpeechRecognitionPhrase::Deserialize(
+      std::move(data), &output));
+  EXPECT_EQ(phrase, output);
+}
+
+TEST(SpeechRecognitionPhraseStructTraitsTest, InvalidEmptyPhrase) {
+  media::SpeechRecognitionPhrase phrase("", 1.0);
+  std::vector<uint8_t> data =
+      media::mojom::SpeechRecognitionPhrase::Serialize(&phrase);
+  media::SpeechRecognitionPhrase output;
+  EXPECT_FALSE(media::mojom::SpeechRecognitionPhrase::Deserialize(
+      std::move(data), &output));
+}
+
+TEST(SpeechRecognitionPhraseStructTraitsTest, InvalidPhraseBoostTooSmall) {
+  media::SpeechRecognitionPhrase phrase("test phrase", -0.1);
+  std::vector<uint8_t> data =
+      media::mojom::SpeechRecognitionPhrase::Serialize(&phrase);
+  media::SpeechRecognitionPhrase output;
+  EXPECT_FALSE(media::mojom::SpeechRecognitionPhrase::Deserialize(
+      std::move(data), &output));
+}
+
+TEST(SpeechRecognitionPhraseStructTraitsTest, InvalidPhraseBoostTooBig) {
+  media::SpeechRecognitionPhrase phrase("test phrase", 10.1);
+  std::vector<uint8_t> data =
+      media::mojom::SpeechRecognitionPhrase::Serialize(&phrase);
+  media::SpeechRecognitionPhrase output;
+  EXPECT_FALSE(media::mojom::SpeechRecognitionPhrase::Deserialize(
+      std::move(data), &output));
+}
+
+TEST(SpeechRecognitionRecognitionContextStructTraitsTest,
+     ValidRecognitionContext) {
+  media::SpeechRecognitionRecognitionContext context;
+  context.phrases.push_back(media::SpeechRecognitionPhrase("test phrase", 0.0));
+  std::vector<uint8_t> data =
+      media::mojom::SpeechRecognitionRecognitionContext::Serialize(&context);
+  media::SpeechRecognitionRecognitionContext output;
+  EXPECT_TRUE(media::mojom::SpeechRecognitionRecognitionContext::Deserialize(
+      std::move(data), &output));
+  EXPECT_EQ(context, output);
+}
+
+TEST(SpeechRecognitionRecognitionContextStructTraitsTest, InvalidEmptyPhrases) {
+  media::SpeechRecognitionRecognitionContext context;
+  std::vector<uint8_t> data =
+      media::mojom::SpeechRecognitionRecognitionContext::Serialize(&context);
+  media::SpeechRecognitionRecognitionContext output;
+  EXPECT_FALSE(media::mojom::SpeechRecognitionRecognitionContext::Deserialize(
+      std::move(data), &output));
+}
+
+}  // namespace media
diff --git a/media/mojo/mojom/speech_recognizer.mojom b/media/mojo/mojom/speech_recognizer.mojom
index dc041d6a..3b433b9 100644
--- a/media/mojo/mojom/speech_recognizer.mojom
+++ b/media/mojo/mojom/speech_recognizer.mojom
@@ -8,6 +8,7 @@
 import "media/mojo/mojom/speech_recognition_error.mojom";
 import "media/mojo/mojom/speech_recognition_grammar.mojom";
 import "media/mojo/mojom/speech_recognition_result.mojom";
+import "media/mojo/mojom/speech_recognition_recognition_context.mojom";
 
 // Created by the renderer and sent to the browser to start a speech recognition
 // session.
@@ -26,6 +27,9 @@
   // Speech grammars to use.
   array<SpeechRecognitionGrammar> grammars;
 
+  // The optional recognition context for speech recognition biasing.
+  SpeechRecognitionRecognitionContext? recognition_context;
+
   // Maximum number of hypotheses allowed for each results.
   uint32 max_hypotheses;
 
diff --git a/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits.cc b/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits.cc
index a41ac3e..673aadd 100644
--- a/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits.cc
+++ b/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits.cc
@@ -333,7 +333,7 @@
   // need to convert the side data to a raw format. We only care about spatial
   // layers since alpha data isn't used by HW decoders and the secure handle is
   // only going to used in new code going forward.
-  if (!input->has_side_data() || input->side_data()->spatial_layers.empty()) {
+  if (!input->side_data() || input->side_data()->spatial_layers.empty()) {
     return {};
   }
   std::vector<uint8_t> raw_data;
@@ -419,7 +419,7 @@
       "Unexpected type for input->side_data(). If you need to change this "
       "assertion, please contact chromeos-gfx-video@google.com.");
 
-  if (input->end_of_stream() || !input->has_side_data()) {
+  if (input->end_of_stream() || !input->side_data()) {
     return nullptr;
   }
   return input->side_data()->Clone();
@@ -496,7 +496,7 @@
   // TODO(b/269383891): Remove this in M120.
   // If the input is an older version than us, then it may have |raw_side_data|
   // set and we need to copy that into the potential values in |side_data|.
-  if (!raw_side_data.empty() && !decoder_buffer->has_side_data()) {
+  if (!raw_side_data.empty() && !decoder_buffer->side_data()) {
     // Spatial layers is always a multiple of 4 with a max size of 12.
     // HW decoders don't use alpha data, so we can ignore that case.
     if (raw_side_data.size() % sizeof(uint32_t) != 0 ||
diff --git a/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits_unittest.cc b/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits_unittest.cc
index e60d06f..064a101 100644
--- a/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits_unittest.cc
+++ b/media/mojo/mojom/stable/stable_video_decoder_types_mojom_traits_unittest.cc
@@ -55,7 +55,7 @@
             base::strict_cast<size_t>(mojom_decoder_buffer->data_size));
   EXPECT_EQ(deserialized_decoder_buffer->is_key_frame(),
             mojom_decoder_buffer->is_key_frame);
-  EXPECT_FALSE(deserialized_decoder_buffer->has_side_data());
+  EXPECT_FALSE(deserialized_decoder_buffer->side_data());
 }
 
 TEST(StableVideoDecoderTypesMojomTraitsTest, InfiniteDecoderBufferDuration) {
@@ -111,7 +111,7 @@
   ASSERT_TRUE(deserialized_decoder_buffer);
 
   ASSERT_FALSE(deserialized_decoder_buffer->end_of_stream());
-  ASSERT_TRUE(deserialized_decoder_buffer->has_side_data());
+  ASSERT_TRUE(deserialized_decoder_buffer->side_data());
   EXPECT_EQ(deserialized_decoder_buffer->side_data()->spatial_layers,
             std::vector<uint32_t>(kValidSpatialLayers,
                                   kValidSpatialLayers + kLayersSize));
diff --git a/media/muxers/webm_muxer.cc b/media/muxers/webm_muxer.cc
index 4d289037..f1007e7 100644
--- a/media/muxers/webm_muxer.cc
+++ b/media/muxers/webm_muxer.cc
@@ -435,8 +435,7 @@
   uint8_t track_index = absl::get_if<AudioParameters>(&frame.params)
                             ? audio_track_index_
                             : video_track_index_;
-  return frame.data->has_side_data() &&
-                 !frame.data->side_data()->alpha_data.empty()
+  return frame.data->side_data() && !frame.data->side_data()->alpha_data.empty()
              ? segment_.AddFrameWithAdditional(
                    frame.data->data(), frame.data->size(),
                    frame.data->side_data()->alpha_data.data(),
diff --git a/net/android/java/src/org/chromium/net/AndroidCertVerifyResult.java b/net/android/java/src/org/chromium/net/AndroidCertVerifyResult.java
index 2a993dd..9876f67 100644
--- a/net/android/java/src/org/chromium/net/AndroidCertVerifyResult.java
+++ b/net/android/java/src/org/chromium/net/AndroidCertVerifyResult.java
@@ -7,6 +7,8 @@
 import org.jni_zero.CalledByNative;
 import org.jni_zero.JNINamespace;
 
+import org.chromium.build.annotations.NullMarked;
+
 import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
@@ -15,6 +17,7 @@
 
 /** The result of a certification verification. */
 @JNINamespace("net::android")
+@NullMarked
 public class AndroidCertVerifyResult {
 
     /** The verification status. One of the values in CertVerifyStatusAndroid. */
diff --git a/net/android/java/src/org/chromium/net/AndroidKeyStore.java b/net/android/java/src/org/chromium/net/AndroidKeyStore.java
index 370aee8..b17d1e1 100644
--- a/net/android/java/src/org/chromium/net/AndroidKeyStore.java
+++ b/net/android/java/src/org/chromium/net/AndroidKeyStore.java
@@ -8,6 +8,8 @@
 import org.jni_zero.JNINamespace;
 
 import org.chromium.base.Log;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.security.InvalidKeyException;
 import java.security.NoSuchAlgorithmException;
@@ -19,6 +21,7 @@
 
 /** Specifies all the dependencies from the native OpenSSL engine on an Android KeyStore. */
 @JNINamespace("net::android")
+@NullMarked
 public class AndroidKeyStore {
     private static final String TAG = "AndroidKeyStore";
 
@@ -78,7 +81,7 @@
      * @return signature as a byte buffer.
      */
     @CalledByNative
-    private static byte[] signWithPrivateKey(
+    private static byte @Nullable [] signWithPrivateKey(
             PrivateKey privateKey, String algorithm, byte[] message) {
         // Hint: Algorithm names come from:
         // http://docs.oracle.com/javase/6/docs/technotes/guides/security/StandardNames.html
@@ -118,7 +121,7 @@
      * @return ciphertext as a byte buffer.
      */
     @CalledByNative
-    private static byte[] encryptWithPrivateKey(
+    private static byte @Nullable [] encryptWithPrivateKey(
             PrivateKey privateKey, String algorithm, byte[] message) {
         Cipher cipher = null;
         try {
diff --git a/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java b/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java
index 3c17a24..fffeebf 100644
--- a/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java
+++ b/net/android/java/src/org/chromium/net/AndroidNetworkLibrary.java
@@ -35,6 +35,8 @@
 import org.chromium.base.ApiCompatibilityUtils;
 import org.chromium.base.ContextUtils;
 import org.chromium.base.ResettersForTesting;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.io.FileDescriptor;
 import java.io.IOException;
@@ -56,13 +58,14 @@
 import java.util.List;
 
 /** This class implements net utilities required by the net component. */
+@NullMarked
 class AndroidNetworkLibrary {
     private static final String TAG = "AndroidNetworkLibrary";
 
     // Cached value indicating if app has ACCESS_NETWORK_STATE permission.
-    private static Boolean sHaveAccessNetworkState;
+    private static @Nullable Boolean sHaveAccessNetworkState;
     // Cached value indicating if app has ACCESS_WIFI_STATE permission.
-    private static Boolean sHaveAccessWifiState;
+    private static @Nullable Boolean sHaveAccessWifiState;
 
     /**
      * @return the mime type (if any) that is associated with the file
@@ -216,7 +219,7 @@
      * WifiManager} for earlier versions. Otherwise, we try to get the WifiInfo via broadcast (Note
      * that this approach does not work on Android P and above).
      */
-    private static WifiInfo getWifiInfo() {
+    private static @Nullable WifiInfo getWifiInfo() {
         if (haveAccessWifiState()) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                 // On Android S+, need to use NetworkCapabilities to get the WifiInfo.
@@ -435,7 +438,7 @@
      */
     @RequiresApi(Build.VERSION_CODES.P)
     @CalledByNative
-    public static DnsStatus getDnsStatusForNetwork(long networkHandle) {
+    public static @Nullable DnsStatus getDnsStatusForNetwork(long networkHandle) {
         // In case the network handle is invalid don't crash, instead return an empty DnsStatus and
         // let native code handle that.
         try {
@@ -452,7 +455,7 @@
      */
     @RequiresApi(Build.VERSION_CODES.M)
     @CalledByNative
-    public static DnsStatus getCurrentDnsStatus() {
+    public static @Nullable DnsStatus getCurrentDnsStatus() {
         return getDnsStatus(null);
     }
 
@@ -461,7 +464,7 @@
      * network. If |network| is null, uses the active network.
      */
     @RequiresApi(Build.VERSION_CODES.M)
-    public static DnsStatus getDnsStatus(Network network) {
+    public static @Nullable DnsStatus getDnsStatus(@Nullable Network network) {
         if (!haveAccessNetworkState()) {
             return null;
         }
diff --git a/net/android/java/src/org/chromium/net/AndroidTrafficStats.java b/net/android/java/src/org/chromium/net/AndroidTrafficStats.java
index cbfd007..b3a2ce8 100644
--- a/net/android/java/src/org/chromium/net/AndroidTrafficStats.java
+++ b/net/android/java/src/org/chromium/net/AndroidTrafficStats.java
@@ -10,8 +10,11 @@
 import org.jni_zero.CalledByNative;
 import org.jni_zero.JNINamespace;
 
+import org.chromium.build.annotations.NullMarked;
+
 /** This class interacts with TrafficStats API provided by Android. */
 @JNINamespace("net::android::traffic_stats")
+@NullMarked
 public class AndroidTrafficStats {
     private AndroidTrafficStats() {}
 
diff --git a/net/android/java/src/org/chromium/net/ChromiumNetworkAdapter.java b/net/android/java/src/org/chromium/net/ChromiumNetworkAdapter.java
index f162947..5c794a1 100644
--- a/net/android/java/src/org/chromium/net/ChromiumNetworkAdapter.java
+++ b/net/android/java/src/org/chromium/net/ChromiumNetworkAdapter.java
@@ -4,6 +4,8 @@
 
 package org.chromium.net;
 
+import org.chromium.build.annotations.NullMarked;
+
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.Proxy;
@@ -11,6 +13,7 @@
 import java.net.URLConnection;
 
 /** Wrapper class for network requests. */
+@NullMarked
 public final class ChromiumNetworkAdapter {
     private ChromiumNetworkAdapter() {}
 
diff --git a/net/android/java/src/org/chromium/net/DnsStatus.java b/net/android/java/src/org/chromium/net/DnsStatus.java
index 0647392..cc2fb93 100644
--- a/net/android/java/src/org/chromium/net/DnsStatus.java
+++ b/net/android/java/src/org/chromium/net/DnsStatus.java
@@ -7,11 +7,15 @@
 import org.jni_zero.CalledByNative;
 import org.jni_zero.JNINamespace;
 
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
+
 import java.net.InetAddress;
 import java.util.List;
 
 /** Class to access DNS server configuration. */
 @JNINamespace("net::android")
+@NullMarked
 public class DnsStatus {
     private final List<InetAddress> mDnsServers;
 
@@ -24,8 +28,8 @@
     public DnsStatus(
             List<InetAddress> dnsServers,
             boolean privateDnsActive,
-            String privateDnsServerName,
-            String searchDomains) {
+            @Nullable String privateDnsServerName,
+            @Nullable String searchDomains) {
         mDnsServers = dnsServers;
         mPrivateDnsActive = privateDnsActive;
         mPrivateDnsServerName = (privateDnsServerName != null) ? privateDnsServerName : "";
diff --git a/net/android/java/src/org/chromium/net/GURLUtils.java b/net/android/java/src/org/chromium/net/GURLUtils.java
index 4905506..1fb65a8b 100644
--- a/net/android/java/src/org/chromium/net/GURLUtils.java
+++ b/net/android/java/src/org/chromium/net/GURLUtils.java
@@ -9,8 +9,11 @@
 import org.jni_zero.JNINamespace;
 import org.jni_zero.NativeMethods;
 
+import org.chromium.build.annotations.NullMarked;
+
 /** Class to access the GURL library from java. */
 @JNINamespace("net")
+@NullMarked
 public final class GURLUtils {
 
     /**
diff --git a/net/android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java b/net/android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java
index 30fdadd..6be257a 100644
--- a/net/android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java
+++ b/net/android/java/src/org/chromium/net/HttpNegotiateAuthenticator.java
@@ -32,6 +32,8 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
 import org.chromium.base.ThreadUtils;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.io.IOException;
 
@@ -60,9 +62,10 @@
  * ================================================================================================
  */
 @JNINamespace("net::android")
+@NullMarked
 public class HttpNegotiateAuthenticator {
     private static final String TAG = "net_auth";
-    private Bundle mSpnegoContext;
+    private @Nullable Bundle mSpnegoContext;
     private final String mAccountType;
 
     /**
@@ -74,16 +77,17 @@
         public long nativeResultObject;
 
         /** Reference to the account manager to use for the various requests. */
+        @SuppressWarnings("NullAway.Init")
         public AccountManager accountManager;
 
         /** Authenticator-specific options for the request, used for AccountManager#getAuthToken. */
-        public Bundle options;
+        public @Nullable Bundle options;
 
         /** Desired token type, used for AccountManager#getAuthToken. */
-        public String authTokenType;
+        public @Nullable String authTokenType;
 
         /** Account to fetch an auth token for. */
-        public Account account;
+        public @Nullable Account account;
     }
 
     /**
@@ -449,6 +453,6 @@
                 long nativeJavaNegotiateResultWrapper,
                 HttpNegotiateAuthenticator caller,
                 int status,
-                String authToken);
+                @Nullable String authToken);
     }
 }
diff --git a/net/android/java/src/org/chromium/net/HttpNegotiateConstants.java b/net/android/java/src/org/chromium/net/HttpNegotiateConstants.java
index 598c759..0556769b 100644
--- a/net/android/java/src/org/chromium/net/HttpNegotiateConstants.java
+++ b/net/android/java/src/org/chromium/net/HttpNegotiateConstants.java
@@ -4,7 +4,10 @@
 
 package org.chromium.net;
 
+import org.chromium.build.annotations.NullMarked;
+
 /** Constants used by Chrome in SPNEGO authentication requests to the Android Account Manager. */
+@NullMarked
 public class HttpNegotiateConstants {
     // Option bundle keys
     //
diff --git a/net/android/java/src/org/chromium/net/HttpUtil.java b/net/android/java/src/org/chromium/net/HttpUtil.java
index 49e95f2..452e419 100644
--- a/net/android/java/src/org/chromium/net/HttpUtil.java
+++ b/net/android/java/src/org/chromium/net/HttpUtil.java
@@ -7,12 +7,15 @@
 import org.jni_zero.JNINamespace;
 import org.jni_zero.NativeMethods;
 
+import org.chromium.build.annotations.NullMarked;
+
 /**
  * Class to access HttpUtil library from Java.
  *
  * The corresponding native code is in net/android/android_http_util.cc.
  */
 @JNINamespace("net")
+@NullMarked
 public final class HttpUtil {
     /**
      * Returns true iff:
diff --git a/net/android/java/src/org/chromium/net/MimeTypeFilter.java b/net/android/java/src/org/chromium/net/MimeTypeFilter.java
index 149a3e23..7cd3f87 100644
--- a/net/android/java/src/org/chromium/net/MimeTypeFilter.java
+++ b/net/android/java/src/org/chromium/net/MimeTypeFilter.java
@@ -7,7 +7,8 @@
 import android.net.Uri;
 import android.webkit.MimeTypeMap;
 
-import androidx.annotation.NonNull;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.io.File;
 import java.io.FileFilter;
@@ -22,6 +23,7 @@
  *  https://wicg.github.io/web-share-target/level-2/#determining-if-a-file-is-accepted
  *  It is also used inside chrome/android/java/src/org/chromium/chrome/browser/photo_picker.
  */
+@NullMarked
 public class MimeTypeFilter implements FileFilter {
     private HashSet<String> mExtensions = new HashSet<>();
     private HashSet<String> mMimeTypes = new HashSet<>();
@@ -35,7 +37,7 @@
      * @param mimeTypes A list of MIME types this filter accepts.
      *                  For example: images/gif, video/*.
      */
-    public MimeTypeFilter(@NonNull List<String> mimeTypes, boolean acceptDirectory) {
+    public MimeTypeFilter(List<String> mimeTypes, boolean acceptDirectory) {
         for (String field : mimeTypes) {
             field = field.trim().toLowerCase(Locale.US);
             if (field.startsWith(".")) {
@@ -54,7 +56,7 @@
     }
 
     /** Returns true if either the uri or the mimeType is accepted by the MimeTypeFilter */
-    public boolean accept(Uri uri, String mimeType) {
+    public boolean accept(Uri uri, @Nullable String mimeType) {
         if (uri != null) {
             String fileExtension =
                     MimeTypeMap.getFileExtensionFromUrl(uri.toString()).toLowerCase(Locale.US);
@@ -77,20 +79,19 @@
     }
 
     @Override
-    public boolean accept(@NonNull File file) {
+    public boolean accept(File file) {
         if (file.isDirectory()) {
             return mAcceptDirectory;
         }
         return accept(Uri.fromFile(file), null);
     }
 
-    private String getMimeTypeFromExtension(@NonNull String ext) {
+    private @Nullable String getMimeTypeFromExtension(String ext) {
         String mimeType = mMimeTypeMap.getMimeTypeFromExtension(ext);
         return (mimeType != null) ? mimeType.toLowerCase(Locale.US) : null;
     }
 
-    @NonNull
-    private static String getMimeSupertype(@NonNull String mimeType) {
+    private static String getMimeSupertype(String mimeType) {
         return mimeType.split("/", 2)[0];
     }
 }
diff --git a/net/android/java/src/org/chromium/net/NetStringUtil.java b/net/android/java/src/org/chromium/net/NetStringUtil.java
index 6b69b59c..f80f5e5 100644
--- a/net/android/java/src/org/chromium/net/NetStringUtil.java
+++ b/net/android/java/src/org/chromium/net/NetStringUtil.java
@@ -7,6 +7,9 @@
 import org.jni_zero.CalledByNative;
 import org.jni_zero.JNINamespace;
 
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
+
 import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.nio.charset.CharsetDecoder;
@@ -16,6 +19,7 @@
 
 /** Utility functions for converting strings between formats when not built with icu. */
 @JNINamespace("net::android")
+@NullMarked
 public class NetStringUtil {
     /**
      * Attempts to convert text in a given character set to a Unicode string. Returns null on
@@ -26,7 +30,7 @@
      * @return Unicode string on success, null on failure.
      */
     @CalledByNative
-    private static String convertToUnicode(ByteBuffer text, String charsetName) {
+    private static @Nullable String convertToUnicode(ByteBuffer text, String charsetName) {
         try {
             Charset charset = Charset.forName(charsetName);
             CharsetDecoder decoder = charset.newDecoder();
@@ -46,7 +50,8 @@
      * @return Unicode string on success, null on failure.
      */
     @CalledByNative
-    private static String convertToUnicodeAndNormalize(ByteBuffer text, String charsetName) {
+    private static @Nullable String convertToUnicodeAndNormalize(
+            ByteBuffer text, String charsetName) {
         String unicodeString = convertToUnicode(text, charsetName);
         if (unicodeString == null) return null;
         return Normalizer.normalize(unicodeString, Normalizer.Form.NFC);
@@ -61,7 +66,8 @@
      * @return Unicode string on success, null on failure.
      */
     @CalledByNative
-    private static String convertToUnicodeWithSubstitutions(ByteBuffer text, String charsetName) {
+    private static @Nullable String convertToUnicodeWithSubstitutions(
+            ByteBuffer text, String charsetName) {
         try {
             Charset charset = Charset.forName(charsetName);
 
@@ -87,7 +93,7 @@
      * @return String converted to uppercase using default locale, null on failure.
      */
     @CalledByNative
-    private static String toUpperCase(String str) {
+    private static @Nullable String toUpperCase(String str) {
         try {
             return str.toUpperCase(Locale.getDefault());
         } catch (Exception e) {
diff --git a/net/android/java/src/org/chromium/net/NetworkActiveNotifier.java b/net/android/java/src/org/chromium/net/NetworkActiveNotifier.java
index b49cc5f..3e8210d 100644
--- a/net/android/java/src/org/chromium/net/NetworkActiveNotifier.java
+++ b/net/android/java/src/org/chromium/net/NetworkActiveNotifier.java
@@ -13,6 +13,7 @@
 import org.jni_zero.NativeMethods;
 
 import org.chromium.base.ContextUtils;
+import org.chromium.build.annotations.NullMarked;
 
 /**
  * Triggers updates to the underlying network state in Chrome alongside NetworkChangeNotifier.
@@ -30,6 +31,7 @@
  * reason).
  */
 @JNINamespace("net")
+@NullMarked
 public class NetworkActiveNotifier implements ConnectivityManager.OnNetworkActiveListener {
     private final ConnectivityManager mConnectivityManager;
     // Native-side observer of the default network active events.
diff --git a/net/android/java/src/org/chromium/net/NetworkChangeNotifier.java b/net/android/java/src/org/chromium/net/NetworkChangeNotifier.java
index f75c038..1ed9aa0 100644
--- a/net/android/java/src/org/chromium/net/NetworkChangeNotifier.java
+++ b/net/android/java/src/org/chromium/net/NetworkChangeNotifier.java
@@ -15,6 +15,8 @@
 
 import org.chromium.base.ObserverList;
 import org.chromium.base.metrics.ScopedSysTraceEvent;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.util.ArrayList;
 
@@ -29,6 +31,7 @@
  * WARNING: This class is not thread-safe.
  */
 @JNINamespace("net")
+@NullMarked
 public class NetworkChangeNotifier {
     /**
      * Alerted when the connection type of the network changes.
@@ -40,14 +43,14 @@
 
     private final ArrayList<Long> mNativeChangeNotifiers;
     private final ObserverList<ConnectionTypeObserver> mConnectionTypeObservers;
-    private NetworkChangeNotifierAutoDetect mAutoDetector;
+    private @Nullable NetworkChangeNotifierAutoDetect mAutoDetector;
     // Last value broadcast via ConnectionTypeChange signal.
     private int mCurrentConnectionType = ConnectionType.CONNECTION_UNKNOWN;
     // Last value broadcast via ConnectionCostChange signal.
     private int mCurrentConnectionCost = ConnectionCost.UNKNOWN;
 
     @SuppressLint("StaticFieldLeak")
-    private static NetworkChangeNotifier sInstance;
+    private static @Nullable NetworkChangeNotifier sInstance;
 
     @VisibleForTesting
     protected NetworkChangeNotifier() {
@@ -461,7 +464,7 @@
     }
 
     // For testing only.
-    public static NetworkChangeNotifierAutoDetect getAutoDetectorForTest() {
+    public static @Nullable NetworkChangeNotifierAutoDetect getAutoDetectorForTest() {
         return getInstance().mAutoDetector;
     }
 
diff --git a/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java b/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
index 5887ec3..5e1dd475 100644
--- a/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
+++ b/net/android/java/src/org/chromium/net/NetworkChangeNotifierAutoDetect.java
@@ -9,6 +9,8 @@
 import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN;
 import static android.net.NetworkCapabilities.TRANSPORT_VPN;
 
+import static org.chromium.build.NullUtil.assumeNonNull;
+
 import android.Manifest.permission;
 import android.annotation.SuppressLint;
 import android.content.BroadcastReceiver;
@@ -42,6 +44,11 @@
 import org.chromium.base.TraceEvent;
 import org.chromium.base.metrics.ScopedSysTraceEvent;
 import org.chromium.build.BuildConfig;
+import org.chromium.build.annotations.EnsuresNonNullIf;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.NullUnmarked;
+import org.chromium.build.annotations.Nullable;
+import org.chromium.build.annotations.RequiresNonNull;
 
 import java.io.IOException;
 import java.net.Socket;
@@ -55,6 +62,7 @@
  */
 // TODO(crbug.com/40479664): Fix this properly.
 @SuppressLint("NewApi")
+@NullMarked
 public class NetworkChangeNotifierAutoDetect extends BroadcastReceiver {
     /** Immutable class representing the state of a device's network. */
     public static class NetworkState {
@@ -75,9 +83,9 @@
                 int type,
                 int subtype,
                 boolean isMetered,
-                String networkIdentifier,
+                @Nullable String networkIdentifier,
                 boolean isPrivateDnsActive,
-                String privateDnsServerName) {
+                @Nullable String privateDnsServerName) {
             mConnected = connected;
             mType = type;
             mSubtype = subtype;
@@ -194,6 +202,7 @@
 
     /** Queries the ConnectivityManager for information about the current connection. */
     static class ConnectivityManagerDelegate {
+        @SuppressWarnings("NullAway.Init") // Due to test-only constructor.
         private final ConnectivityManager mConnectivityManager;
 
         ConnectivityManagerDelegate(Context context) {
@@ -202,16 +211,17 @@
         }
 
         // For testing.
+        @NullUnmarked
         ConnectivityManagerDelegate() {
-            // All the methods below should be overridden.
             mConnectivityManager = null;
+            // All the methods below should be overridden.
         }
 
         /**
          * @param networkInfo The NetworkInfo for the active network.
          * @return the info of the network that is available to this app.
          */
-        private NetworkInfo processActiveNetworkInfo(NetworkInfo networkInfo) {
+        private @Nullable NetworkInfo processActiveNetworkInfo(@Nullable NetworkInfo networkInfo) {
             if (networkInfo == null) {
                 return null;
             }
@@ -315,7 +325,8 @@
          * Fetches NetworkInfo for |network|. Does not account for underlying VPNs; see
          * getNetworkInfo(Network) for a method that does.
          */
-        NetworkInfo getRawNetworkInfo(Network network) {
+        @Nullable
+        NetworkInfo getRawNetworkInfo(@Nullable Network network) {
             try {
                 return mConnectivityManager.getNetworkInfo(network);
             } catch (NullPointerException firstException) {
@@ -329,7 +340,8 @@
         }
 
         /** Fetches NetworkInfo for |network|. */
-        NetworkInfo getNetworkInfo(Network network) {
+        @Nullable
+        NetworkInfo getNetworkInfo(@Nullable Network network) {
             NetworkInfo networkInfo = getRawNetworkInfo(network);
             if (networkInfo != null && networkInfo.getType() == TYPE_VPN) {
                 // When a VPN is in place the underlying network type can be queried via
@@ -395,7 +407,7 @@
          * be retrieved (e.g. {@code network} has disconnected).
          */
         @VisibleForTesting
-        protected NetworkCapabilities getNetworkCapabilities(Network network) {
+        protected @Nullable NetworkCapabilities getNetworkCapabilities(Network network) {
             final int retryCount = 2;
             for (int i = 0; i < retryCount; ++i) {
                 // This try-catch is a workaround for https://crbug.com/1218536. We ignore
@@ -443,6 +455,7 @@
         }
 
         /** Returns the current default {@link Network}, or {@code null} if disconnected. */
+        @Nullable
         Network getDefaultNetwork() {
             Network defaultNetwork = null;
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
@@ -510,7 +523,9 @@
 
     /** Queries the WifiManager for SSID of the current Wifi connection. */
     static class WifiManagerDelegate {
+        @SuppressWarnings("NullAway.Init") // Due to test-only constructor.
         private final Context mContext;
+
         // Lock all members below.
         private final Object mLock = new Object();
 
@@ -524,7 +539,7 @@
 
         // Only valid when mHasWifiPermission is set.
         @GuardedBy("mLock")
-        private WifiManager mWifiManager;
+        private @Nullable WifiManager mWifiManager;
 
         WifiManagerDelegate(Context context) {
             // Getting SSID requires more permissions in later Android releases.
@@ -533,6 +548,7 @@
         }
 
         // For testing.
+        @NullUnmarked
         WifiManagerDelegate() {
             // All the methods below should be overridden.
             mContext = null;
@@ -541,6 +557,8 @@
         // Lazily determine if app has ACCESS_WIFI_STATE permission.
         @GuardedBy("mLock")
         @SuppressLint("WifiManagerPotentialLeak")
+        @SuppressWarnings("NullAway") // Too hard for it to verify.
+        @EnsuresNonNullIf("mWifiManager")
         private boolean hasPermissionLocked() {
             if (mHasWifiPermissionComputed) {
                 return mHasWifiPermission;
@@ -578,7 +596,8 @@
 
         // Fetches WifiInfo and records UMA for NullPointerExceptions.
         @GuardedBy("mLock")
-        private WifiInfo getWifiInfoLocked() {
+        @RequiresNonNull("mWifiManager")
+        private @Nullable WifiInfo getWifiInfoLocked() {
             try {
                 return mWifiManager.getConnectionInfo();
             } catch (NullPointerException firstException) {
@@ -596,7 +615,7 @@
     private class DefaultNetworkCallback extends NetworkCallback {
         // If registered, notify connectionTypeChanged() to look for changes.
         @Override
-        public void onAvailable(Network network) {
+        public void onAvailable(@Nullable Network network) {
             if (mRegistered) {
                 connectionTypeChanged();
             }
@@ -625,8 +644,8 @@
     //    an incorrect disconnected state, see crbug.com/1120144.
     @RequiresApi(Build.VERSION_CODES.P)
     private class AndroidRDefaultNetworkCallback extends NetworkCallback {
-        LinkProperties mLinkProperties;
-        NetworkCapabilities mNetworkCapabilities;
+        @Nullable LinkProperties mLinkProperties;
+        @Nullable NetworkCapabilities mNetworkCapabilities;
 
         @Override
         public void onAvailable(Network network) {
@@ -672,6 +691,7 @@
         // synchronous ConnectivityManager methods which is prohibited inside NetworkCallbacks see
         // "Do NOT call" here:
         // https://developer.android.com/reference/android/net/ConnectivityManager.NetworkCallback#onAvailable(android.net.Network)
+        @NullUnmarked
         private NetworkState getNetworkState(Network network) {
             // Initialize to unknown values then extract more accurate info
             int type = -1;
@@ -723,7 +743,7 @@
     private class MyNetworkCallback extends NetworkCallback {
         // If non-null, this indicates a VPN is in place for the current user, and no other
         // networks are accessible.
-        private Network mVpnInPlace;
+        private @Nullable Network mVpnInPlace;
 
         // Initialize mVpnInPlace.
         void initializeVpnInPlace() {
@@ -763,7 +783,7 @@
          *     disconnected.
          */
         private boolean ignoreConnectedInaccessibleVpn(
-                Network network, NetworkCapabilities capabilities) {
+                Network network, @Nullable NetworkCapabilities capabilities) {
             // Ignore inaccessible VPNs as they don't apply to Chrome.
             return capabilities == null
                     || (capabilities.hasTransport(TRANSPORT_VPN)
@@ -776,7 +796,8 @@
          * @param capabilities {@code NetworkCapabilities} for {@code network} if known, otherwise
          *         {@code null}.
          */
-        private boolean ignoreConnectedNetwork(Network network, NetworkCapabilities capabilities) {
+        private boolean ignoreConnectedNetwork(
+                Network network, @Nullable NetworkCapabilities capabilities) {
             return ignoreNetworkDueToVpn(network)
                     || ignoreConnectedInaccessibleVpn(network, capabilities);
         }
@@ -784,11 +805,12 @@
         @Override
         public void onAvailable(Network network) {
             try (TraceEvent e = TraceEvent.scoped("NetworkChangeNotifierCallback::onAvailable")) {
-                final NetworkCapabilities capabilities =
+                NetworkCapabilities capabilities =
                         mConnectivityManagerDelegate.getNetworkCapabilities(network);
                 if (ignoreConnectedNetwork(network, capabilities)) {
                     return;
                 }
+                capabilities = assumeNonNull(capabilities);
                 final boolean makeVpnDefault =
                         capabilities.hasTransport(TRANSPORT_VPN)
                                 &&
@@ -901,7 +923,7 @@
      * should listen for network changes.
      */
     public abstract static class RegistrationPolicy {
-        private NetworkChangeNotifierAutoDetect mNotifier;
+        private @Nullable NetworkChangeNotifierAutoDetect mNotifier;
 
         /** Start listening for network changes. */
         protected final void register() {
@@ -929,7 +951,7 @@
     private static final String TAG = NetworkChangeNotifierAutoDetect.class.getSimpleName();
 
     // {@link Looper} for the thread this object lives on.
-    private final Looper mLooper;
+    private final @Nullable Looper mLooper;
     // Used to post to the thread this object lives on.
     private final Handler mHandler;
     // {@link IntentFilter} for incoming global broadcast {@link Intent}s this object listens for.
@@ -938,17 +960,23 @@
     private final Observer mObserver;
     private final RegistrationPolicy mRegistrationPolicy;
     // Starting with Android Pie, used to detect changes in default network.
-    private NetworkCallback mDefaultNetworkCallback;
+    private @Nullable NetworkCallback mDefaultNetworkCallback;
 
     // mConnectivityManagerDelegates and mWifiManagerDelegate are only non-final for testing.
     private ConnectivityManagerDelegate mConnectivityManagerDelegate;
+
+    @SuppressWarnings("NullAway.Init")
     private WifiManagerDelegate mWifiManagerDelegate;
+
     // mNetworkCallback and mNetworkRequest are only non-null in Android L and above.
     // mNetworkCallback will be null if ConnectivityManager.registerNetworkCallback() ever fails.
-    private MyNetworkCallback mNetworkCallback;
+    private @Nullable MyNetworkCallback mNetworkCallback;
     private NetworkRequest mNetworkRequest;
     private boolean mRegistered;
+
+    @SuppressWarnings("NullAway.Init")
     private NetworkState mNetworkState;
+
     // When a BroadcastReceiver is registered for a sticky broadcast that has been sent out at
     // least once, onReceive() will immediately be called. mIgnoreNextBroadcast is set to true
     // when this class is registered in such a circumstance, and indicates that the next
@@ -1023,8 +1051,10 @@
     public NetworkChangeNotifierAutoDetect(Observer observer, RegistrationPolicy policy) {
         try (ScopedSysTraceEvent event =
                 ScopedSysTraceEvent.scoped("NetworkChangeNotifierAutoDetect.constructor")) {
-            mLooper = Looper.myLooper();
-            mHandler = new Handler(mLooper);
+            Looper myLooper = Looper.myLooper();
+            assert myLooper != null;
+            mLooper = myLooper;
+            mHandler = new Handler(myLooper);
             mObserver = observer;
             mConnectivityManagerDelegate =
                     new ConnectivityManagerDelegate(ContextUtils.getApplicationContext());
@@ -1233,7 +1263,8 @@
      * @param ignoreNetwork ignore this network as if it is not connected.
      */
     private static Network[] getAllNetworksFiltered(
-            ConnectivityManagerDelegate connectivityManagerDelegate, Network ignoreNetwork) {
+            ConnectivityManagerDelegate connectivityManagerDelegate,
+            @Nullable Network ignoreNetwork) {
         Network[] networks = connectivityManagerDelegate.getAllNetworksUnfiltered();
         // Whittle down |networks| into just the list of networks useful to us.
         int filteredIndex = 0;
@@ -1293,7 +1324,7 @@
      * communication.
      * Returns null when not implemented.
      */
-    public Network getDefaultNetwork() {
+    public @Nullable Network getDefaultNetwork() {
         return mConnectivityManagerDelegate.getDefaultNetwork();
     }
 
diff --git a/net/android/java/src/org/chromium/net/NetworkTrafficAnnotationTag.java b/net/android/java/src/org/chromium/net/NetworkTrafficAnnotationTag.java
index 06535c2..ee7a5b67 100644
--- a/net/android/java/src/org/chromium/net/NetworkTrafficAnnotationTag.java
+++ b/net/android/java/src/org/chromium/net/NetworkTrafficAnnotationTag.java
@@ -6,6 +6,8 @@
 
 import androidx.annotation.VisibleForTesting;
 
+import org.chromium.build.annotations.NullMarked;
+
 import java.nio.charset.StandardCharsets;
 
 /**
@@ -20,6 +22,7 @@
  *   3. Where does the request go? (e.g. a Google server, a website the user is viewing...)
  *   4. How can I disable it if I don't like it?
  */
+@NullMarked
 public class NetworkTrafficAnnotationTag {
     /**
      * For network requests that aren't documented yet. These should be
diff --git a/net/android/java/src/org/chromium/net/ProxyBroadcastReceiver.java b/net/android/java/src/org/chromium/net/ProxyBroadcastReceiver.java
index 91f6fc96..8da4b54 100644
--- a/net/android/java/src/org/chromium/net/ProxyBroadcastReceiver.java
+++ b/net/android/java/src/org/chromium/net/ProxyBroadcastReceiver.java
@@ -12,6 +12,9 @@
 
 import androidx.annotation.RequiresApi;
 
+import org.chromium.build.annotations.NullMarked;
+
+@NullMarked
 final class ProxyBroadcastReceiver extends BroadcastReceiver {
     private final ProxyChangeListener mListener;
 
@@ -22,7 +25,7 @@
     @Override
     @RequiresApi(Build.VERSION_CODES.M)
     public void onReceive(Context context, final Intent intent) {
-        if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
+        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
             mListener.updateProxyConfigFromConnectivityManager(intent);
         }
     }
diff --git a/net/android/java/src/org/chromium/net/ProxyChangeListener.java b/net/android/java/src/org/chromium/net/ProxyChangeListener.java
index 5e2ad799..016f274 100644
--- a/net/android/java/src/org/chromium/net/ProxyChangeListener.java
+++ b/net/android/java/src/org/chromium/net/ProxyChangeListener.java
@@ -30,6 +30,8 @@
 import org.chromium.base.ResettersForTesting;
 import org.chromium.base.TraceEvent;
 import org.chromium.build.BuildConfig;
+import org.chromium.build.annotations.NullMarked;
+import org.chromium.build.annotations.Nullable;
 import org.chromium.build.annotations.UsedByReflection;
 
 import java.lang.reflect.InvocationTargetException;
@@ -46,11 +48,12 @@
  */
 @UsedByReflection("WebView embedders call this to override proxy settings")
 @JNINamespace("net")
+@NullMarked
 public class ProxyChangeListener {
     private static final String TAG = "ProxyChangeListener";
     private static boolean sEnabled = true;
 
-    private final Looper mLooper;
+    private final @Nullable Looper mLooper;
     private final Handler mHandler;
 
     private long mNativePtr;
@@ -62,23 +65,23 @@
     //
     // To avoid triggering as a result of system broadcasts, it is registered with an empty intent
     // filter on M and above.
-    private ProxyReceiver mProxyReceiver;
+    private @Nullable ProxyReceiver mProxyReceiver;
 
     // On M and above we also register |mRealProxyReceiver| with a matching intent filter, to act as
     // a trigger for fetching proxy information via ConnectionManager.
-    private BroadcastReceiver mRealProxyReceiver;
+    private @Nullable BroadcastReceiver mRealProxyReceiver;
 
-    private Delegate mDelegate;
+    private @Nullable Delegate mDelegate;
 
     private static class ProxyConfig {
-        public ProxyConfig(String host, int port, String pacUrl, String[] exclusionList) {
+        public ProxyConfig(String host, int port, @Nullable String pacUrl, String[] exclusionList) {
             mHost = host;
             mPort = port;
             mPacUrl = pacUrl;
             mExclusionList = exclusionList;
         }
 
-        private static ProxyConfig fromProxyInfo(ProxyInfo proxyInfo) {
+        private static @Nullable ProxyConfig fromProxyInfo(@Nullable ProxyInfo proxyInfo) {
             if (proxyInfo == null) {
                 return null;
             }
@@ -105,7 +108,7 @@
 
         public final String mHost;
         public final int mPort;
-        public final String mPacUrl;
+        public final @Nullable String mPacUrl;
         public final String[] mExclusionList;
 
         public static final ProxyConfig DIRECT = new ProxyConfig("", 0, "", new String[0]);
@@ -117,7 +120,9 @@
     }
 
     private ProxyChangeListener() {
-        mLooper = Looper.myLooper();
+        Looper myLooper = Looper.myLooper();
+        assert myLooper != null;
+        mLooper = myLooper;
         mHandler = new Handler(mLooper);
     }
 
@@ -163,7 +168,7 @@
         @Override
         @UsedByReflection("WebView embedders call this to override proxy settings")
         public void onReceive(Context context, final Intent intent) {
-            if (intent.getAction().equals(Proxy.PROXY_CHANGE_ACTION)) {
+            if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
                 runOnThread(() -> proxySettingsChanged(extractNewProxy(intent)));
             }
         }
@@ -175,7 +180,7 @@
     // methods on it. If we fail, return an empty proxy config (meaning
     // use system properties).
     @SuppressWarnings({"PrivateApi", "ObsoleteSdkInt"})
-    private static ProxyConfig extractNewProxy(Intent intent) {
+    private static @Nullable ProxyConfig extractNewProxy(Intent intent) {
         Bundle extras = intent.getExtras();
         if (extras == null) {
             return null;
@@ -227,7 +232,7 @@
         }
     }
 
-    private void proxySettingsChanged(ProxyConfig cfg) {
+    private void proxySettingsChanged(@Nullable ProxyConfig cfg) {
         assertOnThread();
 
         if (!sEnabled) {
@@ -256,7 +261,7 @@
     }
 
     @RequiresApi(Build.VERSION_CODES.M)
-    private ProxyConfig getProxyConfig(Intent intent) {
+    private @Nullable ProxyConfig getProxyConfig(Intent intent) {
         ConnectivityManager connectivityManager =
                 (ConnectivityManager)
                         ContextUtils.getApplicationContext()
@@ -372,7 +377,7 @@
                 ProxyChangeListener caller,
                 String host,
                 int port,
-                String pacUrl,
+                @Nullable String pacUrl,
                 String[] exclusionList);
 
         @NativeClassQualifiedName("ProxyConfigServiceAndroid::JNIDelegate")
diff --git a/net/android/java/src/org/chromium/net/RegistrationPolicyAlwaysRegister.java b/net/android/java/src/org/chromium/net/RegistrationPolicyAlwaysRegister.java
index a347bc4..44e641c 100644
--- a/net/android/java/src/org/chromium/net/RegistrationPolicyAlwaysRegister.java
+++ b/net/android/java/src/org/chromium/net/RegistrationPolicyAlwaysRegister.java
@@ -4,7 +4,10 @@
 
 package org.chromium.net;
 
+import org.chromium.build.annotations.NullMarked;
+
 /** Registration policy which make sure that the listener is always registered. */
+@NullMarked
 public class RegistrationPolicyAlwaysRegister
         extends NetworkChangeNotifierAutoDetect.RegistrationPolicy {
     @Override
diff --git a/net/android/java/src/org/chromium/net/RegistrationPolicyApplicationStatus.java b/net/android/java/src/org/chromium/net/RegistrationPolicyApplicationStatus.java
index 2fa9c290..3233989 100644
--- a/net/android/java/src/org/chromium/net/RegistrationPolicyApplicationStatus.java
+++ b/net/android/java/src/org/chromium/net/RegistrationPolicyApplicationStatus.java
@@ -6,8 +6,10 @@
 
 import org.chromium.base.ApplicationState;
 import org.chromium.base.ApplicationStatus;
+import org.chromium.build.annotations.NullMarked;
 
 /** Registration policy which depends on the ApplicationState. */
+@NullMarked
 public class RegistrationPolicyApplicationStatus
         extends NetworkChangeNotifierAutoDetect.RegistrationPolicy
         implements ApplicationStatus.ApplicationStateListener {
diff --git a/net/android/java/src/org/chromium/net/X509Util.java b/net/android/java/src/org/chromium/net/X509Util.java
index a1150f7..b1c70ae 100644
--- a/net/android/java/src/org/chromium/net/X509Util.java
+++ b/net/android/java/src/org/chromium/net/X509Util.java
@@ -18,6 +18,8 @@
 
 import org.chromium.base.ContextUtils;
 import org.chromium.base.Log;
+import org.chromium.build.annotations.NullUnmarked;
+import org.chromium.build.annotations.Nullable;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
@@ -48,6 +50,7 @@
 
 /** Utility functions for interacting with Android's X.509 certificates. */
 @JNINamespace("net")
+@NullUnmarked
 public class X509Util {
     private static final String TAG = "X509Util";
 
@@ -105,7 +108,7 @@
         }
     }
 
-    private static CertificateFactory sCertificateFactory;
+    private static @Nullable CertificateFactory sCertificateFactory;
 
     private static final String OID_TLS_SERVER_AUTH = "1.3.6.1.5.5.7.3.1";
     private static final String OID_ANY_EKU = "2.5.29.37.0";
@@ -116,27 +119,27 @@
     private static final String OID_SERVER_GATED_MICROSOFT = "1.3.6.1.4.1.311.10.3.3";
 
     /** Trust manager backed up by the read-only system certificate store. */
-    private static X509TrustManagerExtensions sDefaultTrustManager;
+    private static @Nullable X509TrustManagerExtensions sDefaultTrustManager;
 
     /**
      * BroadcastReceiver that listens to change in the system keystore to invalidate certificate
      * caches.
      */
-    private static TrustStorageListener sTrustStorageListener;
+    private static @Nullable TrustStorageListener sTrustStorageListener;
 
     /**
      * Trust manager backed up by a custom certificate store. We need such manager to plant test
      * root CA to the trust store in testing.
      */
-    private static X509TrustManagerExtensions sTestTrustManager;
+    private static @Nullable X509TrustManagerExtensions sTestTrustManager;
 
-    private static KeyStore sTestKeyStore;
+    private static @Nullable KeyStore sTestKeyStore;
 
     /**
      * The system key store. This is used to determine whether a trust anchor is a system trust
      * anchor or user-installed.
      */
-    private static KeyStore sSystemKeyStore;
+    private static @Nullable KeyStore sSystemKeyStore;
 
     /**
      * The directory where system certificates are stored. This is used to determine whether a
@@ -144,14 +147,14 @@
      * sufficient to efficiently query whether a given X500Principal, PublicKey pair is a trust
      * anchor.
      */
-    private static File sSystemCertificateDirectory;
+    private static @Nullable File sSystemCertificateDirectory;
 
     /**
      * An in-memory cache of which trust anchors are system trust roots. This avoids reading and
      * decoding the root from disk on every verification. Mirrors a similar in-memory cache in
      * Conscrypt's X509TrustManager implementation.
      */
-    private static Set<Pair<X500Principal, PublicKey>> sSystemTrustAnchorCache;
+    private static @Nullable Set<Pair<X500Principal, PublicKey>> sSystemTrustAnchorCache;
 
     /**
      * True if the system key store has been loaded. If the "AndroidCAStore" KeyStore instance
@@ -160,7 +163,7 @@
     private static boolean sLoadedSystemKeyStore;
 
     /** A root that will be installed as a user-trusted root for testing purposes. */
-    private static X509Certificate sTestRoot;
+    private static @Nullable X509Certificate sTestRoot;
 
     /** Lock object used to synchronize all calls that modify or depend on the trust managers. */
     private static final Object sLock = new Object();
@@ -251,8 +254,8 @@
      * used. Returns null if no created TrustManager was suitable.
      * @throws KeyStoreException, NoSuchAlgorithmException on error initializing the TrustManager.
      */
-    private static X509TrustManagerExtensions createTrustManager(KeyStore keyStore)
-            throws KeyStoreException, NoSuchAlgorithmException {
+    private static @Nullable X509TrustManagerExtensions createTrustManager(
+            @Nullable KeyStore keyStore) throws KeyStoreException, NoSuchAlgorithmException {
         String algorithm = TrustManagerFactory.getDefaultAlgorithm();
         TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm);
         tmf.init(keyStore);
diff --git a/net/device_bound_sessions/registration_fetcher.cc b/net/device_bound_sessions/registration_fetcher.cc
index 02d84976b..4788820c 100644
--- a/net/device_bound_sessions/registration_fetcher.cc
+++ b/net/device_bound_sessions/registration_fetcher.cc
@@ -124,9 +124,8 @@
   unexportable_key_service.SignSlowlyAsync(
       key_id, base::as_byte_span(header_and_payload), kTaskPriority,
       base::BindOnce(&OnDataSigned, expected_algorithm.value(),
-                     std::ref(unexportable_key_service),
-                     std::move(header_and_payload), key_id,
-                     std::move(callback)));
+                     std::ref(unexportable_key_service), header_and_payload,
+                     key_id, std::move(callback)));
 }
 
 class RegistrationFetcherImpl : public URLRequest::Delegate {
@@ -230,8 +229,20 @@
     current_authorization_ = std::move(authorization);
 
     if (current_challenge_.has_value()) {
-      AttemptChallengeSigning();
-      return;
+      number_of_challenges_++;
+      if (number_of_challenges_ < kMaxChallenges) {
+        AttemptChallengeSigning();
+        return;
+      } else if (session_identifier_.has_value()) {
+        SessionTerminationParams params{*session_identifier_};
+        RunCallbackAndDeleteSelf(
+            std::make_optional<RegistrationFetcher::RegistrationCompleteParams>(
+                std::move(params), key_id_, fetcher_endpoint_));
+        return;
+      } else {
+        RunCallbackAndDeleteSelf(std::nullopt);
+        return;
+      }
     }
 
     // Start a request to get a challenge with the session identifier.
@@ -245,6 +256,7 @@
 
  private:
   static constexpr size_t kMaxSigningFailures = 2;
+  static constexpr size_t kMaxChallenges = 5;
 
   void AttemptChallengeSigning() {
     SignChallengeWithKey(
@@ -378,6 +390,7 @@
   std::optional<std::string> current_challenge_;
   std::optional<std::string> current_authorization_;
   size_t number_of_signing_failures_ = 0;
+  size_t number_of_challenges_ = 0;
 };
 
 RegistrationFetcher::FetcherType g_mock_fetcher = nullptr;
diff --git a/net/device_bound_sessions/registration_fetcher_unittest.cc b/net/device_bound_sessions/registration_fetcher_unittest.cc
index 024a24aa..7549123 100644
--- a/net/device_bound_sessions/registration_fetcher_unittest.cc
+++ b/net/device_bound_sessions/registration_fetcher_unittest.cc
@@ -26,6 +26,7 @@
 #include "net/cookies/cookie_store.h"
 #include "net/cookies/cookie_store_test_callbacks.h"
 #include "net/device_bound_sessions/registration_request_param.h"
+#include "net/device_bound_sessions/test_support.h"
 #include "net/http/http_request_headers.h"
 #include "net/http/http_response_headers.h"
 #include "net/http/http_status_code.h"
@@ -228,7 +229,14 @@
 TEST_F(RegistrationTest, BasicSuccess) {
   crypto::ScopedMockUnexportableKeyProvider scoped_mock_key_provider_;
   server_.RegisterRequestHandler(
-      base::BindRepeating(&ReturnResponse, HTTP_OK, kBasicValidJson));
+      base::BindRepeating([](const test_server::HttpRequest& request) {
+        auto resp_iter = request.headers.find("Sec-Session-Response");
+        EXPECT_TRUE(resp_iter != request.headers.end());
+        if (resp_iter != request.headers.end()) {
+          EXPECT_TRUE(VerifyEs256Jwt(resp_iter->second));
+        }
+        return ReturnResponse(HTTP_OK, kBasicValidJson, request);
+      }));
   ASSERT_TRUE(server_.Start());
 
   TestRegistrationCallback callback;
@@ -1121,6 +1129,35 @@
       1u);
 }
 
+TEST_F(RegistrationTest, TerminateSessionOnRepeatedChallenge) {
+  crypto::ScopedMockUnexportableKeyProvider scoped_mock_key_provider_;
+
+  auto* container = new UnauthorizedThenSuccessResponseContainer(100);
+  server_.RegisterRequestHandler(
+      base::BindRepeating(&UnauthorizedThenSuccessResponseContainer::Return,
+                          base::Owned(container)));
+  ASSERT_TRUE(server_.Start());
+
+  TestRegistrationCallback callback;
+  auto isolation_info = IsolationInfo::CreateTransient();
+  auto request_param = RegistrationRequestParam::CreateForTesting(
+      server_.base_url(), kSessionIdentifier, kChallenge);
+  CreateKeyAndRunCallback(base::BindOnce(
+      &RegistrationFetcher::StartFetchWithExistingKey, std::move(request_param),
+      std::ref(unexportable_key_service()), context_.get(),
+      std::ref(isolation_info), /*net_log_source=*/std::nullopt,
+      callback.callback()));
+  callback.WaitForCall();
+
+  std::optional<RegistrationFetcher::RegistrationCompleteParams> out_params =
+      callback.outcome();
+  ASSERT_TRUE(out_params);
+  const SessionTerminationParams* session_params =
+      std::get_if<SessionTerminationParams>(&out_params->params);
+  ASSERT_TRUE(session_params);
+  EXPECT_EQ(session_params->session_id, kSessionIdentifier);
+}
+
 class RegistrationTokenHelperTest : public testing::Test {
  public:
   RegistrationTokenHelperTest() : unexportable_key_service_(task_manager_) {}
diff --git a/net/device_bound_sessions/test_support.cc b/net/device_bound_sessions/test_support.cc
index 1747962..2c0fe1b 100644
--- a/net/device_bound_sessions/test_support.cc
+++ b/net/device_bound_sessions/test_support.cc
@@ -4,11 +4,27 @@
 
 #include "net/device_bound_sessions/test_support.h"
 
+#include <vector>
+
+#include "base/base64url.h"
+#include "base/compiler_specific.h"
+#include "base/containers/to_vector.h"
+#include "base/json/json_reader.h"
 #include "base/json/json_writer.h"
+#include "base/strings/strcat.h"
 #include "base/strings/string_util.h"
+#include "base/values.h"
+#include "crypto/signature_verifier.h"
 #include "net/test/embedded_test_server/http_request.h"
 #include "net/test/embedded_test_server/http_response.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/boringssl/src/include/openssl/base.h"
+#include "third_party/boringssl/src/include/openssl/bn.h"
+#include "third_party/boringssl/src/include/openssl/bytestring.h"
+#include "third_party/boringssl/src/include/openssl/ec_key.h"
+#include "third_party/boringssl/src/include/openssl/ecdsa.h"
+#include "third_party/boringssl/src/include/openssl/evp.h"
+#include "third_party/boringssl/src/include/openssl/mem.h"
 
 namespace net::device_bound_sessions {
 
@@ -47,6 +63,92 @@
   return nullptr;
 }
 
+std::optional<std::vector<uint8_t>> Es256JwkToSpki(
+    const base::Value::Dict& jwk) {
+  const std::string* x = jwk.FindString("x");
+  const std::string* y = jwk.FindString("y");
+  if (!x || !y) {
+    return std::nullopt;
+  }
+
+  std::optional<std::vector<uint8_t>> x_bytes =
+      base::Base64UrlDecode(*x, base::Base64UrlDecodePolicy::DISALLOW_PADDING);
+  std::optional<std::vector<uint8_t>> y_bytes =
+      base::Base64UrlDecode(*y, base::Base64UrlDecodePolicy::DISALLOW_PADDING);
+  if (!x_bytes || !y_bytes) {
+    return std::nullopt;
+  }
+
+  bssl::UniquePtr<EC_KEY> ec_key(
+      EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
+  if (!ec_key) {
+    return std::nullopt;
+  }
+
+  bssl::UniquePtr<BIGNUM> x_bn(
+      BN_bin2bn(x_bytes->data(), x_bytes->size(), nullptr));
+  bssl::UniquePtr<BIGNUM> y_bn(
+      BN_bin2bn(y_bytes->data(), y_bytes->size(), nullptr));
+  if (!x_bn || !y_bn) {
+    return std::nullopt;
+  }
+
+  if (!EC_KEY_set_public_key_affine_coordinates(ec_key.get(), x_bn.get(),
+                                                y_bn.get())) {
+    return std::nullopt;
+  }
+
+  bssl::UniquePtr<EVP_PKEY> pkey(EVP_PKEY_new());
+  if (!pkey || !EVP_PKEY_set1_EC_KEY(pkey.get(), ec_key.get())) {
+    return std::nullopt;
+  }
+
+  bssl::ScopedCBB cbb;
+  if (!CBB_init(cbb.get(), 0) ||
+      !EVP_marshal_public_key(cbb.get(), pkey.get())) {
+    return std::nullopt;
+  }
+
+  uint8_t* data;
+  size_t len;
+  if (!CBB_finish(cbb.get(), &data, &len)) {
+    return std::nullopt;
+  }
+
+  bssl::UniquePtr<uint8_t> delete_der(data);
+  // SAFETY: `CBB_finish` uses a C-style API.
+  auto spki_span = UNSAFE_BUFFERS(base::span<const uint8_t>(data, len));
+  return base::ToVector(spki_span);
+}
+
+std::optional<std::vector<uint8_t>> RawSigToDerSig(
+    base::span<const uint8_t> raw_sig) {
+  base::span<const uint8_t> r_bytes = raw_sig.first(32u);
+  base::span<const uint8_t> s_bytes = raw_sig.subspan(32u);
+
+  bssl::UniquePtr<ECDSA_SIG> ecdsa_sig(ECDSA_SIG_new());
+  if (!ecdsa_sig) {
+    return std::nullopt;
+  }
+
+  BN_bin2bn(r_bytes.data(), r_bytes.size(), ecdsa_sig->r);
+  BN_bin2bn(s_bytes.data(), s_bytes.size(), ecdsa_sig->s);
+  if (!ecdsa_sig->r || !ecdsa_sig->s) {
+    return std::nullopt;
+  }
+
+  uint8_t* der;
+  size_t der_len;
+  if (!ECDSA_SIG_to_bytes(&der, &der_len, ecdsa_sig.get())) {
+    return std::nullopt;
+  }
+
+  bssl::UniquePtr<uint8_t> delete_der(der);
+  // SAFETY: `ECDSA_SIG_to_bytes` uses a C-style API.
+  auto der_span = UNSAFE_BUFFERS(base::span<const uint8_t>(der, der_len));
+  return base::ToVector(der_span);
+}
+
 }  // namespace
 
 std::pair<base::span<const uint8_t>, std::string>
@@ -101,4 +203,59 @@
   return base::BindRepeating(&RequestHandler, base_url);
 }
 
+bool VerifyEs256Jwt(std::string_view jwt) {
+  // Parse JWT.
+  std::vector<std::string> jwt_sections =
+      base::SplitString(jwt, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
+  if (jwt_sections.size() != 3u) {
+    return false;
+  }
+
+  const std::string& header64 = jwt_sections[0];
+  const std::string& payload64 = jwt_sections[1];
+  const std::string& signature64 = jwt_sections[2];
+
+  std::string payload, signature;
+  if (!base::Base64UrlDecode(
+          payload64, base::Base64UrlDecodePolicy::DISALLOW_PADDING, &payload) ||
+      !base::Base64UrlDecode(signature64,
+                             base::Base64UrlDecodePolicy::DISALLOW_PADDING,
+                             &signature)) {
+    return false;
+  }
+
+  // Extract the JWK.
+  const std::optional<base::Value::Dict> payload_json =
+      base::JSONReader::ReadDict(payload);
+  if (!payload_json) {
+    return false;
+  }
+
+  const base::Value::Dict* jwk = payload_json->FindDict("key");
+  if (!jwk) {
+    return false;
+  }
+
+  // `crypto::SignatureVerifier` expects the public key in the
+  // SubjectPublicKeyInfo format and the signature in the DER format, so convert
+  // accordingly.
+  std::optional<std::vector<uint8_t>> spki = Es256JwkToSpki(*jwk);
+  if (!spki) {
+    return false;
+  }
+
+  std::optional<std::vector<uint8_t>> der_sig =
+      RawSigToDerSig(base::as_byte_span((signature)));
+  if (!der_sig) {
+    return false;
+  }
+
+  crypto::SignatureVerifier verifier;
+  verifier.VerifyInit(crypto::SignatureVerifier::ECDSA_SHA256, der_sig.value(),
+                      spki.value());
+  verifier.VerifyUpdate(
+      base::as_byte_span(base::StrCat({header64, ".", payload64})));
+  return verifier.VerifyFinal();
+}
+
 }  // namespace net::device_bound_sessions
diff --git a/net/device_bound_sessions/test_support.h b/net/device_bound_sessions/test_support.h
index ed1d6b1d8..29c9c70 100644
--- a/net/device_bound_sessions/test_support.h
+++ b/net/device_bound_sessions/test_support.h
@@ -6,6 +6,7 @@
 #define NET_DEVICE_BOUND_SESSIONS_TEST_SUPPORT_H_
 
 #include <string>
+#include <string_view>
 #include <utility>
 
 #include "base/containers/span.h"
@@ -24,6 +25,10 @@
 EmbeddedTestServer::HandleRequestCallback GetTestRequestHandler(
     const GURL& base_url);
 
+// Verify the signature of a JWT using the ES256 JWK stored in the "key" claim
+// in its payload.
+bool VerifyEs256Jwt(std::string_view jwt);
+
 }  // namespace net::device_bound_sessions
 
 #endif  // NET_DEVICE_BOUND_SESSIONS_TEST_SUPPORT_H_
diff --git a/remoting/base/url_loader_network_service_observer.cc b/remoting/base/url_loader_network_service_observer.cc
index 778c805e..46f65d4 100644
--- a/remoting/base/url_loader_network_service_observer.cc
+++ b/remoting/base/url_loader_network_service_observer.cc
@@ -152,6 +152,7 @@
     const url::Origin& request_origin,
     std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
         methods_with_options,
+    const std::optional<std::string>& with_lock,
     OnSharedStorageHeaderReceivedCallback callback) {
   std::move(callback).Run();
 }
diff --git a/remoting/base/url_loader_network_service_observer.h b/remoting/base/url_loader_network_service_observer.h
index 096faf3..e840b188 100644
--- a/remoting/base/url_loader_network_service_observer.h
+++ b/remoting/base/url_loader_network_service_observer.h
@@ -78,6 +78,7 @@
       const url::Origin& request_origin,
       std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
           methods_with_options,
+      const std::optional<std::string>& with_lock,
       OnSharedStorageHeaderReceivedCallback callback) override;
   void Clone(
       mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver>
diff --git a/remoting/host/base/username.cc b/remoting/host/base/username.cc
index 91e066eb..74ec593 100644
--- a/remoting/host/base/username.cc
+++ b/remoting/host/base/username.cc
@@ -29,9 +29,46 @@
 
   std::vector<char> buf(buf_size);
   struct passwd passwd;
-  struct passwd* passwd_result = nullptr;
+  struct passwd* passwd_result;
   uid_t user_id = getuid();
-  getpwuid_r(user_id, &passwd, &(buf[0]), buf_size, &passwd_result);
+
+  // Verify that `user_id` has a valid passwd database record, which matches
+  // the UID for this process. It is possible for multiple usernames to share
+  // the same user id, and some systems may not reliably support lookups by UID.
+  // Therefore, use the username from the environment (which is set by the
+  // parent process in remoting_user_session.cc), and do a lookup by name to ID.
+  // The logic is similar to FindCurrentUsername() from
+  // remoting_user_session.cc, except the re-entrant "_r" lookup functions are
+  // used here, for safety in a multi-threaded program.
+  for (const char* var : {"USER", "LOGNAME"}) {
+    const char* username_from_env = getenv(var);
+    if (!username_from_env) {
+      LOG(WARNING) << "Name '" << var << "' not found in environment.";
+      continue;
+    }
+
+    passwd_result = nullptr;
+    errno = getpwnam_r(username_from_env, &passwd, &(buf[0]), buf_size,
+                       &passwd_result);
+    if (!passwd_result) {
+      PLOG(WARNING) << "getpwnam_r() failed for username: "
+                    << username_from_env;
+      continue;
+    }
+
+    if (passwd_result->pw_uid != user_id) {
+      LOG(WARNING) << "getpwnam_r() for user '" << username_from_env
+                   << "' returned pw_uid " << passwd_result->pw_uid
+                   << " which does not match user id " << user_id;
+      continue;
+    }
+
+    return passwd_result->pw_name;
+  }
+
+  // The method above failed, fall back to a simple id->name lookup.
+  passwd_result = nullptr;
+  errno = getpwuid_r(user_id, &passwd, &(buf[0]), buf_size, &passwd_result);
   if (!passwd_result) {
     PLOG(ERROR) << "getpwuid_r() failed for user " << user_id;
     return std::string();
diff --git a/sandbox/policy/features.cc b/sandbox/policy/features.cc
index 2c7d416..76e52825 100644
--- a/sandbox/policy/features.cc
+++ b/sandbox/policy/features.cc
@@ -118,6 +118,12 @@
 BASE_FEATURE(kEnableCsrssLockdown,
              "EnableCsrssLockdown",
              base::FEATURE_DISABLED_BY_DEFAULT);
+
+// Filters most environment variables out for kService and kServiceWithJit
+// sandboxed processes.
+BASE_FEATURE(kWinSboxFilterServiceEnvironment,
+             "WinSboxFilterServiceEnvironment",
+             base::FEATURE_DISABLED_BY_DEFAULT);
 #endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/sandbox/policy/features.h b/sandbox/policy/features.h
index 78bea56..8564c72a 100644
--- a/sandbox/policy/features.h
+++ b/sandbox/policy/features.h
@@ -38,6 +38,7 @@
     kWinSboxRestrictCoreSharingOnRenderer);
 SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kWinSboxParallelProcessLaunch);
 SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kEnableCsrssLockdown);
+SANDBOX_POLICY_EXPORT BASE_DECLARE_FEATURE(kWinSboxFilterServiceEnvironment);
 #endif  // BUILDFLAG(IS_WIN)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/services/network/public/mojom/url_loader_network_service_observer.mojom b/services/network/public/mojom/url_loader_network_service_observer.mojom
index 4ea89d1..242e797 100644
--- a/services/network/public/mojom/url_loader_network_service_observer.mojom
+++ b/services/network/public/mojom/url_loader_network_service_observer.mojom
@@ -176,7 +176,9 @@
   // the network service for security and privacy; this method then notifies
   // the browser process or other observer implementers that the raw headers
   // have been parsed into an array of
-  // `SharedStorageModifierMethodWithOptions`s.
+  // `SharedStorageModifierMethodWithOptions`s and an optional `with_lock`
+  // option.
+  // https://github.com/WICG/shared-storage#from-response-headers
   //
   // The order of the methods as listed in the header(s) is preserved, so that
   // the browser process (the main implementer of this API) can guarantee that
@@ -193,7 +195,8 @@
   // triggered by response headers and Shared Storage calls from the same
   // renderer process where this request originated.
   OnSharedStorageHeaderReceived(url.mojom.Origin request_origin,
-                 array<SharedStorageModifierMethodWithOptions> methods_with_options) => ();
+                 array<SharedStorageModifierMethodWithOptions> methods_with_options,
+                 string? with_lock) => ();
 
   // Used by the NetworkService to create a copy of this observer.
   // (e.g. when creating an observer for URLLoader from URLLoaderFactory's
diff --git a/services/network/shared_storage/shared_storage_header_utils.cc b/services/network/shared_storage/shared_storage_header_utils.cc
index 70704ba..103f3d04a 100644
--- a/services/network/shared_storage/shared_storage_header_utils.cc
+++ b/services/network/shared_storage/shared_storage_header_utils.cc
@@ -42,6 +42,10 @@
   return method_it->second;
 }
 
+bool IsHeaderItemBatchOptions(std::string_view item_str) {
+  return base::ToLowerASCII(item_str) == "options";
+}
+
 std::optional<SharedStorageHeaderParamType>
 StringToSharedStorageHeaderParamType(std::string_view param_str) {
   auto param_it =
diff --git a/services/network/shared_storage/shared_storage_header_utils.h b/services/network/shared_storage/shared_storage_header_utils.h
index 8f9b881..e47897e 100644
--- a/services/network/shared_storage/shared_storage_header_utils.h
+++ b/services/network/shared_storage/shared_storage_header_utils.h
@@ -39,6 +39,10 @@
 std::optional<SharedStorageModifierMethodType>
 StringToSharedStorageModifierMethodType(std::string_view method_str);
 
+// Returns whether `item_str` is a valid "options" structured header item. This
+// item is used to specify options for a batch of shared storage methods.
+bool IsHeaderItemBatchOptions(std::string_view item_str);
+
 std::optional<SharedStorageHeaderParamType>
 StringToSharedStorageHeaderParamType(std::string_view param_str);
 
diff --git a/services/network/shared_storage/shared_storage_request_helper.cc b/services/network/shared_storage/shared_storage_request_helper.cc
index 1aa705b..7041397 100644
--- a/services/network/shared_storage/shared_storage_request_helper.cc
+++ b/services/network/shared_storage/shared_storage_request_helper.cc
@@ -54,8 +54,7 @@
   request.response_headers()->RemoveHeader(kSharedStorageWriteHeader);
 }
 
-mojom::SharedStorageModifierMethodWithOptionsPtr
-MakeSharedStorageModifierMethodWithOptions(
+const net::structured_headers::Item* ParseIntoSharedStorageHeaderItem(
     const net::structured_headers::ParameterizedMember& parameterized_member) {
   if (parameterized_member.member_is_inner_list ||
       parameterized_member.member.size() != 1) {
@@ -69,6 +68,36 @@
     return nullptr;
   }
 
+  return &item;
+}
+
+std::optional<std::string> ParseWithLockParam(
+    const net::structured_headers::Parameters& params) {
+  for (const auto& [param_key, param_item] : params) {
+    if (!IsStringLike(param_item)) {
+      // Not a valid parameter item type for 'with_lock' option.
+      continue;
+    }
+
+    std::optional<SharedStorageHeaderParamType> param_type =
+        StringToSharedStorageHeaderParamType(param_key);
+    if (!param_type.has_value()) {
+      // Did not find a valid parameter key.
+      continue;
+    }
+
+    if (param_type.value() == SharedStorageHeaderParamType::kWithLock) {
+      return param_item.GetString();
+    }
+  }
+
+  return std::nullopt;
+}
+
+mojom::SharedStorageModifierMethodWithOptionsPtr
+MakeSharedStorageModifierMethodWithOptions(
+    const net::structured_headers::Item& item,
+    const net::structured_headers::Parameters& params) {
   std::optional<SharedStorageModifierMethodType> method_type =
       StringToSharedStorageModifierMethodType(item.GetString());
   if (!method_type.has_value()) {
@@ -81,7 +110,7 @@
   bool ignore_if_present = false;
   std::optional<std::string> with_lock;
 
-  for (const auto& [param_key, param_item] : parameterized_member.params) {
+  for (const auto& [param_key, param_item] : params) {
     if (!IsStringLike(param_item) && !param_item.is_boolean()) {
       // Not a valid parameter item type for "Shared-Storage-Write" header.
       continue;
@@ -266,12 +295,27 @@
       methods_with_options;
   methods_with_options.reserve(list.value().size());
 
+  std::optional<std::string> with_lock;
+
   for (const auto& member : list.value()) {
+    const net::structured_headers::Item* item =
+        ParseIntoSharedStorageHeaderItem(member);
+    if (!item) {
+      parse_results.push_back(false);
+      continue;
+    }
+
     auto method_with_options =
-        MakeSharedStorageModifierMethodWithOptions(member);
+        MakeSharedStorageModifierMethodWithOptions(*item, member.params);
     if (method_with_options) {
       methods_with_options.push_back(std::move(method_with_options));
       parse_results.push_back(true);
+    } else if (IsHeaderItemBatchOptions(item->GetString())) {
+      // The batch "options" item may appear multiple times in the list, and
+      // should override any previously parsed value. Currently, the only
+      // relevant parameter is "with_lock".
+      with_lock = ParseWithLockParam(member.params);
+      parse_results.push_back(true);
     } else {
       parse_results.push_back(false);
     }
@@ -279,6 +323,7 @@
 
   observer_->OnSharedStorageHeaderReceived(
       url::Origin::Create(request.url()), std::move(methods_with_options),
+      with_lock,
       base::BindOnce(&SharedStorageRequestHelper::OnMethodsQueued,
                      weak_ptr_factory_.GetWeakPtr(), std::move(done)));
   return true;
diff --git a/services/network/shared_storage/shared_storage_request_helper_unittest.cc b/services/network/shared_storage/shared_storage_request_helper_unittest.cc
index 08534a3a..2403cb4b 100644
--- a/services/network/shared_storage/shared_storage_request_helper_unittest.cc
+++ b/services/network/shared_storage/shared_storage_request_helper_unittest.cc
@@ -446,8 +446,9 @@
   WaitForHeadersReceived(1);
 
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, request_origin_);
-  EXPECT_TRUE(observer_->headers_received().front().second.empty());
+  EXPECT_EQ(observer_->headers_received().front().request_origin,
+            request_origin_);
+  EXPECT_TRUE(observer_->headers_received().front().methods.empty());
 }
 
 TEST_F(SharedStorageRequestHelperProcessHeaderTest,
@@ -462,9 +463,10 @@
   WaitForHeadersReceived(1);
 
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, request_origin_);
+  EXPECT_EQ(observer_->headers_received().front().request_origin,
+            request_origin_);
   EXPECT_THAT(
-      observer_->headers_received().front().second,
+      observer_->headers_received().front().methods,
       ElementsAre(
           SharedStorageMethodWrapper(MojomClearMethod()),
           SharedStorageMethodWrapper(MojomSetMethod(
@@ -493,9 +495,10 @@
   // The `SharedStorageRequestHelper` skips over it and sends the valid methods
   // it finds.
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, request_origin_);
+  EXPECT_EQ(observer_->headers_received().front().request_origin,
+            request_origin_);
 
-  EXPECT_THAT(observer_->headers_received().front().second,
+  EXPECT_THAT(observer_->headers_received().front().methods,
               ElementsAre(
                   // The superfluous parameter `key` is omitted.
                   SharedStorageMethodWrapper(MojomClearMethod()),
@@ -523,15 +526,16 @@
   WaitForHeadersReceived(1);
 
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, request_origin_);
+  EXPECT_EQ(observer_->headers_received().front().request_origin,
+            request_origin_);
 
-  EXPECT_THAT(observer_->headers_received().front().second,
+  EXPECT_THAT(observer_->headers_received().front().methods,
               ElementsAre(SharedStorageMethodWrapper(
                   MojomSetMethod(/*key=*/u"k", /*value=*/u"v",
                                  /*ignore_if_present=*/false))));
 }
 
-TEST_F(SharedStorageRequestHelperProcessHeaderTest, WithLockOption) {
+TEST_F(SharedStorageRequestHelperProcessHeaderTest, IndividualMethodWithLock) {
   const std::string kHeader =
       "set;key=k;value=v;with_lock=lock1, append;key=k;value=v;with_lock=\"\", "
       "delete;key=k, clear;with_lock=lock2";
@@ -543,10 +547,11 @@
   WaitForHeadersReceived(1);
 
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, request_origin_);
+  EXPECT_EQ(observer_->headers_received().front().request_origin,
+            request_origin_);
 
   EXPECT_THAT(
-      observer_->headers_received().front().second,
+      observer_->headers_received().front().methods,
       ElementsAre(
           SharedStorageMethodWrapper(MojomSetMethod(
               /*key=*/u"k", /*value=*/u"v",
@@ -555,6 +560,89 @@
               /*key=*/u"k", /*value=*/u"v", /*with_lock=*/"")),
           SharedStorageMethodWrapper(MojomDeleteMethod(/*key=*/u"k")),
           SharedStorageMethodWrapper(MojomClearMethod(/*with_lock=*/"lock2"))));
+
+  // Expect no with_lock option for the batch.
+  EXPECT_EQ(observer_->headers_received().front().with_lock, std::nullopt);
+}
+
+TEST_F(SharedStorageRequestHelperProcessHeaderTest, BatchOptionsWithLock) {
+  const std::string kHeader =
+      "set;key=k;value=v;with_lock=lock1, append;key=k;value=v, "
+      "options;with_lock=lock2";
+
+  RegisterSharedStorageHandlerAndStartServer(kHeader);
+
+  auto r = CreateSharedStorageRequest();
+  StartRequestAndProcessHeader(r.get(), kHeader);
+  WaitForHeadersReceived(1);
+
+  EXPECT_EQ(observer_->headers_received().size(), 1u);
+  EXPECT_EQ(observer_->headers_received().front().request_origin,
+            request_origin_);
+
+  EXPECT_THAT(
+      observer_->headers_received().front().methods,
+      ElementsAre(SharedStorageMethodWrapper(MojomSetMethod(
+                      /*key=*/u"k", /*value=*/u"v",
+                      /*ignore_if_present=*/false, /*with_lock=*/"lock1")),
+                  SharedStorageMethodWrapper(MojomAppendMethod(
+                      /*key=*/u"k", /*value=*/u"v"))));
+
+  EXPECT_EQ(observer_->headers_received().front().with_lock, "lock2");
+}
+
+TEST_F(SharedStorageRequestHelperProcessHeaderTest,
+       BatchOptionsWithLock_OverridePreviousOptions) {
+  const std::string kHeader =
+      "set;key=k;value=v;with_lock=lock1, append;key=k;value=v, "
+      "options;with_lock=lock2, options;abc=def";
+
+  RegisterSharedStorageHandlerAndStartServer(kHeader);
+
+  auto r = CreateSharedStorageRequest();
+  StartRequestAndProcessHeader(r.get(), kHeader);
+  WaitForHeadersReceived(1);
+
+  EXPECT_EQ(observer_->headers_received().size(), 1u);
+  EXPECT_EQ(observer_->headers_received().front().request_origin,
+            request_origin_);
+
+  EXPECT_THAT(
+      observer_->headers_received().front().methods,
+      ElementsAre(SharedStorageMethodWrapper(MojomSetMethod(
+                      /*key=*/u"k", /*value=*/u"v",
+                      /*ignore_if_present=*/false, /*with_lock=*/"lock1")),
+                  SharedStorageMethodWrapper(MojomAppendMethod(
+                      /*key=*/u"k", /*value=*/u"v"))));
+
+  EXPECT_EQ(observer_->headers_received().front().with_lock, std::nullopt);
+}
+
+TEST_F(SharedStorageRequestHelperProcessHeaderTest,
+       BatchOptionsWithLock_InTheMiddle) {
+  const std::string kHeader =
+      "set;key=k;value=v;with_lock=lock1, options;abc=def;with_lock=lock2, "
+      "append;key=k;value=v";
+
+  RegisterSharedStorageHandlerAndStartServer(kHeader);
+
+  auto r = CreateSharedStorageRequest();
+  StartRequestAndProcessHeader(r.get(), kHeader);
+  WaitForHeadersReceived(1);
+
+  EXPECT_EQ(observer_->headers_received().size(), 1u);
+  EXPECT_EQ(observer_->headers_received().front().request_origin,
+            request_origin_);
+
+  EXPECT_THAT(
+      observer_->headers_received().front().methods,
+      ElementsAre(SharedStorageMethodWrapper(MojomSetMethod(
+                      /*key=*/u"k", /*value=*/u"v",
+                      /*ignore_if_present=*/false, /*with_lock=*/"lock1")),
+                  SharedStorageMethodWrapper(MojomAppendMethod(
+                      /*key=*/u"k", /*value=*/u"v"))));
+
+  EXPECT_EQ(observer_->headers_received().front().with_lock, "lock2");
 }
 
 namespace {
@@ -619,10 +707,10 @@
     WaitForHeadersReceived(i + 1);
 
     EXPECT_EQ(observer_->headers_received().size(), i + 1);
-    EXPECT_EQ(observer_->headers_received()[i].first, request_origin_);
+    EXPECT_EQ(observer_->headers_received()[i].request_origin, request_origin_);
 
     EXPECT_THAT(
-        observer_->headers_received()[i].second,
+        observer_->headers_received()[i].methods,
         ElementsAre(
             SharedStorageMethodWrapper(MojomSetMethod(
                 /*key=*/u"x", /*value=*/u"y", /*ignore_if_present=*/false)),
diff --git a/services/network/shared_storage/shared_storage_test_url_loader_network_observer.cc b/services/network/shared_storage/shared_storage_test_url_loader_network_observer.cc
index 961fed8..df815fb 100644
--- a/services/network/shared_storage/shared_storage_test_url_loader_network_observer.cc
+++ b/services/network/shared_storage/shared_storage_test_url_loader_network_observer.cc
@@ -23,6 +23,24 @@
 
 namespace network {
 
+SharedStorageTestURLLoaderNetworkObserver::HeaderResult::HeaderResult(
+    const url::Origin& request_origin,
+    std::vector<SharedStorageMethodWrapper> methods,
+    const std::optional<std::string>& with_lock)
+    : request_origin(request_origin),
+      methods(std::move(methods)),
+      with_lock(with_lock) {}
+
+SharedStorageTestURLLoaderNetworkObserver::HeaderResult::HeaderResult(
+    HeaderResult&& other) = default;
+
+SharedStorageTestURLLoaderNetworkObserver::HeaderResult&
+SharedStorageTestURLLoaderNetworkObserver::HeaderResult::operator=(
+    HeaderResult&& other) = default;
+
+SharedStorageTestURLLoaderNetworkObserver::HeaderResult::~HeaderResult() =
+    default;
+
 SharedStorageTestURLLoaderNetworkObserver::
     SharedStorageTestURLLoaderNetworkObserver() = default;
 SharedStorageTestURLLoaderNetworkObserver::
@@ -32,13 +50,15 @@
     const url::Origin& request_origin,
     std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
         methods_with_options,
+    const std::optional<std::string>& with_lock,
     OnSharedStorageHeaderReceivedCallback callback) {
   std::vector<SharedStorageMethodWrapper> transformed =
       base::ToVector(methods_with_options, [](auto& methods_with_options) {
         return SharedStorageMethodWrapper(std::move(methods_with_options));
       });
 
-  headers_received_.emplace_back(request_origin, std::move(transformed));
+  headers_received_.emplace_back(request_origin, std::move(transformed),
+                                 with_lock);
   if (loop_ && loop_->running() &&
       headers_received_.size() >= expected_total_) {
     loop_->Quit();
diff --git a/services/network/shared_storage/shared_storage_test_url_loader_network_observer.h b/services/network/shared_storage/shared_storage_test_url_loader_network_observer.h
index a15656c..d59bbbf4 100644
--- a/services/network/shared_storage/shared_storage_test_url_loader_network_observer.h
+++ b/services/network/shared_storage/shared_storage_test_url_loader_network_observer.h
@@ -24,12 +24,28 @@
 class SharedStorageTestURLLoaderNetworkObserver
     : public TestURLLoaderNetworkObserver {
  public:
+  struct HeaderResult {
+    HeaderResult(const url::Origin& request_origin,
+                 std::vector<SharedStorageMethodWrapper> methods,
+                 const std::optional<std::string>& with_lock);
+
+    HeaderResult(const HeaderResult& other) = delete;
+    HeaderResult& operator=(const HeaderResult& other) = delete;
+
+    HeaderResult(HeaderResult&& other);
+    HeaderResult& operator=(HeaderResult&& other);
+
+    ~HeaderResult();
+
+    url::Origin request_origin;
+    std::vector<SharedStorageMethodWrapper> methods;
+    std::optional<std::string> with_lock;
+  };
+
   SharedStorageTestURLLoaderNetworkObserver();
   ~SharedStorageTestURLLoaderNetworkObserver() override;
 
-  const std::vector<
-      std::pair<url::Origin, std::vector<SharedStorageMethodWrapper>>>&
-  headers_received() const {
+  const std::vector<HeaderResult>& headers_received() const {
     return headers_received_;
   }
 
@@ -38,6 +54,7 @@
       const url::Origin& request_origin,
       std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
           methods_with_options,
+      const std::optional<std::string>& with_lock,
       OnSharedStorageHeaderReceivedCallback callback) override;
 
   void WaitForHeadersReceived(size_t expected_total);
@@ -45,8 +62,7 @@
  private:
   std::unique_ptr<base::RunLoop> loop_;
   size_t expected_total_ = 0;
-  std::vector<std::pair<url::Origin, std::vector<SharedStorageMethodWrapper>>>
-      headers_received_;
+  std::vector<HeaderResult> headers_received_;
 };
 
 }  // namespace network
diff --git a/services/network/test/test_url_loader_network_observer.cc b/services/network/test/test_url_loader_network_observer.cc
index b46a6aa..3683bad7 100644
--- a/services/network/test/test_url_loader_network_observer.cc
+++ b/services/network/test/test_url_loader_network_observer.cc
@@ -82,6 +82,7 @@
     const url::Origin& request_origin,
     std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
         methods_with_options,
+    const std::optional<std::string>& with_lock,
     OnSharedStorageHeaderReceivedCallback callback) {
   std::move(callback).Run();
 }
diff --git a/services/network/test/test_url_loader_network_observer.h b/services/network/test/test_url_loader_network_observer.h
index 5bac4652..7e15db50 100644
--- a/services/network/test/test_url_loader_network_observer.h
+++ b/services/network/test/test_url_loader_network_observer.h
@@ -70,6 +70,7 @@
       const url::Origin& request_origin,
       std::vector<network::mojom::SharedStorageModifierMethodWithOptionsPtr>
           methods_with_options,
+      const std::optional<std::string>& with_lock,
       OnSharedStorageHeaderReceivedCallback callback) override;
   void Clone(
       mojo::PendingReceiver<URLLoaderNetworkServiceObserver> observer) override;
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc
index c886bbb..3099d503 100644
--- a/services/network/url_loader_unittest.cc
+++ b/services/network/url_loader_unittest.cc
@@ -7722,8 +7722,8 @@
   WaitForHeadersReceived(1);
 
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, kTestOrigin);
-  EXPECT_THAT(observer_->headers_received().front().second,
+  EXPECT_EQ(observer_->headers_received().front().request_origin, kTestOrigin);
+  EXPECT_THAT(observer_->headers_received().front().methods,
               ElementsAre(SharedStorageMethodWrapper(MojomClearMethod()),
                           SharedStorageMethodWrapper(
                               MojomSetMethod(/*key=*/u"k", /*value=*/u"v",
@@ -7752,8 +7752,8 @@
   WaitForHeadersReceived(1);
 
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, kTestOrigin);
-  EXPECT_THAT(observer_->headers_received().front().second,
+  EXPECT_EQ(observer_->headers_received().front().request_origin, kTestOrigin);
+  EXPECT_THAT(observer_->headers_received().front().methods,
               ElementsAre(SharedStorageMethodWrapper(MojomClearMethod()),
                           SharedStorageMethodWrapper(
                               MojomSetMethod(/*key=*/u"k", /*value=*/u"v",
@@ -7792,8 +7792,8 @@
   WaitForHeadersReceived(1);
 
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, kTestOrigin);
-  EXPECT_THAT(observer_->headers_received().front().second,
+  EXPECT_EQ(observer_->headers_received().front().request_origin, kTestOrigin);
+  EXPECT_THAT(observer_->headers_received().front().methods,
               ElementsAre(SharedStorageMethodWrapper(MojomClearMethod()),
                           SharedStorageMethodWrapper(
                               MojomSetMethod(/*key=*/u"k", /*value=*/u"v",
@@ -7823,9 +7823,9 @@
   WaitForHeadersReceived(2);
 
   EXPECT_EQ(observer_->headers_received().size(), 2u);
-  EXPECT_EQ(observer_->headers_received().back().first, kTestOrigin);
+  EXPECT_EQ(observer_->headers_received().back().request_origin, kTestOrigin);
   EXPECT_THAT(
-      observer_->headers_received().back().second,
+      observer_->headers_received().back().methods,
       ElementsAre(SharedStorageMethodWrapper(
                       MojomAppendMethod(/*key=*/u"b", /*value=*/u"a")),
                   SharedStorageMethodWrapper(MojomDeleteMethod(/*key=*/u"k"))));
@@ -7869,9 +7869,9 @@
   WaitForHeadersReceived(1);
 
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, kCrossOrigin);
+  EXPECT_EQ(observer_->headers_received().front().request_origin, kCrossOrigin);
   EXPECT_THAT(
-      observer_->headers_received().front().second,
+      observer_->headers_received().front().methods,
       ElementsAre(SharedStorageMethodWrapper(MojomClearMethod()),
                   SharedStorageMethodWrapper(MojomSetMethod(
                       /*key=*/u"k", u"v", /*ignore_if_present=*/false))));
@@ -7955,8 +7955,8 @@
   WaitForHeadersReceived(1);
 
   EXPECT_EQ(observer_->headers_received().size(), 1u);
-  EXPECT_EQ(observer_->headers_received().front().first, kTestOrigin);
-  EXPECT_THAT(observer_->headers_received().front().second,
+  EXPECT_EQ(observer_->headers_received().front().request_origin, kTestOrigin);
+  EXPECT_THAT(observer_->headers_received().front().methods,
               ElementsAre(SharedStorageMethodWrapper(MojomClearMethod()),
                           SharedStorageMethodWrapper(
                               MojomSetMethod(/*key=*/u"k", /*value=*/u"v",
diff --git a/services/video_effects/gpu_channel_host_provider.h b/services/video_effects/gpu_channel_host_provider.h
index 87a818d1..4ee9b369 100644
--- a/services/video_effects/gpu_channel_host_provider.h
+++ b/services/video_effects/gpu_channel_host_provider.h
@@ -5,6 +5,7 @@
 #ifndef SERVICES_VIDEO_EFFECTS_GPU_CHANNEL_HOST_PROVIDER_H_
 #define SERVICES_VIDEO_EFFECTS_GPU_CHANNEL_HOST_PROVIDER_H_
 
+#include "base/memory/ref_counted.h"
 #include "base/memory/scoped_refptr.h"
 
 namespace gpu {
@@ -23,10 +24,8 @@
 // instances of `gpu::GpuChannelHost`. Those are then going to be used to
 // create context providers over which the communication to GPU service will
 // happen.
-class GpuChannelHostProvider {
+class GpuChannelHostProvider : public base::RefCounted<GpuChannelHostProvider> {
  public:
-  virtual ~GpuChannelHostProvider() = default;
-
   // Returns the context provider for WebGPU.
   virtual scoped_refptr<viz::ContextProviderCommandBuffer>
   GetWebGpuContextProvider() = 0;
@@ -40,10 +39,15 @@
   GetSharedImageInterface() = 0;
 
  protected:
+  virtual ~GpuChannelHostProvider() = default;
+
   // Return a connected `gpu::GpuChannelHost`. Implementations should expect
   // this method to be called somewhat frequently when a new Video Effects
   // Service is created.
   virtual scoped_refptr<gpu::GpuChannelHost> GetGpuChannelHost() = 0;
+
+ private:
+  friend class base::RefCounted<GpuChannelHostProvider>;
 };
 
 }  // namespace video_effects
diff --git a/services/video_effects/test_gpu_channel_host_provider.cc b/services/video_effects/test_gpu_channel_host_provider.cc
index 578a4d8..98efe93e 100644
--- a/services/video_effects/test_gpu_channel_host_provider.cc
+++ b/services/video_effects/test_gpu_channel_host_provider.cc
@@ -56,6 +56,8 @@
   return nullptr;
 }
 
+TestGpuChannelHostProvider::~TestGpuChannelHostProvider() = default;
+
 scoped_refptr<gpu::GpuChannelHost>
 TestGpuChannelHostProvider::GetGpuChannelHost() {
   return base::MakeRefCounted<TestGpuChannelHost>(gpu_channel_.get());
diff --git a/services/video_effects/test_gpu_channel_host_provider.h b/services/video_effects/test_gpu_channel_host_provider.h
index 4b97e0dc..10bbd233 100644
--- a/services/video_effects/test_gpu_channel_host_provider.h
+++ b/services/video_effects/test_gpu_channel_host_provider.h
@@ -26,6 +26,7 @@
       override;
 
  protected:
+  ~TestGpuChannelHostProvider() override;
   scoped_refptr<gpu::GpuChannelHost> GetGpuChannelHost() override;
 
  private:
diff --git a/services/video_effects/video_effects_processor_impl.cc b/services/video_effects/video_effects_processor_impl.cc
index 1099398..2342a99f 100644
--- a/services/video_effects/video_effects_processor_impl.cc
+++ b/services/video_effects/video_effects_processor_impl.cc
@@ -36,13 +36,14 @@
     wgpu::Device device,
     mojo::PendingRemote<media::mojom::VideoEffectsManager> manager_remote,
     mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor_receiver,
-    std::unique_ptr<GpuChannelHostProvider> gpu_channel_host_provider,
+    scoped_refptr<GpuChannelHostProvider> gpu_channel_host_provider,
     base::OnceClosure on_unrecoverable_error)
     : device_(device),
       manager_remote_(std::move(manager_remote)),
       processor_receiver_(this, std::move(processor_receiver)),
-      gpu_channel_host_provider_(std::move(gpu_channel_host_provider)),
+      gpu_channel_host_provider_(gpu_channel_host_provider),
       on_unrecoverable_error_(std::move(on_unrecoverable_error)) {
+  CHECK(gpu_channel_host_provider_);
   processor_receiver_.set_disconnect_handler(
       base::BindOnce(&VideoEffectsProcessorImpl::OnMojoDisconnected,
                      weak_ptr_factory_.GetWeakPtr()));
diff --git a/services/video_effects/video_effects_processor_impl.h b/services/video_effects/video_effects_processor_impl.h
index 0f498cd8..1eb35fd 100644
--- a/services/video_effects/video_effects_processor_impl.h
+++ b/services/video_effects/video_effects_processor_impl.h
@@ -40,7 +40,7 @@
       wgpu::Device device,
       mojo::PendingRemote<media::mojom::VideoEffectsManager> manager_remote,
       mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor_receiver,
-      std::unique_ptr<GpuChannelHostProvider> gpu_channel_host_provider,
+      scoped_refptr<GpuChannelHostProvider> gpu_channel_host_provider,
       base::OnceClosure on_unrecoverable_error);
 
   ~VideoEffectsProcessorImpl() override;
@@ -84,7 +84,7 @@
   mojo::Remote<media::mojom::VideoEffectsManager> manager_remote_;
   mojo::Receiver<mojom::VideoEffectsProcessor> processor_receiver_;
 
-  std::unique_ptr<GpuChannelHostProvider> gpu_channel_host_provider_;
+  scoped_refptr<GpuChannelHostProvider> gpu_channel_host_provider_;
 
   // Called when this processor enters a defunct state.
   base::OnceClosure on_unrecoverable_error_;
diff --git a/services/video_effects/video_effects_processor_impl_unittest.cc b/services/video_effects/video_effects_processor_impl_unittest.cc
index 4549697a..69a0b9a 100644
--- a/services/video_effects/video_effects_processor_impl_unittest.cc
+++ b/services/video_effects/video_effects_processor_impl_unittest.cc
@@ -44,21 +44,19 @@
 
 class VideoEffectsProcessorTest : public testing::Test {
   void SetUp() override {
-    auto gpu_channel_host_provider =
-        std::make_unique<TestGpuChannelHostProvider>(gpu_channel_);
+    scoped_refptr<GpuChannelHostProvider> gpu_channel_host_provider =
+        new TestGpuChannelHostProvider(gpu_channel_);
 
     on_processor_error_.emplace();
 
-    processor_impl_.emplace(wgpu::Device{},
-                            manager_receiver_.InitWithNewPipeAndPassRemote(),
-                            processor_remote_.BindNewPipeAndPassReceiver(),
-                            std::move(gpu_channel_host_provider),
-                            on_processor_error_->GetCallback());
+    processor_impl_.emplace(
+        wgpu::Device{}, manager_receiver_.InitWithNewPipeAndPassRemote(),
+        processor_remote_.BindNewPipeAndPassReceiver(),
+        gpu_channel_host_provider, on_processor_error_->GetCallback());
   }
 
  protected:
   base::test::TaskEnvironment task_environment_;
-
   gpu::MockGpuChannel gpu_channel_;
 
   // Processor under test:
diff --git a/services/video_effects/video_effects_service_impl.cc b/services/video_effects/video_effects_service_impl.cc
index 7a243619..c868e29c 100644
--- a/services/video_effects/video_effects_service_impl.cc
+++ b/services/video_effects/video_effects_service_impl.cc
@@ -46,50 +46,43 @@
     return;
   }
 
-  auto gpu = viz::Gpu::Create(std::move(gpu_remote), io_task_runner_);
-  auto gpu_channel_host_provider =
-      std::make_unique<VizGpuChannelHostProvider>(std::move(gpu));
+  // If this is the first request, create the context objects.
+  if (!gpu_channel_host_provider_) {
+    auto gpu = viz::Gpu::Create(std::move(gpu_remote), io_task_runner_);
+    gpu_channel_host_provider_ = new VizGpuChannelHostProvider(std::move(gpu));
+  }
 
   if (device_) {
     // We already have a wgpu::Device.  Go ahead and create the processor.
     FinishCreatingEffectsProcessor(device_id, std::move(manager_remote),
-                                   std::move(processor_receiver),
-                                   std::move(gpu_channel_host_provider));
+                                   std::move(processor_receiver));
     return;
   }
 
-  VizGpuChannelHostProvider* provider_ptr = nullptr;
-  if (!webgpu_device_) {
-    provider_ptr = gpu_channel_host_provider.get();
-  }
-
   // Store the pending request.
   PendingEffectsProcessor pending;
   pending.manager_remote = std::move(manager_remote);
   pending.processor_receiver = std::move(processor_receiver);
-  pending.gpu_channel_host_provider = std::move(gpu_channel_host_provider);
   auto [_, inserted] =
       pending_processors_.insert(std::make_pair(device_id, std::move(pending)));
   CHECK(inserted);
 
   if (!webgpu_device_) {
-    CreateWebGpuDeviceAndEffectsProcessors(
-        provider_ptr->GetWebGpuContextProvider());
+    CreateWebGpuDeviceAndEffectsProcessors();
     return;
   }
   // A wgpu::Device is already being created.  We don't need to do anything as
   // pending processors will be created when it is ready.
 }
 
-void VideoEffectsServiceImpl::CreateWebGpuDeviceAndEffectsProcessors(
-    scoped_refptr<viz::ContextProviderCommandBuffer> context_provider) {
+void VideoEffectsServiceImpl::CreateWebGpuDeviceAndEffectsProcessors() {
   CHECK(!webgpu_device_);
-  CHECK(context_provider);
-
+  CHECK(gpu_channel_host_provider_);
   WebGpuDevice::DeviceLostCallback device_lost_cb = base::BindOnce(
       &VideoEffectsServiceImpl::OnDeviceLost, weak_ptr_factory_.GetWeakPtr());
-  webgpu_device_ = std::make_unique<WebGpuDevice>(std::move(context_provider),
-                                                  std::move(device_lost_cb));
+  webgpu_device_ = std::make_unique<WebGpuDevice>(
+      gpu_channel_host_provider_->GetWebGpuContextProvider(),
+      std::move(device_lost_cb));
 
   WebGpuDevice::DeviceCallback device_cb =
       base::BindOnce(&VideoEffectsServiceImpl::OnDeviceCreated,
@@ -137,10 +130,9 @@
 void VideoEffectsServiceImpl::FinishCreatingEffectsProcessors() {
   // Called in-sequence by OnDeviceCreated().
   for (auto& it : pending_processors_) {
-    FinishCreatingEffectsProcessor(
-        it.first, std::move(it.second.manager_remote),
-        std::move(it.second.processor_receiver),
-        std::move(it.second.gpu_channel_host_provider));
+    FinishCreatingEffectsProcessor(it.first,
+                                   std::move(it.second.manager_remote),
+                                   std::move(it.second.processor_receiver));
   }
   pending_processors_.clear();
 }
@@ -148,8 +140,7 @@
 void VideoEffectsServiceImpl::FinishCreatingEffectsProcessor(
     const std::string& device_id,
     mojo::PendingRemote<media::mojom::VideoEffectsManager> manager_remote,
-    mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor_receiver,
-    std::unique_ptr<GpuChannelHostProvider> gpu_channel_host_provider) {
+    mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor_receiver) {
   // Called in-sequence.
   if (!device_) {
     // Lost the wgpu::Device before the processor could be constructed. We could
@@ -163,8 +154,7 @@
 
   auto effects_processor = std::make_unique<VideoEffectsProcessorImpl>(
       device_, std::move(manager_remote), std::move(processor_receiver),
-      std::move(gpu_channel_host_provider),
-      std::move(on_unrecoverable_processor_error));
+      gpu_channel_host_provider_, std::move(on_unrecoverable_processor_error));
 
   if (!effects_processor->Initialize()) {
     return;
diff --git a/services/video_effects/video_effects_service_impl.h b/services/video_effects/video_effects_service_impl.h
index 2e49a506..fa2a1c7 100644
--- a/services/video_effects/video_effects_service_impl.h
+++ b/services/video_effects/video_effects_service_impl.h
@@ -24,10 +24,6 @@
 #include "services/viz/public/mojom/gpu.mojom-forward.h"
 #include "third_party/dawn/include/dawn/webgpu_cpp.h"
 
-namespace viz {
-class ContextProviderCommandBuffer;
-}
-
 namespace video_effects {
 
 class VideoEffectsProcessorImpl;
@@ -59,8 +55,7 @@
  private:
   // Creates `webgpu_device_` and initializes it asynchronously.  On completion,
   // invokes `FinishCreatingEffectsProcessors()`.
-  void CreateWebGpuDeviceAndEffectsProcessors(
-      scoped_refptr<viz::ContextProviderCommandBuffer> context_provider);
+  void CreateWebGpuDeviceAndEffectsProcessors();
 
   // Callback functions for WebGpuDevice.
   void OnDeviceCreated(wgpu::Device device);
@@ -75,8 +70,7 @@
   void FinishCreatingEffectsProcessor(
       const std::string& device_id,
       mojo::PendingRemote<media::mojom::VideoEffectsManager> manager_remote,
-      mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor_receiver,
-      std::unique_ptr<GpuChannelHostProvider> gpu_channel_host_provider);
+      mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor_receiver);
 
   // Helper - used to clean up instances of `VideoEffectsProcessor`s that are
   // no longer functional.
@@ -109,12 +103,14 @@
 
     mojo::PendingRemote<media::mojom::VideoEffectsManager> manager_remote;
     mojo::PendingReceiver<mojom::VideoEffectsProcessor> processor_receiver;
-    std::unique_ptr<GpuChannelHostProvider> gpu_channel_host_provider;
   };
 
   // Mapping of device ID to pending requests to create effects processors.
   base::flat_map<std::string, PendingEffectsProcessor> pending_processors_;
 
+  // Provides GPU context objects as needed and monitors context lost events.
+  scoped_refptr<GpuChannelHostProvider> gpu_channel_host_provider_;
+
   SEQUENCE_CHECKER(sequence_checker_);
 
   // Must be last:
diff --git a/services/video_effects/viz_gpu_channel_host_provider.cc b/services/video_effects/viz_gpu_channel_host_provider.cc
index 0fc3632..3abc99e 100644
--- a/services/video_effects/viz_gpu_channel_host_provider.cc
+++ b/services/video_effects/viz_gpu_channel_host_provider.cc
@@ -78,8 +78,6 @@
   CHECK(viz_gpu_);
 }
 
-VizGpuChannelHostProvider::~VizGpuChannelHostProvider() = default;
-
 scoped_refptr<viz::ContextProviderCommandBuffer>
 VizGpuChannelHostProvider::GetWebGpuContextProvider() {
   if (webgpu_context_provider_) {
@@ -110,6 +108,8 @@
   return shared_image_interface_;
 }
 
+VizGpuChannelHostProvider::~VizGpuChannelHostProvider() = default;
+
 scoped_refptr<gpu::GpuChannelHost>
 VizGpuChannelHostProvider::GetGpuChannelHost() {
   if (!gpu_channel_host_) {
diff --git a/services/video_effects/viz_gpu_channel_host_provider.h b/services/video_effects/viz_gpu_channel_host_provider.h
index efe47aa..bf25bd1 100644
--- a/services/video_effects/viz_gpu_channel_host_provider.h
+++ b/services/video_effects/viz_gpu_channel_host_provider.h
@@ -19,7 +19,6 @@
 class VizGpuChannelHostProvider : public GpuChannelHostProvider {
  public:
   explicit VizGpuChannelHostProvider(std::unique_ptr<viz::Gpu> viz_gpu);
-  ~VizGpuChannelHostProvider() override;
 
   // GpuChannelHostProvider:
   scoped_refptr<viz::ContextProviderCommandBuffer> GetWebGpuContextProvider()
@@ -30,6 +29,7 @@
       override;
 
  protected:
+  ~VizGpuChannelHostProvider() override;
   scoped_refptr<gpu::GpuChannelHost> GetGpuChannelHost() override;
 
  private:
diff --git a/testing/buildbot/filters/android.emulator_11.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_11.chrome_public_test_apk.filter
index d88fc3e6..68db7a1 100644
--- a/testing/buildbot/filters/android.emulator_11.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/android.emulator_11.chrome_public_test_apk.filter
@@ -1,30 +1,9 @@
-# vr tests do not apply to emulator
--org.chromium.chrome.browser.hardware_acceleration.ManifestHWATest.testAccelerationDisabled
-
 # crbug.com/1036459
 -org.chromium.chrome.browser.ntp.NewTabPageTest.testFocusFakebox
 
 # crbug.com/1040088
 -org.chromium.chrome.browser.payments.PaymentRequestRetryTest.testRetryWithShippingAddressErrorsAndPayerErrors
 
-# crbug.com/1061178
--org.chromium.chrome.browser.tasks.tab_management.TabGridDialogTest.testSwipeToDismiss_Dialog
-
-# crbug.com/1195129
--org.chromium.chrome.browser.omnibox.suggestions.SwitchToTabTest.testSwitchToTabInSearchActivity
--org.chromium.chrome.browser.omnibox.suggestions.SwitchToTabTest.testSwitchToTabSuggestionWhenIncognitoTabOnTop
--org.chromium.chrome.browser.omnibox.suggestions.SwitchToTabTest.testSwitchToTabSuggestion
-
-# crbug.com/1225709
--org.chromium.components.browser_ui.share.ShareImageFileUtilsTest.testSaveBitmapAndMediaStore
-
-# crbug.com/1231259
--org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AddressAccessoryIntegrationTest.testFillsSuggestionOnClick
--org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.CreditCardAccessoryIntegrationTest.testFillsSuggestionOnClick
-
-# crbug.com/1231652
--org.chromium.chrome.browser.autofill.settings.AutofillProfilesFragmentTest.testKeyboardShownOnDpadCenter
-
 # crbug.com/1231656
 -org.chromium.chrome.browser.language.settings.LanguageSettingsTest.testToggleOfferToTranslate
 
diff --git a/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter
index 3fdacafa..e69de29 100644
--- a/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/android.emulator_12.chrome_public_test_apk.filter
@@ -1,29 +0,0 @@
-# vr tests do not apply to emulator
--org.chromium.chrome.browser.hardware_acceleration.ManifestHWATest.testAccelerationDisabled
-
-# crbug.com/1061178
--org.chromium.chrome.browser.tasks.tab_management.TabGridDialogTest.testSwipeToDismiss_Dialog
-
-# crbug.com/1225709
--org.chromium.components.browser_ui.share.ShareImageFileUtilsTest.testSaveBitmapAndMediaStore
-
-# crbug.com/1231259
--org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.AddressAccessoryIntegrationTest.testFillsSuggestionOnClick
--org.chromium.chrome.browser.keyboard_accessory.sheet_tabs.CreditCardAccessoryIntegrationTest.testFillsSuggestionOnClick
-
-# crbug.com/1231652
--org.chromium.chrome.browser.autofill.settings.AutofillProfilesFragmentTest.testKeyboardShownOnDpadCenter
-
-# crbug.com/1188920
--org.chromium.chrome.browser.customtabs.CustomTabExternalNavigationTest.testIntentPickerNotShownForNormalUrl
-
-# crbug.com/1297370
--org.chromium.chrome.browser.multiwindow.MultiWindowIntegrationTest.*
--org.chromium.chrome.browser.multiwindow.MultiWindowUtilsTest.*
--org.chromium.chrome.browser.tabmodel.TabModelMergingTest.*
--org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindow
--org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindowFallback
--org.chromium.chrome.browser.tasks.tab_management.TabSwitcherMultiWindowTest.*
-
-# crbug.com/1195129
--org.chromium.chrome.browser.omnibox.suggestions.SwitchToTabTest.testSwitchToTabSuggestion
diff --git a/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter
index 3bc2d18..b5ba22cb 100644
--- a/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/android.emulator_12l.chrome_public_test_apk.filter
@@ -1,16 +1,3 @@
-# crbug.com/1225709
--org.chromium.components.browser_ui.share.ShareImageFileUtilsTest.testSaveBitmapAndMediaStore
-
-# crbug.com/1231652
--org.chromium.chrome.browser.autofill.settings.AutofillProfilesFragmentTest.testKeyboardShownOnDpadCenter
-
-# crbug.com/1297370
--org.chromium.chrome.browser.multiwindow.MultiWindowIntegrationTest.*
--org.chromium.chrome.browser.multiwindow.MultiWindowUtilsTest.*
--org.chromium.chrome.browser.tabmodel.TabModelMergingTest.*
--org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindow
--org.chromium.chrome.browser.tabmodel.UndoTabModelTest.testOpenRecentlyClosedTabMultiWindowFallback
-
 # crbug.com/1428416
 -org.chromium.chrome.browser.contextmenu.ContextMenuTest.testContextMenuRetrievesLinkOptions
 -org.chromium.chrome.browser.contextmenu.ContextMenuTest.testContextMenuRetrievesImageLinkOptions
@@ -67,9 +54,6 @@
 -org.chromium.chrome.browser.tasks.tab_management.TabGridDialogTest.testTabGroupNaming_afterMergeWithSelectionEditor
 -org.chromium.chrome.browser.tasks.tab_management.TabGridDialogTest.testTabGroupNaming_KeyboardVisibility
 
-# crbug.com/1195129
--org.chromium.chrome.browser.omnibox.suggestions.SwitchToTabTest.testSwitchToTabSuggestion
-
 # crbug.com/1432785
 -org.chromium.chrome.browser.ContentViewFocusTest.testHideSelectionOnPhoneTabSwiping
 
diff --git a/testing/buildbot/filters/android.emulator_o.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_o.chrome_public_test_apk.filter
index 849afba..9e47a6c4 100644
--- a/testing/buildbot/filters/android.emulator_o.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/android.emulator_o.chrome_public_test_apk.filter
@@ -1,6 +1,3 @@
-# TODO(crbug.com/40232146)
--org.chromium.chrome.browser.tasks.tab_management.TabGridDialogTest.testSwipeToDismiss_Dialog
-
 # TODO(crbug.com/40277597)
 -org.chromium.chrome.browser.browsing_data.ClearBrowsingDataFragmentBasicTest.testRenderSearchHistoryLinkSignedOutKnownNonGoogleDSE
 
diff --git a/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter b/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter
index 04caefd..e5509d42 100644
--- a/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter
+++ b/testing/buildbot/filters/android.emulator_p.chrome_public_test_apk.filter
@@ -1,6 +1,3 @@
-# vr tests do not apply to emulator
--org.chromium.chrome.browser.hardware_acceleration.ManifestHWATest.testAccelerationDisabled
-
 # crbug.com/1032118
 -org.chromium.chrome.browser.notifications.StandardNotificationBuilderTest.testSetAll
 
@@ -19,9 +16,6 @@
 # crbug.com/1041822
 -org.chromium.chrome.browser.offlinepages.OfflinePageAutoFetchTest.testAutoFetchTriggersOnDNSErrorWhenOffline
 
-# crbug.com/1061178
--org.chromium.chrome.browser.tasks.tab_management.TabGridDialogTest.testSwipeToDismiss_Dialog
-
 # crbug.com/1061201
 -org.chromium.chrome.browser.history.HistoryActivityTest.testOpenSelectedItems
 
@@ -56,8 +50,5 @@
 # crbug.com/1067673
 -org.chromium.chrome.browser.ntp.cards.NewTabPageRecyclerViewTest.testDismissArticleWithContextMenu
 
-# crbug.com/1187536
--org.chromium.chrome.browser.customtabs.CustomTabExternalNavigationTest.testIntentPickerNotShownForNormalUrl
-
 # crbug.com/1392774
 -org.chromium.chrome.browser.display_cutout.DisplayCutoutTest.testViewportFitCover*
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 8ca39a8..41ab59e 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -8595,7 +8595,9 @@
                 {
                     "name": "Enabled_WebOptInAndKeyNativePages_131",
                     "params": {
-                        "disable_bottom_controls_stacker_y_offset": "false"
+                        "disable_bottom_controls_stacker_y_offset": "false",
+                        "e2e_field_trial_oem_list": "oppo,xiaomi",
+                        "e2e_field_trial_oem_min_versions": "34,34"
                     },
                     "enable_features": [
                         "BottomBrowserControlsRefactor",
@@ -16530,7 +16532,6 @@
     "PdfOutOfProcessIframe": [
         {
             "platforms": [
-                "chromeos",
                 "linux",
                 "mac",
                 "windows"
@@ -17407,28 +17408,6 @@
             ]
         }
     ],
-    "PriceDropNtpIPH": [
-        {
-            "platforms": [
-                "android"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "params": {
-                        "availability": ">=0",
-                        "event_trigger": "name:price_drop_ntp_iph_triggered;comparator:==0;window:365;storage:365",
-                        "event_used": "name:tab_switcher_button_clicked;comparator:any;window:365;storage:365",
-                        "session_rate": "<1"
-                    },
-                    "enable_features": [
-                        "IPH_PriceDropNTP"
-                    ],
-                    "disable_features": []
-                }
-            ]
-        }
-    ],
     "PriceInsightsAndroid": [
         {
             "platforms": [
@@ -25865,6 +25844,21 @@
             ]
         }
     ],
+    "WinSboxFilterServiceEnvironment": [
+        {
+            "platforms": [
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "WinSboxFilterServiceEnvironment"
+                    ]
+                }
+            ]
+        }
+    ],
     "WinSboxNoFakeGdiInit": [
         {
             "platforms": [
diff --git a/third_party/angle b/third_party/angle
index ae97e569..db8e561 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit ae97e569de2cc1e8cb9414b6900ab1886c273c90
+Subproject commit db8e5617bafaa8374b0cd2465de3fce54622f00e
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
index 653324d..d65e4ce1 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -4612,6 +4612,8 @@
   kAdScriptInStackOnCameraRead = 5226,
   kClipboardCustomFormatRead = 5227,
   kClipboardCustomFormatWrite = 5228,
+  kClipboardSvgRead = 5229,
+  kClipboardSvgWrite = 5230,
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots. Also don't add extra
   // spaces or comments in this file. Comments belong next to the usage of
diff --git a/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom
index eb53369a..1290ba6 100644
--- a/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom
+++ b/third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom
@@ -327,6 +327,7 @@
   kHighlight = 269,
   kDRAFT_ErrorIsError = 270,
   kClipboardCustomFormat = 271,
+  kClipboardSvg = 272,
 
   // Add new features immediately above this line. Don't change assigned
   // numbers of any item, and don't reuse removed slots.
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc
index 9f258bc65..5a4d68c 100644
--- a/third_party/blink/renderer/core/dom/document.cc
+++ b/third_party/blink/renderer/core/dom/document.cc
@@ -8884,8 +8884,10 @@
   CountUse(uma_type);
   if (!RuntimeEnabledFeatures::BlockingFocusWithoutUserActivationEnabled())
     return true;
-  return GetExecutionContext()->IsFeatureEnabled(
-      mojom::blink::PermissionsPolicyFeature::kFocusWithoutUserActivation);
+  return GetFrame()->AllowFocusDuringFocusAdvance() ||
+         GetExecutionContext()->IsFeatureEnabled(
+             mojom::blink::PermissionsPolicyFeature::
+                 kFocusWithoutUserActivation);
 }
 
 LazyLoadImageObserver& Document::EnsureLazyLoadImageObserver() {
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 2e74415..00fb081 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -3226,16 +3226,10 @@
 
   ContainerNode::RemovedFrom(insertion_point);
 
-  if (was_in_document) {
-    if (!RuntimeEnabledFeatures::KeepCSSTargetAfterReattachEnabled() &&
-        this == document.CssTarget()) {
-      document.SetCSSTarget(nullptr);
-    }
-
-    if (GetCustomElementState() == CustomElementState::kCustom &&
-        !GetDocument().StatePreservingAtomicMoveInProgress()) {
-      CustomElement::EnqueueDisconnectedCallback(*this);
-    }
+  if (was_in_document &&
+      GetCustomElementState() == CustomElementState::kCustom &&
+      !GetDocument().StatePreservingAtomicMoveInProgress()) {
+    CustomElement::EnqueueDisconnectedCallback(*this);
   }
 
   RecomputeDirectionFromParent();
diff --git a/third_party/blink/renderer/core/frame/frame.h b/third_party/blink/renderer/core/frame/frame.h
index 982c07f0..d334628 100644
--- a/third_party/blink/renderer/core/frame/frame.h
+++ b/third_party/blink/renderer/core/frame/frame.h
@@ -273,6 +273,14 @@
     return had_sticky_user_activation_before_nav_;
   }
 
+  void SetAllowFocusDuringFocusAdvance(bool value) {
+    allow_focus_during_focus_advance_ = value;
+  }
+
+  bool AllowFocusDuringFocusAdvance() const {
+    return allow_focus_during_focus_advance_;
+  }
+
   bool IsAttached() const {
     return lifecycle_.GetState() == FrameLifecycle::kAttached;
   }
@@ -592,6 +600,10 @@
   // navigation.  This is used in autoplay.
   bool had_sticky_user_activation_before_nav_ = false;
 
+  // This is used in focus delegation scenario when
+  // focus-without-user-activation permission policy is set.
+  bool allow_focus_during_focus_advance_ = false;
+
   // This identifier represents the stable identifier between a
   // LocalFrame  <--> RenderFrameHostImpl or a
   // RemoteFrame <--> RenderFrameProxyHost in the browser process.
diff --git a/third_party/blink/renderer/core/frame/local_frame.cc b/third_party/blink/renderer/core/frame/local_frame.cc
index 30b4225..9dbccdb 100644
--- a/third_party/blink/renderer/core/frame/local_frame.cc
+++ b/third_party/blink/renderer/core/frame/local_frame.cc
@@ -2558,27 +2558,21 @@
   DocumentParser* parser = document->OpenForNavigation(
       kForceSynchronousParsing, mime_type, AtomicString("UTF-8"));
 
-  if (RuntimeEnabledFeatures::DocumentInstallChunkingEnabled()) {
-    // Some code creates a very large number of tiny chunks that show up in
-    // |data|, such as InternalPopupMenu. Calling parser->AppendBytes() with
-    // each tiny piece dramatically slows down document loading. By combining
-    // these chunks in a Vector before passing it to parser->AppendBytes() gets
-    // around this problem.
-    Vector<char> current_chunk;
-    for (const auto& segment : data) {
-      current_chunk.AppendSpan(base::span(segment));
-      if (current_chunk.size() > kMaxDocumentChunkSize) {
-        parser->AppendBytes(base::as_byte_span(current_chunk));
-        current_chunk.clear();
-      }
-    }
-    parser->AppendBytes(base::as_byte_span(current_chunk));
-    current_chunk.clear();
-  } else {
-    for (const auto& segment : data) {
-      parser->AppendBytes(base::as_bytes(segment));
+  // Some code creates a very large number of tiny chunks that show up in
+  // |data|, such as InternalPopupMenu. Calling parser->AppendBytes() with
+  // each tiny piece dramatically slows down document loading. By combining
+  // these chunks in a Vector before passing it to parser->AppendBytes() gets
+  // around this problem.
+  Vector<char> current_chunk;
+  for (const auto& segment : data) {
+    current_chunk.AppendSpan(base::span(segment));
+    if (current_chunk.size() > kMaxDocumentChunkSize) {
+      parser->AppendBytes(base::as_byte_span(current_chunk));
+      current_chunk.clear();
     }
   }
+  parser->AppendBytes(base::as_byte_span(current_chunk));
+  current_chunk.clear();
 
   parser->Finish();
 
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc
index 4ce2775..da5f4c0c 100644
--- a/third_party/blink/renderer/core/html/forms/select_type.cc
+++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -456,11 +456,12 @@
         // TODO(lanwei): Will check if we need to add
         // InputDeviceCapabilities here when select menu list gets
         // focus, see https://crbug.com/476530.
-        if (IsAppearanceBasePicker()) {
-          // Because we're activating the <select> on mousedown, not mouseup
-          // or click, this code will immediately show the popover, and the
-          // following mouseup will activate popover light dismiss, which will
-          // immediately close the popover unless we disable it by doing this.
+        if (IsAppearanceBasePicker() && !mouse_event->FromTouch()) {
+          // If the popover is shown before pointerup, then popover light
+          // dismiss will close the popover when the user releases/lifts the
+          // pointer unless we change the pointerdown target like this.
+          // pointerup is fired before mousedown on touch, so this is only
+          // needed when the event is not from touch.
           select_->GetDocument().SetPopoverPointerdownTarget(popover_);
         }
         ShowPopup(mouse_event->FromTouch() ? PopupMenu::kTouch
@@ -736,12 +737,10 @@
   // wrapping the <option>s.
   // We also need to update style before calling OpenPopupMenu in order to avoid
   // an expensive call to popup_->UpdateFromElement in DidRecalcStyle.
-  if (RuntimeEnabledFeatures::SelectPopupLessUpdatesEnabled()) {
-    SetNativePopupIsVisible(true);
-    if (RuntimeEnabledFeatures::CSSPseudoOpenEnabled()) {
-      select_->GetDocument().UpdateStyleAndLayoutForNode(
-          select_, DocumentUpdateReason::kPagePopup);
-    }
+  SetNativePopupIsVisible(true);
+  if (RuntimeEnabledFeatures::CSSPseudoOpenEnabled()) {
+    select_->GetDocument().UpdateStyleAndLayoutForNode(
+        select_, DocumentUpdateReason::kPagePopup);
   }
 
   if (!popup_) {
@@ -749,20 +748,10 @@
         *document.GetFrame(), *select_);
   }
   if (!popup_) {
-    if (RuntimeEnabledFeatures::SelectPopupLessUpdatesEnabled()) {
-      SetNativePopupIsVisible(false);
-    }
+    SetNativePopupIsVisible(false);
     return;
   }
 
-  if (!RuntimeEnabledFeatures::SelectPopupLessUpdatesEnabled()) {
-    SetNativePopupIsVisible(true);
-    if (RuntimeEnabledFeatures::CSSPseudoOpenEnabled()) {
-      select_->GetDocument().UpdateStyleAndLayoutForNode(
-          select_, DocumentUpdateReason::kPagePopup);
-    }
-  }
-
   ObserveTreeMutation();
 
   popup_->Show(type);
diff --git a/third_party/blink/renderer/core/html/resources/customizable_select.css b/third_party/blink/renderer/core/html/resources/customizable_select.css
index 0142a2d0..7c9727e5 100644
--- a/third_party/blink/renderer/core/html/resources/customizable_select.css
+++ b/third_party/blink/renderer/core/html/resources/customizable_select.css
@@ -11,7 +11,7 @@
 select:not(:-internal-list-box) {
   font: -internal-appearance-auto-base-select(-webkit-small-control, inherit);
   color: -internal-appearance-auto-base-select(FieldText, inherit);
-  background-color: -internal-appearance-auto-base-select(Field, color-mix(in lab, currentColor 10%, transparent));
+  background-color: -internal-appearance-auto-base-select(Field, transparent);
   border: 1px solid -internal-appearance-auto-base-select(light-dark(#767676, #858585), currentColor);
   padding-block: -internal-appearance-auto-base-select(0, 0.25em);
   padding-inline: -internal-appearance-auto-base-select(0, 0.5em);
@@ -29,7 +29,7 @@
 
   display: -internal-appearance-auto-base-select(inline-block, inline-flex);
   gap: -internal-appearance-auto-base-select(initial, 0.5em);
-  border-radius: -internal-appearance-auto-base-select(0, 0.25em);
+  border-radius: -internal-appearance-auto-base-select(0, 0.5em);
 
   align-items: -internal-appearance-auto-base-select(center, unset);
 }
@@ -40,10 +40,10 @@
 }
 
 select:not(:-internal-list-box):enabled:hover {
-  background-color: -internal-appearance-auto-base-select(Field, color-mix(in lab, currentColor 20%, transparent));
+  background-color: -internal-appearance-auto-base-select(Field, color-mix(in lab, currentColor 10%, transparent));
 }
 select:not(:-internal-list-box):enabled:active {
-  background-color: -internal-appearance-auto-base-select(Field, color-mix(in lab, currentColor 30%, transparent));
+  background-color: -internal-appearance-auto-base-select(Field, color-mix(in lab, currentColor 20%, transparent));
 }
 
 /* Without this rule, we would be changing the styles for disabled
@@ -117,10 +117,10 @@
 }
 
 select:not(:-internal-list-box) option:enabled:hover {
-  background-color: color-mix(in lab, currentColor 20%, transparent);
+  background-color: color-mix(in lab, currentColor 10%, transparent);
 }
 select:not(:-internal-list-box) option:enabled:active {
-  background-color: color-mix(in lab, currentColor 30%, transparent);
+  background-color: color-mix(in lab, currentColor 20%, transparent);
 }
 select:not(:-internal-list-box) option:disabled {
   color: -internal-appearance-auto-base-select(inherit, color-mix(in lab, currentColor 50%, transparent));
diff --git a/third_party/blink/renderer/core/html/resources/customizable_select_linux.css b/third_party/blink/renderer/core/html/resources/customizable_select_linux.css
index 7b3f40b..06b53ed 100644
--- a/third_party/blink/renderer/core/html/resources/customizable_select_linux.css
+++ b/third_party/blink/renderer/core/html/resources/customizable_select_linux.css
@@ -21,11 +21,11 @@
  * another stylesheet. TODO(crbug.com/378869807): Replace this with at-rules to
  * ensure correct specificity. */
 select:not(:-internal-list-box):not(:-internal-list-box) {
-    background-color: -internal-appearance-auto-base-select(ButtonFace, color-mix(in lab, currentColor 10%, transparent));
+    background-color: -internal-appearance-auto-base-select(ButtonFace, transparent);
 }
 select:not(:-internal-list-box):enabled:hover {
-    background-color: -internal-appearance-auto-base-select(ButtonFace, color-mix(in lab, currentColor 20%, transparent));
+    background-color: -internal-appearance-auto-base-select(ButtonFace, color-mix(in lab, currentColor 10%, transparent));
 }
 select:not(:-internal-list-box):enabled:active {
-    background-color: -internal-appearance-auto-base-select(ButtonFace, color-mix(in lab, currentColor 30%, transparent));
+    background-color: -internal-appearance-auto-base-select(ButtonFace, color-mix(in lab, currentColor 20%, transparent));
 }
diff --git a/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.cc b/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.cc
index 8645a2f..477da50 100644
--- a/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.cc
@@ -1450,8 +1450,7 @@
 
   const StyleContentAlignmentData justify_content =
       FlexibleBoxAlgorithm::ResolvedJustifyContent(style);
-  const StyleContentAlignmentData align_content =
-      FlexibleBoxAlgorithm::ResolvedAlignContent(style);
+  const StyleContentAlignmentData align_content = style.AlignContent();
 
   // Determine the cross-axis free-space.
   const wtf_size_t num_lines = flex_lines->size();
@@ -1466,13 +1465,16 @@
   }
   cross_axis_free_space -= (num_lines - 1) * gap_between_lines_;
 
+  const bool is_align_content_stretch =
+      align_content.Distribution() == ContentDistributionType::kStretch ||
+      (align_content.GetPosition() == ContentPosition::kNormal &&
+       align_content.Distribution() == ContentDistributionType::kDefault);
   if (!is_multi_line_) {
     // A single line flexbox will always be the cross-axis content-size.
     flex_lines->back().line_cross_size = cross_axis_content_size;
     cross_axis_free_space = LayoutUnit();
   } else if (cross_axis_free_space >= LayoutUnit() &&
-             align_content.Distribution() ==
-                 ContentDistributionType::kStretch) {
+             is_align_content_stretch) {
     // Stretch lines in a multi-line flexbox to the available free-space.
     const LayoutUnit delta = cross_axis_free_space / num_lines;
     for (FlexLine& line : *flex_lines) {
diff --git a/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.cc b/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.cc
index c695b35..207fde4f 100644
--- a/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.cc
@@ -54,32 +54,9 @@
   }
 }
 
-ContentPosition BoxPackToContentPosition(EBoxPack box_pack) {
-  switch (box_pack) {
-    case EBoxPack::kCenter:
-      return ContentPosition::kCenter;
-    case EBoxPack::kJustify:
-      return ContentPosition::kFlexStart;
-    case EBoxPack::kStart:
-      return ContentPosition::kFlexStart;
-    case EBoxPack::kEnd:
-      return ContentPosition::kFlexEnd;
-  }
-}
-
-ContentDistributionType BoxPackToContentDistribution(EBoxPack box_pack) {
-  return box_pack == EBoxPack::kJustify ? ContentDistributionType::kSpaceBetween
-                                        : ContentDistributionType::kDefault;
-}
-
 }  // namespace
 
 // static
-bool FlexibleBoxAlgorithm::IsColumnFlow(const ComputedStyle& style) {
-  return style.ResolvedIsColumnFlexDirection();
-}
-
-// static
 bool FlexibleBoxAlgorithm::IsHorizontalFlow(const ComputedStyle& style) {
   if (style.IsHorizontalWritingMode())
     return !style.ResolvedIsColumnFlexDirection();
@@ -87,87 +64,62 @@
 }
 
 // static
-const StyleContentAlignmentData&
-FlexibleBoxAlgorithm::ContentAlignmentNormalBehavior() {
-  // The justify-content property applies along the main axis, but since
-  // flexing in the main axis is controlled by flex, stretch behaves as
-  // flex-start (ignoring the specified fallback alignment, if any).
-  // https://drafts.csswg.org/css-align/#distribution-flex
-  static const StyleContentAlignmentData kNormalBehavior = {
-      ContentPosition::kNormal, ContentDistributionType::kStretch};
-  return kNormalBehavior;
-}
-
-// static
 StyleContentAlignmentData FlexibleBoxAlgorithm::ResolvedJustifyContent(
     const ComputedStyle& style) {
-  const bool is_webkit_box = style.IsDeprecatedWebkitBox();
-  ContentPosition position;
-  if (is_webkit_box) {
-    position = BoxPackToContentPosition(style.BoxPack());
-    // As row-reverse does layout in reverse, it effectively swaps end & start.
-    // -webkit-box didn't do this (-webkit-box always did layout starting at 0,
-    // and increasing).
-    if (style.ResolvedIsRowReverseFlexDirection()) {
-      if (position == ContentPosition::kFlexEnd)
-        position = ContentPosition::kFlexStart;
-      else if (position == ContentPosition::kFlexStart)
-        position = ContentPosition::kFlexEnd;
-    }
-  } else {
-    position =
-        style.ResolvedJustifyContentPosition(ContentAlignmentNormalBehavior());
-
-    const auto writing_direction = style.GetWritingDirection();
-    if (position == ContentPosition::kLeft ||
-        position == ContentPosition::kRight) {
-      if (IsColumnFlow(style)) {
-        if (writing_direction.IsHorizontal()) {
-          // The main-axis is in the top-down direction, fallback to start.
-          position = ContentPosition::kStart;
-        } else {
-          LogicalToPhysical physical(
-              writing_direction, ContentPosition::kStart, ContentPosition::kEnd,
-              ContentPosition::kStart, ContentPosition::kEnd);
-          position = position == ContentPosition::kLeft ? physical.Left()
-                                                        : physical.Right();
-        }
-      } else {
-        position =
-            ((position == ContentPosition::kLeft) == writing_direction.IsLtr())
-                ? ContentPosition::kStart
-                : ContentPosition::kEnd;
+  if (style.IsDeprecatedWebkitBox()) {
+    const ContentPosition position = ([&]() {
+      // -webkit-box row-reverse currently flips the start/end (e.g. it always
+      // uses "start" rather than "flex-start"). Firefox doesn't have this
+      // quirk, we should attempt to remove it.
+      const bool is_row_reverse = style.ResolvedIsRowReverseFlexDirection();
+      switch (style.BoxPack()) {
+        case EBoxPack::kCenter:
+          return ContentPosition::kCenter;
+        case EBoxPack::kJustify:
+        case EBoxPack::kStart:
+          return is_row_reverse ? ContentPosition::kFlexEnd
+                                : ContentPosition::kFlexStart;
+        case EBoxPack::kEnd:
+          return is_row_reverse ? ContentPosition::kFlexStart
+                                : ContentPosition::kFlexEnd;
       }
+    })();
+    const ContentDistributionType distribution =
+        style.BoxPack() == EBoxPack::kJustify
+            ? ContentDistributionType::kSpaceBetween
+            : ContentDistributionType::kDefault;
+    return StyleContentAlignmentData(position, distribution,
+                                     OverflowAlignment::kSafe);
+  }
+
+  const auto writing_direction = style.GetWritingDirection();
+  const StyleContentAlignmentData& justify_content = style.JustifyContent();
+
+  // Coerce "left"/"right" their logical variants.
+  ContentPosition position = justify_content.GetPosition();
+  if (position == ContentPosition::kLeft ||
+      position == ContentPosition::kRight) {
+    if (style.ResolvedIsColumnFlexDirection()) {
+      if (writing_direction.IsHorizontal()) {
+        // The main-axis is in the top-down direction, fallback to start.
+        position = ContentPosition::kStart;
+      } else {
+        LogicalToPhysical physical(
+            writing_direction, ContentPosition::kStart, ContentPosition::kEnd,
+            ContentPosition::kStart, ContentPosition::kEnd);
+        position = position == ContentPosition::kLeft ? physical.Left()
+                                                      : physical.Right();
+      }
+    } else {
+      position =
+          ((position == ContentPosition::kLeft) == writing_direction.IsLtr())
+              ? ContentPosition::kStart
+              : ContentPosition::kEnd;
     }
   }
-  DCHECK_NE(position, ContentPosition::kLeft);
-  DCHECK_NE(position, ContentPosition::kRight);
 
-  ContentDistributionType distribution =
-      is_webkit_box ? BoxPackToContentDistribution(style.BoxPack())
-                    : style.ResolvedJustifyContentDistribution(
-                          ContentAlignmentNormalBehavior());
-  OverflowAlignment overflow = style.JustifyContent().Overflow();
-  if (is_webkit_box) {
-    overflow = OverflowAlignment::kSafe;
-  } else if (distribution == ContentDistributionType::kStretch) {
-    // For flex, justify-content: stretch behaves as flex-start:
-    // https://drafts.csswg.org/css-align/#distribution-flex
-    position = ContentPosition::kFlexStart;
-    distribution = ContentDistributionType::kDefault;
-  }
-  return StyleContentAlignmentData(position, distribution, overflow);
-}
-
-// static
-StyleContentAlignmentData FlexibleBoxAlgorithm::ResolvedAlignContent(
-    const ComputedStyle& style) {
-  ContentPosition position =
-      style.ResolvedAlignContentPosition(ContentAlignmentNormalBehavior());
-  ContentDistributionType distribution =
-      style.ResolvedAlignContentDistribution(ContentAlignmentNormalBehavior());
-  OverflowAlignment overflow = style.AlignContent().Overflow();
-  return StyleContentAlignmentData(position, distribution, overflow);
+  return StyleContentAlignmentData(position, justify_content.Distribution(),
+                                   justify_content.Overflow());
 }
 
 // static
diff --git a/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.h b/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.h
index d701f245..7618139a 100644
--- a/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.h
+++ b/third_party/blink/renderer/core/layout/flex/flexible_box_algorithm.h
@@ -50,11 +50,8 @@
 
  public:
   static bool IsHorizontalFlow(const ComputedStyle&);
-  static bool IsColumnFlow(const ComputedStyle&);
 
-  static const StyleContentAlignmentData& ContentAlignmentNormalBehavior();
   static StyleContentAlignmentData ResolvedJustifyContent(const ComputedStyle&);
-  static StyleContentAlignmentData ResolvedAlignContent(const ComputedStyle&);
   static ItemPosition AlignmentForChild(const ComputedStyle& flexbox_style,
                                         const ComputedStyle& child_style);
 };
diff --git a/third_party/blink/renderer/core/page/focus_controller.cc b/third_party/blink/renderer/core/page/focus_controller.cc
index 38f4356..9884dd30 100644
--- a/third_party/blink/renderer/core/page/focus_controller.cc
+++ b/third_party/blink/renderer/core/page/focus_controller.cc
@@ -1774,11 +1774,14 @@
     document->SetSequentialFocusNavigationStartingPoint(nullptr);
   }
 
-  SetFocusedFrame(new_document.GetFrame());
+  Frame* new_frame = new_document.GetFrame();
+  new_frame->SetAllowFocusDuringFocusAdvance(true);
+  SetFocusedFrame(new_frame);
 
   element->Focus(FocusParams(SelectionBehaviorOnFocus::kReset, type,
                              source_capabilities, FocusOptions::Create(),
                              FocusTrigger::kUserGesture));
+  new_frame->SetAllowFocusDuringFocusAdvance(false);
   return true;
 }
 
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc
index 840cff6..15f88bb 100644
--- a/third_party/blink/renderer/core/style/computed_style.cc
+++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -525,71 +525,6 @@
                                normal_value_behavior, HasOutOfFlowPosition());
 }
 
-StyleContentAlignmentData ResolvedContentAlignment(
-    const StyleContentAlignmentData& value,
-    const StyleContentAlignmentData& normal_behaviour) {
-  return (value.GetPosition() == ContentPosition::kNormal &&
-          value.Distribution() == ContentDistributionType::kDefault)
-             ? normal_behaviour
-             : value;
-}
-
-StyleContentAlignmentData ComputedStyle::ResolvedAlignContent(
-    const StyleContentAlignmentData& normal_behaviour) const {
-  // We will return the behaviour of 'normal' value if needed, which is specific
-  // of each layout model.
-  return ResolvedContentAlignment(AlignContent(), normal_behaviour);
-}
-
-StyleContentAlignmentData ComputedStyle::ResolvedJustifyContent(
-    const StyleContentAlignmentData& normal_behaviour) const {
-  // We will return the behaviour of 'normal' value if needed, which is specific
-  // of each layout model.
-  return ResolvedContentAlignment(JustifyContent(), normal_behaviour);
-}
-
-static inline ContentPosition ResolvedContentAlignmentPosition(
-    const StyleContentAlignmentData& value,
-    const StyleContentAlignmentData& normal_value_behavior) {
-  return (value.GetPosition() == ContentPosition::kNormal &&
-          value.Distribution() == ContentDistributionType::kDefault)
-             ? normal_value_behavior.GetPosition()
-             : value.GetPosition();
-}
-
-static inline ContentDistributionType ResolvedContentAlignmentDistribution(
-    const StyleContentAlignmentData& value,
-    const StyleContentAlignmentData& normal_value_behavior) {
-  return (value.GetPosition() == ContentPosition::kNormal &&
-          value.Distribution() == ContentDistributionType::kDefault)
-             ? normal_value_behavior.Distribution()
-             : value.Distribution();
-}
-
-ContentPosition ComputedStyle::ResolvedJustifyContentPosition(
-    const StyleContentAlignmentData& normal_value_behavior) const {
-  return ResolvedContentAlignmentPosition(JustifyContent(),
-                                          normal_value_behavior);
-}
-
-ContentDistributionType ComputedStyle::ResolvedJustifyContentDistribution(
-    const StyleContentAlignmentData& normal_value_behavior) const {
-  return ResolvedContentAlignmentDistribution(JustifyContent(),
-                                              normal_value_behavior);
-}
-
-ContentPosition ComputedStyle::ResolvedAlignContentPosition(
-    const StyleContentAlignmentData& normal_value_behavior) const {
-  return ResolvedContentAlignmentPosition(AlignContent(),
-                                          normal_value_behavior);
-}
-
-ContentDistributionType ComputedStyle::ResolvedAlignContentDistribution(
-    const StyleContentAlignmentData& normal_value_behavior) const {
-  return ResolvedContentAlignmentDistribution(AlignContent(),
-                                              normal_value_behavior);
-}
-
 bool ComputedStyle::operator==(const ComputedStyle& o) const {
   return InheritedEqual(o) && NonInheritedEqual(o) &&
          InheritedVariablesEqual(o);
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h
index 493e495..3a35eb4 100644
--- a/third_party/blink/renderer/core/style/computed_style.h
+++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -103,7 +103,6 @@
 class ShadowList;
 class ShapeValue;
 class StyleAdjuster;
-class StyleContentAlignmentData;
 class StyleDifference;
 class StyleImage;
 class StyleInheritedVariables;
@@ -398,24 +397,12 @@
                                       const ComputedStyle* old_style,
                                       const ComputedStyle* new_style);
 
-  ContentPosition ResolvedJustifyContentPosition(
-      const StyleContentAlignmentData& normal_value_behavior) const;
-  ContentDistributionType ResolvedJustifyContentDistribution(
-      const StyleContentAlignmentData& normal_value_behavior) const;
-  ContentPosition ResolvedAlignContentPosition(
-      const StyleContentAlignmentData& normal_value_behavior) const;
-  ContentDistributionType ResolvedAlignContentDistribution(
-      const StyleContentAlignmentData& normal_value_behavior) const;
   StyleSelfAlignmentData ResolvedAlignSelf(
       const StyleSelfAlignmentData& normal_value_behavior,
       const ComputedStyle* parent_style = nullptr) const;
-  StyleContentAlignmentData ResolvedAlignContent(
-      const StyleContentAlignmentData& normal_behaviour) const;
   StyleSelfAlignmentData ResolvedJustifySelf(
       const StyleSelfAlignmentData& normal_value_behavior,
       const ComputedStyle* parent_style = nullptr) const;
-  StyleContentAlignmentData ResolvedJustifyContent(
-      const StyleContentAlignmentData& normal_behaviour) const;
 
   CORE_EXPORT StyleDifference
   VisualInvalidationDiff(const Document&, const ComputedStyle&) const;
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc b/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
index b2e905f1..8b3e972 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_reader.cc
@@ -219,6 +219,8 @@
   // only be used on the main thread.
   void Read() override {
     DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+    promise_->GetExecutionContext()->CountUse(WebFeature::kClipboardSvgRead);
     system_clipboard()->ReadSvg(
         WTF::BindOnce(&ClipboardSvgReader::OnRead, WrapPersistent(this)));
   }
diff --git a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
index 35a53a3..8fec37d 100644
--- a/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
+++ b/third_party/blink/renderer/modules/clipboard/clipboard_writer.cc
@@ -210,6 +210,7 @@
     String svg_string = String::FromUTF8(svg_data->ByteSpan());
     const Document* doc = dom_parser->parseFromString(
         svg_string, V8SupportedType(V8SupportedType::Enum::kImageSvgXml));
+    promise_->GetExecutionContext()->CountUse(WebFeature::kClipboardSvgWrite);
     Write(CreateMarkup(doc, kIncludeNode, kResolveAllURLs));
   }
 
diff --git a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc
index a3f9407..2eb0af5 100644
--- a/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc
+++ b/third_party/blink/renderer/modules/mediarecorder/video_track_recorder_unittest.cc
@@ -584,9 +584,9 @@
     EXPECT_GE(third_frame_encoded_data->side_data()->alpha_data.size(),
               kEncodedSizeThreshold);
   } else {
-    EXPECT_FALSE(first_frame_encoded_data->has_side_data());
-    EXPECT_FALSE(second_frame_encoded_data->has_side_data());
-    EXPECT_FALSE(third_frame_encoded_data->has_side_data());
+    EXPECT_FALSE(first_frame_encoded_data->side_data());
+    EXPECT_FALSE(second_frame_encoded_data->side_data());
+    EXPECT_FALSE(third_frame_encoded_data->side_data());
   }
 
   // The encoder is configured non screen content by default.
@@ -1040,11 +1040,11 @@
   run_loop.Run();
 
   const size_t kEmptySize = 0;
-  EXPECT_FALSE(first_frame_encoded_alpha->has_side_data());
-  EXPECT_TRUE(second_frame_encoded_alpha->has_side_data());
+  EXPECT_FALSE(first_frame_encoded_alpha->side_data());
+  EXPECT_TRUE(second_frame_encoded_alpha->side_data());
   EXPECT_GT(second_frame_encoded_alpha->side_data()->alpha_data.size(),
             kEmptySize);
-  EXPECT_TRUE(third_frame_encoded_alpha->has_side_data());
+  EXPECT_TRUE(third_frame_encoded_alpha->side_data());
   EXPECT_GT(third_frame_encoded_alpha->side_data()->alpha_data.size(),
             kEmptySize);
 
diff --git a/third_party/blink/renderer/modules/mediasource/source_buffer.cc b/third_party/blink/renderer/modules/mediasource/source_buffer.cc
index 223771e..eced32d8 100644
--- a/third_party/blink/renderer/modules/mediasource/source_buffer.cc
+++ b/third_party/blink/renderer/modules/mediasource/source_buffer.cc
@@ -155,7 +155,7 @@
       kWebCodecsAudioTrackId);
 
   // Currently, we do not populate any side_data in these converters.
-  DCHECK(!stream_parser_buffer->has_side_data());
+  DCHECK(!stream_parser_buffer->side_data());
 
   stream_parser_buffer->set_timestamp(audio_chunk.buffer()->timestamp());
   // TODO(crbug.com/1144908): Get EncodedAudioChunk to have an optional duration
@@ -180,7 +180,7 @@
       kWebCodecsVideoTrackId);
 
   // Currently, we do not populate any side_data in these converters.
-  DCHECK(!stream_parser_buffer->has_side_data());
+  DCHECK(!stream_parser_buffer->side_data());
 
   stream_parser_buffer->set_timestamp(video_chunk.buffer()->timestamp());
   // TODO(crbug.com/1144908): Get EncodedVideoChunk to have an optional decode
diff --git a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
index 972990b4..e2fe11c 100644
--- a/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
+++ b/third_party/blink/renderer/modules/webaudio/realtime_audio_destination_handler.cc
@@ -291,23 +291,13 @@
   Context()->OnRenderError();
 }
 
-// A flag for using FakeAudioWorker when an AudioContext with "playback"
-// latency outputs silence.
-BASE_FEATURE(kUseFakeAudioWorkerForPlaybackLatency,
-             "UseFakeAudioWorkerForPlaybackLatency",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 void RealtimeAudioDestinationHandler::SetDetectSilenceIfNecessary(
     bool has_automatic_pull_nodes) {
-  // Use a FakeAudioWorker for a silent AudioContext with playback latency only
-  // when it is allowed by a command line flag.
-  if (base::FeatureList::IsEnabled(kUseFakeAudioWorkerForPlaybackLatency)) {
-    // For playback latency, relax the callback timing restriction so the
-    // SilentSinkSuspender can fall back a FakeAudioWorker if necessary.
-    if (latency_hint_.Category() == WebAudioLatencyHint::kCategoryPlayback) {
-      DCHECK(is_detecting_silence_);
-      return;
-    }
+  // For playback latency, relax the callback timing restriction so the
+  // SilentSinkSuspender can fall back a FakeAudioWorker if necessary.
+  if (latency_hint_.Category() == WebAudioLatencyHint::kCategoryPlayback) {
+    DCHECK(is_detecting_silence_);
+    return;
   }
 
   // For other latency profiles (interactive, balanced, exact), use the
diff --git a/third_party/blink/renderer/platform/peerconnection/resolution_monitor.cc b/third_party/blink/renderer/platform/peerconnection/resolution_monitor.cc
index b471b1e..744b395 100644
--- a/third_party/blink/renderer/platform/peerconnection/resolution_monitor.cc
+++ b/third_party/blink/renderer/platform/peerconnection/resolution_monitor.cc
@@ -68,7 +68,7 @@
   std::optional<gfx::Size> GetResolution(
       const media::DecoderBuffer& buffer) override {
     std::vector<uint32_t> frame_sizes;
-    if (buffer.has_side_data()) {
+    if (buffer.side_data()) {
       frame_sizes = buffer.side_data()->spatial_layers;
     }
     parser_.SetStream(buffer.data(), base::checked_cast<off_t>(buffer.size()),
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
index e9fd47c..701c8da6 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter.cc
@@ -187,7 +187,7 @@
   // Fall back to software decoding if there's no support for VP9 spatial
   // layers. See https://crbug.com/webrtc/9304.
   const bool is_spatial_layer_buffer =
-      buffer.has_side_data() && !buffer.side_data()->spatial_layers.empty();
+      buffer.side_data() && !buffer.side_data()->spatial_layers.empty();
   if (codec == media::VideoCodec::kVP9 && is_spatial_layer_buffer &&
       !media::IsVp9kSVCHWDecodingEnabled()) {
     return RTCVideoDecoderFallbackReason::kSpatialLayers;
diff --git a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
index ceebdf2..067a73e2 100644
--- a/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
+++ b/third_party/blink/renderer/platform/peerconnection/rtc_video_decoder_adapter_test.cc
@@ -793,7 +793,7 @@
 
   // Check the side data was not set as there was only 1 spatial layer.
   ASSERT_TRUE(decoder_buffer);
-  if (decoder_buffer->has_side_data()) {
+  if (decoder_buffer->side_data()) {
     EXPECT_TRUE(decoder_buffer->side_data()->spatial_layers.empty());
   }
 }
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 660b898..46d3de5 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1535,12 +1535,6 @@
       name: "DocumentDomain",
     },
     {
-      // This is a performance fix for <select> popups which was enabled by
-      // default in M128.
-      name: "DocumentInstallChunking",
-      status: "stable",
-    },
-    {
       // Enables DocumentIsolationPolicy.
       // See https://https://github.com/WICG/document-isolation-policy.
       name: "DocumentIsolationPolicy",
@@ -2488,13 +2482,6 @@
       origin_trial_feature_name: "JavaScriptCompileHintsMagic",
     },
     {
-      // Allows :target to match elements even after they are removed and
-      // reattached to the document. Enabled in M128, should be safe to remove
-      // in M133.
-      name: "KeepCSSTargetAfterReattach",
-      status: "stable",
-    },
-    {
       name: "KeyboardAccessibleTooltip",
       status: "experimental",
       base_feature: "none",
@@ -3830,14 +3817,6 @@
       public: true,
     },
     {
-      // This flag is a performance optimization which reorganizes some code
-      // for handling <select>'s popup in order to avoid expensive calls to
-      // InternalPopupMenu::UpdateFromElement. Added in M130, should be safe to
-      // remove in M133.
-      name: "SelectPopupLessUpdates",
-      status: "stable",
-    },
-    {
       name: "SendBeaconThrowForBlobWithNonSimpleType",
       public: true,
       status: "stable",
diff --git a/third_party/blink/renderer/platform/scheduler/BUILD.gn b/third_party/blink/renderer/platform/scheduler/BUILD.gn
index ee842d2..89420ce 100644
--- a/third_party/blink/renderer/platform/scheduler/BUILD.gn
+++ b/third_party/blink/renderer/platform/scheduler/BUILD.gn
@@ -28,8 +28,6 @@
     "common/frame_or_worker_scheduler.cc",
     "common/idle_helper.cc",
     "common/idle_helper.h",
-    "common/metrics_helper.cc",
-    "common/metrics_helper.h",
     "common/pollable_thread_safe_flag.cc",
     "common/pollable_thread_safe_flag.h",
     "common/post_cancellable_task.cc",
@@ -151,8 +149,6 @@
     "public/widget_scheduler.h",
     "public/worker_pool.h",
     "public/worker_scheduler.h",
-    "worker/compositor_metrics_helper.cc",
-    "worker/compositor_metrics_helper.h",
     "worker/compositor_thread.cc",
     "worker/compositor_thread.h",
     "worker/compositor_thread_scheduler_impl.cc",
diff --git a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
deleted file mode 100644
index 46bc65d5..0000000
--- a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/scheduler/common/metrics_helper.h"
-
-#include "third_party/blink/renderer/platform/scheduler/common/process_state.h"
-
-namespace blink {
-namespace scheduler {
-
-namespace {
-
-// Threshold for discarding ultra-long tasks. It is assumed that ultra-long
-// tasks are reporting glitches (e.g. system falling asleep on the middle of the
-// task).
-constexpr base::TimeDelta kLongTaskDiscardingThreshold = base::Seconds(30);
-
-}  // namespace
-
-MetricsHelper::MetricsHelper() = default;
-
-MetricsHelper::~MetricsHelper() = default;
-
-bool MetricsHelper::ShouldDiscardTask(
-    const base::sequence_manager::Task& task,
-    const base::sequence_manager::TaskQueue::TaskTiming& task_timing) {
-  // TODO(altimin): Investigate the relationship between thread time and
-  // wall time for discarded tasks.
-  using State = base::sequence_manager ::TaskQueue::TaskTiming::State;
-  return task_timing.state() == State::Finished &&
-         task_timing.wall_duration() > kLongTaskDiscardingThreshold;
-}
-
-}  // namespace scheduler
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h b/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h
deleted file mode 100644
index a0e7ade..0000000
--- a/third_party/blink/renderer/platform/scheduler/common/metrics_helper.h
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_METRICS_HELPER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_METRICS_HELPER_H_
-
-#include "base/task/sequence_manager/task_queue.h"
-#include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
-#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h"
-
-namespace base {
-namespace sequence_manager {
-class TaskQueue;
-}
-}  // namespace base
-
-namespace blink {
-namespace scheduler {
-
-// Helper class to take care of task metrics shared between main thread
-// and worker threads of the renderer process, including per-thread
-// task metrics.
-//
-// Each thread-specific scheduler should have its own subclass of MetricsHelper
-// (MainThreadMetricsHelper, WorkerMetricsHelper, etc).
-// Note that this is code reuse, not data reuse -- each thread should have its
-// own instantiation of this class.
-class PLATFORM_EXPORT MetricsHelper {
-  DISALLOW_NEW();
-
- public:
-  MetricsHelper();
-  MetricsHelper(const MetricsHelper&) = delete;
-  MetricsHelper& operator=(const MetricsHelper&) = delete;
-  ~MetricsHelper();
-
- protected:
-  bool ShouldDiscardTask(
-      const base::sequence_manager::Task& task,
-      const base::sequence_manager::TaskQueue::TaskTiming& task_timing);
-};
-
-}  // namespace scheduler
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_COMMON_METRICS_HELPER_H_
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
index 9b843ae..bf73be2 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.cc
@@ -12,19 +12,12 @@
 #include "base/functional/bind.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/numerics/safe_conversions.h"
-#include "third_party/blink/public/platform/scheduler/web_renderer_process_type.h"
 #include "third_party/blink/renderer/platform/instrumentation/histogram.h"
 #include "third_party/blink/renderer/platform/instrumentation/resource_coordinator/renderer_resource_coordinator.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/frame_scheduler_impl.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
-#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
+#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
 
-namespace blink {
-namespace scheduler {
-
-#define MAIN_THREAD_LOAD_METRIC_NAME "RendererScheduler.RendererMainThreadLoad5"
-#define EXTENSIONS_MAIN_THREAD_LOAD_METRIC_NAME \
-  MAIN_THREAD_LOAD_METRIC_NAME ".Extension"
+namespace blink::scheduler {
 
 #define QUEUEING_DELAY_HISTOGRAM_INIT(name)                       \
   "RendererScheduler.QueueingDuration." name "Priority",          \
@@ -42,12 +35,25 @@
 // Main thread load percentage that is considered low.
 constexpr int kMainThreadTaskLoadLowPercentage = 25;
 
+// Threshold for discarding ultra-long tasks. It is assumed that ultra-long
+// tasks are reporting glitches (e.g. system falling asleep on the middle of the
+// task).
+constexpr base::TimeDelta kLongTaskDiscardingThreshold = base::Seconds(30);
+
+bool ShouldDiscardTask(
+    const base::sequence_manager::TaskQueue::TaskTiming& task_timing) {
+  // TODO(altimin): Investigate the relationship between thread time and
+  // wall time for discarded tasks.
+  using State = base::sequence_manager::TaskQueue::TaskTiming::State;
+  return task_timing.state() == State::Finished &&
+         task_timing.wall_duration() > kLongTaskDiscardingThreshold;
+}
+
 }  // namespace
 
 MainThreadMetricsHelper::MainThreadMetricsHelper(
     MainThreadSchedulerImpl* main_thread_scheduler,
-    base::TimeTicks now,
-    bool renderer_backgrounded)
+    base::TimeTicks now)
     : main_thread_scheduler_(main_thread_scheduler),
       renderer_shutting_down_(false),
       main_thread_load_tracker_(
@@ -56,18 +62,6 @@
               &MainThreadMetricsHelper::RecordMainThreadTaskLoad,
               base::Unretained(this)),
           kThreadLoadTrackerReportingInterval),
-      background_main_thread_load_tracker_(
-          now,
-          base::BindRepeating(
-              &MainThreadMetricsHelper::RecordBackgroundMainThreadTaskLoad,
-              base::Unretained(this)),
-          kThreadLoadTrackerReportingInterval),
-      foreground_main_thread_load_tracker_(
-          now,
-          base::BindRepeating(
-              &MainThreadMetricsHelper::RecordForegroundMainThreadTaskLoad,
-              base::Unretained(this)),
-          kThreadLoadTrackerReportingInterval),
       // Order here must match TaskPriority (in descending priority order).
       queueing_delay_histograms_{
           {QUEUEING_DELAY_HISTOGRAM_INIT("Control")},
@@ -83,29 +77,12 @@
           {QUEUEING_DELAY_HISTOGRAM_INIT("BestEffort")}},
       main_thread_task_load_state_(MainThreadTaskLoadState::kUnknown) {
   main_thread_load_tracker_.Resume(now);
-  if (renderer_backgrounded) {
-    background_main_thread_load_tracker_.Resume(now);
-  } else {
-    foreground_main_thread_load_tracker_.Resume(now);
-  }
 }
 
 MainThreadMetricsHelper::~MainThreadMetricsHelper() = default;
 
-void MainThreadMetricsHelper::OnRendererForegrounded(base::TimeTicks now) {
-  foreground_main_thread_load_tracker_.Resume(now);
-  background_main_thread_load_tracker_.Pause(now);
-}
-
-void MainThreadMetricsHelper::OnRendererBackgrounded(base::TimeTicks now) {
-  foreground_main_thread_load_tracker_.Pause(now);
-  background_main_thread_load_tracker_.Resume(now);
-}
-
 void MainThreadMetricsHelper::OnRendererShutdown(base::TimeTicks now) {
   renderer_shutting_down_ = true;
-  foreground_main_thread_load_tracker_.RecordIdle(now);
-  background_main_thread_load_tracker_.RecordIdle(now);
   main_thread_load_tracker_.RecordIdle(now);
 }
 
@@ -115,20 +92,6 @@
       base::BindRepeating(&MainThreadMetricsHelper::RecordMainThreadTaskLoad,
                           base::Unretained(this)),
       kThreadLoadTrackerReportingInterval);
-
-  background_main_thread_load_tracker_ = ThreadLoadTracker(
-      now,
-      base::BindRepeating(
-          &MainThreadMetricsHelper::RecordBackgroundMainThreadTaskLoad,
-          base::Unretained(this)),
-      kThreadLoadTrackerReportingInterval);
-
-  foreground_main_thread_load_tracker_ = ThreadLoadTracker(
-      now,
-      base::BindRepeating(
-          &MainThreadMetricsHelper::RecordForegroundMainThreadTaskLoad,
-          base::Unretained(this)),
-      kThreadLoadTrackerReportingInterval);
 }
 
 void MainThreadMetricsHelper::DisableMetricsSubsamplingForTesting() {
@@ -139,16 +102,15 @@
     MainThreadTaskQueue* queue,
     const base::sequence_manager::Task& task,
     const base::sequence_manager::TaskQueue::TaskTiming& task_timing) {
-  if (ShouldDiscardTask(task, task_timing))
+  if (ShouldDiscardTask(task_timing)) {
     return;
+  }
 
   // Discard anomalously long idle periods.
   if (last_reported_task_ &&
       task_timing.start_time() - last_reported_task_.value() >
           kLongIdlePeriodDiscardingThreshold) {
     main_thread_load_tracker_.Reset(task_timing.end_time());
-    foreground_main_thread_load_tracker_.Reset(task_timing.end_time());
-    background_main_thread_load_tracker_.Reset(task_timing.end_time());
     return;
   }
 
@@ -158,10 +120,6 @@
   // we stick with wall time.
   main_thread_load_tracker_.RecordTaskTime(task_timing.start_time(),
                                            task_timing.end_time());
-  foreground_main_thread_load_tracker_.RecordTaskTime(task_timing.start_time(),
-                                                      task_timing.end_time());
-  background_main_thread_load_tracker_.RecordTaskTime(task_timing.start_time(),
-                                                      task_timing.end_time());
 
   if (queue && base::TimeTicks::IsHighResolution() &&
       metrics_subsampler_.ShouldSample(sampling_ratio_)) {
@@ -178,91 +136,6 @@
   DCHECK_LE(load_percentage, 100);
 
   ReportLowThreadLoadForPageAlmostIdleSignal(load_percentage);
-
-  UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME, load_percentage);
-
-  if (main_thread_scheduler_->main_thread_only().process_type ==
-      WebRendererProcessType::kExtensionRenderer) {
-    UMA_HISTOGRAM_PERCENTAGE(EXTENSIONS_MAIN_THREAD_LOAD_METRIC_NAME,
-                             load_percentage);
-  }
-
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
-                 "MainThreadScheduler.RendererMainThreadLoad", load_percentage);
-}
-
-void MainThreadMetricsHelper::RecordForegroundMainThreadTaskLoad(
-    base::TimeTicks time,
-    double load) {
-  int load_percentage = static_cast<int>(load * 100);
-  DCHECK_LE(load_percentage, 100);
-
-  switch (main_thread_scheduler_->main_thread_only().process_type) {
-    case WebRendererProcessType::kExtensionRenderer:
-      UMA_HISTOGRAM_PERCENTAGE(EXTENSIONS_MAIN_THREAD_LOAD_METRIC_NAME
-                               ".Foreground",
-                               load_percentage);
-      break;
-    case WebRendererProcessType::kRenderer:
-      UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME ".Foreground",
-                               load_percentage);
-
-      base::TimeDelta time_since_foregrounded =
-          time - main_thread_scheduler_->main_thread_only()
-                     .background_status_changed_at;
-      if (time_since_foregrounded > base::Minutes(1)) {
-        UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME
-                                 ".Foreground.AfterFirstMinute",
-                                 load_percentage);
-      }
-      break;
-  }
-
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
-                 "MainThreadScheduler.RendererMainThreadLoad.Foreground",
-                 load_percentage);
-}
-
-void MainThreadMetricsHelper::RecordBackgroundMainThreadTaskLoad(
-    base::TimeTicks time,
-    double load) {
-  int load_percentage = static_cast<int>(load * 100);
-  DCHECK_LE(load_percentage, 100);
-
-  switch (main_thread_scheduler_->main_thread_only().process_type) {
-    case WebRendererProcessType::kExtensionRenderer:
-      UMA_HISTOGRAM_PERCENTAGE(EXTENSIONS_MAIN_THREAD_LOAD_METRIC_NAME
-                               ".Background",
-                               load_percentage);
-      break;
-    case WebRendererProcessType::kRenderer:
-      UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME ".Background",
-                               load_percentage);
-
-      base::TimeDelta time_since_backgrounded =
-          time - main_thread_scheduler_->main_thread_only()
-                     .background_status_changed_at;
-      if (time_since_backgrounded > base::Minutes(1)) {
-        UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME
-                                 ".Background.AfterFirstMinute",
-                                 load_percentage);
-      }
-      if (time_since_backgrounded > base::Minutes(5)) {
-        UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME
-                                 ".Background.AfterFifthMinute",
-                                 load_percentage);
-      }
-      if (time_since_backgrounded > base::Minutes(10)) {
-        UMA_HISTOGRAM_PERCENTAGE(MAIN_THREAD_LOAD_METRIC_NAME
-                                 ".Background.AfterTenthMinute",
-                                 load_percentage);
-      }
-      break;
-  }
-
-  TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
-                 "MainThreadScheduler.RendererMainThreadLoad.Background",
-                 load_percentage);
 }
 
 void MainThreadMetricsHelper::ReportLowThreadLoadForPageAlmostIdleSignal(
@@ -271,8 +144,9 @@
   // in test harnesses. These messages aren't needed in production code either
   // as the endpoint receiving them dies shortly after and does nothing with
   // them.
-  if (renderer_shutting_down_)
+  if (renderer_shutting_down_) {
     return;
+  }
 
   if (auto* renderer_resource_coordinator =
           RendererResourceCoordinator::Get()) {
@@ -289,5 +163,4 @@
   }
 }
 
-}  // namespace scheduler
-}  // namespace blink
+}  // namespace blink::scheduler
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
index 65897c2a..bcce3c4 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h
@@ -10,16 +10,10 @@
 #include "base/memory/raw_ptr.h"
 #include "base/rand_util.h"
 #include "base/time/time.h"
-#include "third_party/blink/public/platform/task_type.h"
 #include "third_party/blink/renderer/platform/instrumentation/histogram.h"
 #include "third_party/blink/renderer/platform/platform_export.h"
-#include "third_party/blink/renderer/platform/scheduler/common/metrics_helper.h"
 #include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
 #include "third_party/blink/renderer/platform/scheduler/common/thread_load_tracker.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_task_queue.h"
-#include "third_party/blink/renderer/platform/scheduler/main_thread/use_case.h"
-#include "third_party/blink/renderer/platform/scheduler/public/frame_status.h"
-#include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
 
 namespace blink {
 namespace scheduler {
@@ -30,11 +24,10 @@
 
 // Helper class to take care of metrics on behalf of MainThreadScheduler.
 // This class should be used only on the main thread.
-class PLATFORM_EXPORT MainThreadMetricsHelper : public MetricsHelper {
+class PLATFORM_EXPORT MainThreadMetricsHelper {
  public:
   MainThreadMetricsHelper(MainThreadSchedulerImpl* main_thread_scheduler,
-                          base::TimeTicks now,
-                          bool renderer_backgrounded);
+                          base::TimeTicks now);
   MainThreadMetricsHelper(const MainThreadMetricsHelper&) = delete;
   MainThreadMetricsHelper& operator=(const MainThreadMetricsHelper&) = delete;
   ~MainThreadMetricsHelper();
@@ -44,13 +37,9 @@
       const base::sequence_manager::Task& task,
       const base::sequence_manager::TaskQueue::TaskTiming& task_timing);
 
-  void OnRendererForegrounded(base::TimeTicks now);
-  void OnRendererBackgrounded(base::TimeTicks now);
   void OnRendererShutdown(base::TimeTicks now);
 
   void RecordMainThreadTaskLoad(base::TimeTicks time, double load);
-  void RecordForegroundMainThreadTaskLoad(base::TimeTicks time, double load);
-  void RecordBackgroundMainThreadTaskLoad(base::TimeTicks time, double load);
 
   void ResetForTest(base::TimeTicks now);
   void DisableMetricsSubsamplingForTesting();
@@ -68,8 +57,6 @@
   std::optional<base::TimeTicks> last_reported_task_;
 
   ThreadLoadTracker main_thread_load_tracker_;
-  ThreadLoadTracker background_main_thread_load_tracker_;
-  ThreadLoadTracker foreground_main_thread_load_tracker_;
 
   // When adding a new renderer priority, initialize an entry in the constructor
   // and update histograms.xml.
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc
index ca39c8d4..2879ba7f 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper_unittest.cc
@@ -5,21 +5,16 @@
 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_metrics_helper.h"
 
 #include <memory>
+
 #include "base/memory/raw_ptr.h"
 #include "base/task/sequence_manager/test/fake_task.h"
 #include "base/task/sequence_manager/test/sequence_manager_for_test.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/blink/public/common/features.h"
-#include "third_party/blink/public/common/page/launching_process_state.h"
 #include "third_party/blink/renderer/platform/scheduler/common/task_priority.h"
 #include "third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.h"
-#include "third_party/blink/renderer/platform/scheduler/public/frame_scheduler.h"
-#include "third_party/blink/renderer/platform/scheduler/test/fake_frame_scheduler.h"
-#include "third_party/blink/renderer/platform/scheduler/test/fake_page_scheduler.h"
 
 using base::sequence_manager::TaskQueue;
 using base::sequence_manager::FakeTask;
@@ -91,142 +86,12 @@
                                        FakeTaskTiming(start_time, end_time));
   }
 
-  std::unique_ptr<FakeFrameScheduler> CreateFakeFrameSchedulerWithType(
-      FrameStatus frame_status) {
-    FakeFrameScheduler::Builder builder;
-    switch (frame_status) {
-      case FrameStatus::kNone:
-      case FrameStatus::kDetached:
-        return nullptr;
-      case FrameStatus::kMainFrameVisible:
-        builder.SetFrameType(FrameScheduler::FrameType::kMainFrame)
-            .SetIsPageVisible(true)
-            .SetIsFrameVisible(true);
-        break;
-      case FrameStatus::kMainFrameVisibleService:
-        builder.SetFrameType(FrameScheduler::FrameType::kMainFrame)
-            .SetPageScheduler(playing_view_.get())
-            .SetIsFrameVisible(true);
-        break;
-      case FrameStatus::kMainFrameHidden:
-        builder.SetFrameType(FrameScheduler::FrameType::kMainFrame)
-            .SetIsPageVisible(true);
-        break;
-      case FrameStatus::kMainFrameHiddenService:
-        builder.SetFrameType(FrameScheduler::FrameType::kMainFrame)
-            .SetPageScheduler(playing_view_.get());
-        break;
-      case FrameStatus::kMainFrameBackground:
-        builder.SetFrameType(FrameScheduler::FrameType::kMainFrame);
-        break;
-      case FrameStatus::kMainFrameBackgroundExemptSelf:
-        builder.SetFrameType(FrameScheduler::FrameType::kMainFrame)
-            .SetIsExemptFromThrottling(true);
-        break;
-      case FrameStatus::kMainFrameBackgroundExemptOther:
-        builder.SetFrameType(FrameScheduler::FrameType::kMainFrame)
-            .SetPageScheduler(throtting_exempt_view_.get());
-        break;
-      case FrameStatus::kSameOriginVisible:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsPageVisible(true)
-            .SetIsFrameVisible(true);
-        break;
-      case FrameStatus::kSameOriginVisibleService:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetPageScheduler(playing_view_.get())
-            .SetIsFrameVisible(true);
-        break;
-      case FrameStatus::kSameOriginHidden:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsPageVisible(true);
-        break;
-      case FrameStatus::kSameOriginHiddenService:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetPageScheduler(playing_view_.get());
-        break;
-      case FrameStatus::kSameOriginBackground:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe);
-        break;
-      case FrameStatus::kSameOriginBackgroundExemptSelf:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsExemptFromThrottling(true);
-        break;
-      case FrameStatus::kSameOriginBackgroundExemptOther:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetPageScheduler(throtting_exempt_view_.get());
-        break;
-      case FrameStatus::kCrossOriginVisible:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsCrossOriginToNearestMainFrame(true)
-            .SetIsPageVisible(true)
-            .SetIsFrameVisible(true);
-        break;
-      case FrameStatus::kCrossOriginVisibleService:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsCrossOriginToNearestMainFrame(true)
-            .SetPageScheduler(playing_view_.get())
-            .SetIsFrameVisible(true);
-        break;
-      case FrameStatus::kCrossOriginHidden:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsCrossOriginToNearestMainFrame(true)
-            .SetIsPageVisible(true);
-        break;
-      case FrameStatus::kCrossOriginHiddenService:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsCrossOriginToNearestMainFrame(true)
-            .SetPageScheduler(playing_view_.get());
-        break;
-      case FrameStatus::kCrossOriginBackground:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsCrossOriginToNearestMainFrame(true);
-        break;
-      case FrameStatus::kCrossOriginBackgroundExemptSelf:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsCrossOriginToNearestMainFrame(true)
-            .SetIsExemptFromThrottling(true);
-        break;
-      case FrameStatus::kCrossOriginBackgroundExemptOther:
-        builder.SetFrameType(FrameScheduler::FrameType::kSubframe)
-            .SetIsCrossOriginToNearestMainFrame(true)
-            .SetPageScheduler(throtting_exempt_view_.get());
-        break;
-      case FrameStatus::kCount:
-        NOTREACHED();
-    }
-    return builder.Build();
-  }
-
   base::test::TaskEnvironment task_environment_;
   std::unique_ptr<MainThreadSchedulerImpl> scheduler_;
   raw_ptr<MainThreadMetricsHelper> metrics_helper_;
   std::unique_ptr<base::HistogramTester> histogram_tester_;
-  std::unique_ptr<FakePageScheduler> playing_view_ =
-      FakePageScheduler::Builder().SetIsAudioPlaying(true).Build();
-  std::unique_ptr<FakePageScheduler> throtting_exempt_view_ =
-      FakePageScheduler::Builder().SetIsThrottlingExempt(true).Build();
 };
 
-TEST_F(MainThreadMetricsHelperTest, GetFrameStatusTest) {
-  DCHECK_EQ(GetFrameStatus(nullptr), FrameStatus::kNone);
-
-  FrameStatus frame_statuses_tested[] = {
-      FrameStatus::kMainFrameVisible,
-      FrameStatus::kSameOriginHidden,
-      FrameStatus::kCrossOriginHidden,
-      FrameStatus::kSameOriginBackground,
-      FrameStatus::kMainFrameBackgroundExemptSelf,
-      FrameStatus::kSameOriginVisibleService,
-      FrameStatus::kCrossOriginHiddenService,
-      FrameStatus::kMainFrameBackgroundExemptOther};
-  for (FrameStatus frame_status : frame_statuses_tested) {
-    std::unique_ptr<FakeFrameScheduler> frame =
-        CreateFakeFrameSchedulerWithType(frame_status);
-    EXPECT_EQ(GetFrameStatus(frame.get()), frame_status);
-  }
-}
-
 TEST_F(MainThreadMetricsHelperTest, TaskQueueingDelay) {
   metrics_helper_->DisableMetricsSubsamplingForTesting();
   base::TimeTicks queue_time = Now();
diff --git a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
index ef9cbe70..6b0ee2c 100644
--- a/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/main_thread/main_thread_scheduler_impl.cc
@@ -367,10 +367,7 @@
                                &main_thread_scheduler_impl->tracing_controller_,
                                YesNoStateToString),
       background_status_changed_at(now),
-      metrics_helper(
-          main_thread_scheduler_impl,
-          now,
-          renderer_backgrounded),
+      metrics_helper(main_thread_scheduler_impl, now),
       process_type(WebRendererProcessType::kRenderer,
                    "RendererProcessType",
                    &main_thread_scheduler_impl->tracing_controller_,
@@ -945,13 +942,6 @@
 
   UpdatePolicy();
 
-  base::TimeTicks now = NowTicks();
-  if (backgrounded) {
-    main_thread_only().metrics_helper.OnRendererBackgrounded(now);
-  } else {
-    main_thread_only().metrics_helper.OnRendererForegrounded(now);
-  }
-
   ParkableStringManager::Instance().SetRendererBackgrounded(backgrounded);
   memory_purge_manager_.SetRendererBackgrounded(backgrounded);
 }
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.cc b/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.cc
deleted file mode 100644
index 9717ca11..0000000
--- a/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.h"
-
-namespace blink {
-namespace scheduler {
-
-CompositorMetricsHelper::CompositorMetricsHelper() = default;
-
-CompositorMetricsHelper::~CompositorMetricsHelper() = default;
-
-void CompositorMetricsHelper::RecordTaskMetrics(
-    const base::sequence_manager::Task& task,
-    const base::sequence_manager::TaskQueue::TaskTiming& task_timing) {
-  if (ShouldDiscardTask(task, task_timing))
-    return;
-
-  // Any needed metrics should be recorded here.
-}
-
-}  // namespace scheduler
-}  // namespace blink
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.h b/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.h
deleted file mode 100644
index cbce2e1..0000000
--- a/third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2018 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_COMPOSITOR_METRICS_HELPER_H_
-#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_COMPOSITOR_METRICS_HELPER_H_
-
-#include "third_party/blink/renderer/platform/scheduler/common/metrics_helper.h"
-#include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_task_queue.h"
-
-namespace blink {
-namespace scheduler {
-
-class PLATFORM_EXPORT CompositorMetricsHelper : public MetricsHelper {
- public:
-  CompositorMetricsHelper();
-  CompositorMetricsHelper(const CompositorMetricsHelper&) = delete;
-  CompositorMetricsHelper& operator=(const CompositorMetricsHelper&) = delete;
-  ~CompositorMetricsHelper();
-
-  void RecordTaskMetrics(
-      const base::sequence_manager::Task& task,
-      const base::sequence_manager::TaskQueue::TaskTiming& task_timing);
-};
-
-}  // namespace scheduler
-}  // namespace blink
-
-#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_SCHEDULER_WORKER_COMPOSITOR_METRICS_HELPER_H_
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_impl.cc b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_impl.cc
index d1a965f..0a47aa1 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_impl.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_impl.cc
@@ -56,7 +56,6 @@
     base::LazyNow* lazy_now) {
   task_timing->RecordTaskEnd(lazy_now);
   DispatchOnTaskCompletionCallbacks();
-  compositor_metrics_helper_.RecordTaskMetrics(task, *task_timing);
 }
 
 scoped_refptr<scheduler::SingleThreadIdleTaskRunner>
diff --git a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_impl.h b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_impl.h
index 5074f5a..1346160 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_impl.h
+++ b/third_party/blink/renderer/platform/scheduler/worker/compositor_thread_scheduler_impl.h
@@ -10,7 +10,6 @@
 #include "third_party/blink/renderer/platform/scheduler/common/single_thread_idle_task_runner.h"
 #include "third_party/blink/renderer/platform/scheduler/public/compositor_thread_scheduler.h"
 #include "third_party/blink/renderer/platform/scheduler/public/thread_type.h"
-#include "third_party/blink/renderer/platform/scheduler/worker/compositor_metrics_helper.h"
 #include "third_party/blink/renderer/platform/scheduler/worker/non_main_thread_scheduler_base.h"
 
 namespace base {
@@ -69,9 +68,6 @@
   base::TimeTicks WillProcessIdleTask() override;
   void DidProcessIdleTask() override;
   base::TimeTicks NowTicks() override;
-
- private:
-  CompositorMetricsHelper compositor_metrics_helper_;
 };
 
 }  // namespace scheduler
diff --git a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
index 014fd252..b3fd05e 100644
--- a/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
+++ b/third_party/blink/renderer/platform/scheduler/worker/worker_thread_scheduler.cc
@@ -21,7 +21,6 @@
 #include "third_party/blink/public/platform/platform.h"
 #include "third_party/blink/renderer/platform/scheduler/common/auto_advancing_virtual_time_domain.h"
 #include "third_party/blink/renderer/platform/scheduler/common/features.h"
-#include "third_party/blink/renderer/platform/scheduler/common/metrics_helper.h"
 #include "third_party/blink/renderer/platform/scheduler/common/process_state.h"
 #include "third_party/blink/renderer/platform/scheduler/common/throttling/cpu_time_budget_pool.h"
 #include "third_party/blink/renderer/platform/scheduler/common/throttling/task_queue_throttler.h"
diff --git a/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations.py b/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations.py
index 57fcad9..07e4674 100644
--- a/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations.py
+++ b/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations.py
@@ -33,7 +33,6 @@
 import posixpath
 import re
 import traceback
-import os
 from typing import List, Optional
 
 from blinkpy.common import exit_codes
@@ -62,18 +61,8 @@
                         if not exclude_pattern.fullmatch(message))
 
 
-def lint(host, options):
-    # The checks and list of expectation files are generally not
-    # platform-dependent. Still, we need a port to identify test types and
-    # manipulate virtual test paths.
-    finder = PathFinder(host.filesystem)
-    # Add all extra expectation files to be linted.
-    options.additional_expectations.extend([
-        finder.path_from_web_tests('MobileTestExpectations'),
-        finder.path_from_web_tests('WebGPUExpectations'),
-    ])
-    port = host.port_factory.get(options=options)
-
+def lint(port):
+    host = port.host
     failures = []
     warnings = []
     all_system_specifiers = set()
@@ -98,7 +87,7 @@
                 port, expectations_dict={path: content})
             # Check each expectation for issues
             f, w = _check_expectations(host, port, path, test_expectations,
-                                       options, all_test_expectations)
+                                       all_test_expectations)
             failures += f
             warnings += w
 
@@ -281,7 +270,7 @@
     return failures
 
 
-def _check_expectations(host, port, path, test_expectations, options,
+def _check_expectations(host, port, path, test_expectations,
                         all_test_expectations):
     # Check for original expectation lines (from get_updated_lines) instead of
     # expectations filtered for the current port (test_expectations).
@@ -320,8 +309,8 @@
     return failures
 
 
-def check_virtual_test_suites(host, options):
-    port = host.port_factory.get(options=options)
+def check_virtual_test_suites(port):
+    host = port.host
     fs = host.filesystem
     web_tests_dir = port.web_tests_dir()
     virtual_suites = port.virtual_test_suites()
@@ -415,8 +404,8 @@
     return failures
 
 
-def check_test_lists(host, options):
-    port = host.port_factory.get(options=options)
+def check_test_lists(port):
+    host = port.host
     path = host.filesystem.join(port.web_tests_dir(), 'TestLists')
     test_lists_files = host.filesystem.listdir(path)
     failures = []
@@ -450,16 +439,22 @@
 
 
 def run_checks(host, options):
-    failures = []
-    warnings = []
-    if os.getcwd().startswith('/google/cog/cloud'):
+    if host.filesystem.getcwd().startswith('/google/cog/cloud'):
         _log.info('Skipping run_checks for cog workspace')
         return 0
-    f, w = lint(host, options)
-    failures += f
-    warnings += w
-    failures.extend(check_virtual_test_suites(host, options))
-    failures.extend(check_test_lists(host, options))
+    finder = PathFinder(host.filesystem)
+    # Add all extra expectation files to be linted.
+    options.additional_expectations.extend([
+        finder.path_from_web_tests('MobileTestExpectations'),
+        finder.path_from_web_tests('WebGPUExpectations'),
+    ])
+    # The checks and list of expectation files are generally not
+    # platform-dependent. Still, we need a port to identify test types and
+    # manipulate virtual test paths.
+    port = host.port_factory.get(options=options)
+    failures, warnings = lint(port)
+    failures.extend(check_virtual_test_suites(port))
+    failures.extend(check_test_lists(port))
 
     if options.json:
         with open(options.json, 'w') as f:
diff --git a/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations_unittest.py b/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations_unittest.py
index 5b2d3c65..45654a2 100644
--- a/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations_unittest.py
+++ b/third_party/blink/tools/blinkpy/web_tests/lint_test_expectations_unittest.py
@@ -124,9 +124,8 @@
         host.filesystem.write_text_file(
             path_finder.path_from_web_tests('VirtualTestSuites'), '[]')
 
-        host.port_factory.all_port_names = lambda platform=None: [platform]
-
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(
+            host.port_factory.get(options=options))
         self.assertEqual(failures, [])
         self.assertEqual(warnings, [])
 
@@ -141,10 +140,7 @@
         port = host.port_factory.get(options.platform, options=options)
         port.expectations_dict = lambda: {'foo': '-- syntax error1', 'bar': '-- syntax error2'}
 
-        host.port_factory.get = lambda platform=None, options=None: port
-        host.port_factory.all_port_names = lambda platform=None: [port.name()]
-
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(port)
         self.assertTrue(failures)
         self.assertEqual(warnings, [])
 
@@ -163,13 +159,11 @@
         port = host.port_factory.get(options.platform, options=options)
         port.expectations_dict = lambda: {}
 
-        host.port_factory.get = lambda platform=None, options=None: port
-        host.port_factory.all_port_names = lambda platform=None: [port.name()]
         host.filesystem.write_text_file(
             host.filesystem.join(MOCK_WEB_TESTS, 'LeakExpectations'),
             '-- syntax error')
 
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(port)
         self.assertTrue(failures)
         self.assertEqual(warnings, [])
 
@@ -187,10 +181,7 @@
         port = host.port_factory.get(options.platform, options=options)
         port.expectations_dict = lambda: {'flag-specific': 'does/not/exist', 'noproblem': ''}
 
-        host.port_factory.get = lambda platform=None, options=None: port
-        host.port_factory.all_port_names = lambda platform=None: [port.name()]
-
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(port)
         self.assertTrue(failures)
         self.assertEqual(warnings, [])
 
@@ -216,10 +207,7 @@
         port.expectations_dict = lambda: {
             'testexpectations': test_expectations}
 
-        host.port_factory.get = lambda platform=None, options=None: port
-        host.port_factory.all_port_names = lambda platform=None: [port.name()]
-
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(port)
         self.assertTrue(failures)
         self.assertEqual(warnings, [])
 
@@ -265,10 +253,7 @@
             host.filesystem.join(port.web_tests_dir(), 'virtual', 'foo',
                                  'README.md'), 'foo')
 
-        host.port_factory.get = lambda platform=None, options=None: port
-        host.port_factory.all_port_names = lambda platform=None: [port.name()]
-
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(port)
         self.assertTrue(failures)
         self.assertEqual(warnings, [])
 
@@ -302,10 +287,7 @@
         host.filesystem.maybe_make_directory(
             host.filesystem.join(port.web_tests_dir(), 'test2'))
 
-        host.port_factory.get = lambda platform=None, options=None: port
-        host.port_factory.all_port_names = lambda platform=None: [port.name()]
-
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(port)
         self.assertTrue(failures)
         self.assertEqual(warnings, [])
 
@@ -349,10 +331,8 @@
             'testexpectations': test_expectations
         }
         port.test_exists = lambda test: True
-        host.port_factory.get = lambda platform=None, options=None: port
-        host.port_factory.all_port_names = lambda platform=None: [port.name()]
 
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(port)
         self.assertEqual(failures, [])
 
         self.assertEquals(len(warnings), 1)
@@ -387,10 +367,8 @@
                              'virtual/foo/test1/* [ Pass ]\n')
         port.expectations_dict = lambda: {'NeverFixTests': test_expectations}
         port.test_exists = lambda test: True
-        host.port_factory.get = lambda platform=None, options=None: port
-        host.port_factory.all_port_names = lambda platform=None: [port.name()]
 
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(port)
         self.assertEqual(warnings, [])
 
         self.assertEquals(len(failures), 5)
@@ -433,10 +411,8 @@
             'TestExpectations': test_expectations
         }
         port.test_exists = lambda test: True
-        host.port_factory.get = lambda platform=None, options=None: port
-        host.port_factory.all_port_names = lambda platform=None: [port.name()]
 
-        (fail1, fail2), warnings = lint_test_expectations.lint(host, options)
+        (fail1, fail2), warnings = lint_test_expectations.lint(port)
         self.assertRegexpMatches(fail1, '.*virtual/stable/webexposed/test2/.*')
         self.assertRegexpMatches(fail2,
                                  r'.*virtual/stable/webexposed/api\.html.*')
@@ -456,9 +432,8 @@
             'TestExpectations': test_expectations
         }
         port.test_exists = lambda test: True
-        host.port_factory.get = lambda platform=None, options=None: port
 
-        failures, warnings = lint_test_expectations.lint(host, options)
+        failures, warnings = lint_test_expectations.lint(port)
         self.assertEqual(warnings, [])
         self.assertEquals(len(failures), 1)
         self.assertRegexpMatches(failures[0], ':2 .*Skip')
@@ -486,7 +461,7 @@
         host.filesystem.write_text_file(
             finder.path_from_web_tests('exists', '1.html'), '')
 
-        failures = lint_test_expectations.check_test_lists(host, options)
+        failures = lint_test_expectations.check_test_lists(port)
         self.assertEqual(failures, [
             'tests.filter:3 Test does not exist: does/not/exist/',
             'tests.filter:4 Test does not exist: does/not/exist/1.html',
@@ -503,7 +478,6 @@
             'manifest_update': False,
         })
         self.port = self.host.port_factory.get('test', options=self.options)
-        self.host.port_factory.get = lambda options=None: self.port
 
         fs = self.host.filesystem
         manifest_path = fs.join(self.port.web_tests_dir(), 'external', 'wpt',
@@ -529,8 +503,7 @@
         fs = self.host.filesystem
         fs.maybe_make_directory(fs.join(MOCK_WEB_TESTS, 'test'))
 
-        res = lint_test_expectations.check_virtual_test_suites(
-            self.host, self.options)
+        res = lint_test_expectations.check_virtual_test_suites(self.port)
         self.assertEqual(len(res), 2)
 
         fs.write_text_file(
@@ -538,8 +511,7 @@
         fs.write_text_file(
             fs.join(MOCK_WEB_TESTS, 'virtual', 'bar', 'test', 'README.txt'),
             '')
-        res = lint_test_expectations.check_virtual_test_suites(
-            self.host, self.options)
+        res = lint_test_expectations.check_virtual_test_suites(self.port)
         self.assertFalse(res)
 
     def test_check_virtual_test_suites_generated(self):
@@ -580,8 +552,8 @@
                           'virtual_test_suites',
                           return_value=suites):
             self.assertEqual(
-                lint_test_expectations.check_virtual_test_suites(
-                    self.host, self.options), [])
+                lint_test_expectations.check_virtual_test_suites(self.port),
+                [])
 
     def test_check_virtual_test_suites_redundant(self):
         self.port.virtual_test_suites = lambda: [
@@ -594,8 +566,7 @@
 
         self.host.filesystem.exists = lambda _: True
         self.host.filesystem.isdir = lambda _: True
-        res = lint_test_expectations.check_virtual_test_suites(
-            self.host, self.options)
+        res = lint_test_expectations.check_virtual_test_suites(self.port)
         self.assertEqual(len(res), 1)
 
     def test_check_virtual_test_suites_non_redundant(self):
@@ -609,8 +580,7 @@
 
         self.host.filesystem.exists = lambda _: True
         self.host.filesystem.isdir = lambda _: True
-        res = lint_test_expectations.check_virtual_test_suites(
-            self.host, self.options)
+        res = lint_test_expectations.check_virtual_test_suites(self.port)
         self.assertEqual(len(res), 0)
 
     def test_check_virtual_test_suites_bases_and_exclusive_tests(self):
@@ -632,8 +602,7 @@
         fs.write_text_file(
             fs.join(MOCK_WEB_TESTS, 'virtual', 'foo', 'README.md'), '')
         fs.maybe_make_directory(fs.join(MOCK_WEB_TESTS, 'base4'))
-        res = lint_test_expectations.check_virtual_test_suites(
-            self.host, self.options)
+        res = lint_test_expectations.check_virtual_test_suites(self.port)
         self.assertEqual(len(res), 3)
         self.assertRegexpMatches(res[0], 'base2.* or directory')
         self.assertRegexpMatches(res[1], 'base1/missing.html.* or directory')
@@ -652,8 +621,7 @@
 
         self.host.filesystem.exists = lambda _: True
         self.host.filesystem.isdir = lambda _: True
-        res = lint_test_expectations.check_virtual_test_suites(
-            self.host, self.options)
+        res = lint_test_expectations.check_virtual_test_suites(self.port)
         self.assertRegexpMatches(
             res[0],
             'Virtual suite name "testing_prefix_with_larger_character_count_then_the_allowed_amount_of_48" is over the "48" filename length limit'
@@ -668,8 +636,7 @@
         ]
         self.host.filesystem.exists = lambda _: True
         self.host.filesystem.isdir = lambda _: True
-        res = lint_test_expectations.check_virtual_test_suites(
-            self.host, self.options)
+        res = lint_test_expectations.check_virtual_test_suites(self.port)
         self.assertRegexpMatches(res[0],
                                  'Virtual suite name "test" has no owner.')
         self.assertEqual(len(res), 1)
@@ -680,37 +647,35 @@
                              bases=['test'],
                              args=['--arg']),
         ]
-        res2 = lint_test_expectations.check_virtual_test_suites(
-            self.host, self.options)
+        res2 = lint_test_expectations.check_virtual_test_suites(self.port)
         self.assertRegexpMatches(res2[0],
                                  'Virtual suite name "test" has no owner.')
         self.assertEqual(len(res2), 1)
 
 
+@patch.object(lint_test_expectations, 'check_virtual_test_suites',
+              lambda port: [])
+@patch.object(lint_test_expectations, 'check_test_lists', lambda port: [])
 class MainTest(unittest.TestCase):
+
     def setUp(self):
-        self.orig_lint_fn = lint_test_expectations.lint
-        self.orig_check_fn = lint_test_expectations.check_virtual_test_suites
-        lint_test_expectations.check_virtual_test_suites = lambda host, options: []
-        self.orig_check_test_lists = lint_test_expectations.check_test_lists
-        lint_test_expectations.check_test_lists = lambda host, options: []
         self.stderr = StringIO()
 
-    def tearDown(self):
-        lint_test_expectations.lint = self.orig_lint_fn
-        lint_test_expectations.check_virtual_test_suites = self.orig_check_fn
-        lint_test_expectations.check_test_lists = self.orig_check_test_lists
-
     def test_success(self):
-        lint_test_expectations.lint = lambda host, options: ([], [])
-        res = lint_test_expectations.main(['--platform', 'test'], self.stderr)
+        with patch.object(lint_test_expectations,
+                          'lint',
+                          return_value=([], [])):
+            res = lint_test_expectations.main(['--platform', 'test'],
+                                              self.stderr)
         self.assertEqual('', self.stderr.getvalue().strip())
         self.assertEqual(res, 0)
 
     def test_success_with_warning(self):
-        lint_test_expectations.lint = lambda host, options: ([],
-                                                             ['test warning'])
-        res = lint_test_expectations.main(['--platform', 'test'], self.stderr)
+        with patch.object(lint_test_expectations,
+                          'lint',
+                          return_value=([], ['test warning'])):
+            res = lint_test_expectations.main(['--platform', 'test'],
+                                              self.stderr)
         self.assertEqual(
             textwrap.dedent("""\
                 test warning
@@ -720,9 +685,11 @@
         self.assertEqual(res, 2)
 
     def test_failure(self):
-        lint_test_expectations.lint = lambda host, options: (['test failure'],
-                                                             [])
-        res = lint_test_expectations.main(['--platform', 'test'], self.stderr)
+        with patch.object(lint_test_expectations,
+                          'lint',
+                          return_value=(['test failure'], [])):
+            res = lint_test_expectations.main(['--platform', 'test'],
+                                              self.stderr)
         self.assertEqual(
             textwrap.dedent("""\
                 test failure
@@ -732,9 +699,12 @@
         self.assertEqual(res, 1)
 
     def test_failures_with_warnings(self):
-        lint_test_expectations.lint = lambda host, options: (
-            ['test failure', 'test failure'], ['test warning', 'test warning'])
-        res = lint_test_expectations.main(['--platform', 'test'], self.stderr)
+        with patch.object(lint_test_expectations,
+                          'lint',
+                          return_value=(['test failure', 'test failure'],
+                                        ['test warning', 'test warning'])):
+            res = lint_test_expectations.main(['--platform', 'test'],
+                                              self.stderr)
         self.assertEqual(
             textwrap.dedent("""\
                 test failure
@@ -746,17 +716,15 @@
         self.assertEqual(res, 1)
 
     def test_interrupt(self):
-        def interrupting_lint(host, options):  # pylint: disable=unused-argument
-            raise KeyboardInterrupt
-
-        lint_test_expectations.lint = interrupting_lint
-        res = lint_test_expectations.main([], self.stderr, host=MockHost())
+        with patch.object(lint_test_expectations,
+                          'lint',
+                          side_effect=KeyboardInterrupt):
+            res = lint_test_expectations.main([], self.stderr, host=MockHost())
         self.assertEqual(res, exit_codes.INTERRUPTED_EXIT_STATUS)
 
     def test_exception(self):
-        def exception_raising_lint(host, options):  # pylint: disable=unused-argument
-            assert False
-
-        lint_test_expectations.lint = exception_raising_lint
-        res = lint_test_expectations.main([], self.stderr, host=MockHost())
+        with patch.object(lint_test_expectations,
+                          'lint',
+                          side_effect=AssertionError):
+            res = lint_test_expectations.main([], self.stderr, host=MockHost())
         self.assertEqual(res, exit_codes.EXCEPTIONAL_EXIT_STATUS)
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 3da095d..8116f37d 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2686,6 +2686,8 @@
 crbug.com/343720396 external/wpt/html/cross-origin-opener-policy/iframe-popup-same-origin-allow-popups-to-unsafe-none.https.html?1-2 [ Crash Failure Timeout ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/384773801 [ Mac13 ] external/wpt/webrtc/RTCRtpReceiver-jitterBufferTarget.html [ Timeout ]
+crbug.com/384773801 [ Mac14 ] external/wpt/webrtc/RTCRtpReceiver-jitterBufferTarget.html [ Timeout ]
 crbug.com/384549263 [ Mac15 ] external/wpt/webrtc/RTCPeerConnection-constructor.html [ Timeout ]
 crbug.com/384549263 [ Mac15-arm64 ] external/wpt/webrtc/RTCPeerConnection-remote-track-currentTime.https.html [ Skip Timeout ]
 crbug.com/384549263 [ Mac15 ] external/wpt/webrtc/RTCPeerConnection-remote-track-currentTime.https.html [ Skip Timeout ]
@@ -2720,7 +2722,6 @@
 crbug.com/383825172 [ Mac14 ] external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-font-inheriting.tentative.html [ Failure ]
 crbug.com/383825172 [ Mac15-arm64 ] external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-font-inheriting.tentative.html [ Failure ]
 crbug.com/383814062 [ Mac13 ] virtual/disable-raster-inducing-scroll/external/wpt/acid/acid2/reftest.html [ Failure ]
-crbug.com/383825171 external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.html [ Failure ]
 crbug.com/383999267 [ Mac ] external/wpt/editing/run/forwarddelete-chars-following-collapsible-white-space.html [ Failure ]
 crbug.com/383814059 [ Win11-arm64 ] external/wpt/css/css-paint-api/geometry-background-image-tiled-003.https.html [ Failure ]
 [ Mac13 ] external/wpt/webrtc/protocol/video-codecs.https.html [ Timeout ]
@@ -8223,6 +8224,9 @@
 crbug.com/351117372 external/wpt/css/css-writing-modes/vertical-alignment-slr-029.xht [ Crash Pass Timeout ]
 crbug.com/351117372 external/wpt/css/css-writing-modes/vertical-alignment-slr-035.xht [ Crash Pass Timeout ]
 
+# line-clamp
+crbug.com/40336192 external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.tentative.html [ Failure ]
+crbug.com/40336192 virtual/disable-css-line-clamp/external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.tentative.html [ Pass ]
 # disable-css-line-clamp
 crbug.com/40336192 virtual/disable-css-line-clamp/external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-040.html [ Failure ]
 crbug.com/40336192 virtual/disable-css-line-clamp/external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-047.html [ Failure ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index 1422a44..36dea7a 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -238470,7 +238470,7 @@
       ]
      },
      "compute-kind-widget-no-fallback-props-001.html": [
-      "bda712ec50de76607aac917a661f203434dc3431",
+      "a193bee3d9a774897903d1288aae3b62458eceef",
       [
        null,
        [
@@ -308147,7 +308147,19 @@
      "545f0bec6d9822e7862fc4010fb8d52d3dc4b768",
      []
     ],
-    "idb-binary-key-roundtrip-expected.txt": [
+    "idb-binary-key-roundtrip.any-expected.txt": [
+     "3c11fd4d135b6a5a44a7e3877efcb001ed7b3186",
+     []
+    ],
+    "idb-binary-key-roundtrip.any.serviceworker-expected.txt": [
+     "3c11fd4d135b6a5a44a7e3877efcb001ed7b3186",
+     []
+    ],
+    "idb-binary-key-roundtrip.any.sharedworker-expected.txt": [
+     "3c11fd4d135b6a5a44a7e3877efcb001ed7b3186",
+     []
+    ],
+    "idb-binary-key-roundtrip.any.worker-expected.txt": [
      "3c11fd4d135b6a5a44a7e3877efcb001ed7b3186",
      []
     ],
@@ -308193,7 +308205,7 @@
       []
      ],
      "support-get-all.js": [
-      "9362ec14f0476b0f630e3f131b5b2df1a8635d1c",
+      "7336f7e3c2c5d8fd0b140791131205f4309ba4cc",
       []
      ],
      "support-promises.js": [
@@ -311890,7 +311902,7 @@
        []
       ],
       "frame-ancestors-test.sub.js": [
-       "6e816e89b3837bd620fc359045b7c0bf216616f2",
+       "ffa807b9346789b60f984e923a9481bfaf8a05a3",
        []
       ],
       "frame-ancestors.sub.html": [
@@ -413466,11 +413478,11 @@
     "signatures": {
      "tentative": {
       "helper.js": [
-       "c13c6c4dcf6ec0a217a839874cbcdf31eab00990",
+       "cebfc6c6c650ae82c30426386ce631cc5d1b0989",
        []
       ],
       "resource.py": [
-       "e857de46c0a634916e94fa71f6e1182109cbabcd",
+       "50dc235c00286342473b39e55940c883cbff31b4",
        []
       ]
      }
@@ -428330,11 +428342,101 @@
       {}
      ]
     ],
-    "idb-binary-key-roundtrip.htm": [
-     "d1bf4016f93ec1336b7bde8b9d8e8cbffa833f54",
+    "idb-binary-key-roundtrip.any.js": [
+     "0856a05cb64b6e65a9a61f92db57a4eb5e6a4cf7",
      [
-      null,
+      "IndexedDB/idb-binary-key-roundtrip.any.html",
       {
+       "script_metadata": [
+        [
+         "title",
+         "IndexedDB: Binary keys written to a database and read back"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "timeout",
+         "long"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ],
+       "timeout": "long"
+      }
+     ],
+     [
+      "IndexedDB/idb-binary-key-roundtrip.any.serviceworker.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IndexedDB: Binary keys written to a database and read back"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "timeout",
+         "long"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ],
+       "timeout": "long"
+      }
+     ],
+     [
+      "IndexedDB/idb-binary-key-roundtrip.any.sharedworker.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IndexedDB: Binary keys written to a database and read back"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "timeout",
+         "long"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ],
+       "timeout": "long"
+      }
+     ],
+     [
+      "IndexedDB/idb-binary-key-roundtrip.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IndexedDB: Binary keys written to a database and read back"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "timeout",
+         "long"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ],
        "timeout": "long"
       }
      ]
@@ -428819,11 +428921,83 @@
       }
      ]
     ],
-    "idbcursor_continue_delete_objectstore.htm": [
-     "86b4abf113eea27e62e9bbb60fba23e4efb64da5",
+    "idbcursor_continue_delete_objectstore.any.js": [
+     "7c86fab046d13096456d48ef302de51bbe3910f2",
      [
-      null,
-      {}
+      "IndexedDB/idbcursor_continue_delete_objectstore.any.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IDBObjectStore.delete() and IDBCursor.continue()"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/idbcursor_continue_delete_objectstore.any.serviceworker.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IDBObjectStore.delete() and IDBCursor.continue()"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/idbcursor_continue_delete_objectstore.any.sharedworker.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IDBObjectStore.delete() and IDBCursor.continue()"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/idbcursor_continue_delete_objectstore.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IDBObjectStore.delete() and IDBCursor.continue()"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ]
+      }
      ]
     ],
     "idbcursor_continue_index.any.js": [
@@ -428905,11 +429079,83 @@
       }
      ]
     ],
-    "idbcursor_continue_invalid.htm": [
-     "c177c7f5655a94b7b8923238c4fbd928a398ed02",
+    "idbcursor_continue_invalid.any.js": [
+     "b08f362ab2e63f43b68b4ac69d5869a1d6d6f9f2",
      [
-      null,
-      {}
+      "IndexedDB/idbcursor_continue_invalid.any.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IDBCursor.continue()"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/idbcursor_continue_invalid.any.serviceworker.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IDBCursor.continue()"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/idbcursor_continue_invalid.any.sharedworker.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IDBCursor.continue()"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ]
+      }
+     ],
+     [
+      "IndexedDB/idbcursor_continue_invalid.any.worker.html",
+      {
+       "script_metadata": [
+        [
+         "title",
+         "IDBCursor.continue()"
+        ],
+        [
+         "global",
+         "window,worker"
+        ],
+        [
+         "script",
+         "resources/support.js"
+        ]
+       ]
+      }
      ]
     ],
     "idbcursor_continue_objectstore.any.js": [
@@ -431566,7 +431812,7 @@
      ]
     ],
     "idbobjectstore_getAll.any.js": [
-     "ef5fee5be6a625ed235c16a10c8faab0b11ea9fb",
+     "6082163d3d24100994ce30d22797e72ee63386cf",
      [
       "IndexedDB/idbobjectstore_getAll.any.html",
       {
@@ -431594,8 +431840,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ],
      [
@@ -431625,8 +431876,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ],
      [
@@ -431656,8 +431912,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ],
      [
@@ -431687,13 +431948,18 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ]
     ],
     "idbobjectstore_getAllKeys.any.js": [
-     "d51779163b62bcacc28189167bf0d0738979e6c0",
+     "17244f6e49cad5811e860de12e7a17dd0b7a524a",
      [
       "IndexedDB/idbobjectstore_getAllKeys.any.html",
       {
@@ -431721,8 +431987,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ],
      [
@@ -431752,8 +432023,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ],
      [
@@ -431783,8 +432059,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ],
      [
@@ -431814,13 +432095,18 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ]
     ],
     "idbobjectstore_getAllRecords.tentative.any.js": [
-     "12546bb943a11916d44f08a8a74b674bc0ad3163",
+     "9ab885689423eab90c9b634e433ddfb6b28319c2",
      [
       "IndexedDB/idbobjectstore_getAllRecords.tentative.any.html",
       {
@@ -431848,8 +432134,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ],
      [
@@ -431879,8 +432170,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ],
      [
@@ -431910,8 +432206,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ],
      [
@@ -431941,8 +432242,13 @@
         [
          "script",
          "resources/support-promises.js"
+        ],
+        [
+         "timeout",
+         "long"
         ]
-       ]
+       ],
+       "timeout": "long"
       }
      ]
     ],
@@ -458573,6 +458879,20 @@
        {}
       ]
      ],
+     "frame-ancestors-path-ignored.window.js": [
+      "a7897305ae5b43495704aee2d813adf6a4885bb2",
+      [
+       "content-security-policy/frame-ancestors/frame-ancestors-path-ignored.window.html",
+       {
+        "script_metadata": [
+         [
+          "script",
+          "support/frame-ancestors-test.sub.js"
+         ]
+        ]
+       }
+      ]
+     ],
      "frame-ancestors-sandbox-same-origin-self.html": [
       "825f9a8ae3d740f95fbff14cf6260349b03eb917",
       [
@@ -488717,6 +489037,15 @@
        }
       ]
      ],
+     "input-element-pseudo-open.optional.html": [
+      "815594f07aa1d1ba66fc79a006db0f97a42403a5",
+      [
+       null,
+       {
+        "testdriver": true
+       }
+      ]
+     ],
      "marker-animate.html": [
       "d4cd09ae96ef99518e9734f2def1a482aff49476",
       [
@@ -802921,7 +803250,7 @@
          ]
         ],
         "invalid.py": [
-         "6fef42a48f01522a7cfa26baed85d12cdfb4df65",
+         "2e466c645c3d8a90bf412e6d2f8abca3a2d434cf",
          [
           null,
           {}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.tentative.html
similarity index 84%
rename from third_party/blink/web_tests/external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.html
rename to third_party/blink/web_tests/external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.tentative.html
index be7798c2..fb8e0277 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.tentative.html
@@ -1,11 +1,12 @@
 <!DOCTYPE html>
 <meta charset="utf-8">
-<title>line-clamping shouldn't prevent abspos content from painting</title>
+<title>line-clamping perhaps shouldn't prevent abspos content from painting</title>
 <link rel="author" href="mailto:dholbert@mozilla.com" title="Daniel Holbert">
 <link rel="author" href="https://mozilla.org" title="Mozilla">
 <link rel="match" href="../../reference/ref-filled-green-100px-square-only.html">
 <link rel="help" href="https://drafts.csswg.org/css-overflow-4/#propdef--webkit-line-clamp">
 <link rel="help" href="https://bugzil.la/1934547">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/11379">
 <style>
 .line-clamp {
   display: -webkit-box;
diff --git a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html
index bda712e..a193bee3 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-ui/compute-kind-widget-no-fallback-props-001.html
@@ -68,6 +68,8 @@
   'background-image',
   'background-attachment',
   'background-position',
+  'background-position-x',
+  'background-position-y',
   'background-clip',
   'background-origin',
   'background-size',
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/resources/customizable-select-styles.css b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/resources/customizable-select-styles.css
index 65b3c39..ac6d403 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/resources/customizable-select-styles.css
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/resources/customizable-select-styles.css
@@ -51,12 +51,12 @@
 
 .customizable-select-button {
   color: inherit;
-  background-color: color-mix(in lab, currentColor 10%, transparent);
+  background-color: transparent;
   appearance: none;
   padding-block: 0.25em;
   padding-inline: 0.5em;
   border: 1px solid currentColor;
-  border-radius: 0.25em;
+  border-radius: 0.5em;
   cursor: default;
   text-align: inherit;
   /* TODO(crbug.com/41483940): Make display match the UA stylesheet. */
@@ -71,6 +71,14 @@
   min-block-size: max(24px, 1lh);
 }
 
+.customizable-select-button.hover {
+  background-color: color-mix(in lab, currentColor 10%, transparent);
+}
+
+.customizable-select-button.active {
+  background-color: color-mix(in lab, currentColor 20%, transparent);
+}
+
 .customizable-select-button::after {
   content: counter(fake-counter-name, disclosure-open);
 }
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-active-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-active-ref.html
index 9c62188..879138cf 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-active-ref.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-active-ref.html
@@ -1,19 +1,13 @@
 <!DOCTYPE html>
 <link rel=stylesheet href="resources/customizable-select-styles.css">
 
-<div class=customizable-select-button popovertarget=popover id=button>
+<div class="customizable-select-button active" popovertarget=popover id=button>
   <span class=customizable-select-selectedoption>option</span>
 </div>
 <div id=popover popover=auto anchor=button class=customizable-select-popover>
   <div class="customizable-select-option selected">option</div>
 </div>
 
-<style>
-.customizable-select-button {
-  background-color: color-mix(in lab, currentColor 30%, transparent);
-}
-</style>
-
 <script>
 document.getElementById('popover').showPopover();
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-active.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-active.tentative.html
index 3873969..1efbed1a 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-active.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-active.tentative.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class=reftest-wait>
-<meta name=fuzzy content="maxDifference=0-29;totalPixels=0-1">
+<meta name=fuzzy content="maxDifference=0-33;totalPixels=0-1">
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://github.com/w3c/csswg-drafts/issues/10909">
 <link rel=match href="select-appearance-active-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-dark-mode.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-dark-mode.tentative.html
index d2ea44a..57622ad 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-dark-mode.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-dark-mode.tentative.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class=reftest-wait>
-<meta name=fuzzy content="maxDifference=0-1;totalPixels=0-12">
+<meta name=fuzzy content="maxDifference=0-1;totalPixels=0-15">
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://github.com/whatwg/html/issues/9799">
 <link rel=match href="select-appearance-dark-mode-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-disabled-option.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-disabled-option.tentative.html
index b4cd7ba..cfc87b5 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-disabled-option.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-disabled-option.tentative.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class=reftest-wait>
-<meta name=fuzzy content="maxDifference=0-37;totalPixels=0-1">
+<meta name=fuzzy content="maxDifference=0-41;totalPixels=0-1">
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://github.com/whatwg/html/issues/9799">
 <link rel=match href="select-appearance-disabled-option-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-font-inheriting.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-font-inheriting.tentative.html
index f90e7c88..972b6d5 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-font-inheriting.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-font-inheriting.tentative.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class=reftest-wait>
-<meta name=fuzzy content="maxDifference=0-50;totalPixels=0-8">
+<meta name=fuzzy content="maxDifference=0-55;totalPixels=0-8">
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://github.com/whatwg/html/issues/9799">
 <link rel=match href="select-appearance-font-inheriting-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-hover-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-hover-ref.html
index fc658306..8aef34c 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-hover-ref.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-hover-ref.html
@@ -1,12 +1,6 @@
 <!DOCTYPE html>
 <link rel=stylesheet href="resources/customizable-select-styles.css">
 
-<div class=customizable-select-button popovertarget=popover id=button>
+<div class="customizable-select-button hover" popovertarget=popover id=button>
   <span class=customizable-select-selectedoption>option</span>
 </div>
-
-<style>
-.customizable-select-button {
-  background-color: color-mix(in lab, currentColor 20%, transparent);
-}
-</style>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-hover.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-hover.tentative.html
index b5e24d0..ec1a84d9 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-hover.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-hover.tentative.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class=reftest-wait>
-<meta name=fuzzy content="maxDifference=0-33;totalPixels=0-1">
+<meta name=fuzzy content="maxDifference=0-37;totalPixels=0-1">
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://github.com/w3c/csswg-drafts/issues/10909">
 <link rel=match href="select-appearance-hover-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-switching-invalidation.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-switching-invalidation.tentative.html
index fd67d01..d02c2a5 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-switching-invalidation.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-switching-invalidation.tentative.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class=reftest-wait>
-<meta name=fuzzy content="maxDifference=0-40;totalPixels=0-2">
+<meta name=fuzzy content="maxDifference=0-41;totalPixels=0-2">
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://github.com/whatwg/html/issues/9799">
 <link rel=match href="select-appearance-switching-invalidation-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-mouse-behavior.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-mouse-behavior.tentative.html
index d06330f..f9c873eb 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-mouse-behavior.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-mouse-behavior.tentative.html
@@ -15,6 +15,8 @@
 }
 </style>
 
+<div id=lightdismiss>light dismiss</div>
+
 <label for=custombutton>custom button</label>
 <select id=custombutton>
   <button>button</button>
@@ -29,6 +31,15 @@
 </select>
 
 <script>
+function touch(element) {
+  return (new test_driver.Actions()
+    .addPointer('finger', 'touch')
+    .pointerMove(1, 1, {origin: element})
+    .pointerDown()
+    .pointerUp())
+    .send();
+}
+
 for (const id of ['fallbackbutton', 'custombutton']) {
   const select = document.getElementById(id);
   const optionOne = select.querySelector('option.one');
@@ -79,5 +90,26 @@
     assert_false(select.matches(':open'),
       'select picker should be closed after clicking the label.');
   }, `${id}: Clicking the label should focus the select button without opening the picker.`);
+
+  promise_test(async () => {
+    select.value = 'one';
+    await touch(select);
+    assert_true(select.matches(':open'),
+      'Select should open after touching button.');
+
+    await touch(optionTwo);
+    assert_equals(select.value, 'two',
+      'select.value should be updated after touching another option.');
+    assert_false(select.matches(':open'),
+      'Picker should close after touching an option.');
+
+    await touch(select);
+    assert_true(select.matches(':open'),
+      'Select should re-open after touching button.');
+
+    await touch(document.getElementById('lightdismiss'));
+    assert_false(select.matches(':open'),
+      'Select should close via light dismiss when touching outside the picker.');
+  }, `${id}: Touch input should work the same as mouse input.`);
 }
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-open-invalidation.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-open-invalidation.tentative.html
index 10a4417..9fe59fb1 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-open-invalidation.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-open-invalidation.tentative.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class=reftest-wait>
-<meta name=fuzzy content="maxDifference=0-40;totalPixels=0-2">
+<meta name=fuzzy content="maxDifference=0-41;totalPixels=0-2">
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://github.com/whatwg/html/issues/9799">
 <link rel=match href="select-open-invalidation-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-option-hover-styles.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-option-hover-styles.tentative.html
index 48b1a560..0df62f0 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-option-hover-styles.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-option-hover-styles.tentative.html
@@ -37,7 +37,7 @@
   await new Promise(requestAnimationFrame);
   assert_equals(getComputedStyle(optionOne).color, 'rgb(0, 0, 0)',
     'Option color while hovering.');
-  assert_equals(getComputedStyle(optionOne).backgroundColor, 'lab(0 0 0 / 0.2)',
+  assert_equals(getComputedStyle(optionOne).backgroundColor, 'lab(0 0 0 / 0.1)',
     'Option background-color while hovering.');
 
   await (new test_driver.Actions()
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-option-images.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-option-images.tentative.html
index b0c8f27..34678a0 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-option-images.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-option-images.tentative.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class=reftest-wait>
-<meta name=fuzzy content="maxDifference=0-40;totalPixels=0-2">
+<meta name=fuzzy content="maxDifference=0-41;totalPixels=0-2">
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://github.com/whatwg/html/issues/9799">
 <link rel=match href="select-option-images-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-second-child-button.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-second-child-button.tentative.html
index ae21629..4affdee 100644
--- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-second-child-button.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-second-child-button.tentative.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <html class=reftest-wait>
-<meta name=fuzzy content="maxDifference=0-37;totalPixels=0-1">
+<meta name=fuzzy content="maxDifference=0-41;totalPixels=0-1">
 <link rel=author href="mailto:jarhar@chromium.org">
 <link rel=help href="https://github.com/whatwg/html/pull/10629">
 <link rel=match href="select-second-child-button-ref.html">
diff --git a/third_party/blink/web_tests/external/wpt/permissions-policy/experimental-features/focus-without-user-activation-disabled-by-permissions-policy-cross-origin.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/permissions-policy/experimental-features/focus-without-user-activation-disabled-by-permissions-policy-cross-origin.tentative.https.sub.html
new file mode 100644
index 0000000..a62ca0b
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/permissions-policy/experimental-features/focus-without-user-activation-disabled-by-permissions-policy-cross-origin.tentative.https.sub.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<title>Focus without user activation container policy test</title>
+
+<body>
+  <script src="./resources/common.js"></script>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script src="/resources/testdriver.js"></script>
+  <script src="/resources/testdriver-vendor.js"></script>
+  <script src="/permissions-policy/resources/permissions-policy.js"></script>
+  <div id="log"></div>
+  <input id="before" />
+
+  <script>
+    var same_origin_src = '/permissions-policy/experimental-features/resources/permissions-policy-focus-without-user-activation-tab-focus.html';
+    var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
+      same_origin_src;
+    const header = 'permissions policy "focus-without-user-activation" set to "none"';
+
+    const tab_key = "\uE004";
+    const before = document.getElementById("before");
+
+    function subframe_focused() {
+      return new Promise((resolve, reject) => {
+        function tick() {
+          if (document.getElementById("log").innerHTML === "iframe focused") {
+            resolve();
+          } else {
+            requestAnimationFrame(tick.bind(this));
+          }
+        }
+        tick();
+      });
+    }
+
+    window.onmessage = m => {
+      document.getElementById("log").innerHTML = m.data;
+    };
+
+    promise_test(async function (t) {
+      const iframe = createIframe(document.body, {
+        src: cross_origin_src,
+        allow: "focus-without-user-activation none"
+      });
+      await wait_for_load(iframe);
+
+      before.focus();
+      assert_equals(document.activeElement, before, "#before got outer focus");
+
+      await test_driver.send_keys(document.activeElement, tab_key);
+      await subframe_focused();
+      t.add_cleanup(() => {
+        iframe.remove();
+      });
+    }, 'Tab focus from parent frame into cross-origin iframe is allowed with ' + header);
+  </script>
+</body>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/permissions-policy/experimental-features/focus-without-user-activation-disabled-by-permissions-policy.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/permissions-policy/experimental-features/focus-without-user-activation-disabled-by-permissions-policy.tentative.https.sub.html
new file mode 100644
index 0000000..bd43848e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/permissions-policy/experimental-features/focus-without-user-activation-disabled-by-permissions-policy.tentative.https.sub.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<title>Focus without user activation container policy test</title>
+
+<body>
+  <script src="./resources/common.js"></script>
+  <script src="/resources/testharness.js"></script>
+  <script src="/resources/testharnessreport.js"></script>
+  <script src="/resources/testdriver.js"></script>
+  <script src="/resources/testdriver-vendor.js"></script>
+  <script src="/permissions-policy/resources/permissions-policy.js"></script>
+  <div id="log"></div>
+  <input id="before" />
+
+  <script>
+    var same_origin_src = '/permissions-policy/experimental-features/resources/permissions-policy-focus-without-user-activation-tab-focus.html';
+    var cross_origin_src = 'https://{{domains[www]}}:{{ports[https][0]}}' +
+      same_origin_src;
+    const header = 'permissions policy "focus-without-user-activation" set to "none"';
+
+    const tab_key = "\uE004";
+    const before = document.getElementById("before");
+
+    function subframe_focused() {
+      return new Promise((resolve, reject) => {
+        function tick() {
+          if (document.getElementById("log").innerHTML === "iframe focused") {
+            resolve();
+          } else {
+            requestAnimationFrame(tick.bind(this));
+          }
+        }
+        tick();
+      });
+    }
+
+    window.onmessage = m => {
+      document.getElementById("log").innerHTML = m.data;
+    };
+
+    promise_test(async function (t) {
+      const iframe = createIframe(document.body, {
+        src: same_origin_src,
+        allow: "focus-without-user-activation none"
+      });
+      await wait_for_load(iframe);
+
+      before.focus();
+      assert_equals(document.activeElement, before, "#before got outer focus");
+
+      await test_driver.send_keys(document.activeElement, tab_key);
+      await subframe_focused();
+      t.add_cleanup(() => {
+        iframe.remove();
+      });
+    }, 'Tab focus from parent frame into same-origin iframe is allowed with ' + header);
+  </script>
+</body>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/permissions-policy/experimental-features/resources/permissions-policy-focus-without-user-activation-tab-focus.html b/third_party/blink/web_tests/external/wpt/permissions-policy/experimental-features/resources/permissions-policy-focus-without-user-activation-tab-focus.html
new file mode 100644
index 0000000..f612739d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/permissions-policy/experimental-features/resources/permissions-policy-focus-without-user-activation-tab-focus.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+
+<body>
+  <input id="input" type="text">
+</body>
+<script>
+  window.onfocus = function () {
+    document.getElementById("input").focus();
+    parent.postMessage("iframe focused", "*");
+  }
+</script>
\ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/shared-storage/web-locks-header-batch-update.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/shared-storage/web-locks-header-batch-update.tentative.https.sub.html
new file mode 100644
index 0000000..9c79da3
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/shared-storage/web-locks-header-batch-update.tentative.https.sub.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/shared-storage/resources/util.js"></script>
+<script src="/fenced-frame/resources/utils.js"></script>
+
+<body>
+<script>
+'use strict';
+
+promise_test(async t => {
+  const worklet = await sharedStorage.createWorklet('resources/simple-module.js');
+
+  const ancestor_key = token();
+  const url0 = generateURL("/shared-storage/resources/frame0.html",
+                           [ancestor_key]);
+  const url1 = generateURL("/shared-storage/resources/frame1.html",
+                           [ancestor_key]);
+
+  // Invoke `selectURL()` to perform the following steps:
+  // 1. Acquires the lock.
+  // 2. Reads the current value at the given key.
+  // 3. Waits for 500ms.
+  // 4. Sets the shared storage value to the read value appended with the given letter.
+  // 5. Releases the lock.
+  //
+  // After 100ms, send a fetch() request. The response sends the
+  // `Shared-Storage-Write` header that:
+  // - Acquires the same named lock via the batch `options`
+  // - Executes two `append` methods, each appending the same letter.
+  //
+  // Expected behavior: After both of them finish, the value at the given key
+  // should contain the letter repeated three times.
+  //
+  // This demonstrates that:
+  // 1. The `withLock` option is effective, preventing the header batch update
+  //    interfering with the "get and set" operation. If the lock were not used,
+  //    the final value would likely be a single letter.
+  // 2. The header batch update correctly executes all `append` methods within
+  //    the batch.
+  //
+  // Note: This test remains valid even if the header batch update happens
+  // outside the critical section protected by the lock within the worklet. The
+  // test effectively demonstrates mutual exclusion as long as there's a
+  // reasonable chance for the header batch update to occur while the worklet is
+  // still running.
+  const select_url_result = await worklet.selectURL(
+      "get-wait-set-within-lock",
+      [{url: url0}, {url: url1}],
+      {data: {'key': 'key',
+              'lock_name': 'lock1',
+              'append_letter': 'a'},
+      resolveToConfig: true});
+
+  // Busy wait for 100ms.
+  const startWaitTime = Date.now();
+  while (Date.now() - startWaitTime < 100) {}
+
+  // After 100ms, send a fetch() request. The response sends the
+  // `Shared-Storage-Write` header that:
+  // - Acquires the same named lock via the batch `options`
+  // - Executes two `append` methods, each appending the same letter.
+  const rawUpdatesHeader = 'append;key=key;value=a, append;key=key;value=a, options;with_lock=lock1';
+  const updatesHeader = encodeURIComponent(rawUpdatesHeader);
+  const updatesUrl =
+    `/shared-storage/resources/shared-storage-write.py?write=${updatesHeader}`;
+
+  const response = await fetch(updatesUrl, {sharedStorageWritable: true});
+  const sharedStorageWritableHeader = await response.text();
+  assert_equals(sharedStorageWritableHeader, "?1");
+
+  attachFencedFrame(select_url_result, 'opaque-ads');
+  const result = await nextValueFromServer(ancestor_key);
+  assert_equals(result, "frame1_loaded");
+
+  await verifyKeyValueForOrigin('key', 'aaa', location.origin);
+
+  await deleteKeyForOrigin('key', location.origin);
+}, 'Test for batch withLock option in the Shared-Storage-Write response header');
+
+</script>
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/browsing_context/capture_screenshot/invalid.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/browsing_context/capture_screenshot/invalid.py
index 6fef42a..2e466c6 100644
--- a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/browsing_context/capture_screenshot/invalid.py
+++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/browsing_context/capture_screenshot/invalid.py
@@ -142,8 +142,42 @@
         )
 
 
+@pytest.mark.parametrize("value", [True, 42, "foo", []])
+async def test_params_format_invalid_type(bidi_session, top_context, value):
+    with pytest.raises(error.InvalidArgumentException):
+        await bidi_session.browsing_context.capture_screenshot(
+            context=top_context["context"], format=value
+        )
+
+
 async def test_params_format_invalid_value(bidi_session, top_context):
     with pytest.raises(error.InvalidArgumentException):
         await bidi_session.browsing_context.capture_screenshot(
-            context=top_context["context"], format=FormatOptions(type="image/invalid")
+            context=top_context["context"], format={}
+        )
+
+
+@pytest.mark.parametrize("value", [None, True, 42, [], {}])
+async def test_params_format_type_invalid_type(bidi_session, top_context, value):
+    with pytest.raises(error.InvalidArgumentException):
+        await bidi_session.browsing_context.capture_screenshot(
+            context=top_context["context"], format=FormatOptions(type=value)
+        )
+
+
+@pytest.mark.parametrize("value", [True, "foo", [], {}])
+async def test_params_format_quality_invalid_type(bidi_session, top_context, value):
+    with pytest.raises(error.InvalidArgumentException):
+        await bidi_session.browsing_context.capture_screenshot(
+            context=top_context["context"], format=FormatOptions(
+                type="image/jpeg", quality=value)
+        )
+
+
+@pytest.mark.parametrize("value", [-0.1, 1.1])
+async def test_params_format_quality_invalid_value(bidi_session, top_context, value):
+    with pytest.raises(error.InvalidArgumentException):
+        await bidi_session.browsing_context.capture_screenshot(
+            context=top_context["context"], format=FormatOptions(
+                type="image/jpeg", quality=value)
         )
diff --git a/third_party/catapult b/third_party/catapult
index abd0e1e..6349b2a 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit abd0e1e8ccd7f38681b8c9503bbf4c14220c86f3
+Subproject commit 6349b2a0fe82a0f7b941c066fa4e0de03b5fccfa
diff --git a/third_party/chromium-variations b/third_party/chromium-variations
index 75345f6..5474b28 160000
--- a/third_party/chromium-variations
+++ b/third_party/chromium-variations
@@ -1 +1 @@
-Subproject commit 75345f6fdba14f81b63ccf0530c6fb5adfc9a103
+Subproject commit 5474b284a49865e22821f85678c54f8ed0a20f24
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index de2be85..435b93d 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit de2be85f2be617e9893f0a947b0ccee1ce0b5e84
+Subproject commit 435b93d9d72ecd3e120010bdcb955aab030afb75
diff --git a/third_party/llvm-libc/src b/third_party/llvm-libc/src
index 8345f5d..3605d6c 160000
--- a/third_party/llvm-libc/src
+++ b/third_party/llvm-libc/src
@@ -1 +1 @@
-Subproject commit 8345f5d50fb880cc14f06116b5eda267ec222b83
+Subproject commit 3605d6cf39c46e69796ae71e4555ed997a31ff3f
diff --git a/third_party/perfetto b/third_party/perfetto
index 5bf4e2a..2f24aaf 160000
--- a/third_party/perfetto
+++ b/third_party/perfetto
@@ -1 +1 @@
-Subproject commit 5bf4e2a65d76d5a603ff175222d1513f71d28a0b
+Subproject commit 2f24aafc7f8c3f4ca349224bbadab9f54a3e3559
diff --git a/third_party/rust/chromium_crates_io/Cargo.lock b/third_party/rust/chromium_crates_io/Cargo.lock
index 10f0444..3da178b 100644
--- a/third_party/rust/chromium_crates_io/Cargo.lock
+++ b/third_party/rust/chromium_crates_io/Cargo.lock
@@ -142,7 +142,7 @@
 
 [[package]]
 name = "clap"
-version = "4.5.21"
+version = "4.5.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "clap_builder",
@@ -150,7 +150,7 @@
 
 [[package]]
 name = "clap_builder"
-version = "4.5.21"
+version = "4.5.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "anstyle",
diff --git a/third_party/rust/chromium_crates_io/supply-chain/audits.toml b/third_party/rust/chromium_crates_io/supply-chain/audits.toml
index 939b419..87dcb75d 100644
--- a/third_party/rust/chromium_crates_io/supply-chain/audits.toml
+++ b/third_party/rust/chromium_crates_io/supply-chain/audits.toml
@@ -625,6 +625,11 @@
 criteria = ["safe-to-run", "does-not-implement-crypto"]
 delta = "4.5.20 -> 4.5.21"
 
+[[audits.clap]]
+who = "Lukasz Anforowicz <lukasza@chromium.org>"
+criteria = ["safe-to-run", "does-not-implement-crypto"]
+delta = "4.5.21 -> 4.5.23"
+
 [[audits.clap_builder]]
 who = "danakj@chromium.org"
 criteria = ["safe-to-run", "does-not-implement-crypto"]
@@ -708,6 +713,11 @@
 criteria = ["safe-to-run", "does-not-implement-crypto"]
 delta = "4.5.20 -> 4.5.21"
 
+[[audits.clap_builder]]
+who = "Lukasz Anforowicz <lukasza@chromium.org>"
+criteria = ["safe-to-run", "does-not-implement-crypto"]
+delta = "4.5.21 -> 4.5.23"
+
 [[audits.clap_lex]]
 who = "danakj@chromium.org"
 criteria = ["safe-to-run", "does-not-implement-crypto"]
diff --git a/third_party/rust/chromium_crates_io/supply-chain/config.toml b/third_party/rust/chromium_crates_io/supply-chain/config.toml
index 7c4a6ca..b855014 100644
--- a/third_party/rust/chromium_crates_io/supply-chain/config.toml
+++ b/third_party/rust/chromium_crates_io/supply-chain/config.toml
@@ -83,10 +83,10 @@
 [policy."cfg-if:1.0.0"]
 criteria = ["crypto-safe", "safe-to-deploy", "ub-risk-2"]
 
-[policy."clap:4.5.21"]
+[policy."clap:4.5.23"]
 criteria = ["crypto-safe", "safe-to-run"]
 
-[policy."clap_builder:4.5.21"]
+[policy."clap_builder:4.5.23"]
 criteria = ["crypto-safe", "safe-to-run"]
 
 [policy."clap_lex:0.7.4"]
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/.cargo_vcs_info.json b/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/.cargo_vcs_info.json
deleted file mode 100644
index 6e0e512..0000000
--- a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/.cargo_vcs_info.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "git": {
-    "sha1": "2920fb082c987acb72ed1d1f47991c4d157e380d"
-  },
-  "path_in_vcs": ""
-}
\ No newline at end of file
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/.cargo-checksum.json b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/.cargo-checksum.json
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/.cargo-checksum.json
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/.cargo-checksum.json
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/.cargo_vcs_info.json b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/.cargo_vcs_info.json
new file mode 100644
index 0000000..16a1741
--- /dev/null
+++ b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/.cargo_vcs_info.json
@@ -0,0 +1,6 @@
+{
+  "git": {
+    "sha1": "fde45f9aea766fb8de46e3d46e6575f393c3b6b9"
+  },
+  "path_in_vcs": ""
+}
\ No newline at end of file
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/Cargo.lock b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/Cargo.lock
similarity index 98%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/Cargo.lock
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/Cargo.lock
index 825d72de..1c29046 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/Cargo.lock
+++ b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/Cargo.lock
@@ -112,7 +112,7 @@
 
 [[package]]
 name = "clap"
-version = "4.5.21"
+version = "4.5.23"
 dependencies = [
  "automod",
  "clap-cargo",
@@ -137,9 +137,9 @@
 
 [[package]]
 name = "clap_builder"
-version = "4.5.21"
+version = "4.5.23"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
+checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
 dependencies = [
  "anstream",
  "anstyle",
@@ -165,9 +165,9 @@
 
 [[package]]
 name = "clap_lex"
-version = "0.7.1"
+version = "0.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
+checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
 
 [[package]]
 name = "colorchoice"
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/Cargo.toml b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/Cargo.toml
similarity index 99%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/Cargo.toml
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/Cargo.toml
index 71ef2a00..b2838493 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/Cargo.toml
+++ b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2021"
 rust-version = "1.74"
 name = "clap"
-version = "4.5.21"
+version = "4.5.23"
 build = false
 include = [
     "build.rs",
@@ -24,6 +24,7 @@
     "benches/**/*",
     "examples/**/*",
 ]
+autolib = false
 autobins = false
 autoexamples = false
 autotests = false
@@ -461,7 +462,7 @@
 required-features = ["derive"]
 
 [dependencies.clap_builder]
-version = "=4.5.21"
+version = "=4.5.23"
 default-features = false
 
 [dependencies.clap_derive]
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/Cargo.toml.orig b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/Cargo.toml.orig
similarity index 99%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/Cargo.toml.orig
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/Cargo.toml.orig
index 06e089f8..263e2799 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/Cargo.toml.orig
+++ b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/Cargo.toml.orig
@@ -100,7 +100,7 @@
 
 [package]
 name = "clap"
-version = "4.5.21"
+version = "4.5.23"
 description = "A simple to use, efficient, and full-featured Command Line Argument Parser"
 categories = ["command-line-interface"]
 keywords = [
@@ -176,7 +176,7 @@
 bench = false
 
 [dependencies]
-clap_builder = { path = "./clap_builder", version = "=4.5.21", default-features = false }
+clap_builder = { path = "./clap_builder", version = "=4.5.23", default-features = false }
 clap_derive = { path = "./clap_derive", version = "=4.5.18", optional = true }
 
 [dev-dependencies]
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/LICENSE-APACHE b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/LICENSE-APACHE
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/LICENSE-APACHE
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/LICENSE-APACHE
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/LICENSE-MIT b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/LICENSE-MIT
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/LICENSE-MIT
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/LICENSE-MIT
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/README.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/README.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/README.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/README.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/README.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/README.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/README.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/README.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/cargo-example-derive.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/cargo-example-derive.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/cargo-example-derive.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/cargo-example-derive.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/cargo-example-derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/cargo-example-derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/cargo-example-derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/cargo-example-derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/cargo-example.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/cargo-example.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/cargo-example.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/cargo-example.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/cargo-example.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/cargo-example.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/cargo-example.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/cargo-example.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/demo.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/demo.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/demo.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/demo.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/demo.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/demo.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/demo.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/demo.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/augment_args.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/augment_args.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/augment_args.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/augment_args.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/augment_subcommands.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/augment_subcommands.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/augment_subcommands.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/augment_subcommands.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/flatten_hand_args.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/flatten_hand_args.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/flatten_hand_args.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/flatten_hand_args.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/hand_subcommand.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/hand_subcommand.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/hand_subcommand.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/hand_subcommand.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/interop_tests.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/interop_tests.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/derive_ref/interop_tests.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/derive_ref/interop_tests.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/escaped-positional-derive.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/escaped-positional-derive.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/escaped-positional-derive.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/escaped-positional-derive.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/escaped-positional-derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/escaped-positional-derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/escaped-positional-derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/escaped-positional-derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/escaped-positional.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/escaped-positional.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/escaped-positional.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/escaped-positional.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/escaped-positional.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/escaped-positional.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/escaped-positional.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/escaped-positional.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/find.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/find.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/find.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/find.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/find.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/find.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/find.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/find.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/git-derive.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/git-derive.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/git-derive.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/git-derive.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/git-derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/git-derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/git-derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/git-derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/git.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/git.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/git.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/git.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/git.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/git.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/git.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/git.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/multicall-busybox.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/multicall-busybox.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/multicall-busybox.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/multicall-busybox.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/multicall-busybox.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/multicall-busybox.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/multicall-busybox.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/multicall-busybox.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/multicall-hostname.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/multicall-hostname.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/multicall-hostname.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/multicall-hostname.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/multicall-hostname.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/multicall-hostname.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/multicall-hostname.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/multicall-hostname.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/pacman.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/pacman.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/pacman.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/pacman.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/pacman.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/pacman.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/pacman.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/pacman.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/repl-derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/repl-derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/repl-derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/repl-derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/repl.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/repl.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/repl.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/repl.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/01_quick.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/01_quick.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/01_quick.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/01_quick.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/01_quick.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/01_quick.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/01_quick.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/01_quick.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_app_settings.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_app_settings.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_app_settings.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_app_settings.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_app_settings.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_app_settings.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_app_settings.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_app_settings.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_apps.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_apps.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_apps.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_apps.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_apps.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_apps.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_apps.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_apps.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_crate.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_crate.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_crate.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_crate.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_crate.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_crate.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/02_crate.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/02_crate.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_01_flag_bool.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_01_flag_bool.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_01_flag_bool.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_01_flag_bool.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_01_flag_bool.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_01_flag_bool.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_01_flag_bool.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_01_flag_bool.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_01_flag_count.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_01_flag_count.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_01_flag_count.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_01_flag_count.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_01_flag_count.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_01_flag_count.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_01_flag_count.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_01_flag_count.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_02_option.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_02_option.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_02_option.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_02_option.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_02_option.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_02_option.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_02_option.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_02_option.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_02_option_mult.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_02_option_mult.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_02_option_mult.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_02_option_mult.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_02_option_mult.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_02_option_mult.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_02_option_mult.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_02_option_mult.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_03_positional.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_03_positional.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_03_positional.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_03_positional.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_03_positional.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_03_positional.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_03_positional.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_03_positional.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_03_positional_mult.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_03_positional_mult.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_03_positional_mult.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_03_positional_mult.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_03_positional_mult.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_03_positional_mult.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_03_positional_mult.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_03_positional_mult.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_04_subcommands.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_04_subcommands.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_04_subcommands.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_04_subcommands.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_04_subcommands.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_04_subcommands.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_04_subcommands.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_04_subcommands.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_05_default_values.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_05_default_values.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_05_default_values.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_05_default_values.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_05_default_values.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_05_default_values.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/03_05_default_values.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/03_05_default_values.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_01_enum.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_01_enum.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_01_enum.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_01_enum.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_01_enum.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_01_enum.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_01_enum.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_01_enum.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_01_possible.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_01_possible.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_01_possible.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_01_possible.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_01_possible.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_01_possible.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_01_possible.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_01_possible.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_02_parse.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_02_parse.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_02_parse.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_02_parse.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_02_parse.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_02_parse.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_02_parse.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_02_parse.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_02_validate.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_02_validate.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_02_validate.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_02_validate.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_02_validate.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_02_validate.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_02_validate.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_02_validate.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_03_relations.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_03_relations.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_03_relations.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_03_relations.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_03_relations.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_03_relations.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_03_relations.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_03_relations.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_04_custom.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_04_custom.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_04_custom.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_04_custom.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_04_custom.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_04_custom.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/04_04_custom.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/04_04_custom.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/05_01_assert.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/05_01_assert.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_builder/05_01_assert.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_builder/05_01_assert.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/01_quick.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/01_quick.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/01_quick.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/01_quick.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/01_quick.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/01_quick.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/01_quick.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/01_quick.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_app_settings.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_app_settings.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_app_settings.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_app_settings.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_app_settings.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_app_settings.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_app_settings.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_app_settings.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_apps.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_apps.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_apps.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_apps.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_apps.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_apps.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_apps.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_apps.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_crate.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_crate.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_crate.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_crate.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_crate.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_crate.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/02_crate.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/02_crate.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_01_flag_bool.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_01_flag_bool.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_01_flag_bool.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_01_flag_bool.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_01_flag_bool.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_01_flag_bool.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_01_flag_bool.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_01_flag_bool.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_01_flag_count.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_01_flag_count.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_01_flag_count.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_01_flag_count.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_01_flag_count.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_01_flag_count.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_01_flag_count.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_01_flag_count.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_02_option.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_02_option.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_02_option.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_02_option.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_02_option.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_02_option.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_02_option.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_02_option.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_02_option_mult.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_02_option_mult.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_02_option_mult.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_02_option_mult.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_02_option_mult.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_02_option_mult.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_02_option_mult.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_02_option_mult.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_03_positional.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_03_positional.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_03_positional.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_03_positional.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_03_positional.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_03_positional.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_03_positional.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_03_positional.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_03_positional_mult.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_03_positional_mult.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_03_positional_mult.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_03_positional_mult.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_03_positional_mult.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_03_positional_mult.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_03_positional_mult.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_03_positional_mult.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_04_subcommands.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_04_subcommands.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_04_subcommands.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_04_subcommands.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_04_subcommands.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_04_subcommands.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_04_subcommands.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_04_subcommands.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_04_subcommands_alt.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_04_subcommands_alt.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_04_subcommands_alt.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_04_subcommands_alt.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_05_default_values.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_05_default_values.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_05_default_values.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_05_default_values.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_05_default_values.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_05_default_values.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/03_05_default_values.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/03_05_default_values.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_01_enum.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_01_enum.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_01_enum.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_01_enum.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_01_enum.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_01_enum.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_01_enum.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_01_enum.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_02_parse.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_02_parse.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_02_parse.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_02_parse.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_02_parse.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_02_parse.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_02_parse.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_02_parse.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_02_validate.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_02_validate.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_02_validate.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_02_validate.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_02_validate.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_02_validate.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_02_validate.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_02_validate.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_03_relations.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_03_relations.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_03_relations.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_03_relations.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_03_relations.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_03_relations.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_03_relations.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_03_relations.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_04_custom.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_04_custom.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_04_custom.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_04_custom.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_04_custom.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_04_custom.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/04_04_custom.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/04_04_custom.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/05_01_assert.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/05_01_assert.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/tutorial_derive/05_01_assert.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/tutorial_derive/05_01_assert.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/typed-derive.md b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/typed-derive.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/typed-derive.md
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/typed-derive.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/typed-derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/typed-derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/examples/typed-derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/examples/typed-derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/cargo_example.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/cargo_example.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/cargo_example.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/cargo_example.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/cargo_example_derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/cargo_example_derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/cargo_example_derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/cargo_example_derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/escaped_positional.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/escaped_positional.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/escaped_positional.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/escaped_positional.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/escaped_positional_derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/escaped_positional_derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/escaped_positional_derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/escaped_positional_derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/find.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/find.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/find.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/find.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/git.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/git.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/git.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/git.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/git_derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/git_derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/git_derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/git_derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/multicall_busybox.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/multicall_busybox.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/multicall_busybox.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/multicall_busybox.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/multicall_hostname.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/multicall_hostname.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/multicall_hostname.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/multicall_hostname.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/pacman.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/pacman.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/pacman.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/pacman.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/repl.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/repl.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/repl.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/repl.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/repl_derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/repl_derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/repl_derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/repl_derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/typed_derive.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/typed_derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/typed_derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/typed_derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_0.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_0.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_0.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_0.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_1.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_1.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_1.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_1.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_2.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_2.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_2.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_2.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_3.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_3.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_3.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_3.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_4.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_4.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_4.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_4.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_5.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_5.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_5.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_5.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_faq.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_faq.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_faq.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_faq.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_features.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_features.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_features.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_features.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_0.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_0.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_0.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_0.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_1.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_1.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_1.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_1.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_2.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_2.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_2.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_2.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_3.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_3.rs
similarity index 96%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_3.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_3.rs
index 6dc7db2..ea69bf0a 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_3.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_3.rs
@@ -14,7 +14,7 @@
 //! [`PossibleValuesParser`][crate::builder::PossibleValuesParser] or [`Arg::value_parser(["val1",
 //! ...])`][crate::Arg::value_parser] for short.
 //!
-//! This allows you specify the valid values for that argument. If the user does not use one of
+//! This allows you to specify the valid values for that argument. If the user does not use one of
 //! those specific values, they will receive a graceful exit with error message informing them
 //! of the mistake, and what the possible valid values are
 //!
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_4.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_4.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_4.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_4.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_5.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_5.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_5.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_5.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/bin/stdio-fixture.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/bin/stdio-fixture.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/bin/stdio-fixture.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/bin/stdio-fixture.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/lib.rs b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/lib.rs
similarity index 98%
rename from third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/lib.rs
rename to third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/lib.rs
index 01ca100..d58afb8 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/lib.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/lib.rs
@@ -11,7 +11,7 @@
 //! - [Cookbook][_cookbook]
 //! - [FAQ][_faq]
 //! - [Discussions](https://github.com/clap-rs/clap/discussions)
-//! - [CHANGELOG](https://github.com/clap-rs/clap/blob/v4.5.21/CHANGELOG.md) (includes major version migration
+//! - [CHANGELOG](https://github.com/clap-rs/clap/blob/v4.5.23/CHANGELOG.md) (includes major version migration
 //!   guides)
 //!
 //! ## Aspirations
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/.cargo_vcs_info.json b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/.cargo_vcs_info.json
deleted file mode 100644
index 4887ddd..0000000
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/.cargo_vcs_info.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-  "git": {
-    "sha1": "2920fb082c987acb72ed1d1f47991c4d157e380d"
-  },
-  "path_in_vcs": "clap_builder"
-}
\ No newline at end of file
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/.cargo-checksum.json b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/.cargo-checksum.json
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/.cargo-checksum.json
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/.cargo-checksum.json
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/.cargo_vcs_info.json b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/.cargo_vcs_info.json
new file mode 100644
index 0000000..4fcfc53
--- /dev/null
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/.cargo_vcs_info.json
@@ -0,0 +1,6 @@
+{
+  "git": {
+    "sha1": "fde45f9aea766fb8de46e3d46e6575f393c3b6b9"
+  },
+  "path_in_vcs": "clap_builder"
+}
\ No newline at end of file
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/Cargo.toml b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/Cargo.toml
similarity index 98%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/Cargo.toml
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/Cargo.toml
index 5c08cdc2..100fa53 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/Cargo.toml
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/Cargo.toml
@@ -13,7 +13,7 @@
 edition = "2021"
 rust-version = "1.74"
 name = "clap_builder"
-version = "4.5.21"
+version = "4.5.23"
 build = false
 include = [
     "build.rs",
@@ -24,6 +24,7 @@
     "benches/**/*",
     "examples/**/*",
 ]
+autolib = false
 autobins = false
 autoexamples = false
 autotests = false
@@ -77,7 +78,7 @@
 optional = true
 
 [dependencies.clap_lex]
-version = "0.7.0"
+version = "0.7.4"
 
 [dependencies.strsim]
 version = "0.11.0"
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/Cargo.toml.orig b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/Cargo.toml.orig
similarity index 96%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/Cargo.toml.orig
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/Cargo.toml.orig
index 34b3f21..be41a32 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/Cargo.toml.orig
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/Cargo.toml.orig
@@ -1,6 +1,6 @@
 [package]
 name = "clap_builder"
-version = "4.5.21"
+version = "4.5.23"
 description = "A simple to use, efficient, and full-featured Command Line Argument Parser"
 categories = ["command-line-interface"]
 keywords = [
@@ -59,7 +59,7 @@
 bench = false
 
 [dependencies]
-clap_lex = { path = "../clap_lex", version = "0.7.0" }
+clap_lex = { path = "../clap_lex", version = "0.7.4" }
 unicase = { version = "2.6.0", optional = true }
 strsim = { version = "0.11.0",  optional = true }
 anstream = { version = "0.6.7", optional = true }
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/LICENSE-APACHE b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/LICENSE-APACHE
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/LICENSE-APACHE
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/LICENSE-APACHE
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/LICENSE-MIT b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/LICENSE-MIT
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/LICENSE-MIT
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/LICENSE-MIT
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/README.md b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/README.md
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/README.md
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/README.md
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/action.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/action.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/action.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/action.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/app_settings.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/app_settings.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/app_settings.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/app_settings.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg_group.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg_group.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg_group.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg_group.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg_predicate.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg_predicate.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg_predicate.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg_predicate.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg_settings.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg_settings.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg_settings.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg_settings.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/command.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/command.rs
similarity index 99%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/command.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/command.rs
index 0bdb6a7..b019d008 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/command.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/command.rs
@@ -4848,7 +4848,7 @@
 /// A workaround:
 /// <https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999>
 pub(crate) trait Captures<'a> {}
-impl<'a, T> Captures<'a> for T {}
+impl<T> Captures<'_> for T {}
 
 // Internal Query Methods
 impl Command {
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/debug_asserts.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/debug_asserts.rs
similarity index 98%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/debug_asserts.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/debug_asserts.rs
index 9e6154a..001ef8a 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/debug_asserts.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/debug_asserts.rs
@@ -139,12 +139,18 @@
         }
 
         // requires, r_if, r_unless
-        for req in &arg.requires {
+        for (_predicate, req_id) in &arg.requires {
             assert!(
-                cmd.id_exists(&req.1),
+                &arg.id != req_id,
+                "Argument {} cannot require itself",
+                arg.get_id()
+            );
+
+            assert!(
+                cmd.id_exists(req_id),
                 "Command {}: Argument or group '{}' specified in 'requires*' for '{}' does not exist",
                 cmd.get_name(),
-                req.1,
+                req_id,
                 arg.get_id(),
             );
         }
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/ext.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/ext.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/ext.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/ext.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/os_str.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/os_str.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/os_str.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/os_str.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/possible_value.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/possible_value.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/possible_value.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/possible_value.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/range.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/range.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/range.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/range.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/resettable.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/resettable.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/resettable.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/resettable.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/str.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/str.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/str.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/str.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/styled_str.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/styled_str.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/styled_str.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/styled_str.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/styling.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/styling.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/styling.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/styling.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/tests.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/tests.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/tests.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/tests.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/value_hint.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/value_hint.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/value_hint.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/value_hint.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/value_parser.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/value_parser.rs
similarity index 99%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/value_parser.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/value_parser.rs
index f171db8..87757ed 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/value_parser.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/value_parser.rs
@@ -1828,7 +1828,7 @@
     }
 }
 
-/// Parse bool-like string values, everything else is `true`
+/// Parse bool-like string values
 ///
 /// See also:
 /// - [`ValueParser::bool`] for different human readable bool representations
@@ -1877,7 +1877,7 @@
 pub struct BoolishValueParser {}
 
 impl BoolishValueParser {
-    /// Parse bool-like string values, everything else is an error.
+    /// Parse bool-like string values
     pub fn new() -> Self {
         Self {}
     }
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/derive.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/derive.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/derive.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/derive.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/context.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/context.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/context.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/context.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/format.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/format.rs
similarity index 99%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/format.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/format.rs
index 5126ea5..4c22bc2 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/format.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/format.rs
@@ -494,7 +494,7 @@
 
 struct Escape<'s>(&'s str);
 
-impl<'s> std::fmt::Display for Escape<'s> {
+impl std::fmt::Display for Escape<'_> {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         if self.0.contains(char::is_whitespace) {
             std::fmt::Debug::fmt(self.0, f)
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/kind.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/kind.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/kind.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/kind.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/lib.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/lib.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/lib.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/lib.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/macros.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/macros.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/macros.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/macros.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/mkeymap.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/mkeymap.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/mkeymap.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/mkeymap.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/fmt.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/fmt.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/fmt.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/fmt.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/help.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/help.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/help.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/help.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/help_template.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/help_template.rs
similarity index 99%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/help_template.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/help_template.rs
index da08ccd..3b3fc3d 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/help_template.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/help_template.rs
@@ -250,7 +250,7 @@
 }
 
 /// Basic template methods
-impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
+impl HelpTemplate<'_, '_> {
     /// Writes binary name of a Parser Object to the wrapped stream.
     fn write_display_name(&mut self) {
         debug!("HelpTemplate::write_display_name");
@@ -364,7 +364,7 @@
 }
 
 /// Arg handling
-impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
+impl HelpTemplate<'_, '_> {
     /// Writes help for all arguments (options, flags, args, subcommands)
     /// including titles of a Parser Object to the wrapped stream.
     pub(crate) fn write_all_args(&mut self) {
@@ -847,7 +847,7 @@
 }
 
 /// Subcommand handling
-impl<'cmd, 'writer> HelpTemplate<'cmd, 'writer> {
+impl HelpTemplate<'_, '_> {
     /// Writes help for subcommands of a Parser Object to the wrapped stream.
     fn write_flat_subcommands(&mut self, cmd: &Command, first: &mut bool) {
         debug!(
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/core.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/core.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/core.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/core.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/word_separators.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/word_separators.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/word_separators.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/word_separators.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/wrap_algorithms.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/wrap_algorithms.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/wrap_algorithms.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/wrap_algorithms.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/usage.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/usage.rs
similarity index 99%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/usage.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/usage.rs
index d1b861c6..7c4ddc5f 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/usage.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/usage.rs
@@ -97,7 +97,7 @@
 }
 
 #[cfg(feature = "usage")]
-impl<'cmd> Usage<'cmd> {
+impl Usage<'_> {
     // Creates a usage string for display in help messages (i.e. not for errors)
     fn write_help_usage(&self, styled: &mut StyledStr) {
         debug!("Usage::write_help_usage");
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/arg_matcher.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/arg_matcher.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/arg_matcher.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/arg_matcher.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/error.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/error.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/error.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/error.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/features/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/features/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/features/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/features/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/features/suggestions.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/features/suggestions.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/features/suggestions.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/features/suggestions.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/arg_matches.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/arg_matches.rs
similarity index 98%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/arg_matches.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/arg_matches.rs
index 90fbb59..5e4d9dc 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/arg_matches.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/arg_matches.rs
@@ -1388,7 +1388,7 @@
     }
 }
 
-impl<'a> ExactSizeIterator for IdsRef<'a> {}
+impl ExactSizeIterator for IdsRef<'_> {}
 
 /// Iterate over multiple values for an argument via [`ArgMatches::remove_many`].
 ///
@@ -1585,7 +1585,7 @@
     }
 }
 
-impl<'a> ExactSizeIterator for RawValues<'a> {}
+impl ExactSizeIterator for RawValues<'_> {}
 
 /// Creates an empty iterator.
 impl Default for RawValues<'_> {
@@ -1629,7 +1629,7 @@
 }
 
 #[allow(deprecated)]
-impl<'a> DoubleEndedIterator for GroupedValues<'a> {
+impl DoubleEndedIterator for GroupedValues<'_> {
     fn next_back(&mut self) -> Option<Self::Item> {
         if let Some(next) = self.iter.next_back() {
             self.len -= 1;
@@ -1641,11 +1641,11 @@
 }
 
 #[allow(deprecated)]
-impl<'a> ExactSizeIterator for GroupedValues<'a> {}
+impl ExactSizeIterator for GroupedValues<'_> {}
 
 /// Creates an empty iterator. Used for `unwrap_or_default()`.
 #[allow(deprecated)]
-impl<'a> Default for GroupedValues<'a> {
+impl Default for GroupedValues<'_> {
     fn default() -> Self {
         static EMPTY: [Vec<AnyValue>; 0] = [];
         GroupedValues {
@@ -1747,7 +1747,7 @@
 }
 
 impl<'a, T> ExactSizeIterator for OccurrencesRef<'a, T> where Self: 'a {}
-impl<'a, T> Default for OccurrencesRef<'a, T> {
+impl<T> Default for OccurrencesRef<'_, T> {
     fn default() -> Self {
         static EMPTY: [Vec<AnyValue>; 0] = [];
         OccurrencesRef {
@@ -1806,15 +1806,15 @@
     }
 }
 
-impl<'a> DoubleEndedIterator for RawOccurrences<'a> {
+impl DoubleEndedIterator for RawOccurrences<'_> {
     fn next_back(&mut self) -> Option<Self::Item> {
         self.iter.next_back()
     }
 }
 
-impl<'a> ExactSizeIterator for RawOccurrences<'a> {}
+impl ExactSizeIterator for RawOccurrences<'_> {}
 
-impl<'a> Default for RawOccurrences<'a> {
+impl Default for RawOccurrences<'_> {
     fn default() -> Self {
         static EMPTY: [Vec<OsString>; 0] = [];
         RawOccurrences {
@@ -1853,7 +1853,7 @@
     }
 }
 
-impl<'a> ExactSizeIterator for RawOccurrenceValues<'a> {}
+impl ExactSizeIterator for RawOccurrenceValues<'_> {}
 
 /// Iterate over indices for where an argument appeared when parsing, via [`ArgMatches::indices_of`]
 ///
@@ -1882,7 +1882,7 @@
     len: usize,
 }
 
-impl<'a> Iterator for Indices<'a> {
+impl Iterator for Indices<'_> {
     type Item = usize;
 
     fn next(&mut self) -> Option<usize> {
@@ -1898,7 +1898,7 @@
     }
 }
 
-impl<'a> DoubleEndedIterator for Indices<'a> {
+impl DoubleEndedIterator for Indices<'_> {
     fn next_back(&mut self) -> Option<usize> {
         if let Some(next) = self.iter.next_back() {
             self.len -= 1;
@@ -1909,10 +1909,10 @@
     }
 }
 
-impl<'a> ExactSizeIterator for Indices<'a> {}
+impl ExactSizeIterator for Indices<'_> {}
 
 /// Creates an empty iterator.
-impl<'a> Default for Indices<'a> {
+impl Default for Indices<'_> {
     fn default() -> Self {
         static EMPTY: [usize; 0] = [];
         // This is never called because the iterator is empty:
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/matched_arg.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/matched_arg.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/matched_arg.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/matched_arg.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/value_source.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/value_source.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/value_source.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/value_source.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/parser.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/parser.rs
similarity index 99%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/parser.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/parser.rs
index e6d5741..2949c3e1 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/parser.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/parser.rs
@@ -1541,7 +1541,7 @@
 }
 
 // Error, Help, and Version Methods
-impl<'cmd> Parser<'cmd> {
+impl Parser<'_> {
     /// Is only used for the long flag(which is the only one needs fuzzy searching)
     fn did_you_mean_error(
         &mut self,
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/validator.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/validator.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/validator.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/validator.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/any_value.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/any_value.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/any_value.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/any_value.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/color.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/color.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/color.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/color.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/flat_map.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/flat_map.rs
similarity index 98%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/flat_map.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/flat_map.rs
index cb4c7da..d739b92 100644
--- a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/flat_map.rs
+++ b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/flat_map.rs
@@ -215,7 +215,7 @@
     }
 }
 
-impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> {}
+impl<K, V> ExactSizeIterator for Iter<'_, K, V> {}
 
 pub(crate) struct IterMut<'a, K, V> {
     keys: std::slice::IterMut<'a, K>,
@@ -251,4 +251,4 @@
     }
 }
 
-impl<'a, K, V> ExactSizeIterator for IterMut<'a, K, V> {}
+impl<K, V> ExactSizeIterator for IterMut<'_, K, V> {}
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/flat_set.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/flat_set.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/flat_set.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/flat_set.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/graph.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/graph.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/graph.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/graph.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/id.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/id.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/id.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/id.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/mod.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/mod.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/mod.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/mod.rs
diff --git a/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/str_to_bool.rs b/third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/str_to_bool.rs
similarity index 100%
rename from third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/str_to_bool.rs
rename to third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/str_to_bool.rs
diff --git a/third_party/rust/clap/v4/BUILD.gn b/third_party/rust/clap/v4/BUILD.gn
index 7e7f984..b5f456d5 100644
--- a/third_party/rust/clap/v4/BUILD.gn
+++ b/third_party/rust/clap/v4/BUILD.gn
@@ -13,154 +13,154 @@
   epoch = "4"
   crate_type = "rlib"
   crate_root =
-      "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/lib.rs"
+      "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/lib.rs"
   sources = [
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/cargo_example.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/cargo_example_derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/escaped_positional.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/escaped_positional_derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/find.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/git.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/git_derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/multicall_busybox.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/multicall_hostname.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/pacman.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/repl.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/repl_derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_cookbook/typed_derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_0.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_1.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_2.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_3.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_4.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/chapter_5.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/_tutorial/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_derive/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_faq.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_features.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_0.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_1.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_2.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_3.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_4.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/chapter_5.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/_tutorial/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/bin/stdio-fixture.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/lib.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/cargo_example.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/cargo_example_derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/escaped_positional.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/escaped_positional_derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/find.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/git.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/git_derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/multicall_busybox.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/multicall_hostname.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/pacman.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/repl.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/repl_derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_cookbook/typed_derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_0.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_1.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_2.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_3.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_4.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/chapter_5.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/_tutorial/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_derive/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_faq.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_features.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_0.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_1.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_2.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_3.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_4.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/chapter_5.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/_tutorial/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/bin/stdio-fixture.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/lib.rs",
   ]
   inputs = [
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../README.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/README.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/cargo-example-derive.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/cargo-example-derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/cargo-example.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/cargo-example.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/demo.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/demo.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/derive_ref/augment_args.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/derive_ref/augment_subcommands.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/derive_ref/flatten_hand_args.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/derive_ref/hand_subcommand.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/derive_ref/interop_tests.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/escaped-positional-derive.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/escaped-positional-derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/escaped-positional.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/escaped-positional.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/find.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/find.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/git-derive.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/git-derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/git.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/git.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/multicall-busybox.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/multicall-busybox.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/multicall-hostname.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/multicall-hostname.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/pacman.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/pacman.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/repl-derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/repl.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/01_quick.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/01_quick.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/02_app_settings.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/02_app_settings.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/02_apps.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/02_apps.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/02_crate.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/02_crate.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_01_flag_bool.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_01_flag_bool.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_01_flag_count.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_01_flag_count.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_02_option.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_02_option.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_02_option_mult.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_02_option_mult.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_03_positional.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_03_positional.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_03_positional_mult.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_03_positional_mult.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_04_subcommands.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_04_subcommands.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_05_default_values.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/03_05_default_values.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_01_enum.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_01_enum.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_01_possible.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_01_possible.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_02_parse.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_02_parse.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_02_validate.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_02_validate.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_03_relations.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_03_relations.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_04_custom.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/04_04_custom.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_builder/05_01_assert.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/01_quick.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/01_quick.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/02_app_settings.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/02_app_settings.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/02_apps.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/02_apps.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/02_crate.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/02_crate.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_01_flag_bool.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_01_flag_bool.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_01_flag_count.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_01_flag_count.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_02_option.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_02_option.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_02_option_mult.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_02_option_mult.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_03_positional.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_03_positional.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_03_positional_mult.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_03_positional_mult.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_04_subcommands.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_04_subcommands.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_04_subcommands_alt.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_05_default_values.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/03_05_default_values.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_01_enum.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_01_enum.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_02_parse.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_02_parse.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_02_validate.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_02_validate.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_03_relations.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_03_relations.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_04_custom.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/04_04_custom.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/tutorial_derive/05_01_assert.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/typed-derive.md",
-    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.21/src/../examples/typed-derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../README.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/README.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/cargo-example-derive.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/cargo-example-derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/cargo-example.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/cargo-example.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/demo.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/demo.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/derive_ref/augment_args.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/derive_ref/augment_subcommands.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/derive_ref/flatten_hand_args.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/derive_ref/hand_subcommand.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/derive_ref/interop_tests.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/escaped-positional-derive.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/escaped-positional-derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/escaped-positional.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/escaped-positional.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/find.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/find.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/git-derive.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/git-derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/git.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/git.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/multicall-busybox.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/multicall-busybox.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/multicall-hostname.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/multicall-hostname.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/pacman.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/pacman.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/repl-derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/repl.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/01_quick.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/01_quick.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/02_app_settings.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/02_app_settings.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/02_apps.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/02_apps.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/02_crate.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/02_crate.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_01_flag_bool.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_01_flag_bool.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_01_flag_count.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_01_flag_count.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_02_option.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_02_option.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_02_option_mult.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_02_option_mult.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_03_positional.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_03_positional.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_03_positional_mult.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_03_positional_mult.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_04_subcommands.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_04_subcommands.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_05_default_values.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/03_05_default_values.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_01_enum.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_01_enum.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_01_possible.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_01_possible.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_02_parse.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_02_parse.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_02_validate.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_02_validate.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_03_relations.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_03_relations.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_04_custom.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/04_04_custom.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_builder/05_01_assert.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/01_quick.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/01_quick.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/02_app_settings.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/02_app_settings.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/02_apps.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/02_apps.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/02_crate.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/02_crate.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_01_flag_bool.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_01_flag_bool.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_01_flag_count.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_01_flag_count.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_02_option.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_02_option.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_02_option_mult.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_02_option_mult.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_03_positional.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_03_positional.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_03_positional_mult.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_03_positional_mult.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_04_subcommands.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_04_subcommands.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_04_subcommands_alt.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_05_default_values.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/03_05_default_values.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_01_enum.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_01_enum.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_02_parse.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_02_parse.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_02_validate.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_02_validate.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_03_relations.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_03_relations.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_04_custom.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/04_04_custom.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/tutorial_derive/05_01_assert.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/typed-derive.md",
+    "//third_party/rust/chromium_crates_io/vendor/clap-4.5.23/src/../examples/typed-derive.rs",
   ]
 
   build_native_rust_unit_tests = false
   edition = "2021"
-  cargo_pkg_version = "4.5.21"
+  cargo_pkg_version = "4.5.23"
   cargo_pkg_name = "clap"
   cargo_pkg_description = "A simple to use, efficient, and full-featured Command Line Argument Parser"
   library_configs -= [ "//build/config/compiler:chromium_code" ]
diff --git a/third_party/rust/clap/v4/README.chromium b/third_party/rust/clap/v4/README.chromium
index 18f7c1d..39e536e 100644
--- a/third_party/rust/clap/v4/README.chromium
+++ b/third_party/rust/clap/v4/README.chromium
@@ -1,9 +1,9 @@
 Name: clap
 URL: https://crates.io/crates/clap
-Version: 4.5.21
-Revision: 2920fb082c987acb72ed1d1f47991c4d157e380d
+Version: 4.5.23
+Revision: fde45f9aea766fb8de46e3d46e6575f393c3b6b9
 License: Apache-2.0
-License File: //third_party/rust/chromium_crates_io/vendor/clap-4.5.21/LICENSE-APACHE
+License File: //third_party/rust/chromium_crates_io/vendor/clap-4.5.23/LICENSE-APACHE
 Shipped: no
 Security Critical: yes
 
diff --git a/third_party/rust/clap_builder/v4/BUILD.gn b/third_party/rust/clap_builder/v4/BUILD.gn
index 371c9132..31994f7 100644
--- a/third_party/rust/clap_builder/v4/BUILD.gn
+++ b/third_party/rust/clap_builder/v4/BUILD.gn
@@ -12,70 +12,70 @@
   crate_name = "clap_builder"
   epoch = "4"
   crate_type = "rlib"
-  crate_root = "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/lib.rs"
+  crate_root = "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/lib.rs"
   sources = [
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/action.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/app_settings.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg_group.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg_predicate.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/arg_settings.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/command.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/debug_asserts.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/ext.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/os_str.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/possible_value.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/range.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/resettable.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/str.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/styled_str.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/styling.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/tests.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/value_hint.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/builder/value_parser.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/derive.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/context.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/format.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/kind.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/error/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/lib.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/macros.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/mkeymap.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/fmt.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/help.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/help_template.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/core.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/word_separators.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/textwrap/wrap_algorithms.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/output/usage.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/arg_matcher.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/error.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/features/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/features/suggestions.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/arg_matches.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/matched_arg.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/matches/value_source.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/parser.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/parser/validator.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/any_value.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/color.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/flat_map.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/flat_set.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/graph.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/id.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/mod.rs",
-    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/util/str_to_bool.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/action.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/app_settings.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg_group.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg_predicate.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/arg_settings.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/command.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/debug_asserts.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/ext.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/os_str.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/possible_value.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/range.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/resettable.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/str.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/styled_str.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/styling.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/tests.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/value_hint.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/builder/value_parser.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/derive.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/context.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/format.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/kind.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/error/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/lib.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/macros.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/mkeymap.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/fmt.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/help.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/help_template.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/core.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/word_separators.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/textwrap/wrap_algorithms.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/output/usage.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/arg_matcher.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/error.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/features/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/features/suggestions.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/arg_matches.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/matched_arg.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/matches/value_source.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/parser.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/parser/validator.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/any_value.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/color.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/flat_map.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/flat_set.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/graph.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/id.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/mod.rs",
+    "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/util/str_to_bool.rs",
   ]
-  inputs = [ "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/src/../README.md" ]
+  inputs = [ "//third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/src/../README.md" ]
 
   build_native_rust_unit_tests = false
   edition = "2021"
-  cargo_pkg_version = "4.5.21"
+  cargo_pkg_version = "4.5.23"
   cargo_pkg_name = "clap_builder"
   cargo_pkg_description = "A simple to use, efficient, and full-featured Command Line Argument Parser"
   library_configs -= [ "//build/config/compiler:chromium_code" ]
diff --git a/third_party/rust/clap_builder/v4/README.chromium b/third_party/rust/clap_builder/v4/README.chromium
index 7b34197..a770c0f 100644
--- a/third_party/rust/clap_builder/v4/README.chromium
+++ b/third_party/rust/clap_builder/v4/README.chromium
@@ -1,9 +1,9 @@
 Name: clap_builder
 URL: https://crates.io/crates/clap_builder
-Version: 4.5.21
-Revision: 2920fb082c987acb72ed1d1f47991c4d157e380d
+Version: 4.5.23
+Revision: fde45f9aea766fb8de46e3d46e6575f393c3b6b9
 License: Apache-2.0
-License File: //third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/LICENSE-APACHE
+License File: //third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.23/LICENSE-APACHE
 Shipped: no
 Security Critical: yes
 
diff --git a/third_party/skia b/third_party/skia
index b2f3e3f..e56496e 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit b2f3e3f6263ad231a042a2632bd98bfd26ab8ed7
+Subproject commit e56496eb35a3e20114d1a0052348e43b363f3cd4
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src
index 975839c..40d0e32 160000
--- a/third_party/webgpu-cts/src
+++ b/third_party/webgpu-cts/src
@@ -1 +1 @@
-Subproject commit 975839c060fb6cc79bb89e7e5b971c1c8deb8000
+Subproject commit 40d0e32190eb3bcc9c71b408d7b67302477c05ad
diff --git a/third_party/webrtc b/third_party/webrtc
index 588dbe6..b766572 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit 588dbe6fa77914ac09af6bf5c010923fea37a10b
+Subproject commit b766572d2b4aaa82b644a12a9413794da5e02e56
diff --git a/third_party/wpt_tools/README.chromium b/third_party/wpt_tools/README.chromium
index 96b7b02..64ffcc8 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: 39138b0492366aa07ef3e0cce12f67ff2de966a3
+Version: 28cc3c22685edc5ee146f67c8eadc47494a123fe
 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/requirements_firefox.txt b/third_party/wpt_tools/wpt/tools/wptrunner/requirements_firefox.txt
index 5fd08e2..59a9cd7b 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/requirements_firefox.txt
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/requirements_firefox.txt
@@ -1,5 +1,5 @@
 marionette_driver==3.4.0
-mozcrash==2.2.0
+mozcrash==2.2.1
 mozdevice==4.2.0
 mozinstall==2.1.0
 mozleak==0.2
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/environment.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/environment.py
index 9a6d3c8f..868ed8f9 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/environment.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/environment.py
@@ -1,5 +1,6 @@
 # mypy: allow-untyped-defs
 
+import collections
 import contextlib
 import errno
 import json
@@ -114,6 +115,7 @@
         mp_context = mpcontext.get_context()
         self._stack = contextlib.ExitStack()
         self.cache_manager = mp_context.Manager()
+        self.screenshot_caches = collections.defaultdict(self.cache_manager.dict)
         self.stash = serve.stash.StashServer(mp_context=mp_context)
         self.env_extras = env_extras
         self.env_extras_cms = None
@@ -165,6 +167,12 @@
         self._stack.__exit__(exc_type, exc_val, exc_tb)
         self.env_extras_cms = None
 
+    def reset(self):
+        """Reset state between retry attempts to isolate failures."""
+        for cache in self.screenshot_caches.values():
+            cache.clear()
+        # TODO: Clear the stash.
+
     @contextlib.contextmanager
     def ignore_interrupts(self):
         prev_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/base.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/base.py
index aef3357..26a0483 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/base.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/executors/base.py
@@ -34,7 +34,8 @@
                        "target_platform": run_info_data["os"]}
 
     if test_type in ("reftest", "print-reftest"):
-        executor_kwargs["screenshot_cache"] = test_environment.cache_manager.dict()
+        screenshot_cache = test_environment.screenshot_caches[test_type, subsuite.name]
+        executor_kwargs["screenshot_cache"] = screenshot_cache
         executor_kwargs["reftest_screenshot"] = kwargs["reftest_screenshot"]
 
     if test_type == "wdspec":
@@ -417,7 +418,7 @@
         return self.executor.logger
 
     def get_hash(self, test, viewport_size, dpi, page_ranges):
-        key = (self.subsuite, test.url, viewport_size, dpi)
+        key = (test.url, viewport_size, dpi)
 
         if key not in self.screenshot_cache:
             success, data = self.get_screenshot_list(test, viewport_size, dpi, page_ranges)
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testloader.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testloader.py
index 5969f4e..b574777 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testloader.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/testloader.py
@@ -168,7 +168,7 @@
                                                            str(self.run_info))
 
 
-def read_include_from_file(file):
+def read_test_prefixes_from_file(file):
     new_include = []
     with open(file) as f:
         for line in f:
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptcommandline.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptcommandline.py
index 421c003..d0fa429 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptcommandline.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptcommandline.py
@@ -159,6 +159,8 @@
                                       help="A file listing URL prefix for tests")
     test_selection_group.add_argument("--exclude", action="append",
                                       help="URL prefix to exclude")
+    test_selection_group.add_argument("--exclude-file", action="store",
+                                      help="A file listing URL prefix for tests")
     test_selection_group.add_argument("--include-manifest", type=abs_path,
                                       help="Path to manifest listing tests to include")
     test_selection_group.add_argument("--test-groups", dest="test_groups_file", type=abs_path,
diff --git a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptrunner.py b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptrunner.py
index fbaed2e..40a9aec 100644
--- a/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptrunner.py
+++ b/third_party/wpt_tools/wpt/tools/wptrunner/wptrunner/wptrunner.py
@@ -85,16 +85,20 @@
     include = kwargs["include"]
     if kwargs["include_file"]:
         include = include or []
-        include.extend(testloader.read_include_from_file(kwargs["include_file"]))
+        include.extend(testloader.read_test_prefixes_from_file(kwargs["include_file"]))
+    exclude = kwargs["exclude"]
+    if kwargs["exclude_file"]:
+        exclude = exclude or []
+        exclude.extend(testloader.read_test_prefixes_from_file(kwargs["exclude_file"]))
     if test_groups:
         include = testloader.update_include_for_groups(test_groups, include)
 
     if kwargs["tags"] or kwargs["exclude_tags"]:
         test_filters.append(testloader.TagFilter(kwargs["tags"], kwargs["exclude_tags"]))
 
-    if include or kwargs["exclude"] or kwargs["include_manifest"] or kwargs["default_exclude"]:
+    if include or exclude or kwargs["include_manifest"] or kwargs["default_exclude"]:
         manifest_filters.append(testloader.TestFilter(include=include,
-                                                      exclude=kwargs["exclude"],
+                                                      exclude=exclude,
                                                       manifest_path=kwargs["include_manifest"],
                                                       test_manifests=test_manifests,
                                                       explicit=kwargs["default_exclude"]))
@@ -295,6 +299,7 @@
                             test_loader.subsuites,
                             kwargs["run_by_dir"])
 
+        test_environment.reset()
         with ManagerGroup("web-platform-tests",
                           test_queue_builder,
                           test_implementations,
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index f89060fb..ae7b881 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -10945,6 +10945,8 @@
   <int value="5226" label="AdScriptInStackOnCameraRead"/>
   <int value="5227" label="ClipboardCustomFormatRead"/>
   <int value="5228" label="ClipboardCustomFormatWrite"/>
+  <int value="5229" label="ClipboardSvgRead"/>
+  <int value="5230" label="ClipboardSvgWrite"/>
 </enum>
 
 <!-- LINT.ThenChange(//third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom:WebFeature) -->
@@ -16046,6 +16048,8 @@
   <int value="-1741468321" label="NtpMostRelevantTabResumptionModule:enabled"/>
   <int value="-1740519217" label="disable-software-rasterizer"/>
   <int value="-1740093155" label="UnifiedMediaView:disabled"/>
+  <int value="-1739547247"
+      label="ShowWarningsForSuspiciousNotifications:enabled"/>
   <int value="-1739475391" label="AppCollectionFolderRefresh:disabled"/>
   <int value="-1738416948" label="OptimizationHints:enabled"/>
   <int value="-1738273185"
@@ -20437,7 +20441,6 @@
   <int value="15872227"
       label="OmniboxDiscardTemporaryInputOnTabSwitch:disabled"/>
   <int value="16804822" label="SpeakOnMuteEnabled:disabled"/>
-  <int value="19629326" label="OmniboxExperimentalKeywordMode:enabled"/>
   <int value="19815558" label="EnableSettingsShortcutSearch:disabled"/>
   <int value="20023271" label="AllowApnModificationPolicy:disabled"/>
   <int value="20238651" label="DeprecatedExternalPickerFunction:enabled"/>
@@ -21240,6 +21243,7 @@
   <int value="336429189" label="DisallowUnsafeHttpDownloads:disabled"/>
   <int value="336830575" label="DeviceForceScheduledReboot:enabled"/>
   <int value="337637199" label="HttpsFirstModeIncognito:disabled"/>
+  <int value="337894107" label="TabstripDedupe:enabled"/>
   <int value="338662897" label="AndroidNightModeTabReparenting:disabled"/>
   <int value="339388667" label="SyncAndroidPromosWithTitle:enabled"/>
   <int value="339419844" label="EmojiSuggestAddition:enabled"/>
@@ -23253,6 +23257,7 @@
       label="SignedExchangePrefetchCacheForNavigations:disabled"/>
   <int value="1146944555" label="CrosExpandSodaLanguages:enabled"/>
   <int value="1147703885" label="SecondaryGoogleAccountUsage:enabled"/>
+  <int value="1147801492" label="TabstripDedupe:disabled"/>
   <int value="1147924185" label="enable-navigation-predictor-renderer-warmup"/>
   <int value="1148284632" label="NewTabPageUIMd:disabled"/>
   <int value="1148637402"
@@ -23757,7 +23762,6 @@
   <int value="1335052342" label="AccessibilityDeprecateTypeAnnounce:disabled"/>
   <int value="1335454908" label="ShoppingCollection:enabled"/>
   <int value="1338356182" label="AutofillAssistantChromeEntry:disabled"/>
-  <int value="1338510325" label="lacros-selection"/>
   <int value="1338606926" label="BatterySaverModeAvailable:enabled"/>
   <int value="1338745937" label="NotificationWidthIncrease:disabled"/>
   <int value="1338864675" label="EnableTouchableAppContextMenu:disabled"/>
@@ -24645,7 +24649,6 @@
   <int value="1687768359" label="ServiceWorkerBypassFetchHandler:disabled"/>
   <int value="1687958931" label="QuickDeleteAndroidSurvey:disabled"/>
   <int value="1687987218" label="OmniboxGroupingFramework:enabled"/>
-  <int value="1688075820" label="OmniboxExperimentalKeywordMode:disabled"/>
   <int value="1689001971" label="ProjectorLocalPlayback:enabled"/>
   <int value="1689123607" label="enable-app-link"/>
   <int value="1689183477" label="enable-merge-key-char-events"/>
@@ -24855,6 +24858,7 @@
   <int value="1771548551" label="DisableKeepaliveFetch:enabled"/>
   <int value="1772248386" label="SeedAccountsRevamp:enabled"/>
   <int value="1772277480" label="DefaultBrowserPromptRefresh:enabled"/>
+  <int value="1772341349" label="(Obsolete) lacros-selection"/>
   <int value="1772454319" label="enable-storage-manager"/>
   <int value="1772618273"
       label="WebAuthenticationFilterGooglePasskeys:disabled"/>
@@ -25696,6 +25700,8 @@
   <int value="2092605092" label="ChromeHomeShowGoogleGWhenUrlCleared:disabled"/>
   <int value="2092968851" label="SharingSendViaSync:enabled"/>
   <int value="2093235103" label="default-tile-width"/>
+  <int value="2093392187"
+      label="ShowWarningsForSuspiciousNotifications:disabled"/>
   <int value="2093949489" label="ArrayPrototypeValues:enabled"/>
   <int value="2094335682" label="StreamlinedUsbPrinterSetup:enabled"/>
   <int value="2095250358"
@@ -34250,6 +34256,7 @@
   <int value="269" label="Highlight"/>
   <int value="270" label="DRAFT_ErrorIsError"/>
   <int value="271" label="ClipboardCustomFormat"/>
+  <int value="272" label="ClipboardSvg"/>
 </enum>
 
 <!-- LINT.ThenChange(//third_party/blink/public/mojom/use_counter/metrics/webdx_feature.mojom:WebDXFeature) -->
diff --git a/tools/metrics/histograms/metadata/android/enums.xml b/tools/metrics/histograms/metadata/android/enums.xml
index eaebb7b..1ff2bec 100644
--- a/tools/metrics/histograms/metadata/android/enums.xml
+++ b/tools/metrics/histograms/metadata/android/enums.xml
@@ -1828,6 +1828,58 @@
   <int value="29" label="void setupAutoFill(Message)"/>
 </enum>
 
+<enum name="WebPageContentProviderEvent">
+  <int value="0" label="GET_CONTENT_URI_FAILED">
+    WebPageContentProvider failed to generate a URI for the current web page,
+    nothing will be attached to AssistContent
+  </int>
+  <int value="1" label="QUERY">
+    WebPageContentProvider received a query by an external app
+  </int>
+  <int value="2" label="QUERY_FAILED_CURRENT_TAB_CHANGED">
+    WebPageContentProvider returned an empty cursor while processing a query
+    because the current tab no longer matches
+  </int>
+  <int value="3" label="QUERY_FAILED_INVALID_URI">
+    WebPageContentProvider threw an error while processing a query because it
+    had an invalid URI
+  </int>
+  <int value="4" label="QUERY_FAILED_INVALID_ID">
+    WebPageContentProvider returned an empty cursor while processing a query
+    because the URI had an invalid id (e.g. non existing or no longer valid).
+  </int>
+  <int value="5" label="QUERY_FAILED_TO_GET_CURRENT_TAB">
+    WebPageContentProvider returned an empty cursor while processing a query
+    because we failed to get the current tab from the browser process
+  </int>
+  <int value="6" label="QUERY_SUCCEEDED_ALREADY_EXTRACTING">
+    WebPageContentProvider returned a cursor with a pending result for a page
+    extraction task that was already running
+  </int>
+  <int value="7" label="QUERY_SUCCEEDED_RETURNED_EXTRACTED">
+    WebPageContentProvider returned a cursor with page contents successfully
+  </int>
+  <int value="8" label="QUERY_SUCCEEDED_STARTED_EXTRACTION">
+    WebPageContentProvider successfully started a page extraction task and
+    returned a cursor with a pending result
+  </int>
+  <int value="9" label="TEXT_EXTRACTION_FAILED_EMPTY_RESULT">
+    WebPageContentProvider's page extraction task failed to execute
+  </int>
+  <int value="10" label="TEXT_EXTRACTION_FAILED_TAB_CHANGED">
+    WebPageContentProvider's page extraction task succeeded, but the result was
+    discarded because the tab is no longer current
+  </int>
+  <int value="11" label="TEXT_EXTRACTION_SUCCEEDED">
+    WebPageContentProvider's page extraction task completed successfully and
+    observers were notified
+  </int>
+  <int value="12" label="TIMEOUT">
+    The last URI generated by WebPageContentProvider was not queried on time and
+    it's no longer valid.
+  </int>
+</enum>
+
 <enum name="WebViewApiCall">
 <!-- LINT.IfChange(WebViewApiCall) -->
 
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml
index 88d2fe1..575ca86 100644
--- a/tools/metrics/histograms/metadata/android/histograms.xml
+++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -459,6 +459,101 @@
   </summary>
 </histogram>
 
+<histogram name="Android.AssistContent.AttachedUrl" enum="BooleanSuccess"
+    expires_after="2025-03-01">
+  <owner>salg@google.com</owner>
+  <owner>ssid@google.com</owner>
+  <summary>
+    Records whether the current web page URI was attached to an AssistContent
+    object when assistant was invoked while ChromeActivity was in the
+    foreground.
+  </summary>
+</histogram>
+
+<histogram name="Android.AssistContent.StructuredDataAttachedSuccess.Pdf"
+    enum="BooleanSuccess" expires_after="2025-03-01">
+  <owner>salg@google.com</owner>
+  <owner>ssid@google.com</owner>
+  <summary>
+    Records whether PDF structured data was successfully attached to an
+    AssistContent object when assistant was invoked while ChromeActivity was in
+    the foreground.
+
+    Only recorded when the &quot;AndroidPdfAssistContent&quot; feature is
+    enabled and assistant is invoked while viewing a PDF.
+  </summary>
+</histogram>
+
+<histogram name="Android.AssistContent.StructuredDataAttachedSuccess.WebPage"
+    enum="BooleanSuccess" expires_after="2025-03-01">
+  <owner>salg@google.com</owner>
+  <owner>ssid@google.com</owner>
+  <summary>
+    Records whether web page structured data was successfully attached to an
+    AssistContent object when assistant was invoked while ChromeActivity was in
+    the foreground.
+
+    Only recorded when the &quot;PageContentProvider&quot; feature is enabled
+    and assistant is invoked while viewing a web page.
+  </summary>
+</histogram>
+
+<histogram name="Android.AssistContent.WebPageContentProvider.Events"
+    enum="WebPageContentProviderEvent" expires_after="2025-03-01">
+  <owner>salg@google.com</owner>
+  <owner>ssid@google.com</owner>
+  <summary>
+    Records events related to WebPageContentProvider as it generates a URI for
+    an external app and as it handles queries from said external app.
+  </summary>
+</histogram>
+
+<histogram
+    name="Android.AssistContent.WebPageContentProvider.Latency.CreateToExtractionStart"
+    units="ms" expires_after="2025-03-01">
+  <owner>salg@google.com</owner>
+  <owner>ssid@google.com</owner>
+  <summary>
+    Records the amount of time passed between sending a web page content
+    provider URI to an external app and receiving a query from an external app
+    with the same URI (this starts a content extraction task).
+  </summary>
+</histogram>
+
+<histogram
+    name="Android.AssistContent.WebPageContentProvider.Latency.CreateToFinalQuery"
+    units="ms" expires_after="2025-03-01">
+  <owner>salg@google.com</owner>
+  <owner>ssid@google.com</owner>
+  <summary>
+    Records the total amount of time passed between sending a web page content
+    provider URI to an external app and it receiving the web page's contents.
+  </summary>
+</histogram>
+
+<histogram
+    name="Android.AssistContent.WebPageContentProvider.Latency.ExtractionEndToFinalQuery"
+    units="ms" expires_after="2025-03-01">
+  <owner>salg@google.com</owner>
+  <owner>ssid@google.com</owner>
+  <summary>
+    Records the amount of time passed between notifying an external app that a
+    web page content provider URI has changed and receiving a query from an
+    external app with the same URI (this returns the extracted content).
+  </summary>
+</histogram>
+
+<histogram
+    name="Android.AssistContent.WebPageContentProvider.Latency.ExtractionStartToEnd"
+    units="ms" expires_after="2025-03-01">
+  <owner>salg@google.com</owner>
+  <owner>ssid@google.com</owner>
+  <summary>
+    Records the amount of time passed while extracting a web page's contents,
+    when done an external application is notified that their URI has changed.
+  </summary>
+</histogram>
+
 <histogram name="Android.Automotive.DeviceLockDialogAction.{Source}"
     enum="DeviceLockDialogAction" expires_after="2025-07-01">
   <owner>clhager@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index 3aaf67f..e08f4177 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -3636,37 +3636,6 @@
   <affected-histogram name="Media.Remoting.SessionStopTrigger"/>
 </histogram_suffixes>
 
-<histogram_suffixes name="RendererScheduler_MainThreadLoadSplit" separator=".">
-  <suffix name="Background"
-      label="Main thread load when the renderer is backgrounded. This does
-             not include extension renderers."/>
-  <suffix name="Background.AfterFifthMinute"
-      label="Main thread load when the renderer is backgrounded for longer
-             than five minutes. This does not include extension renderers."/>
-  <suffix name="Background.AfterFirstMinute"
-      label="Main thread load when the renderer is backgrounded for longer
-             than one minute. Most of loading tasks are expected to complete
-             by then. This does not include extension renderers."/>
-  <suffix name="Background.AfterTenthMinute"
-      label="Main thread load when the renderer is backgrounded for longer
-             than ten minutes. This does not include extension renderers."/>
-  <suffix name="Extension" label="This only includes extension renderers"/>
-  <suffix name="Extension.Background"
-      label="Main thread load when the renderer is backgrounded. This only
-             includes extension renderers."/>
-  <suffix name="Extension.Foreground"
-      label="Main thread load when the renderer is foregrounded. This only
-             includes extension renderers."/>
-  <suffix name="Foreground"
-      label="Main thread load when the renderer is foregrounded. This does
-             not include extension renderers."/>
-  <suffix name="Foreground.AfterFirstMinute"
-      label="Main thread load when the renderer is foregrounded for longer
-             than one minute. Most of loading tasks are expected to complete
-             by then. This does not include extension renderers."/>
-  <affected-histogram name="RendererScheduler.RendererMainThreadLoad5"/>
-</histogram_suffixes>
-
 <histogram_suffixes name="RendererThreadType" separator=".">
   <suffix name="Compositor"
       label="Measurement taken on the compositor thread."/>
diff --git a/tools/metrics/histograms/metadata/media/enums.xml b/tools/metrics/histograms/metadata/media/enums.xml
index e1c2091..93a69bc 100644
--- a/tools/metrics/histograms/metadata/media/enums.xml
+++ b/tools/metrics/histograms/metadata/media/enums.xml
@@ -1479,14 +1479,6 @@
   <int value="2" label="Registered Automatic"/>
 </enum>
 
-<enum name="MediaSessionSuspendedSource">
-  <int value="0" label="System Transient"/>
-  <int value="1" label="System Permanent"/>
-  <int value="2" label="UI"/>
-  <int value="3" label="CONTENT"/>
-  <int value="4" label="System Transient Duck"/>
-</enum>
-
 <enum name="MediaSinkType">
   <int value="0" label="Cast"/>
   <int value="1" label="Cast Audio Group"/>
diff --git a/tools/metrics/histograms/metadata/media/histograms.xml b/tools/metrics/histograms/metadata/media/histograms.xml
index 6aa4b9f1..d3ca6d1 100644
--- a/tools/metrics/histograms/metadata/media/histograms.xml
+++ b/tools/metrics/histograms/metadata/media/histograms.xml
@@ -5464,16 +5464,6 @@
   </summary>
 </histogram>
 
-<histogram name="Media.Session.Suspended" enum="MediaSessionSuspendedSource"
-    expires_after="2022-02-06">
-  <owner>steimel@chromium.org</owner>
-  <owner>media-dev-uma@chromium.org</owner>
-  <summary>
-    The number of times a media session is suspended and why it has been
-    suspended.
-  </summary>
-</histogram>
-
 <histogram name="Media.SRC.VideoCodec.MP4" enum="VideoCodec"
     expires_after="never">
 <!-- expires-never: Codec and container support planning metric. -->
diff --git a/tools/metrics/histograms/metadata/omnibox/enums.xml b/tools/metrics/histograms/metadata/omnibox/enums.xml
index 5ec4b846..e8e61f12 100644
--- a/tools/metrics/histograms/metadata/omnibox/enums.xml
+++ b/tools/metrics/histograms/metadata/omnibox/enums.xml
@@ -70,6 +70,8 @@
   <int value="10" label="Not allowed because the input is a focus or is empty"/>
   <int value="11" label="Not allowed because the input length is too short"/>
   <int value="12" label="Not allowed because the input looks like a URL"/>
+  <int value="13"
+      label="Not allowed because the user is not enterprise eligible"/>
 </enum>
 
 <enum name="DocumentSuggestRequestEvent">
diff --git a/tools/metrics/histograms/metadata/renderer/histograms.xml b/tools/metrics/histograms/metadata/renderer/histograms.xml
index 212f5ea..2f0d012 100644
--- a/tools/metrics/histograms/metadata/renderer/histograms.xml
+++ b/tools/metrics/histograms/metadata/renderer/histograms.xml
@@ -589,21 +589,6 @@
   </token>
 </histogram>
 
-<histogram name="RendererScheduler.RendererMainThreadLoad5" units="%"
-    expires_after="2025-06-08">
-  <owner>altimin@chromium.org</owner>
-  <summary>
-    Renderer main thread load (percentage of time spent in tasks), reported in
-    one second chunks.
-
-    See http://bit.ly/chromium-renderer-main-thread-load-metric for details.
-
-    This metric is emitted when the renderer main thread task is completed or
-    renderer is backgrounded or foregrounded, at most once per second per
-    renderer amortized.
-  </summary>
-</histogram>
-
 <histogram name="RendererSyncIPC.ElapsedTime" units="ms" expires_after="M85">
   <owner>ppi@chromium.org</owner>
   <summary>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index 66b713b..3035dc8 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -21,8 +21,8 @@
             "full_remote_path": "perfetto-luci-artifacts/5bf4e2a65d76d5a603ff175222d1513f71d28a0b/mac-arm64/trace_processor_shell"
         },
         "linux": {
-            "hash": "6732a9390a195cdf1573174c41c79892bd862c87",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/5bf4e2a65d76d5a603ff175222d1513f71d28a0b/trace_processor_shell"
+            "hash": "f7fb4eb76e8ddab7b5331bd3d5c7411dbb19eeee",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/2f24aafc7f8c3f4ca349224bbadab9f54a3e3559/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/accessibility/platform/ax_platform_node_cocoa.mm b/ui/accessibility/platform/ax_platform_node_cocoa.mm
index f765eed..46c0a60 100644
--- a/ui/accessibility/platform/ax_platform_node_cocoa.mm
+++ b/ui/accessibility/platform/ax_platform_node_cocoa.mm
@@ -780,11 +780,7 @@
     case ax::mojom::Role::kListBox:
       return NSAccessibilityListRole;
     case ax::mojom::Role::kListBoxOption:
-      // Short term solution that allows children until Mac gets a more
-      // appropriate role for options than AXStaticText, which can result
-      // truncation or incorrect announcements of the option text when there are
-      // children.
-      return NSAccessibilityMenuItemRole;
+      return NSAccessibilityStaticTextRole;
     case ax::mojom::Role::kListGrid:
       return NSAccessibilityTableRole;
     case ax::mojom::Role::kListMarker:
diff --git a/ui/accessibility/platform/browser_accessibility_cocoa.mm b/ui/accessibility/platform/browser_accessibility_cocoa.mm
index 8bd55333..b9448be 100644
--- a/ui/accessibility/platform/browser_accessibility_cocoa.mm
+++ b/ui/accessibility/platform/browser_accessibility_cocoa.mm
@@ -1497,8 +1497,12 @@
   DCHECK(_owner->node()->IsDataValid());
 
   if (ui::IsNameExposedInAXValueForRole([self internalRole])) {
-    std::u16string name =
-        _owner->GetString16Attribute(ax::mojom::StringAttribute::kName);
+    std::u16string name = _owner->GetTextContentUTF16();
+    // Leaf node with aria-label will have empty text content.
+    // e.g. <div role="option" aria-label="label">content</div>
+    // So we use its computed name for AXValue.
+    if (name.empty())
+      name = _owner->GetNameAsString16();
     if (!IsSelectedStateRelevant(_owner)) {
       return base::SysUTF16ToNSString(name);
     }
@@ -1511,6 +1515,7 @@
         is_selected ? IDS_AX_OBJECT_SELECTED : IDS_AX_OBJECT_NOT_SELECTED;
     std::u16string name_with_selection = base::ReplaceStringPlaceholders(
         _owner->GetLocalizedString(msg_id), {name}, nullptr);
+
     return base::SysUTF16ToNSString(name_with_selection);
   }
 
diff --git a/ui/color/color_id.h b/ui/color/color_id.h
index c98a2d3..0826e03 100644
--- a/ui/color/color_id.h
+++ b/ui/color/color_id.h
@@ -437,6 +437,7 @@
   E_CPONLY(kColorTabBackgroundHighlightedFocused) \
   E_CPONLY(kColorTabBorderSelected) \
   E_CPONLY(kColorTabContentSeparator) \
+  E_CPONLY(kColorTabForegroundDisabled) \
   E_CPONLY(kColorTabForeground) \
   E_CPONLY(kColorTabForegroundSelected) \
   E_CPONLY(kColorTableBackground) \
diff --git a/ui/color/ui_color_mixer.cc b/ui/color/ui_color_mixer.cc
index 4e5eeb0..b563810b 100644
--- a/ui/color/ui_color_mixer.cc
+++ b/ui/color/ui_color_mixer.cc
@@ -226,6 +226,7 @@
         SetAlpha(std::move(tab_background_base), 0x53);
   }
   mixer[kColorTabContentSeparator] = {kColorMidground};
+  mixer[kColorTabForegroundDisabled] = {kColorSysStateDisabled};
   mixer[kColorTableGroupingIndicator] = {kColorItemHighlight};
   mixer[kColorTableHeaderBackground] = {kColorTableBackground};
   mixer[kColorTableHeaderForeground] = {kColorTableForeground};
diff --git a/ui/views/controls/menu/menu_item_view.cc b/ui/views/controls/menu/menu_item_view.cc
index b4cd3e5a..c8e5fbf1 100644
--- a/ui/views/controls/menu/menu_item_view.cc
+++ b/ui/views/controls/menu/menu_item_view.cc
@@ -398,6 +398,13 @@
                             Type::kTitle);
 }
 
+MenuItemView* MenuItemView::AddTitleAt(const std::u16string& label,
+                                       size_t index) {
+  return AddMenuItemAt(index, ui::MenuModel::kTitleId, label, std::u16string(),
+                       std::u16string(), ui::ImageModel(), ui::ImageModel(),
+                       Type::kTitle, ui::NORMAL_SEPARATOR);
+}
+
 MenuItemView* MenuItemView::AppendSubMenu(int item_id,
                                           const std::u16string& label,
                                           const ui::ImageModel& icon) {
diff --git a/ui/views/controls/menu/menu_item_view.h b/ui/views/controls/menu/menu_item_view.h
index b56a9e4..a34483ae 100644
--- a/ui/views/controls/menu/menu_item_view.h
+++ b/ui/views/controls/menu/menu_item_view.h
@@ -216,6 +216,7 @@
                                const ui::ImageModel& icon = ui::ImageModel());
 
   MenuItemView* AppendTitle(const std::u16string& label);
+  MenuItemView* AddTitleAt(const std::u16string& label, size_t index);
 
   // Append a submenu to this menu.
   // The returned pointer is owned by this menu.
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc
index 58d1b610..f021377 100644
--- a/ui/views/controls/tabbed_pane/tabbed_pane.cc
+++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -169,6 +169,19 @@
   SetState(selected() ? State::kActive : State::kInactive);
 }
 
+void TabbedPaneTab::UpdateEnabledColor(bool enabled) {
+  if (enabled) {
+    UpdateTitleColor();
+    UpdateIconColor();
+  } else {
+    title_->SetEnabledColorId(ui::kColorTabForegroundDisabled);
+    if (icon_view_) {
+      icon_view_->SetImage(
+          GetImageModelForTab(ui::kColorTabForegroundDisabled));
+    }
+  }
+}
+
 void TabbedPaneTab::OnGestureEvent(ui::GestureEvent* event) {
   switch (event->type()) {
     case ui::EventType::kGestureTapDown:
@@ -458,6 +471,16 @@
   }
 }
 
+void TabbedPaneTabStrip::SetEnabled(bool enabled) {
+  if (GetEnabled() == enabled) {
+    return;
+  }
+  View::SetEnabled(enabled);
+  for (size_t i = 0; i < GetTabCount(); ++i) {
+    GetTabAtIndex(i)->UpdateEnabledColor(enabled);
+  }
+}
+
 // Computes the starting and ending points of the selection slider for a given
 // tab from the origin.
 //
@@ -702,6 +725,11 @@
         rect, GetColorProvider()->GetColor(ui::kColorTabContentSeparator));
   }
 
+  // No need to draw the selection marker if the tab strip is disabled.
+  if (!GetEnabled()) {
+    return;
+  }
+
   TabbedPaneTab* tab = GetSelectedTab();
   if (!tab) {
     return;
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.h b/ui/views/controls/tabbed_pane/tabbed_pane.h
index 590d86c..274ea4dc 100644
--- a/ui/views/controls/tabbed_pane/tabbed_pane.h
+++ b/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -194,6 +194,8 @@
   bool OnKeyPressed(const ui::KeyEvent& event) override;
   void OnThemeChanged() override;
 
+  void UpdateEnabledColor(bool enabled);
+
  private:
   static constexpr int kIconSize = 16;
   static constexpr int kIconRightMargin = kIconSize / 2;
@@ -268,6 +270,8 @@
   void AnimationProgressed(const gfx::Animation* animation) override;
   void AnimationEnded(const gfx::Animation* animation) override;
 
+  void SetEnabled(bool enabled);
+
   // Called by TabbedPaneTabStrip when the selected tab changes. This function
   // is only called if |from_tab| is not null, i.e., there was a previously
   // selected tab.