diff --git a/DEPS b/DEPS
index da95a75..8a9806a 100644
--- a/DEPS
+++ b/DEPS
@@ -253,7 +253,7 @@
   'screen_ai_windows_386': 'version:127.5',
 
   # siso CIPD package version.
-  'siso_version': 'git_revision:e9812e4893d596fa06b74355e2b6ff47e0307e32',
+  'siso_version': 'git_revision:332cc31376cbaab640d0622ed3619f3200e1f1e1',
 
   # download libaom test data
   'download_libaom_testdata': False,
@@ -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': '6f4b9ae57761436c222a02facc36f260e7b08ed8',
+  'src_internal_revision': '64fabe2c75866b08875218107a8dc334ad0c3ecf',
   # 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': '4c5f736b89157519dcdad75c9801c1af9d765f8f',
+  'skia_revision': '9495576979226fc3eac8acb6b29aaef09ffd9da2',
   # 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': 'ccf65c8be1900e218b8df6aba22268449525d836',
+  'angle_revision': '963be02fe0408707d8e2fcc30e294e1f361a0611',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -300,7 +300,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling BoringSSL
   # and whatever else without interference from each other.
-  'boringssl_revision': '470d9b07dd07353b7b0880f5b843f489ca24330e',
+  'boringssl_revision': '57f525e425a95e7c89fa2df926fa93273bd47311',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling Fuchsia sdk
   # and whatever else without interference from each other.
@@ -348,7 +348,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling catapult
   # and whatever else without interference from each other.
-  'catapult_revision': '350ba7c712c9e1af86954eea7db34d2a6fad294c',
+  'catapult_revision': '40c51c5d3e7e1a69ebc277adb03c78d0058151b2',
   # 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.
@@ -356,7 +356,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
-  'crossbench_revision': '93a7369e66a419ceede2a0124d95d42243533832',
+  'crossbench_revision': '4c647135c01c82af0907269c326346cc24f334e3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libFuzzer
   # 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': '3c18d9b9ab9158565e4378e9899f66b020030b63',
+  'devtools_frontend_revision': '2e1b6ce3712118681e7919265bf9fe135dd77d6b',
   # 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.
@@ -396,7 +396,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'bb1dbd8ad562999d1e142b519d49075ae9bc0253',
+  'dawn_revision': '67e21d0f9ae8c7e2db7ba7bb3d8b89687714e2a8',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # 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':    'ab2f32b66014843f072d32d72c560b7dd229c0f3',
+  'llvm_libc_revision':    'de6fc6ccb31619c9ba67ba849d4572835229f270',
 
   # If you change this, also update the libc++ revision in
   # //buildtools/deps_revisions.gni.
@@ -1304,7 +1304,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '6c91b3d63c04c2c5907dd772e25f5bdfc70c771f',
+    '60af337f9ae927559294f121715cdc1155a86c66',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -1313,7 +1313,7 @@
   },
 
   'src/ios/third_party/earl_grey2/src': {
-      'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '56144f8685227fc7f7af1ea2152d816d372d1d0a',
+      'url': Var('chromium_git') + '/external/github.com/google/EarlGrey.git' + '@' + '598d8e856bc259d9632cd26e944d46d721c43071',
       'condition': 'checkout_ios',
   },
 
@@ -1769,7 +1769,7 @@
   # Tools used when building Chrome for Chrome OS. This affects both the Simple
   # Chrome workflow, as well as the chromeos-chrome ebuild.
   'src/third_party/chromite': {
-      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '825cf77f9079c0f6882fc45913e471b1407d6ef8',
+      'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'd8cadf19e5362d8d204ff96dcda6644dedbe9029',
       'condition': 'checkout_chromeos',
   },
 
@@ -1799,13 +1799,13 @@
 
 
   'src/third_party/depot_tools':
-    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'c30219e4a720a4f91f66983fdb11c5a665da63ac',
+    Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '25fede45b3488984d27555820e823644697e748e',
 
   'src/third_party/devtools-frontend/src':
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '2534d7deee0d3f46def3299aced0f4866ac978de',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'b6bd78d495c40d4370348a7c9f4c5b9351f1dde7',
     'condition': 'checkout_src_internal',
   },
 
@@ -2080,7 +2080,7 @@
     Var('chromium_git') + '/external/libaddressinput.git' + '@' + 'e8712e415627f22d0b00ebee8db99547077f39bd',
 
   'src/third_party/libaom/source/libaom':
-    Var('aomedia_git') + '/aom.git' + '@' +  'ff9badefdf0f98f758ec22fc5bf3816ebdeafd61',
+    Var('aomedia_git') + '/aom.git' + '@' +  '0063380307ea8f388d24ddf824724418a8f2237d',
 
   'src/third_party/libavif/src':
     Var('chromium_git') + '/external/github.com/AOMediaCodec/libavif.git' + '@' + Var('libavif_revision'),
@@ -2306,7 +2306,7 @@
     Var('pdfium_git') + '/pdfium.git' + '@' +  Var('pdfium_revision'),
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b4c1dfa24715ef5600fd068b646447707cb9ee08',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + 'b5c4a751ca8d5736accf47a9cdfc1a58ff2ef814',
 
   'src/base/tracing/test/data': {
     'bucket': 'perfetto',
@@ -2668,13 +2668,13 @@
     Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '450cceb587613ac1469c5a131fac15935c99e0e7',
 
   'src/third_party/webgpu-cts/src':
-    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '3ed497b59345978f8460b5e375e7cd18f3b98872',
+    Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '58d51090746647c523ddda207a5ecd5cc3cc1d58',
 
   'src/third_party/webpagereplay':
     Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'),
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '8d5b344b05e2415be08d31a21c09f89c1d220741',
+    Var('webrtc_git') + '/src.git' + '@' + 'a2c84a713ff9bda1add0c1c1f7a03983fe110b15',
 
   # 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.
@@ -2789,7 +2789,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/eche_app/app',
-        'version': 'imGKQfWCx3GCPyTyEAT0PWmDgK1sZjiTf7vtfjDZy_4C',
+        'version': 'qZm-7Wud-fUyBPomEkj7og51mxBNC6y4LN1irXirYgAC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4224,7 +4224,7 @@
 
   'src/chrome/app/theme/google_chrome': {
       'url': Var('chrome_git') + '/chrome/theme/google_chrome.git' + '@' +
-        '50ebc6a7fdc7a9e2b65119d5e4f7e866e265eb70',
+        '1d807d1b5ffc29e13e3c05260ce8a44401e3582d',
       'condition': 'checkout_src_internal',
   },
 
@@ -4414,7 +4414,7 @@
 
   'src/components/optimization_guide/internal': {
       'url': Var('chrome_git') + '/chrome/components/optimization_guide.git' + '@' +
-        '5953b2f79e0d2274f7f053f9d5ce8956a09ccfd5',
+        '4381a0f78e891579dc1e0353486886b1fc2b59e0',
       'condition': 'checkout_src_internal',
   },
 
@@ -4480,7 +4480,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        '3f2de6eed730e6f96f37636ea84815c933f28496',
+        'd844ad608bd4f17d8d82a66fd63bc1e83939e366',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
index 961dad6d..6f24f529 100644
--- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
+++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -206,6 +206,12 @@
         Flag.baseFeature(
                 NetFeatures.OPTIMIZE_PARSING_DATA_URLS, "Enables optimizing parsing data: URLs."),
         Flag.baseFeature(
+                NetFeatures.SIMDUTF_BASE64_SUPPORT,
+                "Use the simdutf library to base64 decode data: URLs."),
+        Flag.baseFeature(
+                NetFeatures.FURTHER_OPTIMIZE_PARSING_DATA_URLS,
+                "Further optimize parsing data: URLs."),
+        Flag.baseFeature(
                 AwFeatures.WEBVIEW_EXTRA_HEADERS_SAME_ORIGIN_ONLY,
                 "Only allow extra headers added via loadUrl() to be sent to the same origin "
                         + "as the original request."),
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc
index d3a9629e..5ab8006 100644
--- a/ash/capture_mode/capture_mode_session.cc
+++ b/ash/capture_mode/capture_mode_session.cc
@@ -745,6 +745,7 @@
   // cursor.
   const bool is_event_on_action_button =
       action_container_widget_ &&
+      action_container_widget_->GetLayer()->GetTargetOpacity() &&
       action_container_widget_->GetWindowBoundsInScreen().Contains(
           location_in_screen);
   if (is_event_on_action_button) {
@@ -756,6 +757,7 @@
   // cursor.
   const bool is_event_on_feedback_button =
       feedback_button_widget_ &&
+      feedback_button_widget_->GetLayer()->GetTargetOpacity() &&
       feedback_button_widget_->GetWindowBoundsInScreen().Contains(
           location_in_screen);
   if (is_event_on_feedback_button) {
@@ -940,9 +942,9 @@
   }
 
   for (const auto& pair : widget_opacity_map) {
-    ui::Layer* layer = pair.first->GetLayer();
+    views::Widget* widget = pair.first;
     const float& opacity = pair.second;
-    capture_mode_util::AnimateToOpacity(layer, opacity);
+    capture_mode_util::AnimateToOpacity(widget, opacity);
   }
 }
 
@@ -995,6 +997,7 @@
   layer()->SchedulePaint(layer()->bounds());
   UpdateCaptureLabelWidget(CaptureLabelAnimation::kNone);
   UpdateActionContainerWidget();
+  UpdateFeedbackButtonWidget();
   UpdateCursor(display::Screen::GetScreen()->GetCursorScreenPoint(),
                /*is_touch=*/false);
 
@@ -1013,6 +1016,7 @@
   MaybeUpdateSelfieCamInSessionVisibility();
   UpdateCaptureLabelWidget(CaptureLabelAnimation::kNone);
   UpdateActionContainerWidget();
+  UpdateFeedbackButtonWidget();
   UpdateCursor(display::Screen::GetScreen()->GetCursorScreenPoint(),
                /*is_touch=*/false);
 
@@ -3385,7 +3389,10 @@
 }
 
 void CaptureModeSession::UpdateFeedbackButtonWidget() {
-  if (!IsSunfishAllowedAndEnabled()) {
+  if (ShouldHideFeedbackWidget(feedback_button_widget_.get())) {
+    if (feedback_button_widget_ && feedback_button_widget_->IsVisible()) {
+      feedback_button_widget_->Hide();
+    }
     return;
   }
 
@@ -3403,8 +3410,8 @@
                                 base::Unretained(this)),
             u"Send Feedback", PillButton::Type::kDefaultWithIconLeading,
             &kFeedbackIcon));
-    feedback_button_widget_->ShowInactive();
   }
+  feedback_button_widget_->ShowInactive();
 
   // TODO(hewer): Determine the behavior/appearance of the feedback button and
   // search results panel to avoid overlap.
@@ -3426,6 +3433,10 @@
     return false;
   }
 
+  if (!IsSunfishAllowedAndEnabled()) {
+    return true;
+  }
+
   // If drag for capture region is in progress, the feedback button should be
   // hidden.
   if (is_drag_in_progress_) {
diff --git a/ash/capture_mode/capture_mode_session.h b/ash/capture_mode/capture_mode_session.h
index 3e9b77f..922282a7 100644
--- a/ash/capture_mode/capture_mode_session.h
+++ b/ash/capture_mode/capture_mode_session.h
@@ -470,8 +470,8 @@
   // finishes executing.
   void OnScannerActionExecuted(bool success);
 
-  // Creates the feedback button widget if it wasn't previously created, and
-  // updates the widget's bounds.
+  // Creates the feedback button widget if it wasn't previously created and
+  // should be shown, and updates the widget's bounds and visibility.
   void UpdateFeedbackButtonWidget();
 
   // Returns true if `widget` is the `feedback_button_widget_` and we should
diff --git a/ash/capture_mode/capture_mode_util.cc b/ash/capture_mode/capture_mode_util.cc
index 47ddcb5d..d6fda536 100644
--- a/ash/capture_mode/capture_mode_util.cc
+++ b/ash/capture_mode/capture_mode_util.cc
@@ -606,13 +606,21 @@
   }
 }
 
-void AnimateToOpacity(ui::Layer* layer,
+void AnimateToOpacity(views::Widget* widget,
                       const float opacity,
                       const base::TimeDelta duration) {
+  ui::Layer* layer = widget->GetLayer();
   if (layer->GetTargetOpacity() == opacity) {
     return;
   }
 
+  // If the target opacity is 0.f, disable events on the widget.
+  const bool visible = opacity != 0.f;
+  widget->GetContentsView()->SetCanProcessEventsWithinSubtree(visible);
+  widget->GetNativeWindow()->SetEventTargetingPolicy(
+      visible ? aura::EventTargetingPolicy::kTargetAndDescendants
+              : aura::EventTargetingPolicy::kNone);
+
   views::AnimationBuilder()
       .SetPreemptionStrategy(
           ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET)
diff --git a/ash/capture_mode/capture_mode_util.h b/ash/capture_mode/capture_mode_util.h
index 1ee8f0e..dfb1c08 100644
--- a/ash/capture_mode/capture_mode_util.h
+++ b/ash/capture_mode/capture_mode_util.h
@@ -252,7 +252,7 @@
                                 ActionButtonViewID id);
 
 ASH_EXPORT void AnimateToOpacity(
-    ui::Layer* layer,
+    views::Widget* widget,
     const float opacity,
     const base::TimeDelta duration =
         capture_mode::kCaptureUIOpacityChangeDuration);
diff --git a/ash/capture_mode/sunfish_unittest.cc b/ash/capture_mode/sunfish_unittest.cc
index 563df8a..65b125f 100644
--- a/ash/capture_mode/sunfish_unittest.cc
+++ b/ash/capture_mode/sunfish_unittest.cc
@@ -47,6 +47,7 @@
 #include "ash/shell.h"
 #include "ash/style/icon_button.h"
 #include "ash/style/pill_button.h"
+#include "ash/style/tab_slider_button.h"
 #include "ash/system/toast/anchored_nudge_manager_impl.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test/ash_test_util.h"
@@ -1000,43 +1001,67 @@
   // Start default mode. Test the buttons are hidden.
   auto* controller =
       StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kImage);
-  ASSERT_TRUE(controller->IsActive());
+  VerifyActiveBehavior(BehaviorType::kDefault);
   auto* session =
       static_cast<CaptureModeSession*>(controller->capture_mode_session());
   CaptureModeSessionTestApi session_test_api(session);
   ASSERT_FALSE(session_test_api.GetActionContainerWidget());
 
-  // Select a region and wait for the buttons to show up.
+  // Select a region large enough that the video capture button will not
+  // intersect with where the search action button previously was and wait for
+  // the buttons to show up.
   auto* generator = GetEventGenerator();
-  SelectCaptureModeRegion(generator, gfx::Rect(10, 10, 40, 40),
+  SelectCaptureModeRegion(generator, gfx::Rect(10, 10, 200, 200),
                           /*release_mouse=*/true, /*verify_region=*/true);
   auto* container_widget = session_test_api.GetActionContainerWidget();
   ASSERT_TRUE(container_widget->IsVisible());
   ASSERT_EQ(session_test_api.GetActionButtons().size(), 1u);
-  EXPECT_TRUE(
-      session_test_api.GetButtonWithViewID(ActionButtonViewID::kSearchButton));
+  auto* search_button =
+      session_test_api.GetButtonWithViewID(ActionButtonViewID::kSearchButton);
+  gfx::Rect search_button_bounds(search_button->GetBoundsInScreen());
 
   // Set the type to `kVideo`. Test the buttons are hidden.
   controller->SetType(CaptureModeType::kVideo);
   EXPECT_FALSE(container_widget->IsVisible());
   EXPECT_EQ(session_test_api.GetActionButtons().size(), 0u);
+  auto* label_view = session_test_api.GetCaptureLabelView();
+  ASSERT_TRUE(label_view->IsRecordingTypeDropDownButtonVisible());
+  const gfx::Rect capture_button_bounds(label_view->capture_button_container()
+                                            ->capture_button()
+                                            ->GetBoundsInScreen());
+  ASSERT_FALSE(capture_button_bounds.Intersects(search_button_bounds));
+  auto* cursor_manager = Shell::Get()->cursor_manager();
+
+  // Hover over where the search button was previously shown.
+  generator->MoveMouseTo(search_button_bounds.CenterPoint());
+  EXPECT_EQ(ui::mojom::CursorType::kCell, cursor_manager->GetCursor().type());
 
   // Switch back to `kImage` then select a region.
   controller->SetType(CaptureModeType::kImage);
-  SelectCaptureModeRegion(generator, gfx::Rect(100, 100, 50, 50),
+  CaptureModeTestApi().SetUserSelectedRegion(gfx::Rect());
+  SelectCaptureModeRegion(generator, gfx::Rect(10, 10, 200, 200),
                           /*release_mouse=*/true, /*verify_region=*/true);
   EXPECT_TRUE(container_widget->IsVisible());
   EXPECT_EQ(session_test_api.GetActionButtons().size(), 1u);
-  EXPECT_TRUE(
-      session_test_api.GetButtonWithViewID(ActionButtonViewID::kSearchButton));
+  search_button =
+      session_test_api.GetButtonWithViewID(ActionButtonViewID::kSearchButton);
+  ASSERT_TRUE(search_button);
+  EXPECT_TRUE(search_button->GetVisible());
+  search_button_bounds = search_button->GetBoundsInScreen();
 
   // Set the source to `kFullscreen`. Test the buttons are hidden.
   controller->SetSource(CaptureModeSource::kFullscreen);
   EXPECT_FALSE(container_widget->IsVisible());
   EXPECT_EQ(session_test_api.GetActionButtons().size(), 0u);
+  EXPECT_EQ(ui::mojom::CursorType::kCustom, cursor_manager->GetCursor().type());
+
+  // Hover over where the search button was previously shown.
+  generator->MoveMouseTo(search_button_bounds.CenterPoint());
+  EXPECT_EQ(ui::mojom::CursorType::kCustom, cursor_manager->GetCursor().type());
 
   // Switch back to `kRegion` then select a region.
   controller->SetSource(CaptureModeSource::kRegion);
+  CaptureModeTestApi().SetUserSelectedRegion(gfx::Rect());
   SelectCaptureModeRegion(generator, gfx::Rect(10, 10, 50, 50),
                           /*release_mouse=*/true, /*verify_region=*/true);
   EXPECT_TRUE(container_widget->IsVisible());
@@ -1053,6 +1078,48 @@
   // image region.
 }
 
+TEST_F(SunfishTest, HideFeedbackButtonOnSourceTypeChange) {
+  // Start default image region capture mode.
+  auto* controller =
+      StartCaptureSession(CaptureModeSource::kRegion, CaptureModeType::kImage);
+  CaptureModeSessionTestApi session_test_api(
+      controller->capture_mode_session());
+  views::Widget* feedback_button_widget =
+      session_test_api.GetFeedbackButtonWidget();
+  ASSERT_TRUE(feedback_button_widget);
+  EXPECT_EQ(1.f, feedback_button_widget->GetLayer()->GetTargetOpacity());
+
+  // Simulate clicking the video toggle button to change the type.
+  LeftClickOn(GetVideoToggleButton());
+  ASSERT_EQ(CaptureModeType::kVideo, controller->type());
+
+  // Test the feedback button is hidden and hovering over it does not update the
+  // cursor.
+  ASSERT_TRUE(feedback_button_widget);
+  EXPECT_FALSE(feedback_button_widget->IsVisible());
+  EXPECT_EQ(0.f, feedback_button_widget->GetLayer()->GetTargetOpacity());
+
+  auto* generator = GetEventGenerator();
+  generator->MoveMouseTo(
+      feedback_button_widget->GetWindowBoundsInScreen().CenterPoint());
+  auto* cursor_manager = Shell::Get()->cursor_manager();
+  EXPECT_EQ(ui::mojom::CursorType::kCell, cursor_manager->GetCursor().type());
+
+  // Switch back to image region capture.
+  LeftClickOn(GetImageToggleButton());
+  ASSERT_EQ(CaptureModeType::kImage, controller->type());
+
+  // Test the feedback button is re-shown and hovering over it updates the
+  // cursor.
+  ASSERT_TRUE(feedback_button_widget);
+  EXPECT_TRUE(feedback_button_widget->IsVisible());
+  EXPECT_EQ(1.f, feedback_button_widget->GetLayer()->GetTargetOpacity());
+
+  generator->MoveMouseTo(
+      feedback_button_widget->GetWindowBoundsInScreen().CenterPoint());
+  EXPECT_EQ(ui::mojom::CursorType::kHand, cursor_manager->GetCursor().type());
+}
+
 // Tests that the search button is re-shown on region selected or adjusted in
 // default mode.
 TEST_F(SunfishTest, ShowSearchButtonOnRegionAdjusted) {
diff --git a/ash/components/arc/DEPS b/ash/components/arc/DEPS
index 0308db8..0bbe492 100644
--- a/ash/components/arc/DEPS
+++ b/ash/components/arc/DEPS
@@ -11,6 +11,7 @@
   "+components/user_manager",
   "+components/user_prefs",
   "+content/public/browser",
+  "+mojo/core",
   "+storage/browser/file_system",
 ]
 
diff --git a/ash/components/arc/midis/arc_midis_bridge.cc b/ash/components/arc/midis/arc_midis_bridge.cc
index f621b17..3a92bb8 100644
--- a/ash/components/arc/midis/arc_midis_bridge.cc
+++ b/ash/components/arc/midis/arc_midis_bridge.cc
@@ -11,6 +11,7 @@
 #include "base/functional/bind.h"
 #include "base/memory/singleton.h"
 #include "chromeos/ash/components/dbus/arc/arc_midis_client.h"
+#include "mojo/core/configuration.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/system/invitation.h"
@@ -91,6 +92,9 @@
   mojo::PlatformChannel channel;
   mojo::ScopedMessagePipeHandle server_pipe =
       invitation.AttachMessagePipe("arc-midis-pipe");
+  if (!mojo::core::GetConfiguration().is_broker_process) {
+    invitation.set_extra_flags(MOJO_SEND_INVITATION_FLAG_SHARE_BROKER);
+  }
   mojo::OutgoingInvitation::Send(std::move(invitation),
                                  base::kNullProcessHandle,
                                  channel.TakeLocalEndpoint());
diff --git a/ash/constants/ash_switches.cc b/ash/constants/ash_switches.cc
index 863d159..84225629 100644
--- a/ash/constants/ash_switches.cc
+++ b/ash/constants/ash_switches.cc
@@ -507,9 +507,6 @@
 // Enables ARCVM realtime VCPU feature.
 const char kEnableArcVmRtVcpu[] = "enable-arcvm-rt-vcpu";
 
-// Adds ash-browser back to launcher, even if in LacrosOnly mode.
-const char kEnableAshDebugBrowser[] = "enable-ash-debug-browser";
-
 // Used to override `kDisableBirchWeatherApiForTesting` for specific tast tests.
 const char kEnableBirchWeatherApiForTestingOverride[] =
     "enable-birch-weather-api-for-testing-override";
@@ -1221,11 +1218,6 @@
       kOobeShowAccessibilityButtonOnMarketingOptInForTesting);
 }
 
-bool IsAshDebugBrowserEnabled() {
-  return base::CommandLine::ForCurrentProcess()->HasSwitch(
-      kEnableAshDebugBrowser);
-}
-
 bool IsTabletFormFactor() {
   return base::CommandLine::ForCurrentProcess()->HasSwitch(
       kEnableTabletFormFactor);
diff --git a/ash/constants/ash_switches.h b/ash/constants/ash_switches.h
index 50190539..63e51d1 100644
--- a/ash/constants/ash_switches.h
+++ b/ash/constants/ash_switches.h
@@ -156,7 +156,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kEnableArcVm[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kEnableArcVmDlc[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kEnableArcVmRtVcpu[];
-COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kEnableAshDebugBrowser[];
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const char kEnableBirchWeatherApiForTestingOverride[];
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kEnableCastReceiver[];
@@ -422,9 +421,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 bool ShouldShowAccessibilityButtonOnMarketingOptInForTesting();
 
-// Returns true if ash-debug browser is enabled.
-COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAshDebugBrowserEnabled();
-
 // Returns true if the device is of tablet form factor.
 COMPONENT_EXPORT(ASH_CONSTANTS) bool IsTabletFormFactor();
 
diff --git a/base/third_party/icu/README.chromium b/base/third_party/icu/README.chromium
index 691795d..1eabd82 100644
--- a/base/third_party/icu/README.chromium
+++ b/base/third_party/icu/README.chromium
@@ -1,7 +1,7 @@
 Name: ICU
 URL: http://site.icu-project.org/
 Version: 60
-License: Unicode
+License: Unicode-DFS-2016, ICU
 License File: LICENSE
 Security Critical: yes
 Shipped: no
diff --git a/base/tracing/protos/chrome_track_event.proto b/base/tracing/protos/chrome_track_event.proto
index 8c48802..56315a2 100644
--- a/base/tracing/protos/chrome_track_event.proto
+++ b/base/tracing/protos/chrome_track_event.proto
@@ -383,6 +383,29 @@
   repeated DebugAnnotation debug_annotations = 99;
 }
 
+// Describes the CrossOriginIsolated state of a page. See the definition of
+// WebExposedIsolationInfo for more information.
+message WebExposedIsolationInfo {
+  optional bool is_isolated = 1;
+  optional string origin = 2;
+  optional bool is_isolated_application = 3;
+}
+
+// Contains the URL and some additional information necessary to pick a
+// SiteInstance and process during a navigation. See the definition of UrlInfo
+// for more information about individual fields.
+message UrlInfo {
+  optional string url = 1;
+  optional string origin = 2;
+  optional bool is_sandboxed = 3;
+  optional bool is_pdf = 4;
+  optional bool is_coop_isolation_requested = 5;
+  optional int32 origin_isolation_request = 6;
+  optional bool is_prefetch_with_cross_site_contamination = 7;
+  optional WebExposedIsolationInfo web_exposed_isolation_info = 8;
+  optional string storage_partition_config = 9;
+}
+
 // Next ID: 7
 message RenderViewHost {
   // The RenderViewHostMapId for the RenderViewHost.
@@ -2450,5 +2473,9 @@
         android_choreographer_frame_callback_data = 1070;
 
     optional CurrentTask current_task = 1071;
+
+    optional WebExposedIsolationInfo web_exposed_isolation_info = 1072;
+
+    optional UrlInfo url_info = 1073;
   }
 }
diff --git a/build/config/siso/android.star b/build/config/siso/android.star
index 40d5fd3..6951d36 100644
--- a/build/config/siso/android.star
+++ b/build/config/siso/android.star
@@ -9,6 +9,18 @@
 load("@builtin//struct.star", "module")
 load("./config.star", "config")
 
+# TODO: crbug.com/323091468 - Propagate target android ABI and
+# android SDK version from GN, and remove the hardcoded filegroups.
+__archs = [
+    "aarch64-linux-android",
+    "arm-linux-androideabi",
+    "i686-linux-android",
+    "riscv64-linux-android",
+    "x86_64-linux-android",
+]
+
+__versions = list(range(21, 34))
+
 def __enabled(ctx):
     if "args.gn" in ctx.metadata:
         gn_args = gn.args(ctx)
@@ -17,7 +29,15 @@
     return False
 
 def __filegroups(ctx):
-    return {}
+    fg = {}
+    for arch in __archs:
+        for ver in __versions:
+            group = "third_party/android_toolchain/ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/%s/%d:link" % (arch, ver)
+            fg[group] = {
+                "type": "glob",
+                "includes": ["*"],
+            }
+    return fg
 
 def __step_config(ctx, step_config):
     remote_run = True  # Turn this to False when you do file access trace.
@@ -429,6 +449,7 @@
 android = module(
     "android",
     enabled = __enabled,
+    archs = __archs,
     step_config = __step_config,
     filegroups = __filegroups,
     handlers = __handlers,
diff --git a/build/config/siso/clang_linux.star b/build/config/siso/clang_linux.star
index 5dc3ebf6..42825f1 100644
--- a/build/config/siso/clang_linux.star
+++ b/build/config/siso/clang_linux.star
@@ -4,29 +4,13 @@
 # found in the LICENSE file.
 """Siso configuration for clang/linux."""
 
-load("@builtin//path.star", "path")
 load("@builtin//struct.star", "module")
 load("./android.star", "android")
-load("./ar.star", "ar")
 load("./clang_all.star", "clang_all")
-load("./clang_code_coverage_wrapper.star", "clang_code_coverage_wrapper")
-load("./config.star", "config")
+load("./clang_unix.star", "clang_unix")
 load("./fuchsia.star", "fuchsia")
-load("./gn_logs.star", "gn_logs")
 load("./win_sdk.star", "win_sdk")
 
-# TODO: b/323091468 - Propagate target android ABI and android SDK version
-# from GN, and remove the hardcoded filegroups.
-android_archs = [
-    "aarch64-linux-android",
-    "arm-linux-androideabi",
-    "i686-linux-android",
-    "riscv64-linux-android",
-    "x86_64-linux-android",
-]
-
-android_versions = list(range(21, 35))
-
 def __filegroups(ctx):
     fg = {
         # for precomputed subtrees
@@ -133,93 +117,14 @@
         },
     }
     if android.enabled(ctx):
-        for arch in android_archs:
-            for ver in android_versions:
-                group = "third_party/android_toolchain/ndk/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/%s/%d:link" % (arch, ver)
-                fg[group] = {
-                    "type": "glob",
-                    "includes": ["*"],
-                }
+        fg.update(android.filegroups(ctx))
     if fuchsia.enabled(ctx):
         fg.update(fuchsia.filegroups(ctx))
     fg.update(clang_all.filegroups(ctx))
     return fg
 
-def __clang_compile_coverage(ctx, cmd):
-    clang_command = clang_code_coverage_wrapper.run(ctx, list(cmd.args))
-    ctx.actions.fix(args = clang_command)
-
-def __clang_alink(ctx, cmd):
-    # check command line to see "-T" and "-S".
-    # rm -f obj/third_party/angle/libangle_common.a && "../../third_party/llvm-build/Release+Asserts/bin/llvm-ar" -T -S -r -c -D obj/third_party/angle/libangle_common.a @"obj/third_party/angle/libangle_common.a.rsp"
-    if not ("-T" in cmd.args[-1] and "-S" in cmd.args[-1]):
-        print("not thin archive without symbol table")
-        return
-
-    # create thin archive without symbol table by handler.
-    rspfile_content = str(cmd.rspfile_content)
-    inputs = []
-    for fname in rspfile_content.split(" "):
-        inputs.append(ctx.fs.canonpath(fname))
-    data = ar.create(ctx, path.dir(cmd.outputs[0]), inputs)
-    ctx.actions.write(cmd.outputs[0], data)
-    ctx.actions.exit(exit_status = 0)
-
-def __clang_link(ctx, cmd):
-    inputs = []
-    sysroot = ""
-    target = ""
-    args = cmd.args
-    if args[0] == "/bin/sh":
-        args = args[2].split(" ")
-    for i, arg in enumerate(args):
-        if i == 1:
-            driver = ctx.fs.canonpath(arg)  # driver script
-            if ctx.fs.exists(driver):
-                inputs.append(driver + ":link")
-            continue
-        if arg.startswith("--sysroot="):
-            sysroot = arg.removeprefix("--sysroot=")
-            sysroot = ctx.fs.canonpath(sysroot)
-            inputs.append(sysroot + ":link")
-        elif arg == "-isysroot":
-            sysroot = ctx.fs.canonpath(args[i + 1])
-            inputs.append(sysroot + ":link")
-        elif arg.startswith("--target="):
-            target = arg.removeprefix("--target=")
-        elif arg.startswith("-L"):
-            lib_path = ctx.fs.canonpath(arg.removeprefix("-L"))
-            inputs.append(lib_path + ":link")
-        elif arg.startswith("-Wl,-exported_symbols_list,"):
-            export_path = ctx.fs.canonpath(arg.removeprefix("-Wl,-exported_symbols_list,"))
-            inputs.append(export_path)
-        elif arg == "-sectcreate":
-            # -sectcreate <arg1> <arg2> <arg3>
-            inputs.append(ctx.fs.canonpath(args[i + 3]))
-        elif arg.startswith("-Wcrl,"):
-            crls = arg.removeprefix("-Wcrl,").split(",")
-            crl = ctx.fs.canonpath(crls[1])
-            if ctx.fs.exists(crl):
-                inputs.append(crl + ":link")
-        elif arg == "--":
-            clang_base = ctx.fs.canonpath(path.dir(path.dir(cmd.args[i + 1])))
-            inputs.append(clang_base + ":link")
-
-    for arch in android_archs:
-        if target.startswith(arch):
-            android_ver = target.removeprefix(arch)
-            inputs.extend([
-                sysroot + "/usr/lib/" + arch + "/" + android_ver + ":link",
-            ])
-            break
-
-    ctx.actions.fix(inputs = cmd.inputs + inputs)
-
-__handlers = {
-    "clang_compile_coverage": __clang_compile_coverage,
-    "clang_alink": __clang_alink,
-    "clang_link": __clang_link,
-}
+__handlers = {}
+__handlers.update(clang_unix.handlers)
 
 def __step_config(ctx, step_config):
     step_config["input_deps"].update({
@@ -276,153 +181,8 @@
     })
     step_config["input_deps"].update(clang_all.input_deps)
 
-    input_root_absolute_path = gn_logs.read(ctx).get("clang_need_input_root_absolute_path") == "true"
-    canonicalize_dir = not input_root_absolute_path
-
-    step_config["rules"].extend([
-        {
-            "name": "clang/cxx",
-            "action": "(.*_)?cxx",
-            "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang++ ",
-            "inputs": [
-                "third_party/llvm-build/Release+Asserts/bin/clang++",
-            ],
-            "remote": True,
-            "input_root_absolute_path": input_root_absolute_path,
-            "canonicalize_dir": canonicalize_dir,
-            "timeout": "2m",
-        },
-        {
-            "name": "clang/cc",
-            "action": "(.*_)?cc",
-            "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang ",
-            "inputs": [
-                "third_party/llvm-build/Release+Asserts/bin/clang",
-            ],
-            "remote": True,
-            "input_root_absolute_path": input_root_absolute_path,
-            "canonicalize_dir": canonicalize_dir,
-            "timeout": "2m",
-        },
-        {
-            "name": "clang/asm",
-            "action": "(.*_)?asm",
-            "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang",
-            "inputs": [
-                "third_party/llvm-build/Release+Asserts/bin/clang",
-            ],
-            "remote": config.get(ctx, "cog"),
-            "input_root_absolute_path": input_root_absolute_path,
-            "canonicalize_dir": canonicalize_dir,
-            "timeout": "2m",
-        },
-        {
-            "name": "clang-coverage/cxx",
-            "action": "(.*_)?cxx",
-            "command_prefix": "\"python3\" ../../build/toolchain/clang_code_coverage_wrapper.py",
-            "inputs": [
-                "third_party/llvm-build/Release+Asserts/bin/clang++",
-            ],
-            "handler": "clang_compile_coverage",
-            "remote": True,
-            "input_root_absolute_path": input_root_absolute_path,
-            "canonicalize_dir": canonicalize_dir,
-            "timeout": "2m",
-        },
-        {
-            "name": "clang-coverage/cc",
-            "action": "(.*_)?cc",
-            "command_prefix": "\"python3\" ../../build/toolchain/clang_code_coverage_wrapper.py",
-            "inputs": [
-                "third_party/llvm-build/Release+Asserts/bin/clang",
-            ],
-            "handler": "clang_compile_coverage",
-            "remote": True,
-            "input_root_absolute_path": input_root_absolute_path,
-            "canonicalize_dir": canonicalize_dir,
-            "timeout": "2m",
-        },
-        {
-            "name": "clang/alink/llvm-ar",
-            "action": "(.*_)?alink",
-            "inputs": [
-                # TODO: b/316267242 - Add inputs to GN config.
-                "third_party/llvm-build/Release+Asserts/bin/llvm-ar",
-            ],
-            "exclude_input_patterns": [
-                "*.cc",
-                "*.h",
-                "*.js",
-                "*.pak",
-                "*.py",
-            ],
-            "handler": "clang_alink",
-            "remote": config.get(ctx, "remote-link"),
-            "canonicalize_dir": True,
-            "timeout": "2m",
-            "platform_ref": "large",
-            "accumulate": True,
-        },
-        {
-            "name": "clang/solink",
-            "action": "(.*_)?solink",
-            "handler": "clang_link",
-            "exclude_input_patterns": [
-                "*.cc",
-                "*.h",
-                "*.js",
-                "*.pak",
-                "*.py",
-            ],
-            "remote": config.get(ctx, "remote-link"),
-            "canonicalize_dir": True,
-            "platform_ref": "large",
-            "timeout": "2m",
-        },
-        {
-            "name": "clang/link",
-            "action": "(.*_)?link",
-            "handler": "clang_link",
-            "exclude_input_patterns": [
-                "*.cc",
-                "*.h",
-                "*.js",
-                "*.pak",
-                "*.py",
-            ],
-            "remote": config.get(ctx, "remote-link"),
-            "canonicalize_dir": True,
-            "platform_ref": "large",
-            "timeout": "10m",
-        },
-    ])
+    step_config["rules"].extend(clang_unix.rules(ctx))
     if win_sdk.enabled(ctx):
-        step_config["rules"].extend([
-            {
-                "name": "clang-cl/cxx",
-                "action": "(.*_)?cxx",
-                "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang-cl ",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang-cl",
-                ],
-                "remote": True,
-                "input_root_absolute_path": input_root_absolute_path,
-                "canonicalize_dir": canonicalize_dir,
-                "timeout": "2m",
-            },
-            {
-                "name": "clang-cl/cc",
-                "action": "(.*_)?cc",
-                "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang-cl ",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang-cl",
-                ],
-                "remote": True,
-                "input_root_absolute_path": input_root_absolute_path,
-                "canonicalize_dir": canonicalize_dir,
-                "timeout": "2m",
-            },
-        ])
         win_sdk.step_config(ctx, step_config)
     return step_config
 
diff --git a/build/config/siso/clang_mac.star b/build/config/siso/clang_mac.star
index 2b5106a..c1836a24 100644
--- a/build/config/siso/clang_mac.star
+++ b/build/config/siso/clang_mac.star
@@ -8,7 +8,7 @@
 load("@builtin//path.star", "path")
 load("@builtin//struct.star", "module")
 load("./clang_all.star", "clang_all")
-load("./clang_code_coverage_wrapper.star", "clang_code_coverage_wrapper")
+load("./clang_unix.star", "clang_unix")
 load("./config.star", "config")
 load("./gn_logs.star", "gn_logs")
 load("./mac_sdk.star", "mac_sdk")
@@ -20,13 +20,8 @@
     fg.update(clang_all.filegroups(ctx))
     return fg
 
-def __clang_compile_coverage(ctx, cmd):
-    clang_command = clang_code_coverage_wrapper.run(ctx, list(cmd.args))
-    ctx.actions.fix(args = clang_command)
-
-__handlers = {
-    "clang_compile_coverage": __clang_compile_coverage,
-}
+__handlers = {}
+__handlers.update(clang_unix.handlers)
 
 def __step_config(ctx, step_config):
     cfg = "buildtools/reclient_cfgs/chromium-browser-clang/rewrapper_mac.cfg"
@@ -44,131 +39,16 @@
         })
         step_config["input_deps"].update(clang_all.input_deps)
 
-        gn_logs_data = gn_logs.read(ctx)
-        input_root_absolute_path = gn_logs_data.get("clang_need_input_root_absolute_path") == "true"
-        input_root_absolute_path_for_objc = gn_logs_data.get("clang_need_input_root_absolute_path_for_objc") == "true"
+        clang_rules = clang_unix.rules(ctx)
 
-        canonicalize_dir = not input_root_absolute_path
-        canonicalize_dir_for_objc = not input_root_absolute_path_for_objc
-
-        step_config["rules"].extend([
-            {
-                "name": "clang/cxx",
-                "action": "(.*_)?cxx",
-                "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang++",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang++",
-                ],
-                "platform_ref": "clang",
-                "remote": True,
-                "input_root_absolute_path": input_root_absolute_path,
-                "canonicalize_dir": canonicalize_dir,
-                "remote_wrapper": reproxy_config["remote_wrapper"],
-                "timeout": "2m",
-            },
-            {
-                "name": "clang/cc",
-                "action": "(.*_)?cc",
-                "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang",
-                ],
-                "platform_ref": "clang",
-                "remote": True,
-                "input_root_absolute_path": input_root_absolute_path,
-                "canonicalize_dir": canonicalize_dir,
-                "remote_wrapper": reproxy_config["remote_wrapper"],
-                "timeout": "2m",
-            },
-            {
-                "name": "clang/objcxx",
-                "action": "(.*_)?objcxx",
-                "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang++",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang++",
-                ],
-                "platform_ref": "clang",
-                "remote": True,
-                "remote_wrapper": reproxy_config["remote_wrapper"],
-                "timeout": "2m",
-                "input_root_absolute_path": input_root_absolute_path_for_objc,
-                "canonicalize_dir": canonicalize_dir_for_objc,
-            },
-            {
-                "name": "clang/objc",
-                "action": "(.*_)?objc",
-                "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang",
-                ],
-                "platform_ref": "clang",
-                "remote": True,
-                "remote_wrapper": reproxy_config["remote_wrapper"],
-                "timeout": "2m",
-                "input_root_absolute_path": input_root_absolute_path_for_objc,
-                "canonicalize_dir": canonicalize_dir_for_objc,
-            },
-            {
-                "name": "clang-coverage/cxx",
-                "action": "(.*_)?cxx",
-                "command_prefix": "python3 ../../build/toolchain/clang_code_coverage_wrapper.py",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang++",
-                ],
-                "handler": "clang_compile_coverage",
-                "platform_ref": "clang",
-                "remote": True,
-                "input_root_absolute_path": input_root_absolute_path,
-                "canonicalize_dir": canonicalize_dir,
-                "remote_wrapper": reproxy_config["remote_wrapper"],
-                "timeout": "2m",
-            },
-            {
-                "name": "clang-coverage/cc",
-                "action": "(.*_)?cc",
-                "command_prefix": "python3 ../../build/toolchain/clang_code_coverage_wrapper.py",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang",
-                ],
-                "handler": "clang_compile_coverage",
-                "platform_ref": "clang",
-                "remote": True,
-                "input_root_absolute_path": input_root_absolute_path,
-                "canonicalize_dir": canonicalize_dir,
-                "remote_wrapper": reproxy_config["remote_wrapper"],
-                "timeout": "2m",
-            },
-            {
-                "name": "clang-coverage/objcxx",
-                "action": "(.*_)?objcxx",
-                "command_prefix": "python3 ../../build/toolchain/clang_code_coverage_wrapper.py",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang++",
-                ],
-                "handler": "clang_compile_coverage",
-                "platform_ref": "clang",
-                "remote": True,
-                "remote_wrapper": reproxy_config["remote_wrapper"],
-                "timeout": "2m",
-                "input_root_absolute_path": input_root_absolute_path_for_objc,
-                "canonicalize_dir": canonicalize_dir_for_objc,
-            },
-            {
-                "name": "clang-coverage/objc",
-                "action": "(.*_)?objc",
-                "command_prefix": "python3 ../../build/toolchain/clang_code_coverage_wrapper.py",
-                "inputs": [
-                    "third_party/llvm-build/Release+Asserts/bin/clang",
-                ],
-                "handler": "clang_compile_coverage",
-                "platform_ref": "clang",
-                "remote": True,
-                "remote_wrapper": reproxy_config["remote_wrapper"],
-                "timeout": "2m",
-                "input_root_absolute_path": input_root_absolute_path_for_objc,
-                "canonicalize_dir": canonicalize_dir_for_objc,
-            },
-        ])
+        for rule in clang_rules:
+            if "remote" in rule and rule["remote"]:
+                rule["remote_wrapper"] = reproxy_config["remote_wrapper"]
+                if "platform_ref" not in rule:
+                    rule["platform_ref"] = "clang"
+                elif rule["platform_ref"] == "large":
+                    rule["platform_ref"] = "clang_large"
+            step_config["rules"].append(rule)
     elif gn.args(ctx).get("use_remoteexec") == "true":
         fail("remoteexec requires rewrapper config")
     return step_config
diff --git a/build/config/siso/clang_unix.star b/build/config/siso/clang_unix.star
new file mode 100644
index 0000000..599edf7f
--- /dev/null
+++ b/build/config/siso/clang_unix.star
@@ -0,0 +1,319 @@
+# -*- bazel-starlark -*-
+# 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.
+"""Siso configuration for clang/unix."""
+
+load("@builtin//path.star", "path")
+load("@builtin//struct.star", "module")
+load("./android.star", "android")
+load("./ar.star", "ar")
+load("./clang_code_coverage_wrapper.star", "clang_code_coverage_wrapper")
+load("./config.star", "config")
+load("./gn_logs.star", "gn_logs")
+load("./win_sdk.star", "win_sdk")
+
+def __clang_compile_coverage(ctx, cmd):
+    clang_command = clang_code_coverage_wrapper.run(ctx, list(cmd.args))
+    ctx.actions.fix(args = clang_command)
+
+def __clang_alink(ctx, cmd):
+    if not config.get(ctx, "remote-link"):
+        return
+
+    # check command line to see "-T" and "-S".
+    # rm -f obj/third_party/angle/libangle_common.a && "../../third_party/llvm-build/Release+Asserts/bin/llvm-ar" -T -S -r -c -D obj/third_party/angle/libangle_common.a @"obj/third_party/angle/libangle_common.a.rsp"
+    if not ("-T" in cmd.args[-1] and "-S" in cmd.args[-1]):
+        print("not thin archive without symbol table")
+        return
+
+    # create thin archive without symbol table by handler.
+    rspfile_content = str(cmd.rspfile_content)
+    inputs = []
+    for fname in rspfile_content.split(" "):
+        inputs.append(ctx.fs.canonpath(fname))
+    data = ar.create(ctx, path.dir(cmd.outputs[0]), inputs)
+    ctx.actions.write(cmd.outputs[0], data)
+    ctx.actions.exit(exit_status = 0)
+
+def __clang_link(ctx, cmd):
+    if not config.get(ctx, "remote-link"):
+        return
+    inputs = []
+    sysroot = ""
+    target = ""
+    args = cmd.args
+    if args[0] == "/bin/sh":
+        args = args[2].split(" ")
+    for i, arg in enumerate(args):
+        if i == 1:
+            driver = ctx.fs.canonpath(arg)  # driver script
+            if ctx.fs.exists(driver):
+                inputs.append(driver + ":link")
+            continue
+        if arg.startswith("--sysroot="):
+            sysroot = arg.removeprefix("--sysroot=")
+            sysroot = ctx.fs.canonpath(sysroot)
+            inputs.append(sysroot + ":link")
+        elif arg == "-isysroot":
+            sysroot = ctx.fs.canonpath(args[i + 1])
+            inputs.append(sysroot + ":link")
+        elif arg.startswith("--target="):
+            target = arg.removeprefix("--target=")
+        elif arg.startswith("-L"):
+            lib_path = ctx.fs.canonpath(arg.removeprefix("-L"))
+            inputs.append(lib_path + ":link")
+        elif arg.startswith("-Wl,-exported_symbols_list,"):
+            export_path = ctx.fs.canonpath(arg.removeprefix("-Wl,-exported_symbols_list,"))
+            inputs.append(export_path)
+        elif arg == "-sectcreate":
+            # -sectcreate <arg1> <arg2> <arg3>
+            inputs.append(ctx.fs.canonpath(args[i + 3]))
+        elif arg.startswith("-Wcrl,"):
+            crls = arg.removeprefix("-Wcrl,").split(",")
+            if len(crls) == 2:
+                crl = ctx.fs.canonpath(crls[1])
+                if ctx.fs.exists(crl):
+                    inputs.append(crl + ":link")
+        elif arg == "--":
+            clang_base = ctx.fs.canonpath(path.dir(path.dir(cmd.args[i + 1])))
+            inputs.append(clang_base + ":link")
+
+    for arch in android.archs:
+        if target.startswith(arch):
+            android_ver = target.removeprefix(arch)
+            inputs.extend([
+                sysroot + "/usr/lib/" + arch + "/" + android_ver + ":link",
+            ])
+            break
+
+    ctx.actions.fix(inputs = cmd.inputs + inputs)
+
+__handlers = {
+    "clang_compile_coverage": __clang_compile_coverage,
+    "clang_alink": __clang_alink,
+    "clang_link": __clang_link,
+}
+
+def __rules(ctx):
+    gn_logs_data = gn_logs.read(ctx)
+    input_root_absolute_path = gn_logs_data.get("clang_need_input_root_absolute_path") == "true"
+    input_root_absolute_path_for_objc = gn_logs_data.get("clang_need_input_root_absolute_path_for_objc") == "true"
+
+    canonicalize_dir = not input_root_absolute_path
+    canonicalize_dir_for_objc = not input_root_absolute_path_for_objc
+
+    rules = [
+        {
+            "name": "clang/cxx",
+            "action": "(.*_)?cxx",
+            "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang++ ",
+            "inputs": [
+                "third_party/llvm-build/Release+Asserts/bin/clang++",
+            ],
+            "exclude_input_patterns": ["*.stamp"],
+            "remote": True,
+            "input_root_absolute_path": input_root_absolute_path,
+            "canonicalize_dir": canonicalize_dir,
+            "timeout": "2m",
+        },
+        {
+            "name": "clang/cc",
+            "action": "(.*_)?cc",
+            "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang ",
+            "inputs": [
+                "third_party/llvm-build/Release+Asserts/bin/clang",
+            ],
+            "exclude_input_patterns": ["*.stamp"],
+            "remote": True,
+            "input_root_absolute_path": input_root_absolute_path,
+            "canonicalize_dir": canonicalize_dir,
+            "timeout": "2m",
+        },
+        {
+            "name": "clang/objcxx",
+            "action": "(.*_)?objcxx",
+            "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang++",
+            "inputs": [
+                "third_party/llvm-build/Release+Asserts/bin/clang++",
+            ],
+            "exclude_input_patterns": ["*.stamp"],
+            "remote": True,
+            "timeout": "2m",
+            "input_root_absolute_path": input_root_absolute_path_for_objc,
+            "canonicalize_dir": canonicalize_dir_for_objc,
+        },
+        {
+            "name": "clang/objc",
+            "action": "(.*_)?objc",
+            "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang",
+            "inputs": [
+                "third_party/llvm-build/Release+Asserts/bin/clang",
+            ],
+            "exclude_input_patterns": ["*.stamp"],
+            "remote": True,
+            "timeout": "2m",
+            "input_root_absolute_path": input_root_absolute_path_for_objc,
+            "canonicalize_dir": canonicalize_dir_for_objc,
+        },
+        {
+            "name": "clang/asm",
+            "action": "(.*_)?asm",
+            "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang",
+            "inputs": [
+                "third_party/llvm-build/Release+Asserts/bin/clang",
+            ],
+            "remote": config.get(ctx, "cog"),
+            "input_root_absolute_path": input_root_absolute_path,
+            "canonicalize_dir": canonicalize_dir,
+            "timeout": "2m",
+        },
+        {
+            "name": "clang-coverage/cxx",
+            "action": "(.*_)?cxx",
+            "command_prefix": "\"python3\" ../../build/toolchain/clang_code_coverage_wrapper.py",
+            "inputs": [
+                "third_party/llvm-build/Release+Asserts/bin/clang++",
+            ],
+            "exclude_input_patterns": ["*.stamp"],
+            "handler": "clang_compile_coverage",
+            "remote": True,
+            "input_root_absolute_path": input_root_absolute_path,
+            "canonicalize_dir": canonicalize_dir,
+            "timeout": "2m",
+        },
+        {
+            "name": "clang-coverage/cc",
+            "action": "(.*_)?cc",
+            "command_prefix": "\"python3\" ../../build/toolchain/clang_code_coverage_wrapper.py",
+            "inputs": [
+                "third_party/llvm-build/Release+Asserts/bin/clang",
+            ],
+            "exclude_input_patterns": ["*.stamp"],
+            "handler": "clang_compile_coverage",
+            "remote": True,
+            "input_root_absolute_path": input_root_absolute_path,
+            "canonicalize_dir": canonicalize_dir,
+            "timeout": "2m",
+        },
+        {
+            "name": "clang-coverage/objcxx",
+            "action": "(.*_)?objcxx",
+            "command_prefix": "\"python3\" ../../build/toolchain/clang_code_coverage_wrapper.py",
+            "inputs": [
+                "third_party/llvm-build/Release+Asserts/bin/clang++",
+            ],
+            "exclude_input_patterns": ["*.stamp"],
+            "handler": "clang_compile_coverage",
+            "remote": True,
+            "timeout": "2m",
+            "input_root_absolute_path": input_root_absolute_path_for_objc,
+            "canonicalize_dir": canonicalize_dir_for_objc,
+        },
+        {
+            "name": "clang-coverage/objc",
+            "action": "(.*_)?objc",
+            "command_prefix": "\"python3\" ../../build/toolchain/clang_code_coverage_wrapper.py",
+            "inputs": [
+                "third_party/llvm-build/Release+Asserts/bin/clang",
+            ],
+            "exclude_input_patterns": ["*.stamp"],
+            "handler": "clang_compile_coverage",
+            "remote": True,
+            "timeout": "2m",
+            "input_root_absolute_path": input_root_absolute_path_for_objc,
+            "canonicalize_dir": canonicalize_dir_for_objc,
+        },
+        {
+            "name": "clang/alink/llvm-ar",
+            "action": "(.*_)?alink",
+            "inputs": [
+                # TODO: crbug.com/316267242 - Add inputs to GN config.
+                "third_party/llvm-build/Release+Asserts/bin/llvm-ar",
+            ],
+            "exclude_input_patterns": [
+                "*.cc",
+                "*.h",
+                "*.js",
+                "*.pak",
+                "*.py",
+                "*.stamp",
+            ],
+            "handler": "clang_alink",
+            "remote": config.get(ctx, "remote-link"),
+            "canonicalize_dir": True,
+            "timeout": "2m",
+            "platform_ref": "large",
+            "accumulate": True,
+        },
+        {
+            "name": "clang/solink",
+            "action": "(.*_)?solink",
+            "handler": "clang_link",
+            "exclude_input_patterns": [
+                "*.cc",
+                "*.h",
+                "*.js",
+                "*.pak",
+                "*.py",
+                "*.stamp",
+            ],
+            "remote": config.get(ctx, "remote-link"),
+            "canonicalize_dir": True,
+            "platform_ref": "large",
+            "timeout": "2m",
+        },
+        {
+            "name": "clang/link",
+            "action": "(.*_)?link",
+            "handler": "clang_link",
+            "exclude_input_patterns": [
+                "*.cc",
+                "*.h",
+                "*.js",
+                "*.pak",
+                "*.py",
+                "*.stamp",
+            ],
+            "remote": config.get(ctx, "remote-link"),
+            "canonicalize_dir": True,
+            "platform_ref": "large",
+            "timeout": "10m",
+        },
+    ]
+    if win_sdk.enabled(ctx):
+        rules.extend([
+            {
+                "name": "clang-cl/cxx",
+                "action": "(.*_)?cxx",
+                "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang-cl ",
+                "inputs": [
+                    "third_party/llvm-build/Release+Asserts/bin/clang-cl",
+                ],
+                "exclude_input_patterns": ["*.stamp"],
+                "remote": True,
+                "input_root_absolute_path": input_root_absolute_path,
+                "canonicalize_dir": canonicalize_dir,
+                "timeout": "2m",
+            },
+            {
+                "name": "clang-cl/cc",
+                "action": "(.*_)?cc",
+                "command_prefix": "../../third_party/llvm-build/Release+Asserts/bin/clang-cl ",
+                "inputs": [
+                    "third_party/llvm-build/Release+Asserts/bin/clang-cl",
+                ],
+                "exclude_input_patterns": ["*.stamp"],
+                "remote": True,
+                "input_root_absolute_path": input_root_absolute_path,
+                "canonicalize_dir": canonicalize_dir,
+                "timeout": "2m",
+            },
+        ])
+    return rules
+
+clang_unix = module(
+    "clang_unix",
+    handlers = __handlers,
+    rules = __rules,
+)
diff --git a/build/config/siso/main.star b/build/config/siso/main.star
index f41bad7..e887362 100644
--- a/build/config/siso/main.star
+++ b/build/config/siso/main.star
@@ -42,19 +42,20 @@
         properties["gn_args:" + k] = v
     for k, v in gn_logs.read(ctx).items():
         properties["gn_logs:" + k] = v
+    container_image = "docker://gcr.io/chops-public-images-prod/rbe/siso-chromium/linux@sha256:ef35d347f4a4a2d32b76fd908e66e96f59bf8ba7379fd5626548244c45343b2b"
     step_config = {
         "properties": properties,
         "platforms": {
             "default": {
                 "OSFamily": "Linux",
-                "container-image": "docker://gcr.io/chops-public-images-prod/rbe/siso-chromium/linux@sha256:912808c295e578ccde53b0685bcd0d56c15d7a03e819dcce70694bfe3fdab35e",
+                "container-image": container_image,
                 "label:action_default": "1",
             },
             # Large workers are usually used for Python actions like generate bindings, mojo generators etc
             # They can run on Linux workers.
             "large": {
                 "OSFamily": "Linux",
-                "container-image": "docker://gcr.io/chops-public-images-prod/rbe/siso-chromium/linux@sha256:912808c295e578ccde53b0685bcd0d56c15d7a03e819dcce70694bfe3fdab35e",
+                "container-image": container_image,
                 # As of Jul 2023, the action_large pool uses n2-highmem-8 with 200GB of pd-ssd.
                 # The pool is intended for the following actions.
                 #  - slow actions that can benefit from multi-cores and/or faster disk I/O. e.g. link, mojo, generate bindings etc.
diff --git a/build/toolchain/apple/toolchain.gni b/build/toolchain/apple/toolchain.gni
index 5cf427c..9d8583fb 100644
--- a/build/toolchain/apple/toolchain.gni
+++ b/build/toolchain/apple/toolchain.gni
@@ -200,8 +200,8 @@
                       root_build_dir) + " --files-to-instrument=" +
           rebase_path(toolchain_coverage_instrumentation_input_file,
                       root_build_dir) + " --target-os=" + target_os
-      cc = "$python_path $_coverage_wrapper ${cc}"
-      cxx = "$python_path $_coverage_wrapper ${cxx}"
+      cc = "\"$python_path\" $_coverage_wrapper ${cc}"
+      cxx = "\"$python_path\" $_coverage_wrapper ${cxx}"
     }
 
     linker_driver_env = "TOOL_VERSION=${tool_versions.linker_driver}"
diff --git a/buildtools/reclient_cfgs/nacl/rewrapper_linux.cfg b/buildtools/reclient_cfgs/nacl/rewrapper_linux.cfg
index f469025..0a0771d 100644
--- a/buildtools/reclient_cfgs/nacl/rewrapper_linux.cfg
+++ b/buildtools/reclient_cfgs/nacl/rewrapper_linux.cfg
@@ -1,5 +1,5 @@
 # use the same platform container image as build/config/siso/main.star
-platform=container-image=docker://gcr.io/chops-public-images-prod/rbe/siso-chromium/linux@sha256:912808c295e578ccde53b0685bcd0d56c15d7a03e819dcce70694bfe3fdab35e,label:action_default=1
+platform=container-image=docker://gcr.io/chops-public-images-prod/rbe/siso-chromium/linux@sha256:ef35d347f4a4a2d32b76fd908e66e96f59bf8ba7379fd5626548244c45343b2b,label:action_default=1
 server_address=unix:///tmp/reproxy.sock
 labels=type=compile,compiler=nacl,lang=cpp
 exec_strategy=racing
diff --git a/chrome/app/theme/chrome_unscaled_resources.grd b/chrome/app/theme/chrome_unscaled_resources.grd
index e09e345d..20c1829 100644
--- a/chrome/app/theme/chrome_unscaled_resources.grd
+++ b/chrome/app/theme/chrome_unscaled_resources.grd
@@ -101,8 +101,6 @@
       <if expr="chromeos_ash">
         <include name="IDR_CHROME_APP_ICON_32" file="${branding_path_component}/chromeos/chrome_app_icon_32.png" type="BINDATA" />
         <include name="IDR_CHROME_APP_ICON_192" file="${branding_path_component}/chromeos/chrome_app_icon_192.png" type="BINDATA" />
-        <include name="IDR_DEBUG_CHROME_APP_ICON_32" file="${branding_path_component}/chromeos/debug_chrome_app_icon_32.png" type="BINDATA" />
-        <include name="IDR_DEBUG_CHROME_APP_ICON_192" file="${branding_path_component}/chromeos/debug_chrome_app_icon_192.png" type="BINDATA" />
         <include name="IDR_WEBSTORE_APP_ICON_16" file="${branding_path_component}/chromeos/webstore_app_icon_16.png" type="BINDATA" />
         <include name="IDR_WEBSTORE_APP_ICON_128" file="${branding_path_component}/chromeos/webstore_app_icon_128.png" type="BINDATA" />
       </if>
diff --git a/chrome/app/theme/chromium/chromeos/debug_chrome_app_icon_192.png b/chrome/app/theme/chromium/chromeos/debug_chrome_app_icon_192.png
deleted file mode 100644
index 8b5db773..0000000
--- a/chrome/app/theme/chromium/chromeos/debug_chrome_app_icon_192.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/chromium/chromeos/debug_chrome_app_icon_32.png b/chrome/app/theme/chromium/chromeos/debug_chrome_app_icon_32.png
deleted file mode 100644
index 70867113..0000000
--- a/chrome/app/theme/chromium/chromeos/debug_chrome_app_icon_32.png
+++ /dev/null
Binary files differ
diff --git a/chrome/app/theme/google_chrome b/chrome/app/theme/google_chrome
index 50ebc6a..1d807d1 160000
--- a/chrome/app/theme/google_chrome
+++ b/chrome/app/theme/google_chrome
@@ -1 +1 @@
-Subproject commit 50ebc6a7fdc7a9e2b65119d5e4f7e866e265eb70
+Subproject commit 1d807d1b5ffc29e13e3c05260ce8a44401e3582d
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index 2a19fb6..edf75cd8 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -1023,27 +1023,10 @@
 
 const char kLacrosAvailabilityIgnoreInternalName[] =
     "lacros-availability-ignore";
-const char kLacrosStabilityInternalName[] = "lacros-stability";
 const char kLacrosWaylandLoggingInternalName[] = "lacros-wayland-logging";
 const char kArcEnableVirtioBlkForDataInternalName[] =
     "arc-enable-virtio-blk-for-data";
 
-const FeatureEntry::Choice kLacrosStabilityChoices[] = {
-    {flags_ui::kGenericExperimentChoiceDefault, "", ""},
-    {ash::standalone_browser::kLacrosStabilityChannelCanary,
-     ash::standalone_browser::kLacrosStabilitySwitch,
-     ash::standalone_browser::kLacrosStabilityChannelCanary},
-    {ash::standalone_browser::kLacrosStabilityChannelDev,
-     ash::standalone_browser::kLacrosStabilitySwitch,
-     ash::standalone_browser::kLacrosStabilityChannelDev},
-    {ash::standalone_browser::kLacrosStabilityChannelBeta,
-     ash::standalone_browser::kLacrosStabilitySwitch,
-     ash::standalone_browser::kLacrosStabilityChannelBeta},
-    {ash::standalone_browser::kLacrosStabilityChannelStable,
-     ash::standalone_browser::kLacrosStabilitySwitch,
-     ash::standalone_browser::kLacrosStabilityChannelStable},
-};
-
 const char kLacrosSelectionInternalName[] = "lacros-selection";
 const char kProjectorServerSideSpeechRecognition[] =
     "enable-projector-server-side-speech-recognition";
@@ -4834,9 +4817,6 @@
     {ash::standalone_browser::kLacrosAvailabilityPolicyInternalName, "", "",
      kOsCrOS, MULTI_VALUE_TYPE(kLacrosAvailabilityPolicyChoices)},
     // Used to carry the policy value crossing the Chrome process lifetime.
-    {kLacrosStabilityInternalName, flag_descriptions::kLacrosStabilityName,
-     flag_descriptions::kLacrosStabilityDescription, kOsCrOS,
-     MULTI_VALUE_TYPE(kLacrosStabilityChoices)},
     {kLacrosWaylandLoggingInternalName,
      flag_descriptions::kLacrosWaylandLoggingName,
      flag_descriptions::kLacrosWaylandLoggingDescription, kOsCrOS,
@@ -11965,10 +11945,6 @@
         ash::switches::kArcEnableAttestation);
   }
 
-  if (!strcmp(kLacrosStabilityInternalName, entry.internal_name)) {
-    return !crosapi::browser_util::IsLacrosAllowedToBeEnabled();
-  }
-
   if (!strcmp(kArcEnableVirtioBlkForDataInternalName, entry.internal_name)) {
     return !arc::IsArcVmEnabled();
   }
diff --git a/chrome/browser/accessibility/accessibility_state_utils.cc b/chrome/browser/accessibility/accessibility_state_utils.cc
index d8d3793..21b32e9 100644
--- a/chrome/browser/accessibility/accessibility_state_utils.cc
+++ b/chrome/browser/accessibility/accessibility_state_utils.cc
@@ -33,8 +33,8 @@
   return AccessibilityManager::Get() &&
          AccessibilityManager::Get()->IsSpokenFeedbackEnabled();
 #else
-  // TODO(katie): Can we use AXMode in Chrome OS as well? May need to stop
-  // Switch Access and Select-to-Speak from setting kScreenReader.
+  // TODO(crbug.com/383057958): Consider updating this to return true only when
+  // an actual screen reader is enabled.
   ui::AXMode mode =
       content::BrowserAccessibilityState::GetInstance()->GetAccessibilityMode();
   return mode.has_mode(ui::AXMode::kScreenReader);
diff --git a/chrome/browser/accessibility/accessibility_state_utils.h b/chrome/browser/accessibility/accessibility_state_utils.h
index 2297eb3..f09e9fd 100644
--- a/chrome/browser/accessibility/accessibility_state_utils.h
+++ b/chrome/browser/accessibility/accessibility_state_utils.h
@@ -7,7 +7,10 @@
 
 namespace accessibility_state_utils {
 
-// Returns true if a screen reader is enabled on any platform.
+// On ChromeOS returns true if the screen reader is enabled.
+// On other platforms returns true if screen reader mode is enabled, which can
+// be true if any functionality that needs screen reader compatibility is
+// enabled.
 bool IsScreenReaderEnabled();
 
 // Overrides |IsScreenReaderEnabled| for testing.
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc b/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
index dc061b5..f0cb68d 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
@@ -35,12 +35,6 @@
                                      : IDR_ARC_SUPPORT_ICON_192_PNG;
   }
 
-  if (ash::switches::IsAshDebugBrowserEnabled() &&
-      id == app_constants::kChromeAppId) {
-    return UseSmallIcon(size_in_dip) ? IDR_DEBUG_CHROME_APP_ICON_32
-                                     : IDR_DEBUG_CHROME_APP_ICON_192;
-  }
-
   return icon_key.resource_id;
 }
 
diff --git a/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc b/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc
index f465816..b8cb36b 100644
--- a/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc
+++ b/chrome/browser/apps/app_service/app_icon/web_app_icon_unittest.cc
@@ -55,7 +55,6 @@
 #include "chrome/browser/ash/arc/icon_decode_request.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/grit/chrome_unscaled_resources.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "components/services/app_service/public/cpp/icon_loader.h"
 #include "components/services/app_service/public/cpp/icon_types.h"
 #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
diff --git a/chrome/browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc b/chrome/browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc
index bd7653a..593f36a 100644
--- a/chrome/browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc
+++ b/chrome/browser/apps/app_service/metrics/app_platform_metrics_service_unittest.cc
@@ -45,7 +45,6 @@
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/test/base/test_browser_window_aura.h"
 #include "chrome/test/base/testing_profile.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "chromeos/components/mgs/managed_guest_session_test_utils.h"
 #include "chromeos/dbus/power/fake_power_manager_client.h"
 #include "chromeos/dbus/power_manager/idle.pb.h"
diff --git a/chrome/browser/ash/app_list/app_list_client_impl_browsertest.cc b/chrome/browser/ash/app_list/app_list_client_impl_browsertest.cc
index 658c513c..7c2c605 100644
--- a/chrome/browser/ash/app_list/app_list_client_impl_browsertest.cc
+++ b/chrome/browser/ash/app_list/app_list_client_impl_browsertest.cc
@@ -89,7 +89,6 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/ash/components/browser_context_helper/browser_context_helper.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "components/account_id/account_id.h"
 #include "components/app_constants/constants.h"
 #include "components/browser_sync/browser_sync_switches.h"
diff --git a/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc b/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc
index 2438539..24fca48 100644
--- a/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc
+++ b/chrome/browser/ash/app_mode/startup_app_launcher_unittest.cc
@@ -59,7 +59,6 @@
 #include "chrome/test/base/testing_profile_manager.h"
 #include "chromeos/ash/components/login/login_state/login_state.h"
 #include "chromeos/ash/components/settings/cros_settings_names.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "chromeos/ash/components/standalone_browser/standalone_browser_features.h"
 #include "chromeos/crosapi/mojom/chrome_app_kiosk_service.mojom-forward.h"
 #include "chromeos/crosapi/mojom/chrome_app_kiosk_service.mojom-shared.h"
diff --git a/chrome/browser/ash/arc/auth/BUILD.gn b/chrome/browser/ash/arc/auth/BUILD.gn
index 3f76596..17ca67e 100644
--- a/chrome/browser/ash/arc/auth/BUILD.gn
+++ b/chrome/browser/ash/arc/auth/BUILD.gn
@@ -76,7 +76,6 @@
     "//chrome/browser/ui/ash/multi_user",
     "//chrome/test:test_support",
     "//chromeos/ash/components/cryptohome",
-    "//chromeos/ash/components/standalone_browser",
     "//components/account_id",
     "//components/policy/core/common",
     "//components/prefs",
diff --git a/chrome/browser/ash/arc/auth/arc_auth_service_browsertest.cc b/chrome/browser/ash/arc/auth/arc_auth_service_browsertest.cc
index df288c0b..297ce99 100644
--- a/chrome/browser/ash/arc/auth/arc_auth_service_browsertest.cc
+++ b/chrome/browser/ash/arc/auth/arc_auth_service_browsertest.cc
@@ -64,8 +64,6 @@
 #include "chrome/test/base/in_process_browser_test.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/cryptohome/cryptohome_parameters.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
-#include "chromeos/ash/components/standalone_browser/standalone_browser_features.h"
 #include "components/account_id/account_id.h"
 #include "components/account_manager_core/chromeos/account_manager_facade_factory.h"
 #include "components/policy/core/common/cloud/device_management_service.h"
@@ -298,15 +296,6 @@
   // InProcessBrowserTest:
   ~ArcAuthServiceTest() override = default;
 
-  void SetUp() override {
-    std::vector<base::test::FeatureRef> lacros =
-        ash::standalone_browser::GetFeatureRefs();
-    lacros.push_back(
-        ash::standalone_browser::features::kLacrosForSupervisedUsers);
-    feature_list_.InitWithFeatures({}, lacros);
-    InProcessBrowserTest::SetUp();
-  }
-
   void SetUpCommandLine(base::CommandLine* command_line) override {
     arc::SetArcAvailableCommandLineForTesting(command_line);
   }
@@ -585,7 +574,6 @@
   std::unique_ptr<base::RunLoop> run_loop_;
   std::unique_ptr<AccountAppsAvailabilitySetter> arc_availability_setter_;
   std::unique_ptr<TestSettingsWindowManager> settings_window_manager_;
-  base::test::ScopedFeatureList feature_list_;
   base::test::ScopedCommandLine scoped_command_line_;
 
   // Not owned.
diff --git a/chrome/browser/ash/arc/keymaster/DEPS b/chrome/browser/ash/arc/keymaster/DEPS
index 84917428..0753d5c 100644
--- a/chrome/browser/ash/arc/keymaster/DEPS
+++ b/chrome/browser/ash/arc/keymaster/DEPS
@@ -17,5 +17,5 @@
   "+chrome/services/keymaster/public/mojom",
 
   # Dependencies outside of //chrome:
-  "+mojo/core/embedder",
+  "+mojo/core",
 ]
diff --git a/chrome/browser/ash/arc/keymaster/arc_keymaster_bridge.cc b/chrome/browser/ash/arc/keymaster/arc_keymaster_bridge.cc
index 1f56599..752843ad2 100644
--- a/chrome/browser/ash/arc/keymaster/arc_keymaster_bridge.cc
+++ b/chrome/browser/ash/arc/keymaster/arc_keymaster_bridge.cc
@@ -14,6 +14,7 @@
 #include "base/memory/singleton.h"
 #include "base/process/process_handle.h"
 #include "chromeos/ash/components/dbus/arc/arc_keymaster_client.h"
+#include "mojo/core/configuration.h"
 #include "mojo/core/embedder/embedder.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
@@ -141,6 +142,9 @@
     std::move(callback).Run(false);
     return;
   }
+  if (!mojo::core::GetConfiguration().is_broker_process) {
+    invitation.set_extra_flags(MOJO_SEND_INVITATION_FLAG_SHARE_BROKER);
+  }
 
   // Bootstrap cert_store channel attached to the same invitation.
   cert_store_bridge_->BindToInvitation(&invitation);
diff --git a/chrome/browser/ash/arc/keymint/DEPS b/chrome/browser/ash/arc/keymint/DEPS
index 642a4984..8db2afb60 100644
--- a/chrome/browser/ash/arc/keymint/DEPS
+++ b/chrome/browser/ash/arc/keymint/DEPS
@@ -16,4 +16,7 @@
   # directory basis. See //tools/chromeos/gen_deps.sh for details.
   "+chrome/services/keymint/public/mojom",
   "+chrome/test/base",
+
+  # Dependencies outside of //chrome:
+  "+mojo/core",
 ]
diff --git a/chrome/browser/ash/arc/keymint/arc_keymint_bridge.cc b/chrome/browser/ash/arc/keymint/arc_keymint_bridge.cc
index 7a1f9bc..04830d8 100644
--- a/chrome/browser/ash/arc/keymint/arc_keymint_bridge.cc
+++ b/chrome/browser/ash/arc/keymint/arc_keymint_bridge.cc
@@ -9,6 +9,7 @@
 #include "base/memory/singleton.h"
 #include "chrome/browser/ash/arc/keymint/cert_store_bridge_keymint.h"
 #include "chromeos/ash/components/dbus/arc/arc_keymint_client.h"
+#include "mojo/core/configuration.h"
 #include "mojo/core/embedder/embedder.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 
@@ -177,6 +178,9 @@
     std::move(callback).Run(false);
     return;
   }
+  if (!mojo::core::GetConfiguration().is_broker_process) {
+    invitation.set_extra_flags(MOJO_SEND_INVITATION_FLAG_SHARE_BROKER);
+  }
 
   // Bootstrap cert_store channel attached to the same invitation.
   cert_store_bridge_->BindToInvitation(&invitation);
diff --git a/chrome/browser/ash/crosapi/BUILD.gn b/chrome/browser/ash/crosapi/BUILD.gn
index 35d1a27..d91d4ed 100644
--- a/chrome/browser/ash/crosapi/BUILD.gn
+++ b/chrome/browser/ash/crosapi/BUILD.gn
@@ -595,7 +595,6 @@
     "//chrome/browser/ui/webui/ash/app_install",
     "//chrome/test:test_support",
     "//chromeos/ash/components/dbus/shill",
-    "//chromeos/ash/components/standalone_browser:test_support",
     "//chromeos/crosapi/mojom",
     "//components/component_updater/ash",
     "//printing",
@@ -702,7 +701,6 @@
     "//chromeos/ash/components/disks:test_support",
     "//chromeos/ash/components/login/login_state",
     "//chromeos/ash/components/standalone_browser",
-    "//chromeos/ash/components/standalone_browser:test_support",
     "//chromeos/ash/components/system",
     "//chromeos/crosapi/cpp:cpp",
     "//chromeos/crosapi/cpp:crosapi_constants",
diff --git a/chrome/browser/ash/crosapi/browser_loader_unittest.cc b/chrome/browser/ash/crosapi/browser_loader_unittest.cc
index 0a6d3c255..e6bf022 100644
--- a/chrome/browser/ash/crosapi/browser_loader_unittest.cc
+++ b/chrome/browser/ash/crosapi/browser_loader_unittest.cc
@@ -21,7 +21,6 @@
 #include "base/version.h"
 #include "chrome/browser/ash/crosapi/lacros_selection_loader.h"
 #include "chrome/browser/ash/crosapi/lacros_selection_loader_factory.h"
-#include "chromeos/ash/components/standalone_browser/browser_support.h"
 #include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 #include "components/component_updater/ash/component_manager_ash.h"
 #include "components/policy/core/common/policy_map.h"
@@ -29,8 +28,6 @@
 #include "content/public/test/browser_task_environment.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
-using ash::standalone_browser::BrowserSupport;
-
 namespace crosapi {
 namespace {
 
diff --git a/chrome/browser/ash/crosapi/browser_manager.cc b/chrome/browser/ash/crosapi/browser_manager.cc
index b7cb46a..2861c85f 100644
--- a/chrome/browser/ash/crosapi/browser_manager.cc
+++ b/chrome/browser/ash/crosapi/browser_manager.cc
@@ -72,7 +72,6 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
 #include "chromeos/ash/components/browser_context_helper/browser_context_helper.h"
-#include "chromeos/ash/components/standalone_browser/browser_support.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"
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc
index e1c3f2b6..22e3531 100644
--- a/chrome/browser/ash/crosapi/browser_util.cc
+++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -30,7 +30,6 @@
 #include "chrome/common/chrome_features.h"
 #include "chrome/common/chrome_paths.h"
 #include "chromeos/ash/components/channel/channel_info.h"
-#include "chromeos/ash/components/standalone_browser/browser_support.h"
 #include "chromeos/ash/components/standalone_browser/lacros_availability.h"
 #include "chromeos/ash/components/standalone_browser/standalone_browser_features.h"
 #include "chromeos/crosapi/cpp/crosapi_constants.h"
@@ -121,18 +120,6 @@
   return base_path.Append("lacros");
 }
 
-bool IsLacrosAllowedToBeEnabled() {
-  if (!ash::standalone_browser::BrowserSupport::IsInitializedForPrimaryUser()) {
-    // This function must be called only after user session starts.
-    base::debug::DumpWithoutCrashing();
-    // Returning false for compatibility.
-    // TODO(crbug.com/40286020): replace this logic by CHECK/DCHECK.
-    return false;
-  }
-  return ash::standalone_browser::BrowserSupport::GetForPrimaryUser()
-      ->IsAllowed();
-}
-
 bool IsLacrosEnabled() {
   return false;
 }
@@ -141,26 +128,6 @@
   return true;
 }
 
-bool IsLacrosOnlyBrowserAllowed() {
-  if (!ash::standalone_browser::BrowserSupport::IsInitializedForPrimaryUser()) {
-    // This function must be called only after user session starts.
-    base::debug::DumpWithoutCrashing();
-    // Returning false for compatibility.
-    // TODO(crbug.com/40286020): replace this logic by CHECK/DCHECK.
-    return false;
-  }
-  return ash::standalone_browser::BrowserSupport::GetForPrimaryUser()
-      ->IsAllowed();
-}
-
-bool IsLacrosOnlyFlagAllowed() {
-  return IsLacrosOnlyBrowserAllowed() &&
-         // Hide lacros_only flag for guest sessions as they do always start
-         // with a fresh and anonymous profile, hence ignoring this setting.
-         !UserManager::Get()->IsLoggedInAsGuest() &&
-         (GetCachedLacrosAvailability() == LacrosAvailability::kUserChoice);
-}
-
 bool IsLacrosChromeAppsEnabled() {
   return false;
 }
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h
index 2f0c7c9..44854ef 100644
--- a/chrome/browser/ash/crosapi/browser_util.h
+++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -79,10 +79,6 @@
 // Returns the user directory for lacros-chrome.
 base::FilePath GetUserDataDir();
 
-// Returns true if the Lacros feature is allowed to be enabled for primary user.
-// This checks user type, chrome channel and enterprise policy.
-bool IsLacrosAllowedToBeEnabled();
-
 // Returns true if the Lacros feature is enabled for the primary user.
 bool IsLacrosEnabled();
 
@@ -91,16 +87,6 @@
 // DEPRECATED. Please use !IsLacrosEnabled().
 bool IsAshWebBrowserEnabled();
 
-// Returns true if Lacros can be used as the only browser
-// for the current session.
-// Note that IsLacrosEnabled may return false, even if this returns
-// true, specifically, if the feature is disabled by user/policy.
-bool IsLacrosOnlyBrowserAllowed();
-
-// Returns true if `ash::standalone_browser::features::kLacrosOnly` flag is
-// allowed to be configured on about:flags page.
-bool IsLacrosOnlyFlagAllowed();
-
 // Returns true if chrome apps should be routed through Lacros instead of ash.
 bool IsLacrosChromeAppsEnabled();
 
diff --git a/chrome/browser/ash/crosapi/browser_util_unittest.cc b/chrome/browser/ash/crosapi/browser_util_unittest.cc
index d5b1f726..fd4e5c0 100644
--- a/chrome/browser/ash/crosapi/browser_util_unittest.cc
+++ b/chrome/browser/ash/crosapi/browser_util_unittest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/test/base/scoped_testing_local_state.h"
 #include "chrome/test/base/testing_browser_process.h"
-#include "chromeos/ash/components/standalone_browser/browser_support.h"
 #include "chromeos/ash/components/standalone_browser/lacros_availability.h"
 #include "chromeos/ash/components/standalone_browser/lacros_selection.h"
 #include "chromeos/ash/components/standalone_browser/standalone_browser_features.h"
@@ -54,7 +53,6 @@
       const ScopedLacrosAvailabilityCache&) = delete;
   ~ScopedLacrosAvailabilityCache() {
     browser_util::ClearLacrosAvailabilityCacheForTest();
-    ash::standalone_browser::BrowserSupport::Shutdown();
   }
 
  private:
@@ -66,12 +64,6 @@
         base::Value(GetLacrosAvailabilityPolicyName(lacros_availability)),
         /*external_data_fetcher=*/nullptr);
     browser_util::CacheLacrosAvailability(policy);
-    if (ash::standalone_browser::BrowserSupport::
-            IsInitializedForPrimaryUser()) {
-      ash::standalone_browser::BrowserSupport::Shutdown();
-    }
-    ash::standalone_browser::BrowserSupport::InitializeForPrimaryUser(
-        policy, false, false);
   }
 };
 
@@ -87,13 +79,7 @@
   }
 
   void TearDown() override {
-    if (ash::standalone_browser::BrowserSupport::
-            IsInitializedForPrimaryUser()) {
-      ash::standalone_browser::BrowserSupport::Shutdown();
-    }
     fake_user_manager_.Reset();
-    ash::standalone_browser::BrowserSupport::SetCpuSupportedForTesting(
-        std::nullopt);
   }
 
   const user_manager::User* AddRegularUser(const std::string& email,
@@ -106,8 +92,6 @@
       fake_user_manager_->UserLoggedIn(account_id, user->username_hash(),
                                        /*browser_restart=*/false,
                                        /*is_child=*/false);
-      ash::standalone_browser::BrowserSupport::InitializeForPrimaryUser(
-          policy::PolicyMap(), false, false);
     }
     return user;
   }
@@ -139,11 +123,6 @@
   EXPECT_TRUE(browser_util::IsAshWebBrowserEnabled());
 }
 
-TEST_F(BrowserUtilTest, LacrosOnlyBrowserAllowed) {
-  AddRegularUser("user@test.com");
-  EXPECT_TRUE(browser_util::IsLacrosOnlyBrowserAllowed());
-}
-
 TEST_F(BrowserUtilTest, MetadataMissing) {
   EXPECT_FALSE(browser_util::DoesMetadataSupportNewAccountManager(nullptr));
 }
@@ -315,28 +294,6 @@
   }
 }
 
-// Lacros availability has no effect on non-googlers
-TEST_F(BrowserUtilTest, LacrosAvailabilityIgnoreNonGoogle) {
-  AddRegularUser("user@random.com");
-
-  base::test::ScopedCommandLine cmd_line;
-  cmd_line.GetProcessCommandLine()->AppendSwitch(
-      ash::switches::kLacrosAvailabilityIgnore);
-  ScopedLacrosAvailabilityCache cache(LacrosAvailability::kLacrosDisallowed);
-  EXPECT_FALSE(browser_util::IsLacrosAllowedToBeEnabled());
-}
-
-// Lacros availability has an effect on googlers
-TEST_F(BrowserUtilTest, LacrosAvailabilityIgnoreGoogleDisableToUserChoice) {
-  AddRegularUser("user@google.com");
-
-  base::test::ScopedCommandLine cmd_line;
-  cmd_line.GetProcessCommandLine()->AppendSwitch(
-      ash::switches::kLacrosAvailabilityIgnore);
-  ScopedLacrosAvailabilityCache cache(LacrosAvailability::kLacrosDisallowed);
-  EXPECT_TRUE(browser_util::IsLacrosAllowedToBeEnabled());
-}
-
 // Lacros availability has an effect on googlers
 TEST_F(BrowserUtilTest, LacrosAvailabilityIgnoreGoogleEnableToUserChoice) {
   AddRegularUser("user@google.com");
@@ -345,7 +302,6 @@
   cmd_line.GetProcessCommandLine()->AppendSwitch(
       ash::switches::kLacrosAvailabilityIgnore);
   ScopedLacrosAvailabilityCache cache(LacrosAvailability::kLacrosOnly);
-  EXPECT_TRUE(browser_util::IsLacrosAllowedToBeEnabled());
   EXPECT_FALSE(browser_util::IsLacrosEnabled());
 }
 
diff --git a/chrome/browser/ash/crosapi/stateful_lacros_loader_unittest.cc b/chrome/browser/ash/crosapi/stateful_lacros_loader_unittest.cc
index 16e7b80..1b6800b 100644
--- a/chrome/browser/ash/crosapi/stateful_lacros_loader_unittest.cc
+++ b/chrome/browser/ash/crosapi/stateful_lacros_loader_unittest.cc
@@ -21,7 +21,6 @@
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/component_updater/cros_component_installer_chromeos.h"
 #include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
-#include "chromeos/ash/components/standalone_browser/browser_support.h"
 #include "components/component_updater/ash/fake_component_manager_ash.h"
 #include "components/component_updater/component_updater_paths.h"
 #include "components/component_updater/mock_component_updater_service.h"
diff --git a/chrome/browser/ash/growth/campaigns_manager_session.cc b/chrome/browser/ash/growth/campaigns_manager_session.cc
index 781fdd5..928c0ed2 100644
--- a/chrome/browser/ash/growth/campaigns_manager_session.cc
+++ b/chrome/browser/ash/growth/campaigns_manager_session.cc
@@ -97,9 +97,7 @@
 }
 
 bool IsWebBrowserAppId(std::string_view app_id) {
-  return app_id == app_constants::kChromeAppId ||
-         app_id == app_constants::kAshDebugBrowserAppId ||
-         app_id == app_constants::kLacrosAppId;
+  return app_id == app_constants::kChromeAppId;
 }
 
 bool IsAppVisible(const apps::InstanceUpdate& update) {
@@ -444,7 +442,6 @@
 
   switch (app_type.value()) {
     case apps::AppType::kUnknown:
-      // e.g Ash debug browser.
       break;
     case apps::AppType::kChromeApp:
       HandleWebBrowserInstanceUpdate(update);
diff --git a/chrome/browser/ash/growth/campaigns_manager_session.h b/chrome/browser/ash/growth/campaigns_manager_session.h
index d186418..a247afe 100644
--- a/chrome/browser/ash/growth/campaigns_manager_session.h
+++ b/chrome/browser/ash/growth/campaigns_manager_session.h
@@ -77,9 +77,9 @@
   // Handles Arc instance update.
   void HandleArcInstanceUpdate(const apps::InstanceUpdate& update);
 
-  // Handles Chrome browser and Lacros browser instance update. It caches
-  // current web browser context but defers campaign trigger to
-  // PrimaryPageChanged when page navigations happens.
+  // Handles Chrome browser instance update. It caches current web browser
+  // context but defers campaign trigger to PrimaryPageChanged when page
+  // navigations happens.
   void HandleWebBrowserInstanceUpdate(const apps::InstanceUpdate& update);
 
   // Handles Pwa or Swa instance update.
diff --git a/chrome/browser/ash/input_method/editor_switch_unittest.cc b/chrome/browser/ash/input_method/editor_switch_unittest.cc
index 5d2cb89..7e09fd3 100644
--- a/chrome/browser/ash/input_method/editor_switch_unittest.cc
+++ b/chrome/browser/ash/input_method/editor_switch_unittest.cc
@@ -19,7 +19,6 @@
 #include "chrome/test/base/testing_browser_process.h"
 #include "chrome/test/base/testing_profile.h"
 #include "chrome/test/base/testing_profile_manager.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "chromeos/ui/base/app_types.h"
 #include "chromeos/ui/base/window_properties.h"
diff --git a/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc b/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc
index 8526e60..c4e45a5 100644
--- a/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc
+++ b/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc
@@ -60,7 +60,6 @@
 #include "chrome/test/base/testing_profile_manager.h"
 #include "chromeos/ash/components/install_attributes/stub_install_attributes.h"
 #include "chromeos/ash/components/network/network_handler.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "chromeos/ash/components/standalone_browser/standalone_browser_features.h"
 #include "components/account_id/account_id.h"
 #include "components/crash/core/common/crash_key.h"
diff --git a/chrome/browser/ash/login/screens/sync_consent_browsertest.cc b/chrome/browser/ash/login/screens/sync_consent_browsertest.cc
index b73e8459..b716d8f 100644
--- a/chrome/browser/ash/login/screens/sync_consent_browsertest.cc
+++ b/chrome/browser/ash/login/screens/sync_consent_browsertest.cc
@@ -42,7 +42,6 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/test/base/testing_profile_manager.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "components/prefs/pref_service.h"
 #include "components/signin/public/base/consent_level.h"
 #include "components/signin/public/identity_manager/account_capabilities_test_mutator.h"
diff --git a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
index a69c7cf..2c96700c 100644
--- a/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
+++ b/chrome/browser/banners/app_banner_manager_desktop_browsertest.cc
@@ -35,7 +35,6 @@
 #include "chrome/browser/web_applications/web_app_provider.h"
 #include "chrome/common/chrome_features.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "components/password_manager/content/common/web_ui_constants.h"
 #include "components/password_manager/core/common/password_manager_features.h"
 #include "components/webapps/browser/banners/app_banner_metrics.h"
@@ -53,18 +52,6 @@
 
 namespace webapps {
 
-namespace {
-
-std::vector<base::test::FeatureRef> GetDisabledFeatures() {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  return ash::standalone_browser::GetFeatureRefs();
-#else
-  return {};
-#endif
-}
-
-}  // namespace
-
 using State = AppBannerManager::State;
 
 class AppBannerManagerDesktopBrowserTest
@@ -75,7 +62,6 @@
             AppBannerSettingsHelper::ScopeTotalEngagementForTesting(0)) {}
 
   void SetUp() override {
-    scoped_feature_list_.InitWithFeatures({}, GetDisabledFeatures());
     TestAppBannerManagerDesktop::SetUp();
     AppBannerManagerBrowserTestBase::SetUp();
   }
@@ -96,7 +82,6 @@
       const AppBannerManagerDesktopBrowserTest&) = delete;
 
  protected:
-  base::test::ScopedFeatureList scoped_feature_list_;
   // Scope engagement needed to trigger banners instantly.
   base::AutoReset<double> total_engagement_;
 };
@@ -475,8 +460,6 @@
     : public AppBannerManagerDesktopBrowserTest {
  public:
   void SetUp() override {
-    scoped_feature_list_.InitWithFeatures(
-        /*enabled_features=*/{}, GetDisabledFeatures());
     TestAppBannerManagerDesktop::SetUp();
     AppBannerManagerBrowserTestBase::SetUp();
   }
diff --git a/chrome/browser/extensions/chrome_component_extension_resource_manager.cc b/chrome/browser/extensions/chrome_component_extension_resource_manager.cc
index 30712d6..c863c64 100644
--- a/chrome/browser/extensions/chrome_component_extension_resource_manager.cc
+++ b/chrome/browser/extensions/chrome_component_extension_resource_manager.cc
@@ -98,9 +98,6 @@
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS)
-    // These icons may be replaced with "IDR_DEBUG_CHROME_APP_ICON_{32,192}"
-    // in "chrome/browser/apps/app_service/app_icon/app_icon_reader.cc"
-    // or "chrome/browser/ui/views/frame/browser_view.cc"
     {"chrome_app/chrome_app_icon_32.png", IDR_CHROME_APP_ICON_32},
     {"chrome_app/chrome_app_icon_192.png", IDR_CHROME_APP_ICON_192},
 #if BUILDFLAG(ENABLE_INK)
diff --git a/chrome/browser/extensions/component_loader.cc b/chrome/browser/extensions/component_loader.cc
index 2ab370d7..66934260 100644
--- a/chrome/browser/extensions/component_loader.cc
+++ b/chrome/browser/extensions/component_loader.cc
@@ -489,10 +489,7 @@
   if (!skip_session_components) {
     AddWebStoreApp();
 #if BUILDFLAG(IS_CHROMEOS)
-    if (crosapi::browser_util::IsAshWebBrowserEnabled() ||
-        ash::switches::IsAshDebugBrowserEnabled()) {
-      AddChromeApp();
-    }
+    AddChromeApp();
 #endif  // BUILDFLAG(IS_CHROMEOS)
 #if BUILDFLAG(ENABLE_PDF)
     Add(pdf_extension_util::GetManifest(),
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index de629b9..c71b92f 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -137,6 +137,7 @@
     &features::kGenericSensorExtraClasses,
     &features::kBackForwardCache,
     &features::kBoardingPassDetector,
+    &features::kHttpsFirstBalancedMode,
     &features::kNetworkServiceInProcess,
     &features::kChangeUnfocusedPriority,
     &features::kElasticOverscroll,
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index ad69e63..890367ef 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -365,6 +365,7 @@
     public static final String HIDE_TABLET_TOOLBAR_DOWNLOAD_BUTTON =
             "HideTabletToolbarDownloadButton";
     public static final String HISTORY_JOURNEYS = "Journeys";
+    public static final String HTTPS_FIRST_BALANCED_MODE = "HttpsFirstBalancedMode";
     public static final String INCOGNITO_SCREENSHOT = "IncognitoScreenshot";
     public static final String INTEREST_FEED_V2_HEARTS = "InterestFeedV2Hearts";
     public static final String IP_PROTECTION_V1 = "IpProtectionV1";
diff --git a/chrome/browser/lens/region_search/lens_region_search_controller.h b/chrome/browser/lens/region_search/lens_region_search_controller.h
index 8da92417..b37d4cc 100644
--- a/chrome/browser/lens/region_search/lens_region_search_controller.h
+++ b/chrome/browser/lens/region_search/lens_region_search_controller.h
@@ -93,10 +93,6 @@
   // companion.
   lens::AmbientSearchEntryPoint entry_point_;
 
-  // Variable for tracking whether or not to force the region search to open
-  // results in a new tab, instead of the side panel.
-  bool force_open_in_new_tab_ = false;
-
   bool in_capture_mode_ = false;
 
   std::unique_ptr<image_editor::ScreenshotFlow> screenshot_flow_;
diff --git a/chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.h b/chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.h
index a68fd62e..e2f17aa 100644
--- a/chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.h
+++ b/chrome/browser/performance_manager/test_support/test_user_performance_tuning_manager_environment.h
@@ -57,11 +57,13 @@
   raw_ptr<base::test::TestBatteryLevelProvider> battery_level_provider_;
   std::unique_ptr<base::BatteryStateSampler> battery_sampler_;
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Some tests combine this helper with other helpers that also initialize
   // FakePowerManagerClient. E.g. BrowserWithTestWindowTest tests. True if we
   // called chromeos::PowerManagerClient::InitializeFake, because we are then
   // responsible for cleanup.
   bool tear_down_power_manager_client_ = false;
+#endif
 
   bool throttling_enabled_ = false;
   bool child_process_tuning_enabled_ = false;
diff --git a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.cc b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.cc
index e94eeaa..69a2ade 100644
--- a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.cc
+++ b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.cc
@@ -311,7 +311,7 @@
   }
 
   return has_audio_focus_ && is_playing_ && WasRecentlyAudible() &&
-         has_safe_url_ && MeetsEngagementScore() &&
+         has_safe_url_ && MeetsMediaEngagementConditions() &&
          has_sufficiently_visible_video_;
 }
 
@@ -330,7 +330,12 @@
   return audible_helper->WasRecentlyAudible();
 }
 
-bool AutoPictureInPictureTabHelper::MeetsEngagementScore() const {
+bool AutoPictureInPictureTabHelper::MeetsMediaEngagementConditions() const {
+  // Skip checking media engagement when content setting is set to allow.
+  if (GetCurrentContentSetting() == CONTENT_SETTING_ALLOW) {
+    return true;
+  }
+
   if (!media_engagement_service_) {
     return false;
   }
@@ -394,8 +399,8 @@
   CHECK(g_browser_process);
   CHECK(g_browser_process->safe_browsing_service());
 
-  auto* rfh = content::MediaSession::Get(web_contents())->GetRoutedFrame();
-  if (!rfh || !rfh->IsInPrimaryMainFrame()) {
+  std::optional<content::RenderFrameHost*> rfh = GetPrimaryMainRoutedFrame();
+  if (!rfh) {
     return;
   }
 
@@ -410,7 +415,8 @@
                             async_tasks_weak_factory_.GetWeakPtr()));
   }
 
-  safe_browsing_checker_client_->CheckUrlSafety(rfh->GetLastCommittedURL());
+  safe_browsing_checker_client_->CheckUrlSafety(
+      rfh.value()->GetLastCommittedURL());
 }
 
 void AutoPictureInPictureTabHelper::EnsureAutoPipSettingHelper() {
diff --git a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h
index ba90c60..6b77813 100644
--- a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h
+++ b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper.h
@@ -191,11 +191,12 @@
   // recently.
   bool WasRecentlyAudible() const;
 
-  // Returns true if the tab has high media engagement, false otherwise.
+  // Returns true if the tab has high media engagement or content setting is set
+  // to `CONTENT_SETTING_ALLOW`, false otherwise.
   //
   // Among other cases, this method will also return false if the media session
-  // router frame either does not exist or is not in the primary main frame.
-  bool MeetsEngagementScore() const;
+  // routed frame either does not exist or is not in the primary main frame.
+  bool MeetsMediaEngagementConditions() const;
 
   // Returns the current state of the 'Auto Picture-in-Picture' content
   // setting for the current website of the observed WebContents.
diff --git a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper_browsertest.cc b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper_browsertest.cc
index e072d61..bbd2448c 100644
--- a/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper_browsertest.cc
+++ b/chrome/browser/picture_in_picture/auto_picture_in_picture_tab_helper_browsertest.cc
@@ -835,10 +835,10 @@
   EXPECT_FALSE(tab_helper->has_safe_url_);
   EXPECT_FALSE(tab_helper->has_sufficiently_visible_video_);
 
-  // Verify that `MeetsEngagementScore` returns false (even though the mock high
-  // engagement is set to return true), since the video element is within a
-  // remote iframe.
-  EXPECT_FALSE(tab_helper->MeetsEngagementScore());
+  // Verify that `MeetsMediaEngagementConditions` returns false (even though the
+  // mock high engagement is set to return true), since the video element is
+  // within a remote iframe.
+  EXPECT_FALSE(tab_helper->MeetsMediaEngagementConditions());
 }
 
 IN_PROC_BROWSER_TEST_F(AutoPictureInPictureWithVideoPlaybackBrowserTest,
@@ -980,6 +980,30 @@
   SwitchToNewTabAndDontExpectAutopip();
 }
 
+IN_PROC_BROWSER_TEST_F(
+    AutoPictureInPictureWithVideoPlaybackBrowserTest,
+    DoesVideoAutopip_ContentSettingAllowAndLowEngagementScore) {
+  // Load a page that registers for autopip and start video playback.
+  LoadAutoVideoVisibilityPipPage(browser());
+  auto* web_contents = browser()->tab_strip_model()->GetActiveWebContents();
+  PlayVideo(web_contents);
+  WaitForAudioFocusGained();
+  WaitForMediaSessionPlaying(web_contents);
+
+  AddOverlayToVideo(web_contents, /*should_occlude*/ false);
+  ForceLifecycleUpdate(web_contents);
+  WaitForWasRecentlyAudible(web_contents);
+
+  // Set content setting to allow and has high media engagement to false.
+  SetContentSetting(web_contents, CONTENT_SETTING_ALLOW);
+  SetExpectedHasHighEngagement(false);
+
+  // Verify that we did enter pip, even though media engagement is low. This is
+  // because media engagement is ignored when content setting is set to allow.
+  SwitchToNewTabAndBackAndExpectAutopip(/*should_video_pip=*/true,
+                                        /*should_document_pip=*/false);
+}
+
 // TODO(crbug.com/40923043): Flaky on "Linux ASan LSan Tests (1)"
 #if BUILDFLAG(IS_LINUX) && defined(ADDRESS_SANITIZER) && defined(LEAK_SANITIZER)
 #define MAYBE_OpensAndClosesDocumentAutopip_VideoSufficientlyVisible \
diff --git a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
index a2515b9..4d6c7d23 100644
--- a/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
+++ b/chrome/browser/policy/messaging_layer/upload/record_handler_impl.cc
@@ -154,9 +154,6 @@
   ConfigFileAttachedCallback config_file_attached_cb_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
-  // Set to |true| if force_confirm flag is present. |false| by default.
-  bool force_confirm_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
-
   SEQUENCE_CHECKER(sequence_checker_);
 };
 
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 03ca7ab9..0cf338f 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -213,7 +213,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/browser_support.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"
@@ -664,8 +663,6 @@
       ash::ProfileHelper::IsPrimaryProfile(this)) {
     auto& map = profile_policy_connector_->policy_service()->GetPolicies(
         policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME, std::string()));
-    ash::standalone_browser::BrowserSupport::InitializeForPrimaryUser(
-        map, IsNewProfile(), IsRegularProfile());
     crosapi::browser_util::CacheLacrosAvailability(map);
     ash::standalone_browser::CacheLacrosSelection(map);
   }
@@ -1210,8 +1207,6 @@
         auto& map = profile_policy_connector_->policy_service()->GetPolicies(
             policy::PolicyNamespace(policy::POLICY_DOMAIN_CHROME,
                                     std::string()));
-        ash::standalone_browser::BrowserSupport::InitializeForPrimaryUser(
-            map, IsNewProfile(), IsRegularProfile());
         crosapi::browser_util::CacheLacrosAvailability(map);
         ash::standalone_browser::CacheLacrosSelection(map);
       }
diff --git a/chrome/browser/resources/on_device_internals/tools.html b/chrome/browser/resources/on_device_internals/tools.html
index a58c1b6a..453b10d 100644
--- a/chrome/browser/resources/on_device_internals/tools.html
+++ b/chrome/browser/resources/on_device_internals/tools.html
@@ -42,7 +42,7 @@
   }
 
   .model-text {
-    margin: 0 5px 20px 5px;
+    margin: 15px 5px 20px 0;
   }
 
   .session {
@@ -51,7 +51,10 @@
 
   .action-button {
     margin-inline-end: 8px;
-    margin-top: 10px;
+  }
+
+  .image-buttons {
+    margin-bottom: 10px;
   }
 
   #imageInput {
@@ -120,6 +123,9 @@
     Load
   </cr-button>
 </cr-input>
+<cr-checkbox slot="suffix" checked="{{enableImageInput_}}">
+  Enable images
+</cr-checkbox>
 <div class="model-text">
   [[getModelText_(modelPath_, loadModelDuration_)]]
   <div class="throbber" hidden$="[[!isLoading_(loadModelStart_)]]"></div>
@@ -155,21 +161,23 @@
     placeholder="Place control tokens {$SYSTEM, $MODEL, $USER, $END} on their own lines, in between lines of text."
     value="{{text_}}">
 </cr-textarea>
-<div class="image-error">[[imageError_]]</div>
-<div hidden$="[[file_]]">
-  <cr-button class="floating-button"
-      disabled="[[!canUploadFile_(currentResponse_, model_, file_)]]"
-      on-click="onAddImageClick_">
-    <cr-icon icon="cr:add" slot="prefix-icon"></cr-icon>
-    Add image
+<div class="image-buttons" hidden$="[[!imagesEnabled_(model_, baseModel_)]]">
+  <div class="image-error">[[imageError_]]</div>
+  <div hidden$="[[imageFile_]]">
+    <cr-button class="floating-button"
+        disabled="[[!canUploadFile_(currentResponse_, model_, imageFile_)]]"
+        on-click="onAddImageClick_">
+      <cr-icon icon="cr:add" slot="prefix-icon"></cr-icon>
+      Add image
+    </cr-button>
+    <input id="imageInput" type="file"></input>
+  </div>
+  <cr-button class="floating-button" hidden$="[[!imageFile_]]"
+      on-click="onRemoteImageClick_">
+    <cr-icon icon="cr:delete" slot="prefix-icon"></cr-icon>
+    [[imageFile_.name]]
   </cr-button>
-  <input id="imageInput" type="file"></input>
 </div>
-<cr-button class="floating-button" hidden$="[[!file_]]"
-    on-click="onRemoteImageClick_">
-  <cr-icon icon="cr:delete" slot="prefix-icon"></cr-icon>
-  [[file_.name]]
-</cr-button>
 <div>
   <cr-button class="action-button"
       disabled="[[!canExecute_(currentResponse_, model_)]]"
diff --git a/chrome/browser/resources/on_device_internals/tools.ts b/chrome/browser/resources/on_device_internals/tools.ts
index 5a8aaba..bae9a1c5 100644
--- a/chrome/browser/resources/on_device_internals/tools.ts
+++ b/chrome/browser/resources/on_device_internals/tools.ts
@@ -3,12 +3,13 @@
 // found in the LICENSE file.
 
 import '//resources/cr_elements/cr_button/cr_button.js';
+import '//resources/cr_elements/cr_checkbox/cr_checkbox.js';
 import '//resources/cr_elements/cr_collapse/cr_collapse.js';
+import '//resources/cr_elements/cr_expand_button/cr_expand_button.js';
 import '//resources/cr_elements/cr_hidden_style.css.js';
 import '//resources/cr_elements/cr_input/cr_input.js';
 import '//resources/cr_elements/cr_shared_vars.css.js';
 import '//resources/cr_elements/cr_textarea/cr_textarea.js';
-import '//resources/cr_elements/cr_expand_button/cr_expand_button.js';
 
 import type {CrInputElement} from '//resources/cr_elements/cr_input/cr_input.js';
 import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
@@ -108,6 +109,10 @@
         type: Array,
         value: () => [],
       },
+      baseModel_: {
+        type: Object,
+        value: null,
+      },
       model_: {
         type: Object,
         value: null,
@@ -119,9 +124,10 @@
       contextExpanded_: Boolean,
       contextLength_: Number,
       contextText_: String,
+      enableImageInput_: Boolean,
       topK_: Number,
       temperature_: Number,
-      file_: {
+      imageFile_: {
         type: Object,
         value: null,
       },
@@ -143,6 +149,7 @@
   private loadModelDuration_: number;
   private loadModelStart_: number;
   private modelPath_: string;
+  private baseModel_: OnDeviceModelRemote|null;
   private model_: OnDeviceModelRemote|null;
   private performanceClassText_: string;
   private responses_: Response[];
@@ -150,7 +157,8 @@
   private temperature_: number = 0;
   private text_: string;
   private topK_: number = 1;
-  private file_: File|null = null;
+  private imageFile_: File|null = null;
+  private enableImageInput_: boolean = false;
 
   private proxy_: BrowserProxy = BrowserProxy.getInstance();
   private responseRouter_: StreamingResponderCallbackRouter =
@@ -187,7 +195,7 @@
   }
 
   private onRemoteImageClick_() {
-    this.file_ = null;
+    this.imageFile_ = null;
     this.$.imageInput.value = '';
   }
 
@@ -198,6 +206,7 @@
     }
     this.error_ = 'Service crashed, please reload the model.';
     this.model_ = null;
+    this.baseModel_ = null;
     this.modelPath_ = '';
     this.loadModelStart_ = 0;
     this.$.modelInput.focus();
@@ -206,17 +215,22 @@
   private onImageChange_() {
     this.imageError_ = '';
     if ((this.$.imageInput.files?.length ?? 0) > 0) {
-      this.file_ = this.$.imageInput.files!.item(0) ?? null;
+      this.imageFile_ = this.$.imageInput.files!.item(0) ?? null;
     } else {
-      this.file_ = null;
+      this.imageFile_ = null;
     }
   }
 
   private async onModelSelected_() {
     this.error_ = '';
+    if (this.baseModel_) {
+      this.baseModel_.$.close();
+    }
     if (this.model_) {
       this.model_.$.close();
     }
+    this.imageFile_ = null;
+    this.baseModel_ = null;
     this.model_ = null;
     this.loadModelStart_ = new Date().getTime();
     const modelPath = this.$.modelInput.value;
@@ -227,13 +241,31 @@
     // <if expr="not is_win">
     const processedPath = modelPath;
     // </if>
-    const newModel = new OnDeviceModelRemote();
-    const {result} = await this.proxy_.handler.loadModel(
-        {path: processedPath}, newModel.$.bindNewPipeAndPassReceiver());
+    const baseModel = new OnDeviceModelRemote();
+    let newModel = new OnDeviceModelRemote();
+    let {result} = await this.proxy_.handler.loadModel(
+        {path: processedPath}, baseModel.$.bindNewPipeAndPassReceiver());
+    if (result === LoadModelResult.kSuccess && this.enableImageInput_) {
+      result = (await baseModel.loadAdaptation(
+                    {
+                      enableImageInput: true,
+                      maxTokens: 0,
+                      assets: {
+                        weights: null,
+                        weightsPath: null,
+                      },
+                    },
+                    newModel.$.bindNewPipeAndPassReceiver()))
+                   .result;
+    } else {
+      // No adaptation needed, just use the base model.
+      newModel = baseModel;
+    }
     if (result !== LoadModelResult.kSuccess) {
       this.error_ =
           'Unable to load model. Specify a correct and absolute path.';
     } else {
+      this.baseModel_ = baseModel;
       this.model_ = newModel;
       this.model_.onConnectionError.addListener(() => {
         this.onServiceCrashed_();
@@ -288,7 +320,7 @@
   }
 
   private async decodeBitmap_() {
-    const data = new Uint8Array(await this.file_!.arrayBuffer());
+    const data = new Uint8Array(await this.imageFile_!.arrayBuffer());
     if (data.byteLength <= 0) {
       return null;
     }
@@ -323,12 +355,12 @@
       return;
     }
     const pieces = textToInputPieces(this.text_);
-    if (this.file_ !== null) {
+    if (this.imageFile_ !== null) {
       const bitmap = await this.decodeBitmap_();
       if (bitmap) {
         pieces.unshift({bitmap});
       } else {
-        this.file_ = null;
+        this.imageFile_ = null;
         this.imageError_ = 'Image is invalid';
         return;
       }
@@ -371,19 +403,27 @@
   }
 
   private canUploadFile_(): boolean {
-    return this.canExecute_() && this.file_ === null;
+    return this.canExecute_() && this.imageFile_ === null;
   }
 
   private isLoading_(): boolean {
     return this.loadModelStart_ !== 0;
   }
 
+  private imagesEnabled_(): boolean {
+    return this.model_ !== this.baseModel_;
+  }
+
   private getModelText_(): string {
     if (this.modelPath_.length === 0) {
       return '';
     }
-    return 'Model loaded from ' + this.modelPath_ + ' in ' +
+    let text = 'Model loaded from ' + this.modelPath_ + ' in ' +
         this.loadModelDuration_ + 'ms';
+    if (this.imagesEnabled_()) {
+      text += ' [images enabled]';
+    }
+    return text;
   }
 }
 
diff --git a/chrome/browser/resources/print_preview/ui/print_preview_shared.css b/chrome/browser/resources/print_preview/ui/print_preview_shared.css
index 8ca8d62d..2e52f96 100644
--- a/chrome/browser/resources/print_preview/ui/print_preview_shared.css
+++ b/chrome/browser/resources/print_preview/ui/print_preview_shared.css
@@ -15,15 +15,7 @@
   margin-bottom: 2px;
   margin-top: 2px;
   min-height: 32px;
-  padding-bottom: 1px;
-<if expr="is_win or is_macosx">
-  /* The following platform-specific rule is necessary to get adjacent
-   * buttons, text inputs, and so forth to align on their borders while
-   * also aligning on the text's baselines. */
-  padding-bottom: 2px;
-</if>
   padding-inline-end: 32px;
-  padding-top: 1px;
   user-select: none;
   --md-select-width: calc(100% - 2 * var(--print-preview-sidebar-margin));
 }
diff --git a/chrome/browser/speech/speech_recognition_client_browser_interface.h b/chrome/browser/speech/speech_recognition_client_browser_interface.h
index 64f7fba..89237e8 100644
--- a/chrome/browser/speech/speech_recognition_client_browser_interface.h
+++ b/chrome/browser/speech/speech_recognition_client_browser_interface.h
@@ -85,8 +85,11 @@
   void NotifyLiveCaptionObservers(bool enabled);
 
   bool waiting_on_live_caption_ = false;
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   bool waiting_on_babel_orca_ = false;
   bool babel_orca_enabled_ = false;
+#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
   mojo::RemoteSet<media::mojom::SpeechRecognitionBrowserObserver>
       live_caption_availibility_observers_;
diff --git a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
index 7485dbc..49776ab8 100644
--- a/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
+++ b/chrome/browser/sync/test/integration/single_client_nigori_sync_test.cc
@@ -79,7 +79,6 @@
 #include "ash/constants/ash_switches.h"
 #include "chrome/browser/ash/sync/sync_error_notifier.h"
 #include "chrome/browser/ash/sync/sync_error_notifier_factory.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "components/trusted_vault/features.h"
 #include "ui/views/test/widget_test.h"
 #include "ui/views/widget/any_widget_observer.h"
diff --git a/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc b/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc
index 329e768..3cc1ae4 100644
--- a/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc
+++ b/chrome/browser/sync/test/integration/web_apps_sync_test_base.cc
@@ -14,7 +14,6 @@
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_features.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #endif
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -26,7 +25,6 @@
 
 WebAppsSyncTestBase::WebAppsSyncTestBase(TestType test_type)
     : SyncTest(test_type) {
-  std::vector<base::test::FeatureRef> disabled_features;
   std::vector<base::test::FeatureRef> enabled_features;
 
 #if BUILDFLAG(IS_CHROMEOS)
@@ -39,12 +37,7 @@
 
   enabled_features.push_back(features::kWebAppDontAddExistingAppsToSync);
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-  // Disable Lacros, so that Web Apps get synced in the Ash browser.
-  base::Extend(disabled_features, ash::standalone_browser::GetFeatureRefs());
-#endif
-
-  scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
+  scoped_feature_list_.InitWithFeatures(enabled_features, {});
 }
 
 WebAppsSyncTestBase::~WebAppsSyncTestBase() = default;
diff --git a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TabGroupSyncRemoteObserver.java b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TabGroupSyncRemoteObserver.java
index 63bb19c..1dec284 100644
--- a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TabGroupSyncRemoteObserver.java
+++ b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TabGroupSyncRemoteObserver.java
@@ -131,4 +131,9 @@
     @Override
     public void onTabGroupLocalIdChanged(
             String syncTabGroupId, @Nullable LocalTabGroupId localTabGroupId) {}
+
+    @Override
+    public void onLocalObservationModeChanged(boolean observeLocalChanges) {
+        mEnableLocalObserverCallback.onResult(observeLocalChanges);
+    }
 }
diff --git a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TabGroupSyncRemoteObserverUnitTest.java b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TabGroupSyncRemoteObserverUnitTest.java
index b7955672..88f55b2 100644
--- a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TabGroupSyncRemoteObserverUnitTest.java
+++ b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TabGroupSyncRemoteObserverUnitTest.java
@@ -192,6 +192,15 @@
         verify(mLocalMutationHelper, never()).closeTabGroup(any(), anyInt());
     }
 
+    @Test
+    public void testOnLocalObservationModeChanged() {
+        Assert.assertTrue(mEnabledLocalObservers);
+        mRemoteObserver.onLocalObservationModeChanged(false);
+        Assert.assertFalse(mEnabledLocalObservers);
+        mRemoteObserver.onLocalObservationModeChanged(true);
+        Assert.assertTrue(mEnabledLocalObservers);
+    }
+
     private class TestTabCreationDelegate implements TabCreationDelegate {
         private int mNextTabId;
 
diff --git a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TestTabGroupSyncService.java b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TestTabGroupSyncService.java
index ccbf69c..82cb7c6 100644
--- a/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TestTabGroupSyncService.java
+++ b/chrome/browser/tab_group_sync/android/java/src/org/chromium/chrome/browser/tab_group_sync/TestTabGroupSyncService.java
@@ -108,6 +108,14 @@
     public void updateLocalTabId(LocalTabGroupId localGroupId, String syncTabId, int localTabId) {}
 
     @Override
+    public void setLocalObservationMode(boolean observeLocalChanges) {}
+
+    @Override
+    public boolean isObservingLocalChanges() {
+        return true;
+    }
+
+    @Override
     public boolean isRemoteDevice(String syncCacheGuid) {
         boolean isLocal =
                 TextUtils.isEmpty(syncCacheGuid)
diff --git a/chrome/browser/ui/ash/editor_menu/editor_menu_view.cc b/chrome/browser/ui/ash/editor_menu/editor_menu_view.cc
index 3ceb7efb..6cfc8de7 100644
--- a/chrome/browser/ui/ash/editor_menu/editor_menu_view.cc
+++ b/chrome/browser/ui/ash/editor_menu/editor_menu_view.cc
@@ -294,7 +294,7 @@
                          std::make_unique<views::View>());
     tabbed_pane_->AddTab(GetEditorMenuLobsterTitle(),
                          std::make_unique<views::View>());
-    tabbed_pane_->set_listener(this);
+    tabbed_pane_->SetListener(this);
   } else if (text_and_image_mode_ == TextAndImageMode::kEditorWriteOnly) {
     auto* title = title_container_->AddChildView(std::make_unique<views::Label>(
         GetEditorMenuWriteCardTitle(), views::style::CONTEXT_DIALOG_TITLE,
diff --git a/chrome/browser/ui/ash/shelf/BUILD.gn b/chrome/browser/ui/ash/shelf/BUILD.gn
index f129c54..85e2c432 100644
--- a/chrome/browser/ui/ash/shelf/BUILD.gn
+++ b/chrome/browser/ui/ash/shelf/BUILD.gn
@@ -250,7 +250,6 @@
     "//chromeos/ash/components/dbus/seneschal",
     "//chromeos/ash/components/file_manager:constants",
     "//chromeos/ash/components/scalable_iph:constants",
-    "//chromeos/ash/components/standalone_browser",
     "//components/account_id",
     "//components/app_constants",
     "//components/exo",
@@ -318,7 +317,6 @@
     "//chrome/common",
     "//chrome/test:test_support",
     "//chromeos/ash/components/file_manager:constants",
-    "//chromeos/ash/components/standalone_browser",
     "//chromeos/constants",
     "//components/app_constants",
     "//components/crx_file",
diff --git a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_browsertest.cc b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_browsertest.cc
index 9033bfa..6d9e0f5 100644
--- a/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_browsertest.cc
+++ b/chrome/browser/ui/ash/shelf/app_service/app_service_app_window_browsertest.cc
@@ -47,7 +47,6 @@
 #include "chrome/browser/web_applications/test/web_app_install_test_utils.h"
 #include "chrome/browser/web_applications/web_app_install_info.h"
 #include "chrome/test/base/ui_test_utils.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "components/app_constants/constants.h"
 #include "components/exo/shell_surface_util.h"
 #include "components/services/app_service/public/cpp/app_instance_waiter.h"
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
index 962369ed..de11278f 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
@@ -110,7 +110,6 @@
 #include "chrome/common/pref_names.h"
 #include "chrome/test/base/ui_test_utils.h"
 #include "chromeos/ash/components/file_manager/app_id.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "components/app_constants/constants.h"
 #include "components/crx_file/id_util.h"
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc
index f23b74e..838d133 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs.cc
@@ -96,8 +96,7 @@
     if (!sync_item->item_pin_ordinal.IsValid()) {
       continue;
     }
-    if (exclude_chrome && (item_id == app_constants::kChromeAppId ||
-                           item_id == app_constants::kAshDebugBrowserAppId)) {
+    if (exclude_chrome && item_id == app_constants::kChromeAppId) {
       continue;
     }
     if (position.IsValid() && !compare(position, sync_item->item_pin_ordinal)) {
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs_unittest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs_unittest.cc
index d698412..70d6c052 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_prefs_unittest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_prefs_unittest.cc
@@ -34,7 +34,6 @@
 #include "chrome/test/base/testing_profile.h"
 #include "chromeos/ash/components/file_manager/app_id.h"
 #include "chromeos/ash/components/scalable_iph/scalable_iph_constants.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "chromeos/constants/chromeos_features.h"
 #include "components/app_constants/constants.h"
 #include "components/services/app_service/public/cpp/app.h"
diff --git a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h
index 43f48b2..cb04cee 100644
--- a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h
+++ b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h
@@ -109,8 +109,6 @@
   std::unique_ptr<TestAutofillBubble> mandatory_reauth_bubble_view_;
   std::unique_ptr<TestAutofillBubble> save_card_confirmation_bubble_view_;
   std::unique_ptr<TestAutofillBubble> save_iban_confirmation_bubble_view_;
-
-  int save_card_confirmation_bubble_shown_count_ = 0;
 };
 
 }  // namespace autofill
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index 003d6ec..22c1af5 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -105,7 +105,6 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_features.h"
 #include "base/containers/extend.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #endif
 
 using content::RenderFrameHost;
@@ -230,9 +229,6 @@
         // tests.
         features::kHttpsUpgrades,
     };
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-    base::Extend(disabled, ash::standalone_browser::GetFeatureRefs());
-#endif
     scoped_feature_list_.InitWithFeatures(/*enabled_features=*/{}, disabled);
   }
 
diff --git a/chrome/browser/ui/lens/lens_overlay_controller.cc b/chrome/browser/ui/lens/lens_overlay_controller.cc
index 0ab9684..c2b37c9a 100644
--- a/chrome/browser/ui/lens/lens_overlay_controller.cc
+++ b/chrome/browser/ui/lens/lens_overlay_controller.cc
@@ -2695,6 +2695,11 @@
   state_ = state_ == State::kOverlayAndResults ? State::kOverlayAndResults
                                                : State::kLivePageAndResults;
 
+  // The searchbox text is set once the URL loads in the results frame, however,
+  // adding it here allows the user to see the text query in the searchbox while
+  // a long query loads.
+  SetSearchboxInputText(search_box_text);
+
   results_side_panel_coordinator_->RegisterEntryAndShow();
   MaybeLaunchSurvey();
 }
diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller.cc b/chrome/browser/ui/lens/lens_overlay_query_controller.cc
index d688486..f5c20a14 100644
--- a/chrome/browser/ui/lens/lens_overlay_query_controller.cc
+++ b/chrome/browser/ui/lens/lens_overlay_query_controller.cc
@@ -438,6 +438,17 @@
                       additional_search_query_params);
     return;
   }
+
+  // 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_) {
+    pending_contextual_query_callback_ =
+        base::BindOnce(&LensOverlayQueryController::SendContextualTextQuery,
+                       weak_ptr_factory_.GetWeakPtr(), query_text,
+                       lens_selection_type, additional_search_query_params);
+    return;
+  }
+
   // Include the vit to get contextualized results.
   additional_search_query_params = AddVisualInputTypeQueryParam(
       additional_search_query_params, underlying_content_type_);
@@ -535,7 +546,8 @@
     const std::string& http_method,
     const base::TimeDelta& timeout,
     const std::vector<std::string>& request_headers,
-    const std::vector<std::string>& cors_exempt_headers) {
+    const std::vector<std::string>& cors_exempt_headers,
+    const UploadProgressCallback upload_progress_callback) {
   // If provided, serialize the request to a string to include as the request
   // post data.
   std::string request_string;
@@ -559,6 +571,7 @@
       EndpointFetcher::RequestParams::Builder()
           .SetCredentialsMode(CredentialsMode::kInclude)
           .SetSetSiteForCookies(true)
+          .SetUploadProgressCallback(upload_progress_callback)
           .Build());
 }
 
@@ -630,7 +643,7 @@
   cluster_info_endpoint_fetcher_ = CreateEndpointFetcher(
       nullptr, fetch_url, kHttpGetMethod,
       base::Milliseconds(lens::features::GetLensOverlayServerRequestTimeout()),
-      request_headers, cors_exempt_headers);
+      request_headers, cors_exempt_headers, base::DoNothing());
 
   // Finally, perform the request.
   cluster_info_endpoint_fetcher_->PerformRequest(
@@ -1011,6 +1024,7 @@
   page_content_access_token_fetcher_.reset();
 
   // Pass no response callback because this is a fire and forget request.
+  page_content_request_in_progress_ = true;
   PerformFetchRequest(
       &request, &headers,
       base::Milliseconds(
@@ -1019,7 +1033,10 @@
           &LensOverlayQueryController::OnPageContentEndpointFetcherCreated,
           weak_ptr_factory_.GetWeakPtr()),
       base::BindOnce(&LensOverlayQueryController::PageContentResponseHandler,
-                     weak_ptr_factory_.GetWeakPtr()));
+                     weak_ptr_factory_.GetWeakPtr()),
+      base::BindRepeating(
+          &LensOverlayQueryController::PageContentUploadProgressHandler,
+          weak_ptr_factory_.GetWeakPtr()));
 }
 
 void LensOverlayQueryController::PageContentResponseHandler(
@@ -1033,6 +1050,18 @@
       /*encoded_analytics_id=*/std::nullopt);
 }
 
+void LensOverlayQueryController::PageContentUploadProgressHandler(
+    uint64_t position,
+    uint64_t total) {
+  if (position == total) {
+    page_content_request_in_progress_ = false;
+    if (pending_contextual_query_callback_) {
+      base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
+          FROM_HERE, std::move(pending_contextual_query_callback_));
+    }
+  }
+}
+
 void LensOverlayQueryController::SendInteraction(
     lens::mojom::CenterRotatedBoxPtr region,
     std::optional<std::string> query_text,
@@ -1380,7 +1409,8 @@
     const base::TimeDelta& timeout,
     base::OnceCallback<void(std::unique_ptr<EndpointFetcher>)>
         fetcher_created_callback,
-    EndpointFetcherCallback response_received_callback) {
+    EndpointFetcherCallback response_received_callback,
+    UploadProgressCallback upload_progress_callback) {
   CHECK(request);
   CHECK(request_headers);
 
@@ -1400,9 +1430,9 @@
 
   // Create the EndpointFetcher, responsible for making the request using our
   // given params.
-  std::unique_ptr<EndpointFetcher> endpoint_fetcher =
-      CreateEndpointFetcher(request, fetch_url, kHttpPostMethod, timeout,
-                            *request_headers, cors_exempt_headers);
+  std::unique_ptr<EndpointFetcher> endpoint_fetcher = CreateEndpointFetcher(
+      request, fetch_url, kHttpPostMethod, timeout, *request_headers,
+      cors_exempt_headers, upload_progress_callback);
   EndpointFetcher* fetcher = endpoint_fetcher.get();
 
   // Run callback that the fetcher was created. This is used to keep the
diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller.h b/chrome/browser/ui/lens/lens_overlay_query_controller.h
index 734f9e4..11f447f 100644
--- a/chrome/browser/ui/lens/lens_overlay_query_controller.h
+++ b/chrome/browser/ui/lens/lens_overlay_query_controller.h
@@ -64,6 +64,8 @@
 // Callback type alias for the OAuth headers created.
 using OAuthHeadersCreatedCallback =
     base::OnceCallback<void(std::vector<std::string>)>;
+using UploadProgressCallback =
+    base::RepeatingCallback<void(uint64_t position, uint64_t total)>;
 
 // Manages queries on behalf of a Lens overlay.
 class LensOverlayQueryController {
@@ -171,7 +173,9 @@
       const std::string& http_method,
       const base::TimeDelta& timeout,
       const std::vector<std::string>& request_headers,
-      const std::vector<std::string>& cors_exempt_headers);
+      const std::vector<std::string>& cors_exempt_headers,
+      const UploadProgressCallback upload_progress_callback =
+          base::NullCallback());
 
   // Sends a latency Gen204 ping if enabled, calculating the latency duration
   // from the start time ticks and base::TimeTicks::Now().
@@ -333,6 +337,9 @@
   // Handles the endpoint fetch response for the page content request.
   void PageContentResponseHandler(std::unique_ptr<EndpointResponse> response);
 
+  // Handles the prgress of the page content upload request.
+  void PageContentUploadProgressHandler(uint64_t position, uint64_t total);
+
   // Sends the interaction data, triggering async image cropping and fetching
   // the request.
   void SendInteraction(
@@ -424,7 +431,9 @@
       const base::TimeDelta& timeout,
       base::OnceCallback<void(std::unique_ptr<EndpointFetcher>)>
           fetcher_created_callback,
-      EndpointFetcherCallback response_received_callback);
+      EndpointFetcherCallback response_received_callback,
+      const UploadProgressCallback upload_progress_callback =
+          base::NullCallback());
 
   // Creates a client context proto to be attached to a server request.
   lens::LensOverlayClientContext CreateClientContext();
@@ -607,6 +616,13 @@
   // always be the first interaction in a query flow.
   bool parent_query_sent_ = false;
 
+  // Whether or not a page content upload request is in progress.
+  bool page_content_request_in_progress_ = false;
+
+  // Callback for a pending contextual query that is waiting for the page
+  // content request to finish uploading.
+  base::OnceClosure pending_contextual_query_callback_;
+
   // Whether or not a page contents request has been sent.
   bool page_contents_request_sent_ = false;
 
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 1dd5b9f..6d2b91ac 100644
--- a/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc
+++ b/chrome/browser/ui/lens/lens_overlay_query_controller_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "base/base64url.h"
 #include "base/containers/span.h"
+#include "base/memory/weak_ptr.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
@@ -154,9 +155,7 @@
 
 class LensOverlayQueryControllerTest : public testing::Test {
  public:
-  LensOverlayQueryControllerTest()
-      : task_environment_(content::BrowserTaskEnvironment::IO_MAINLOOP,
-                          base::test::TaskEnvironment::TimeSource::MOCK_TIME) {
+  LensOverlayQueryControllerTest() {
     fake_variations_client_ = std::make_unique<FakeVariationsClient>();
   }
 
@@ -167,7 +166,16 @@
   LensOverlaySuggestInputsCallback GetSuggestInputsCallback() {
     return base::BindRepeating(
         &LensOverlayQueryControllerTest::HandleSuggestInputsResponse,
-        base::Unretained(this));
+        weak_factory_.GetWeakPtr());
+  }
+
+  // Waiting for the final call of the suggest inputs callback cannot be done
+  // with base::test::RunUntil() because the suggest callback won't wake up the
+  // RunUntil() loop. Instead, we use a RunLoop to wait for the suggest inputs
+  // callback to be called, and manually exit the RunLoop when the suggest
+  // inputs are ready with encoded image signals.
+  void WaitForSuggestInputsWithEncodedImageSignals() {
+    suggest_inputs_run_loop.Run();
   }
 
   lens::LensOverlayGen204Controller* GetGen204Controller() {
@@ -300,11 +308,14 @@
 
  protected:
   base::test::ScopedFeatureList feature_list_;
-  content::BrowserTaskEnvironment task_environment_;
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
   std::unique_ptr<TestingProfile> profile_;
   std::unique_ptr<lens::FakeLensOverlayGen204Controller> gen204_controller_;
   std::unique_ptr<FakeVariationsClient> fake_variations_client_;
   lens::proto::LensOverlaySuggestInputs latest_suggest_inputs_;
+  base::RunLoop suggest_inputs_run_loop;
+  base::WeakPtrFactory<LensOverlayQueryControllerTest> weak_factory_{this};
 
   TestingProfile* profile() { return profile_.get(); }
 
@@ -327,11 +338,20 @@
 
     feature_list_.InitWithFeaturesAndParameters(
         {kDefaultLensOverlayContextualSearchboxParams}, {});
+    testing::Test::SetUp();
   }
 
   void HandleSuggestInputsResponse(
       lens::proto::LensOverlaySuggestInputs suggest_inputs) {
     latest_suggest_inputs_ = suggest_inputs;
+    // This callback does not wake up the RunLoop used in RunUntil(). Instead,
+    // we use a RunLoop to wait for the suggest inputs callback to be called.
+    // If the caller is waiting for the suggest inputs callback, exit the
+    // RunLoop if the suggest inputs are ready with encoded image signals.
+    if (suggest_inputs_run_loop.running() &&
+        latest_suggest_inputs_.has_encoded_image_signals()) {
+      suggest_inputs_run_loop.Quit();
+    }
   }
 };
 
@@ -361,9 +381,8 @@
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
 
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
   query_controller.EndQuery();
-  ASSERT_TRUE(full_image_response_future.IsReady());
 
   // Check initial fetch objects request is correct.
   auto sent_object_request = query_controller.sent_full_image_objects_request();
@@ -435,9 +454,8 @@
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
 
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
   query_controller.EndQuery();
-  ASSERT_TRUE(full_image_response_future.IsReady());
 
   // Check the server session id is attached to the fetch url.
   std::string session_id_value;
@@ -514,8 +532,9 @@
   identity_test_env.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
       kFakeOAuthToken, base::Time::Max());
 
-  task_environment_.RunUntilIdle();
-  ASSERT_EQ(1, query_controller.num_cluster_info_fetch_requests_sent());
+  // Wait for the cluster info request to be sent.
+  ASSERT_TRUE(full_image_response_future.Wait());
+  EXPECT_EQ(1, query_controller.num_cluster_info_fetch_requests_sent());
 
   // Reset the cluster info state.
   query_controller.ResetRequestClusterInfoStateForTesting();
@@ -537,11 +556,10 @@
   identity_test_env.WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
       kFakeOAuthToken, base::Time::Max());
 
-  task_environment_.RunUntilIdle();
+  // Wait for the cluster info request to be sent.
+  ASSERT_TRUE(url_response_future.Wait());
+  EXPECT_EQ(2, query_controller.num_cluster_info_fetch_requests_sent());
   query_controller.EndQuery();
-
-  // Verify the cluster info was refetched.
-  ASSERT_EQ(2, query_controller.num_cluster_info_fetch_requests_sent());
 }
 
 TEST_F(LensOverlayQueryControllerTest,
@@ -582,9 +600,9 @@
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
 
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
   query_controller.EndQuery();
-  ASSERT_TRUE(full_image_response_future.IsReady());
+
   ASSERT_FALSE(
       latest_suggest_inputs_.send_gsession_vsrid_for_contextual_suggest());
   ASSERT_FALSE(latest_suggest_inputs_.send_gsession_vsrid_for_lens_suggest());
@@ -633,7 +651,8 @@
       std::vector<lens::mojom::CenterRotatedBoxPtr>(),
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
+
+  ASSERT_TRUE(full_image_response_future.Wait());
 
   auto region = lens::mojom::CenterRotatedBox::New();
   region->box = gfx::RectF(30, 40, 50, 60);
@@ -642,7 +661,8 @@
   query_controller.SendRegionSearch(std::move(region), lens::REGION_SEARCH,
                                     additional_search_query_params,
                                     std::nullopt);
-  task_environment_.RunUntilIdle();
+
+  ASSERT_TRUE(url_response_future.Wait());
   query_controller.EndQuery();
 
   // Check the server session id is attached to the fetch url.
@@ -692,7 +712,7 @@
       std::vector<lens::mojom::CenterRotatedBoxPtr>(),
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
 
   auto region = lens::mojom::CenterRotatedBox::New();
   region->box = gfx::RectF(30, 40, 50, 60);
@@ -701,7 +721,10 @@
   query_controller.SendRegionSearch(std::move(region), lens::REGION_SEARCH,
                                     additional_search_query_params,
                                     std::nullopt);
-  task_environment_.RunUntilIdle();
+
+  // Wait for async flows to complete.
+  ASSERT_TRUE(url_response_future.Wait());
+  WaitForSuggestInputsWithEncodedImageSignals();
   query_controller.EndQuery();
 
   std::string unused_start_time;
@@ -721,6 +744,7 @@
                 .user_selection_data()
                 .selection_type(),
             lens::REGION_SEARCH);
+
   ASSERT_EQ(latest_suggest_inputs_.encoded_image_signals(),
             kTestSuggestSignals);
   ASSERT_EQ(latest_suggest_inputs_.search_session_id(), kTestSearchSessionId);
@@ -821,7 +845,6 @@
       std::vector<lens::mojom::CenterRotatedBoxPtr>(),
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
 
   ASSERT_EQ(query_controller.num_cluster_info_fetch_requests_sent(), 1);
 
@@ -832,7 +855,7 @@
   query_controller.SendRegionSearch(std::move(region), lens::REGION_SEARCH,
                                     additional_search_query_params,
                                     std::nullopt);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
   query_controller.EndQuery();
 
   // Despite the full image response not being ready, the search url should
@@ -887,7 +910,7 @@
       std::vector<lens::mojom::CenterRotatedBoxPtr>(),
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
 
   SkBitmap region_bitmap = CreateNonEmptyBitmap(100, 100);
   region_bitmap.setAlphaType(kOpaque_SkAlphaType);
@@ -898,7 +921,9 @@
   query_controller.SendRegionSearch(
       std::move(region), lens::REGION_SEARCH, additional_search_query_params,
       std::make_optional<SkBitmap>(region_bitmap));
-  task_environment_.RunUntilIdle();
+
+  ASSERT_TRUE(url_response_future.Wait());
+  WaitForSuggestInputsWithEncodedImageSignals();
   query_controller.EndQuery();
 
   std::string unused_start_time;
@@ -1017,7 +1042,7 @@
       std::vector<lens::mojom::CenterRotatedBoxPtr>(),
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
 
   auto region = lens::mojom::CenterRotatedBox::New();
   region->box = gfx::RectF(30, 40, 50, 60);
@@ -1026,7 +1051,8 @@
   query_controller.SendMultimodalRequest(
       std::move(region), kTestQueryText, lens::MULTIMODAL_SEARCH,
       additional_search_query_params, std::nullopt);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
+  WaitForSuggestInputsWithEncodedImageSignals();
   query_controller.EndQuery();
 
   std::string unused_start_time;
@@ -1125,12 +1151,12 @@
       std::vector<lens::mojom::CenterRotatedBoxPtr>(),
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
 
   query_controller.SendTextOnlyQuery(
       "", lens::LensOverlaySelectionType::SELECT_TEXT_HIGHLIGHT,
       additional_search_query_params);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
   query_controller.EndQuery();
 
   std::string actual_encoded_video_context;
@@ -1201,11 +1227,13 @@
       std::make_optional<std::string>(kTestPageTitle),
       std::vector<lens::mojom::CenterRotatedBoxPtr>(), fake_content_bytes,
       lens::MimeType::kPdf, 0, base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
+
   query_controller.SendContextualTextQuery(
       kTestQueryText, lens::LensOverlaySelectionType::MULTIMODAL_SEARCH,
       additional_search_query_params);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
+  WaitForSuggestInputsWithEncodedImageSignals();
   query_controller.EndQuery();
 
   ASSERT_TRUE(full_image_response_future.IsReady());
@@ -1334,11 +1362,12 @@
       std::make_optional<std::string>(kTestPageTitle),
       std::vector<lens::mojom::CenterRotatedBoxPtr>(), fake_content_bytes,
       lens::MimeType::kHtml, 0, base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
   query_controller.SendContextualTextQuery(
       kTestQueryText, lens::LensOverlaySelectionType::MULTIMODAL_SEARCH,
       additional_search_query_params);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
+  WaitForSuggestInputsWithEncodedImageSignals();
   query_controller.EndQuery();
 
   ASSERT_TRUE(full_image_response_future.IsReady());
@@ -1467,11 +1496,12 @@
       std::make_optional<std::string>(kTestPageTitle),
       std::vector<lens::mojom::CenterRotatedBoxPtr>(), fake_content_bytes,
       lens::MimeType::kPlainText, 0, base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
   query_controller.SendContextualTextQuery(
       kTestQueryText, lens::LensOverlaySelectionType::MULTIMODAL_SEARCH,
       additional_search_query_params);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
+  WaitForSuggestInputsWithEncodedImageSignals();
   query_controller.EndQuery();
 
   ASSERT_TRUE(full_image_response_future.IsReady());
@@ -1562,6 +1592,65 @@
 }
 
 TEST_F(LensOverlayQueryControllerTest,
+       FetchTextOnlyInteractionWithLargeUpload_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;
+  std::vector<uint8_t> fake_content_bytes({1, 2, 3, 4});
+  query_controller.StartQueryFlow(
+      bitmap, GURL(kTestPageUrl),
+      std::make_optional<std::string>(kTestPageTitle),
+      std::vector<lens::mojom::CenterRotatedBoxPtr>(), fake_content_bytes,
+      lens::MimeType::kPlainText, 0, base::TimeTicks::Now());
+  ASSERT_TRUE(full_image_response_future.Wait());
+  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,
        SendPageContentUpdateRequest_IncrementsSequence) {
   InitFeaturesWithClusterInfoOptimization();
   base::test::TestFuture<std::vector<lens::mojom::OverlayObjectPtr>,
@@ -1604,9 +1693,8 @@
   // Immediately send a page content update request.
   query_controller.SendPageContentUpdateRequest(
       fake_content_bytes, lens::MimeType::kPlainText, GURL(kTestPageUrl));
-  task_environment_.RunUntilIdle();
 
-  ASSERT_TRUE(full_image_response_future.IsReady());
+  ASSERT_TRUE(full_image_response_future.Wait());
 
   // The full image and page content requests should have the same request id.
   ASSERT_EQ(query_controller.sent_request_id().sequence_id(), 1);
@@ -1620,7 +1708,6 @@
   std::vector<uint8_t> new_fake_content_bytes({5, 6, 7, 8});
   query_controller.SendPageContentUpdateRequest(
       new_fake_content_bytes, lens::MimeType::kPlainText, GURL(kTestPageUrl));
-  task_environment_.RunUntilIdle();
 
   // The new page content request should have a different sequence ID.
   ASSERT_EQ(query_controller.sent_request_id().sequence_id(), 1);
@@ -1670,23 +1757,22 @@
       std::vector<lens::mojom::CenterRotatedBoxPtr>(),
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown,
       /**/ 0, base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
 
-  ASSERT_TRUE(full_image_response_future.IsReady());
+  // Wait for the full image response to be received, then clear the future.
+  ASSERT_TRUE(full_image_response_future.Wait());
   full_image_response_future.Clear();
 
   task_environment_.FastForwardBy(base::TimeDelta(base::Minutes(60)));
   query_controller.SendRegionSearch(std::move(region), lens::REGION_SEARCH,
                                     additional_search_query_params,
                                     std::nullopt);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
   query_controller.EndQuery();
 
   // The full image response having another value, after it was already
   // cleared, indicates that the query controller successfully started a
   // new query flow due to the timeout occurring.
   ASSERT_TRUE(full_image_response_future.IsReady());
-  ASSERT_TRUE(url_response_future.IsReady());
   ASSERT_EQ(query_controller.latency_gen_204_counter(
                 LatencyType::kFullPageObjectsRequestFetchLatency),
             2);
@@ -1733,7 +1819,7 @@
       std::vector<lens::mojom::CenterRotatedBoxPtr>(),
       /*underlying_content_bytes=*/{}, lens::MimeType::kUnknown, 0,
       base::TimeTicks::Now());
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(full_image_response_future.Wait());
 
   ASSERT_TRUE(full_image_response_future.IsReady());
   std::string first_analytics_id =
@@ -1741,7 +1827,8 @@
   query_controller.SendRegionSearch(std::move(region), lens::REGION_SEARCH,
                                     additional_search_query_params,
                                     std::nullopt);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
+  WaitForSuggestInputsWithEncodedImageSignals();
   query_controller.EndQuery();
 
   ASSERT_TRUE(url_response_future.IsReady());
@@ -1967,7 +2054,7 @@
   query_controller.SendMultimodalRequest(
       std::move(region), kTestQueryText, lens::MULTIMODAL_SEARCH,
       additional_search_query_params, std::nullopt);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
   query_controller.EndQuery();
 
   // Verify the routing info is included in the request id.
@@ -2032,7 +2119,7 @@
   query_controller.SendMultimodalRequest(
       std::move(region), kTestQueryText, lens::MULTIMODAL_SEARCH,
       additional_search_query_params, std::nullopt);
-  task_environment_.RunUntilIdle();
+  ASSERT_TRUE(url_response_future.Wait());
   query_controller.EndQuery();
 
   // Verify the routing info is included in the request id.
diff --git a/chrome/browser/ui/lens/test_lens_overlay_query_controller.cc b/chrome/browser/ui/lens/test_lens_overlay_query_controller.cc
index 7615922d..e85cd9d6 100644
--- a/chrome/browser/ui/lens/test_lens_overlay_query_controller.cc
+++ b/chrome/browser/ui/lens/test_lens_overlay_query_controller.cc
@@ -157,7 +157,8 @@
     const std::string& http_method,
     const base::TimeDelta& timeout,
     const std::vector<std::string>& request_headers,
-    const std::vector<std::string>& cors_exempt_headers) {
+    const std::vector<std::string>& cors_exempt_headers,
+    const UploadProgressCallback upload_progress_callback) {
   lens::LensOverlayServerResponse fake_server_response;
   std::string fake_server_response_string;
   google_apis::ApiErrorCode fake_server_response_code =
@@ -217,6 +218,18 @@
   fake_endpoint_response.response = fake_server_response_string;
   fake_endpoint_response.http_status_code = fake_server_response_code;
 
+  if (upload_progress_callback) {
+    last_upload_progress_callback_ = std::move(upload_progress_callback);
+  }
+  // If there is an upload progress callback, run it immedietly with 100%
+  // progress, unless disable_page_upload_response_callback in which case the
+  // caller will need to call the callback manually.
+  if (!disable_page_upload_response_callback &&
+      !last_upload_progress_callback_.is_null()) {
+    // Simulate the upload progress callback completing the upload.
+    std::move(last_upload_progress_callback_).Run(1, 1);
+  }
+
   auto response = std::make_unique<FakeEndpointFetcher>(fake_endpoint_response);
   response->disable_responding_ = disable_response;
   return response;
diff --git a/chrome/browser/ui/lens/test_lens_overlay_query_controller.h b/chrome/browser/ui/lens/test_lens_overlay_query_controller.h
index 5eb9bbf..459909a1 100644
--- a/chrome/browser/ui/lens/test_lens_overlay_query_controller.h
+++ b/chrome/browser/ui/lens/test_lens_overlay_query_controller.h
@@ -64,6 +64,14 @@
         next_full_image_request_should_return_error;
   }
 
+  void set_disable_page_upload_response_callback(bool disable) {
+    disable_page_upload_response_callback = disable;
+  }
+
+  void RunUploadProgressCallback() {
+    std::move(last_upload_progress_callback_).Run(1, 1);
+  }
+
   // Accessors.
   const GURL& sent_fetch_url() const { return sent_fetch_url_; }
 
@@ -190,7 +198,8 @@
       const std::string& http_method,
       const base::TimeDelta& timeout,
       const std::vector<std::string>& request_headers,
-      const std::vector<std::string>& cors_exempt_headers) override;
+      const std::vector<std::string>& cors_exempt_headers,
+      const UploadProgressCallback upload_progress_callback) override;
 
   void SendLatencyGen204IfEnabled(
       lens::LensOverlayGen204Controller::LatencyType latency_type,
@@ -214,6 +223,10 @@
   // If true, the next full image request will return an error.
   bool next_full_image_request_should_return_error_ = false;
 
+  // If true, the CreateEndpointFetcher will not automatically respond with a
+  // complete upload to the UploadProgressCallback.
+  bool disable_page_upload_response_callback = false;
+
   // The last url for which a fetch request was sent by the query controller.
   GURL sent_fetch_url_;
 
@@ -281,6 +294,9 @@
   // controller.
   base::flat_map<lens::LensOverlayGen204Controller::LatencyType, int>
       latency_gen_204_counter_;
+
+  // The last upload progress callback sent by the query controller.
+  UploadProgressCallback last_upload_progress_callback_;
 };
 
 }  // namespace lens
diff --git a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc
index 36db518..b6924fe 100644
--- a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc
+++ b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.cc
@@ -334,8 +334,6 @@
       role_(role),
       capturer_name_(std::move(capturer_name)),
       ui_(ui),
-      favicons_used_for_switch_to_tab_button_(
-          favicons_used_for_switch_to_tab_button),
       capture_type_(capture_type) {
   stop_button_ = std::make_unique<StopButton>(ui_, capture_type_);
 
diff --git a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h
index d3dc58f7..8c20380 100644
--- a/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h
+++ b/chrome/browser/ui/tab_sharing/tab_sharing_infobar_delegate.h
@@ -163,9 +163,6 @@
   // Creates and removes delegate's infobar; outlives delegate.
   const raw_ptr<TabSharingUI, AcrossTasksDanglingUntriaged> ui_;
 
-  // TODO(crbug.com/40188004): Re-enable favicons by default or drop the code.
-  const bool favicons_used_for_switch_to_tab_button_;
-
   // Indicates whether this instance is used for casting or capturing.
   const TabShareType capture_type_;
 
diff --git a/chrome/browser/ui/views/autofill/address_bubbles_icon_view.cc b/chrome/browser/ui/views/autofill/address_bubbles_icon_view.cc
index cf2bd97..e1d102e 100644
--- a/chrome/browser/ui/views/autofill/address_bubbles_icon_view.cc
+++ b/chrome/browser/ui/views/autofill/address_bubbles_icon_view.cc
@@ -30,6 +30,7 @@
                          "SaveAutofillAddress",
                          kActionShowAddressesBubbleOrPage) {
   GetViewAccessibility().SetName(GetTextForTooltipAndAccessibleName());
+  UpdateTooltipText();
 }
 
 AddressBubblesIconView::~AddressBubblesIconView() = default;
@@ -58,6 +59,7 @@
 
   SetVisible(should_show);
   GetViewAccessibility().SetName(GetTextForTooltipAndAccessibleName());
+  UpdateTooltipText();
 }
 
 std::u16string
diff --git a/chrome/browser/ui/views/autofill/payments/save_payment_icon_view.cc b/chrome/browser/ui/views/autofill/payments/save_payment_icon_view.cc
index c742b97..64c672f2 100644
--- a/chrome/browser/ui/views/autofill/payments/save_payment_icon_view.cc
+++ b/chrome/browser/ui/views/autofill/payments/save_payment_icon_view.cc
@@ -51,6 +51,7 @@
   command_id_ = command_id;
   SetUpForInOutAnimation();
   GetViewAccessibility().SetName(GetTextForTooltipAndAccessibleName());
+  UpdateTooltipText();
 }
 
 SavePaymentIconView::~SavePaymentIconView() = default;
@@ -84,6 +85,7 @@
   SetVisible(should_show);
 
   GetViewAccessibility().SetName(GetTextForTooltipAndAccessibleName());
+  UpdateTooltipText();
 
   if (command_enabled && controller->ShouldShowSavingPaymentAnimation()) {
     SetEnabled(false);
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_pane_view.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_pane_view.cc
index 4061323..bfdc9ba 100644
--- a/chrome/browser/ui/views/desktop_capture/desktop_media_pane_view.cc
+++ b/chrome/browser/ui/views/desktop_capture/desktop_media_pane_view.cc
@@ -18,7 +18,10 @@
     DesktopMediaList::Type type,
     std::unique_ptr<views::View> content_view,
     std::unique_ptr<ShareAudioView> share_audio_view)
-    : type_(type) {
+#if BUILDFLAG(IS_MAC)
+    : type_(type)
+#endif
+  {
   layout_ = SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kVertical, gfx::Insets(0)));
 
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_pane_view.h b/chrome/browser/ui/views/desktop_capture/desktop_media_pane_view.h
index b979789a..e972f0f 100644
--- a/chrome/browser/ui/views/desktop_capture/desktop_media_pane_view.h
+++ b/chrome/browser/ui/views/desktop_capture/desktop_media_pane_view.h
@@ -49,9 +49,10 @@
 #if BUILDFLAG(IS_MAC)
   bool PermissionRequired() const;
   void MakePermissionPaneView();
-#endif
 
   const DesktopMediaList::Type type_;
+#endif
+
   raw_ptr<views::BoxLayout> layout_ = nullptr;
   raw_ptr<DesktopMediaContentPaneView> content_pane_view_ = nullptr;
   raw_ptr<DesktopMediaPermissionPaneViewMac> permission_pane_view_ = nullptr;
diff --git a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
index 77d309d..883678c 100644
--- a/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
+++ b/chrome/browser/ui/views/desktop_capture/desktop_media_picker_views.cc
@@ -588,7 +588,7 @@
         break;
       }
     }
-    tabbed_pane->set_listener(this);
+    tabbed_pane->SetListener(this);
     tabbed_pane->SetFocusBehavior(views::View::FocusBehavior::NEVER);
     tabbed_pane_ = AddChildView(std::move(tabbed_pane));
   } else {
diff --git a/chrome/browser/ui/views/frame/browser_root_view.cc b/chrome/browser/ui/views/frame/browser_root_view.cc
index 99731743..42b9210 100644
--- a/chrome/browser/ui/views/frame/browser_root_view.cc
+++ b/chrome/browser/ui/views/frame/browser_root_view.cc
@@ -594,6 +594,7 @@
     params.tabstrip_index = insertion_index;
     base::RecordAction(base::UserMetricsAction("Tab_DropURLOnTab"));
     params.disposition = WindowOpenDisposition::CURRENT_TAB;
+    params.initiator_origin = event.data().GetRendererTaintedOrigin();
     params.source_contents = model->GetWebContentsAt(insertion_index);
     params.window_action = NavigateParams::SHOW_WINDOW;
     Navigate(&params);
@@ -613,6 +614,7 @@
         insertion_index < model->count()) {
       params.group = model->GetTabGroupForTab(insertion_index);
     }
+    params.initiator_origin = event.data().GetRendererTaintedOrigin();
     params.window_action = NavigateParams::SHOW_WINDOW;
     Navigate(&params);
   }
diff --git a/chrome/browser/ui/views/frame/browser_root_view.h b/chrome/browser/ui/views/frame/browser_root_view.h
index 3452bc06..acb3cac 100644
--- a/chrome/browser/ui/views/frame/browser_root_view.h
+++ b/chrome/browser/ui/views/frame/browser_root_view.h
@@ -97,6 +97,8 @@
   friend class BrowserRootViewBrowserTest;
   FRIEND_TEST_ALL_PREFIXES(BrowserRootViewBrowserTest, ClearDropInfo);
   FRIEND_TEST_ALL_PREFIXES(BrowserRootViewBrowserTest, DropOrderingCorrect);
+  FRIEND_TEST_ALL_PREFIXES(BrowserRootViewBrowserTest,
+                           InitiatorOriginForDroppedLink);
 
   // Used during a drop session of a url. Tracks the position of the drop.
   struct DropInfo {
diff --git a/chrome/browser/ui/views/frame/browser_root_view_browsertest.cc b/chrome/browser/ui/views/frame/browser_root_view_browsertest.cc
index 45c6f8d..0d8f092 100644
--- a/chrome/browser/ui/views/frame/browser_root_view_browsertest.cc
+++ b/chrome/browser/ui/views/frame/browser_root_view_browsertest.cc
@@ -18,6 +18,7 @@
 #include "content/public/browser/web_contents.h"
 #include "content/public/test/browser_test.h"
 #include "content/public/test/browser_test_utils.h"
+#include "content/public/test/navigation_handle_observer.h"
 #include "ui/base/dragdrop/drag_drop_types.h"
 #include "ui/base/dragdrop/drop_target_event.h"
 #include "ui/base/dragdrop/mojom/drag_drop_types.mojom.h"
@@ -431,3 +432,42 @@
                      std::nullopt);
   }
 }
+
+IN_PROC_BROWSER_TEST_F(BrowserRootViewBrowserTest,
+                       InitiatorOriginForDroppedLink) {
+  TabStripModel* model = browser()->tab_strip_model();
+  ASSERT_TRUE(AddTabAtIndex(0, GURL("about:blank"), ui::PAGE_TRANSITION_LINK));
+  using BrowserRootView::DropIndex::RelativeToIndex::kReplaceIndex;
+  ui::mojom::DragOperation drag_operation;
+
+  // Set drop event data with initiator origin.
+  ui::OSExchangeData data;
+  GURL target_url("about:blank?1");
+  url::Origin initiator_origin =
+      url::Origin::Create(GURL("https://www.initiator.com/"));
+  data.SetURL(target_url, std::u16string());
+  data.MarkRendererTaintedFromOrigin(initiator_origin);
+
+  ui::DropTargetEvent event(data, gfx::PointF(), gfx::PointF(),
+                            ui::DragDropTypes::DRAG_COPY);
+
+  std::unique_ptr<BrowserRootView::DropInfo> drop_info =
+      std::make_unique<BrowserRootView::DropInfo>();
+  drop_info->urls.push_back(target_url);
+  drop_info->index.emplace();
+  drop_info->index->index = 0;
+  drop_info->index->relative_to_index = kReplaceIndex;
+
+  // Add observer to web contents to track the navigation.
+  content::WebContents* contents = model->GetActiveWebContents();
+  content::NavigationHandleObserver observer(contents, target_url);
+
+  // Call NavigateToDroppedUrls and verify the initiator origin.
+  browser_root_view()->NavigateToDroppedUrls(std::move(drop_info), event,
+                                             drag_operation, nullptr);
+  content::WaitForLoadStop(contents);
+
+  EXPECT_EQ(target_url, contents->GetLastCommittedURL());
+  EXPECT_TRUE(observer.last_initiator_origin().has_value());
+  EXPECT_EQ(initiator_origin, observer.last_initiator_origin().value());
+}
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc
index 7c4cff2..ddecdfd 100644
--- a/chrome/browser/ui/views/frame/browser_view.cc
+++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -3993,10 +3993,7 @@
 #if BUILDFLAG(IS_CHROMEOS)
   ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
   if (browser_->is_type_normal()) {
-    int resource_id = ash::switches::IsAshDebugBrowserEnabled()
-                          ? IDR_DEBUG_CHROME_APP_ICON_192
-                          : IDR_CHROME_APP_ICON_192;
-    return ui::ImageModel::FromImage(rb.GetImageNamed(resource_id));
+    return ui::ImageModel::FromImage(rb.GetImageNamed(IDR_CHROME_APP_ICON_192));
   }
   auto* window = GetNativeWindow();
   int override_window_icon_resource_id =
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc
index f4a30e2..c4cf8f65f 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc
+++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.cc
@@ -114,6 +114,22 @@
   }
 }
 
+void CookieControlsIconView::UpdateTooltipText() {
+  if (!custom_tooltip_text_.empty()) {
+    SetCachedTooltipText(custom_tooltip_text_);
+  } else {
+    PageActionIconView::UpdateTooltipText();
+  }
+}
+
+std::u16string CookieControlsIconView::GetAlternativeAccessibleName() const {
+  if (!custom_tooltip_text_.empty()) {
+    return custom_tooltip_text_;
+  }
+
+  return PageActionIconView::GetAlternativeAccessibleName();
+}
+
 void CookieControlsIconView::MaybeShowIPH() {
   CHECK(browser_->window());
   user_education::FeaturePromoParams params(
@@ -220,7 +236,10 @@
   if (protections_changed_ || label()->GetText().empty()) {
     SetLabelForStatus();
   }
-  SetTooltipText(l10n_util::GetStringUTF16(GetLabelForStatus()));
+
+  custom_tooltip_text_ = l10n_util::GetStringUTF16(GetLabelForStatus());
+  SetTooltipText(custom_tooltip_text_);
+
   if (protections_on_ && should_highlight_) {
     if (blocking_status_ == CookieBlocking3pcdStatus::kNotIn3pcd) {
       MaybeShowIPH();
diff --git a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.h b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.h
index ffaf6ea..a3963e5 100644
--- a/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.h
+++ b/chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_icon_view.h
@@ -45,6 +45,10 @@
   // PageActionIconView:
   views::BubbleDialogDelegate* GetBubble() const override;
   void UpdateImpl() override;
+  void UpdateTooltipText() override;
+
+  // Button:
+  std::u16string GetAlternativeAccessibleName() const override;
 
   CookieControlsBubbleCoordinator* GetCoordinatorForTesting() const;
   void SetCoordinatorForTesting(
@@ -85,6 +89,8 @@
   bool should_highlight_ = false;
   GURL last_visited_url_;
 
+  std::u16string custom_tooltip_text_;
+
   // True if calls to UpdateImpl should noop for testing purposes.
   // TODO: 344042974 - Remove this once the issue has been resolved.
   bool disable_updates_for_testing_ = false;
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
index 2bca3e8..e72ae48 100644
--- a/chrome/browser/ui/views/page_action/page_action_icon_view.cc
+++ b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
@@ -14,6 +14,7 @@
 #include "chrome/browser/ui/views/location_bar/location_bar_util.h"
 #include "chrome/browser/ui/views/page_action/page_action_icon_loading_indicator_view.h"
 #include "chrome/browser/ui/views/page_action/page_action_icon_view_observer.h"
+#include "page_action_icon_view.h"
 #include "ui/accessibility/ax_enums.mojom.h"
 #include "ui/base/l10n/l10n_util.h"
 #include "ui/base/metadata/metadata_impl_macros.h"
@@ -86,6 +87,12 @@
   button_controller()->set_notify_action(
       views::ButtonController::NotifyAction::kOnRelease);
   UpdateBorder();
+
+  name_changed_subscription_ =
+      GetViewAccessibility().AddStringAttributeChangedCallback(
+          ax::mojom::StringAttribute::kName,
+          base::BindRepeating(&PageActionIconView::OnAXNameChanged,
+                              base::Unretained(this)));
 }
 
 PageActionIconView::~PageActionIconView() = default;
@@ -125,13 +132,14 @@
   InstallLoadingIndicator();
 }
 
-std::u16string PageActionIconView::GetTextForTooltipAndAccessibleName() const {
-  return GetViewAccessibility().GetCachedName();
+void PageActionIconView::OnAXNameChanged(
+    ax::mojom::StringAttribute attribute,
+    const std::optional<std::string>& name) {
+  UpdateTooltipText();
 }
 
-std::u16string PageActionIconView::GetTooltipText(const gfx::Point& p) const {
-  return IsBubbleShowing() ? std::u16string()
-                           : GetTextForTooltipAndAccessibleName();
+std::u16string PageActionIconView::GetTextForTooltipAndAccessibleName() const {
+  return GetViewAccessibility().GetCachedName();
 }
 
 void PageActionIconView::ViewHierarchyChanged(
@@ -237,6 +245,8 @@
   active_ = active;
   UpdateIconImage();
   OnPropertyChanged(&active_, views::kPropertyEffectsNone);
+  // For StarView
+  UpdateTooltipText();
 }
 
 bool PageActionIconView::GetActive() const {
@@ -253,6 +263,7 @@
     UpdateImpl();
   }
   UpdateBorder();
+  UpdateTooltipText();
 }
 
 void PageActionIconView::UpdateIconImage() {
@@ -310,6 +321,12 @@
   }
 }
 
+void PageActionIconView::UpdateTooltipText() {
+  SetCachedTooltipText(IsBubbleShowing()
+                           ? std::u16string()
+                           : GetTextForTooltipAndAccessibleName());
+}
+
 void PageActionIconView::InstallLoadingIndicator() {
   if (loading_indicator_) {
     return;
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.h b/chrome/browser/ui/views/page_action/page_action_icon_view.h
index 8705c17..2d6226f 100644
--- a/chrome/browser/ui/views/page_action/page_action_icon_view.h
+++ b/chrome/browser/ui/views/page_action/page_action_icon_view.h
@@ -160,7 +160,6 @@
   virtual void OnPressed(bool activated) {}
 
   // IconLabelBubbleView:
-  std::u16string GetTooltipText(const gfx::Point& p) const override;
   void ViewHierarchyChanged(
       const views::ViewHierarchyChangedDetails& details) override;
   void OnThemeChanged() override;
@@ -170,6 +169,8 @@
   bool ShouldUpdateInkDropOnClickCanceled() const override;
   void UpdateBorder() override;
 
+  virtual void UpdateTooltipText();
+
  protected:
   // Calls OnExecuting and runs |command_id_| with a valid |command_updater_|.
   virtual void ExecuteCommand(ExecuteSource source);
@@ -209,6 +210,9 @@
  private:
   void InstallLoadingIndicator();
 
+  void OnAXNameChanged(ax::mojom::StringAttribute attribute,
+                       const std::optional<std::string>& name);
+
   // What color to paint the icon with.
   SkColor icon_color_ = gfx::kPlaceholderColor;
 
@@ -243,6 +247,8 @@
 
   base::ObserverList<PageActionIconViewObserver>::UncheckedAndDanglingUntriaged
       observer_list_;
+
+  base::CallbackListSubscription name_changed_subscription_;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_PAGE_ACTION_PAGE_ACTION_ICON_VIEW_H_
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view_unittest.cc b/chrome/browser/ui/views/page_action/page_action_icon_view_unittest.cc
index 09ee2b21..4af23ecd 100644
--- a/chrome/browser/ui/views/page_action/page_action_icon_view_unittest.cc
+++ b/chrome/browser/ui/views/page_action/page_action_icon_view_unittest.cc
@@ -80,8 +80,18 @@
 
   views::BubbleDialogDelegate* GetBubble() const override { return nullptr; }
 
+  bool IsBubbleShowing() const override {
+    return is_bubble_showing_override_ ? true
+                                       : PageActionIconView::IsBubbleShowing();
+  }
+
   bool IsLabelVisible() const { return label()->GetVisible(); }
 
+  void SetIsBubbleShowingOverride(bool is_bubble_showing_override) {
+    is_bubble_showing_override_ = is_bubble_showing_override;
+    Update();
+  }
+
  protected:
   // PageActionIconView:
   void OnExecuting(ExecuteSource execute_source) override {}
@@ -89,6 +99,9 @@
     return gfx::kNoneIcon;
   }
   void UpdateImpl() override {}
+
+ private:
+  bool is_bubble_showing_override_ = false;
 };
 
 class TestPageActionIconViewWithIconImage : public TestPageActionIconView {
@@ -161,6 +174,58 @@
   EXPECT_FALSE(view()->IsLabelVisible());
 }
 
+TEST_F(PageActionIconViewTest, TooltipText) {
+  view()->AnimateIn(std::nullopt);
+  EXPECT_FALSE(view()->IsBubbleShowing());
+  EXPECT_EQ(view()->GetTooltipText(gfx::Point()),
+            view()->GetTextForTooltipAndAccessibleName());
+  EXPECT_EQ(view()->GetTooltipText(gfx::Point()), u"TestTooltip");
+
+  view()->GetViewAccessibility().SetName(u"NewTooltip");
+
+  EXPECT_FALSE(view()->IsBubbleShowing());
+  EXPECT_EQ(view()->GetTooltipText(gfx::Point()),
+            view()->GetTextForTooltipAndAccessibleName());
+  EXPECT_EQ(view()->GetTooltipText(gfx::Point()), u"NewTooltip");
+
+  view()->SetIsBubbleShowingOverride(true);
+
+  EXPECT_TRUE(view()->IsBubbleShowing());
+  EXPECT_EQ(view()->GetTooltipText(gfx::Point()), u"");
+}
+
+TEST_F(PageActionIconViewTest, TooltipTextAccessibility) {
+  view()->AnimateIn(std::nullopt);
+
+  ui::AXNodeData data;
+  EXPECT_FALSE(view()->IsBubbleShowing());
+  view()->GetViewAccessibility().GetAccessibleNodeData(&data);
+  EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName),
+            view()->GetTooltipText());
+  EXPECT_NE(data.GetString16Attribute(ax::mojom::StringAttribute::kDescription),
+            view()->GetTooltipText());
+
+  view()->GetViewAccessibility().SetName(u"NewTooltip");
+
+  data = ui::AXNodeData();
+  EXPECT_FALSE(view()->IsBubbleShowing());
+  view()->GetViewAccessibility().GetAccessibleNodeData(&data);
+  EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kName),
+            view()->GetTooltipText());
+  EXPECT_NE(data.GetString16Attribute(ax::mojom::StringAttribute::kDescription),
+            view()->GetTooltipText());
+
+  view()->SetIsBubbleShowingOverride(true);
+
+  data = ui::AXNodeData();
+  EXPECT_TRUE(view()->IsBubbleShowing());
+  view()->GetViewAccessibility().GetAccessibleNodeData(&data);
+  EXPECT_NE(data.GetString16Attribute(ax::mojom::StringAttribute::kName),
+            view()->GetTooltipText());
+  EXPECT_EQ(data.GetString16Attribute(ax::mojom::StringAttribute::kDescription),
+            view()->GetTooltipText());
+}
+
 TEST_F(PageActionIconViewTest, ShouldNotResetSlideAnimationWhenShowIcons) {
   delegate()->set_should_hide_page_action_icons(true);
   view()->AnimateIn(std::nullopt);
diff --git a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
index ed2b561..5126c10 100644
--- a/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
+++ b/chrome/browser/ui/views/page_action/pwa_install_view_browsertest.cc
@@ -105,7 +105,6 @@
 #include "chrome/browser/ash/app_list/arc/arc_app_list_prefs.h"
 #include "chrome/browser/ash/arc/arc_util.h"
 #include "chrome/browser/ash/arc/session/arc_session_manager.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 namespace webapps {
@@ -164,14 +163,8 @@
          {{feature_engagement::kIPHDemoModeFeatureChoiceParam,
            feature_engagement::kIPHDesktopPwaInstallFeature.name}}},
         {feature_engagement::kIPHDesktopPwaInstallFeature, {}}};
-    std::vector<base::test::FeatureRef> disabled_features;
 
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-    base::Extend(disabled_features, ash::standalone_browser::GetFeatureRefs());
-#endif  // BUILDFLAG(IS_CHROMEOS_ASH)
-
-    features_.InitWithFeaturesAndParameters(enabled_features,
-                                            disabled_features);
+    features_.InitWithFeaturesAndParameters(enabled_features, {});
   }
 
   PwaInstallViewBrowserTest(const PwaInstallViewBrowserTest&) = delete;
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
index 5305669..2992043 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_icon_views.cc
@@ -43,6 +43,7 @@
   const std::u16string tooltip_and_accessible_name_text =
       GetTextForTooltipAndAccessibleName();
   GetViewAccessibility().SetName(tooltip_and_accessible_name_text);
+  UpdateTooltipText();
 
   // TODO(b/353777476): Strip out pinned toolbar button code into a shared
   // controller for page action and pinned button.
@@ -68,6 +69,7 @@
   const std::u16string tooltip_and_accessible_name_text =
       GetTextForTooltipAndAccessibleName();
   GetViewAccessibility().SetName(tooltip_and_accessible_name_text);
+  UpdateTooltipText();
 
   // TODO(b/353777476): Strip out pinned toolbar button code into a shared
   // controller for page action and pinned button.
diff --git a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.cc b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.cc
index ebfd1fc..83651b5 100644
--- a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.cc
+++ b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.cc
@@ -62,8 +62,7 @@
     content::WebContents* web_contents,
     signin_metrics::AccessPoint access_point,
     base::OnceCallback<void(content::WebContents*)> move_callback)
-    : controller_(*web_contents, access_point, std::move(move_callback)),
-      access_point_(access_point) {
+    : controller_(*web_contents, access_point, std::move(move_callback)) {
   SetLayoutManager(std::make_unique<views::FillLayout>());
 
   Profile* profile =
diff --git a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.h b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.h
index 534ca91..82234316 100644
--- a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.h
+++ b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.h
@@ -54,7 +54,6 @@
   void AddedToWidget() override;
 
   autofill::AutofillBubbleSignInPromoController controller_;
-  const signin_metrics::AccessPoint access_point_;
   std::unique_ptr<DiceSigninPromoDelegate> dice_sign_in_promo_delegate_;
   base::ScopedObservation<views::Widget, views::WidgetObserver>
       scoped_widget_observation_{this};
diff --git a/chrome/browser/ui/views/task_manager_view.cc b/chrome/browser/ui/views/task_manager_view.cc
index f4bf484..2b1fe8b 100644
--- a/chrome/browser/ui/views/task_manager_view.cc
+++ b/chrome/browser/ui/views/task_manager_view.cc
@@ -400,20 +400,14 @@
 }
 
 std::unique_ptr<views::View> TaskManagerView::CreateTabbedPane() {
-  auto tabs = std::make_unique<views::TabbedPane>(
+  auto tabs = std::make_unique<views::TabbedPaneTabStrip>(
       views::TabbedPane::Orientation::kHorizontal,
-      views::TabbedPane::TabStripStyle::kCompactWithIcon);
-  tabs->SetCrossAxisAlignment(views::LayoutAlignment::kStart);
-  tabs->SetPreferredSize(
-      gfx::Size(kTaskManagerHeaderWidth, kTaskManagerHeaderHeight));
-  tabs->SetProperty(views::kFlexBehaviorKey,
-                    views::FlexSpecification(
-                        views::MinimumFlexSizeRule::kScaleToMinimumSnapToZero,
-                        views::MaximumFlexSizeRule::kPreferred));
+      views::TabbedPane::TabStripStyle::kCompactWithIcon,
+      /*tabbed_pane=*/nullptr);
+  tabs->SetDefaultFlex(0);
 
   for (const auto& tab : kTabDefinitions) {
-    tabs->AddTab(l10n_util::GetStringUTF16(tab.title_id),
-                 std::make_unique<views::View>(), tab.icon);
+    tabs->AddTab(l10n_util::GetStringUTF16(tab.title_id), tab.icon);
   }
   tabs->set_listener(this);
 
@@ -447,8 +441,7 @@
       CreateSeparator(gfx::Insets::TLBR(0, 0, separator_spacing, 0));
 
   // Allow empty spacing and the search bar to flex freely.
-  header_layout->SetFlexForView(tabs.get(), 1);
-  header_layout->SetFlexForView(empty_view.get(), 1);
+  header_layout->SetFlexForView(empty_view.get(), 2);
   header_layout->SetFlexForView(search_bar.get(), 3);
 
   // Set the layout manager for the parent container to BoxLayout.
diff --git a/chrome/browser/ui/views/task_manager_view.h b/chrome/browser/ui/views/task_manager_view.h
index e46e2d6..7df6d30 100644
--- a/chrome/browser/ui/views/task_manager_view.h
+++ b/chrome/browser/ui/views/task_manager_view.h
@@ -57,9 +57,6 @@
   TaskManagerView& operator=(const TaskManagerView&) = delete;
   ~TaskManagerView() override;
 
-  static constexpr size_t kTaskManagerHeaderWidth = 250;
-  static constexpr size_t kTaskManagerHeaderHeight = 32;
-
   // Shows the Task Manager window, or re-activates an existing one.
   static task_manager::TaskManagerTableModel* Show(
       Browser* browser,
diff --git a/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc b/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
index 5ccc224..e39042d 100644
--- a/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/partial_translate_bubble_view.cc
@@ -521,7 +521,7 @@
       views::CreateEmptyBorder(gfx::Insets::VH(2, 20)));
   tabbed_pane_->GetTabAt(1)->SetBorder(
       views::CreateEmptyBorder(gfx::Insets::VH(2, 20)));
-  tabbed_pane_->set_listener(this);
+  tabbed_pane_->SetListener(this);
 
   auto* padding_view =
       tab_view_top_row_->AddChildView(std::make_unique<views::View>());
@@ -1061,9 +1061,9 @@
     // other than user interaction, |this| needs to unregister from listening
     // to the tabbed pane events otherwise it'll trigger an additional
     // translation as if the user had clicked the tabs.
-    tabbed_pane_->set_listener(nullptr);
+    tabbed_pane_->SetListener(nullptr);
     tabbed_pane_->SelectTabAt(1, false);
-    tabbed_pane_->set_listener(this);
+    tabbed_pane_->SetListener(this);
   } else if (view_state ==
                  PartialTranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE &&
              tabbed_pane_->GetSelectedTabIndex() != 0) {
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc
index 5d7ffb6..3c824cd 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -646,7 +646,7 @@
       views::CreateEmptyBorder(gfx::Insets::VH(2, 20)));
   tabbed_pane_->GetTabAt(1)->SetBorder(
       views::CreateEmptyBorder(gfx::Insets::VH(2, 20)));
-  tabbed_pane_->set_listener(this);
+  tabbed_pane_->SetListener(this);
 
   auto* padding_view =
       horizontal_view->AddChildView(std::make_unique<views::View>());
@@ -1098,9 +1098,9 @@
     // other than user interaction, |this| needs to unregister from listening
     // to the tabbed pane events otherwise it'll trigger an additional
     // translation as if the user had clicked the tabs.
-    tabbed_pane_->set_listener(nullptr);
+    tabbed_pane_->SetListener(nullptr);
     tabbed_pane_->SelectTabAt(1, false);
-    tabbed_pane_->set_listener(this);
+    tabbed_pane_->SetListener(this);
   } else if (view_state == TranslateBubbleModel::VIEW_STATE_BEFORE_TRANSLATE &&
              tabbed_pane_->GetSelectedTabIndex() != 0) {
     tabbed_pane_->SelectTabAt(0);
diff --git a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
index 1988267..64a3d73 100644
--- a/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
+++ b/chrome/browser/ui/views/web_apps/web_app_integration_test_driver.cc
@@ -161,7 +161,6 @@
 #include "ash/constants/ash_features.h"
 #include "chrome/browser/apps/app_service/app_service_proxy.h"
 #include "chrome/browser/ui/views/apps/app_dialog/app_uninstall_dialog_view.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #else
 #include "chrome/browser/ui/webui/app_home/app_home.mojom.h"
 #include "chrome/browser/ui/webui/app_home/app_home_page_handler.h"
@@ -4714,7 +4713,6 @@
 
 WebAppIntegrationTest::WebAppIntegrationTest() : helper_(this) {
   std::vector<base::test::FeatureRef> enabled_features;
-  std::vector<base::test::FeatureRef> disabled_features;
   enabled_features.push_back(blink::features::kDesktopPWAsSubApps);
   enabled_features.push_back(blink::features::kDesktopPWAsTabStrip);
   enabled_features.push_back(features::kDesktopPWAsTabStripSettings);
@@ -4724,21 +4722,13 @@
   enabled_features.push_back(features::kRecordWebAppDebugInfo);
   enabled_features.push_back(features::kWebAppDontAddExistingAppsToSync);
 #if BUILDFLAG(IS_CHROMEOS)
-  // WebAppIntegrationTest runs in Ash only when Lacros is disabled.
-  // If Lacros is enabled, WebAppIntegrationTest runs in Lacros with crosapi
-  // enabled.
-  //
-  // TODO(crbug.com/375937556): Revise this now that the Lacros support is
-  // removed.
-  base::Extend(disabled_features, ash::standalone_browser::GetFeatureRefs());
-
   // TODO(crbug.com/40236806): Update test driver to work with new UI.
   enabled_features.push_back(apps::features::kLinkCapturingUiUpdate);
 #else
   // TODO(b/313492499): Update test driver to work with new intent picker UI.
   enabled_features.push_back(features::kPwaNavigationCapturing);
 #endif  // BUILDFLAG(IS_CHROMEOS)
-  scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
+  scoped_feature_list_.InitWithFeatures(enabled_features, {});
 }
 
 WebAppIntegrationTest::~WebAppIntegrationTest() = default;
diff --git a/chrome/browser/ui/webui/on_device_internals/on_device_internals_page_handler.cc b/chrome/browser/ui/webui/on_device_internals/on_device_internals_page_handler.cc
index 412dcb4..ee69491 100644
--- a/chrome/browser/ui/webui/on_device_internals/on_device_internals_page_handler.cc
+++ b/chrome/browser/ui/webui/on_device_internals/on_device_internals_page_handler.cc
@@ -63,7 +63,6 @@
     const base::FilePath& model_path,
     mojo::PendingReceiver<on_device_model::mojom::OnDeviceModel> model,
     LoadModelCallback callback) {
-  base_model_.reset();
 #if BUILDFLAG(USE_CHROMEOS_MODEL_SERVICE)
   // We treat the file path as a UUID on ChromeOS.
   base::Uuid uuid = base::Uuid::ParseLowercase(model_path.value());
@@ -111,32 +110,14 @@
     mojo::PendingReceiver<on_device_model::mojom::OnDeviceModel> model,
     LoadModelCallback callback,
     on_device_model::ModelAssets assets) {
-  auto receiver = base_model_.BindNewPipeAndPassReceiver();
   auto params = on_device_model::mojom::LoadModelParams::New();
   params->assets = std::move(assets);
   params->max_tokens = 4096;
-  GetService().LoadModel(
-      std::move(params), std::move(receiver),
-      base::BindOnce(&OnDeviceInternalsPageHandler::LoadAdaptation,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(model),
-                     std::move(callback)));
+  GetService().LoadModel(std::move(params), std::move(model),
+                         std::move(callback));
 }
 #endif
 
-void OnDeviceInternalsPageHandler::LoadAdaptation(
-    mojo::PendingReceiver<on_device_model::mojom::OnDeviceModel> model,
-    LoadModelCallback callback,
-    on_device_model::mojom::LoadModelResult result) {
-  if (result != on_device_model::mojom::LoadModelResult::kSuccess) {
-    std::move(callback).Run(result);
-    return;
-  }
-  auto params = on_device_model::mojom::LoadAdaptationParams::New();
-  params->enable_image_input = true;
-  base_model_->LoadAdaptation(std::move(params), std::move(model),
-                              std::move(callback));
-}
-
 void OnDeviceInternalsPageHandler::GetEstimatedPerformanceClass(
     GetEstimatedPerformanceClassCallback callback) {
   GetService().GetEstimatedPerformanceClass(
diff --git a/chrome/browser/ui/webui/on_device_internals/on_device_internals_page_handler.h b/chrome/browser/ui/webui/on_device_internals/on_device_internals_page_handler.h
index f66287b..a42e203a 100644
--- a/chrome/browser/ui/webui/on_device_internals/on_device_internals_page_handler.h
+++ b/chrome/browser/ui/webui/on_device_internals/on_device_internals_page_handler.h
@@ -65,16 +65,10 @@
                          int source_line,
                          const std::string& message) override;
 
-  void LoadAdaptation(
-      mojo::PendingReceiver<on_device_model::mojom::OnDeviceModel> model,
-      LoadModelCallback callback,
-      on_device_model::mojom::LoadModelResult result);
-
   mojo::Receiver<mojom::OnDeviceInternalsPageHandler> receiver_;
   mojo::Remote<mojom::OnDeviceInternalsPage> page_;
 
   mojo::Remote<Service> service_;
-  mojo::Remote<on_device_model::mojom::OnDeviceModel> base_model_;
 
   // Logger to receive the debug logs from the optimization guide service. Not
   // owned. Guaranteed to outlive |this|, since the logger is owned by the
diff --git a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_manager_unittest.cc
index c1e260f5..2ac5c5a6 100644
--- a/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_manager_unittest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/policy/isolated_web_app_policy_manager_unittest.cc
@@ -602,6 +602,9 @@
       test_managed_guest_session_ =
           std::make_unique<profiles::testing::ScopedTestManagedGuestSession>();
     }
+#else
+    // Suppress -Wunused-private-field warning.
+    (void)is_user_session_;
 #endif  // BUILDFLAG(IS_CHROMEOS)
 
 #if BUILDFLAG(ENABLE_NACL)
diff --git a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
index 62b2e41..73c3d516 100644
--- a/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
+++ b/chrome/browser/web_applications/manifest_update_manager_browsertest.cc
@@ -128,7 +128,6 @@
 #if BUILDFLAG(IS_CHROMEOS_ASH)
 #include "ash/constants/ash_features.h"
 #include "chrome/browser/ash/system_web_apps/test_support/test_system_web_app_installation.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #endif
 
 #if BUILDFLAG(IS_LINUX)
@@ -330,12 +329,7 @@
  public:
   ManifestUpdateManagerBrowserTest()
       : update_dialog_scope_(SetIdentityUpdateDialogActionForTesting(
-            AppIdentityUpdate::kSkipped)) {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-    scoped_feature_list_.InitWithFeatures(
-        {}, ash::standalone_browser::GetFeatureRefs());
-#endif
-  }
+            AppIdentityUpdate::kSkipped)) {}
   ManifestUpdateManagerBrowserTest(const ManifestUpdateManagerBrowserTest&) =
       delete;
   ManifestUpdateManagerBrowserTest& operator=(
diff --git a/chrome/browser/web_applications/policy/web_app_policy_manager_unittest.cc b/chrome/browser/web_applications/policy/web_app_policy_manager_unittest.cc
index 6c13c4df..5dd0b9f 100644
--- a/chrome/browser/web_applications/policy/web_app_policy_manager_unittest.cc
+++ b/chrome/browser/web_applications/policy/web_app_policy_manager_unittest.cc
@@ -69,7 +69,6 @@
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
 #include "chrome/browser/ash/profiles/profile_helper.h"
 #include "chrome/browser/ash/system_web_apps/test_support/test_system_web_app_manager.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "components/user_manager/scoped_user_manager.h"
 #include "components/user_manager/user_names.h"
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc b/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc
index f5cd8ef..a83a9ea 100644
--- a/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc
+++ b/chrome/browser/web_applications/preinstalled_web_app_manager_unittest.cc
@@ -50,7 +50,6 @@
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_switches.h"
 #include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "chromeos/ash/components/system/fake_statistics_provider.h"
 #include "chromeos/ash/components/system/statistics_provider.h"
 #include "components/user_manager/scoped_user_manager.h"
@@ -77,13 +76,7 @@
 
 class PreinstalledWebAppManagerTest : public testing::Test {
  public:
-  PreinstalledWebAppManagerTest() {
-#if BUILDFLAG(IS_CHROMEOS_ASH)
-    scoped_feature_list_.InitWithFeatures(
-        {}, /*disabled_features=*/ash::standalone_browser::GetFeatureRefs());
-#endif
-  }
-
+  PreinstalledWebAppManagerTest() = default;
   PreinstalledWebAppManagerTest(const PreinstalledWebAppManagerTest&) = delete;
   PreinstalledWebAppManagerTest& operator=(
       const PreinstalledWebAppManagerTest&) = delete;
@@ -258,7 +251,6 @@
   raw_ptr<FakeWebAppProvider> provider_ = nullptr;
   std::unique_ptr<Profile> profile_;
 
-  base::test::ScopedFeatureList scoped_feature_list_;
   // To support context of browser threads.
   content::BrowserTaskEnvironment task_environment_;
 };
diff --git a/chrome/browser/web_applications/web_app_proto_utils_unittest.cc b/chrome/browser/web_applications/web_app_proto_utils_unittest.cc
index 2784755..ce9b1151 100644
--- a/chrome/browser/web_applications/web_app_proto_utils_unittest.cc
+++ b/chrome/browser/web_applications/web_app_proto_utils_unittest.cc
@@ -39,13 +39,9 @@
   // sync_pb::WebAppIconInfo* icon_info = sync_proto.add_icon_infos();
   // icon_info->set_url(kIconUrl);
   // sync_proto.SerializeAsString()
-  const std::string serialized_proto = {
-      10,  29,  104, 116, 116, 112, 115, 58,  47,  47,  101, 120, 97,
-      109, 112, 108, 101, 46,  99,  111, 109, 47,  108, 97,  117, 110,
-      99,  104, 117, 114, 108, 18,  9,   84,  101, 115, 116, 32,  110,
-      97,  109, 101, 24,  1,   50,  30,  18,  28,  104, 116, 116, 112,
-      115, 58,  47,  47,  101, 120, 97,  109, 112, 108, 101, 46,  99,
-      111, 109, 47,  105, 99,  111, 110, 46,  112, 110, 103};
+  const std::string serialized_proto =
+      "\n\035https://example.com/launchurl\022\tTest "
+      "name\030\0012\036\022\034https://example.com/icon.png";
 
   // Parse the proto.
   sync_pb::WebAppSpecifics sync_proto;
@@ -153,11 +149,9 @@
   //     sync_pb::WebAppSpecifics::BROWSER);
   // sync_proto.set_test_new_field("hello");
   // sync_proto.SerializeAsString();
-  const std::string serialized_proto = {
-      10,  29,  104, 116, 116, 112, 115, 58,  47,  47,  101, 120, 97,  109,
-      112, 108, 101, 46,  99,  111, 109, 47,  108, 97,  117, 110, 99,  104,
-      117, 114, 108, 18,  9,   84,  101, 115, 116, 32,  110, 97,  109, 101,
-      24,  1,   -6,  -75, -65, 20,  5,   104, 101, 108, 108, 111};
+  const std::string serialized_proto =
+      "\n\035https://example.com/launchurl\022\tTest "
+      "name\030\001\372\265\277\024\005hello";
 
   // Parse the proto.
   sync_pb::WebAppSpecifics sync_proto;
@@ -194,11 +188,8 @@
   // sync_proto.set_user_display_mode_default(
   //     sync_pb::WebAppSpecifics::TEST_NEW_ENUM);
   // sync_proto.SerializeAsString();
-  const std::string serialized_proto = {
-      10,  29,  104, 116, 116, 112, 115, 58,  47,  47,  101, 120,
-      97,  109, 112, 108, 101, 46,  99,  111, 109, 47,  108, 97,
-      117, 110, 99,  104, 117, 114, 108, 18,  9,   84,  101, 115,
-      116, 32,  110, 97,  109, 101, 24,  -33, -10, -57, 2};
+  const std::string serialized_proto =
+      "\n\035https://example.com/launchurl\022\tTest name\030\337\366\307\002";
 
   // Parse the proto.
   sync_pb::WebAppSpecifics sync_proto;
diff --git a/chrome/browser/webauthn/enclave_authenticator_browsertest.cc b/chrome/browser/webauthn/enclave_authenticator_browsertest.cc
index 266ca82..dd0f1eb 100644
--- a/chrome/browser/webauthn/enclave_authenticator_browsertest.cc
+++ b/chrome/browser/webauthn/enclave_authenticator_browsertest.cc
@@ -1243,8 +1243,9 @@
 
 #if BUILDFLAG(IS_MAC)
 
+// TODO(crbug.com/383203166): Disabled on Mac for test failures.
 IN_PROC_BROWSER_TEST_F(EnclaveAuthenticatorWithPinBrowserTest,
-                       RegisterICloudDriveEnabled_NoGPMDefault) {
+                       DISABLED_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.
@@ -2898,8 +2899,15 @@
   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,
-                       NotForSameGoogleAccount) {
+                       MAYBE_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 a875f3c..042654f 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1733767079-ed63c072f29731992bce06cff737692ed97385b5-106ceb1dbb65b494b52551528e96d9ece104b539.profdata
+chrome-android32-main-1733788618-2096c1951c9b84a84582c46055670670c7ca6534-872845b531cb7018551c5793e17b3723042fff57.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index a8a9aac..b43b6a8 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1733781667-37533ee21663a405a7aa7e79705522e2a79c7e4c-a9a4618437c029c65dc912e1353ded0f64b343bf.profdata
+chrome-android64-main-1733796456-402bd8c89662b7dd01bec246eef4f7a675820d3b-7e857a6426b8b0b86181e1665b7084809e4af280.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 3a7f9ba..8b15201 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1733774340-bcc1732025173044819df3950e5b70e88d7942a3-91cb2eade960b99f42ad2507e1e5be0845354b64.profdata
+chrome-mac-arm-main-1733803095-0d1080d69caff4521a69ac6ae1c2ecd9d4280393-5bc05a8d3e602a1ddce3d91e95de39b50b5852dc.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 65b0f2b..2773df3 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1733767079-b3d6270d7f4b1d37f738ad00cfe96d0f842e89d6-106ceb1dbb65b494b52551528e96d9ece104b539.profdata
+chrome-mac-main-1733788618-fb22938060ccc681da1f8fba516ffba3eec86d2c-872845b531cb7018551c5793e17b3723042fff57.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 9af14b3..31b28de 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1733767079-f8726634af4e02f6af95cdfb21766002aa8b165f-106ceb1dbb65b494b52551528e96d9ece104b539.profdata
+chrome-win-arm64-main-1733788618-bb1752d174daf945d1b973af9dc0e83c6c38d84a-872845b531cb7018551c5793e17b3723042fff57.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 5bf32ea..0f9f07f 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1733767079-79f2e89737866f9feb5de7fab78a48f83b91bab0-106ceb1dbb65b494b52551528e96d9ece104b539.profdata
+chrome-win32-main-1733788618-581dac89a428443a95aa82f2d81500b223ff5ab5-872845b531cb7018551c5793e17b3723042fff57.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 123be91f..61d9005 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1733756395-c0bc61fbd13cca77055ecfa7d99842ca75e4a3d4-ab9e8b4788f6c05494f8c5b1ced0918acf62dda1.profdata
+chrome-win64-main-1733788618-befca43d813d42d0b506449ace5e9dc9af14211c-872845b531cb7018551c5793e17b3723042fff57.profdata
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc
index 8e63262a3..2de0f27 100644
--- a/chrome/common/chrome_features.cc
+++ b/chrome/common/chrome_features.cc
@@ -603,9 +603,15 @@
 
 // Enables HTTPS-First Mode in a balanced configuration that doesn't warn on
 // HTTP when HTTPS can't be reasonably expected.
+#if BUILDFLAG(IS_ANDROID)
+BASE_FEATURE(kHttpsFirstBalancedMode,
+             "HttpsFirstBalancedMode",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+#else
 BASE_FEATURE(kHttpsFirstBalancedMode,
              "HttpsFirstBalancedMode",
              base::FEATURE_ENABLED_BY_DEFAULT);
+#endif
 
 // Automatically enables HTTPS-First Mode in a balanced configuration when
 // possible.
diff --git a/chrome/services/cups_proxy/DEPS b/chrome/services/cups_proxy/DEPS
index 8e1c5fa..c79cba02 100644
--- a/chrome/services/cups_proxy/DEPS
+++ b/chrome/services/cups_proxy/DEPS
@@ -2,5 +2,6 @@
   "+chromeos/printing",
   "+chrome/services/ipp_parser",
   "+chromeos/ash/components/dbus/cups_proxy",
+  "+mojo/core",
   "+third_party/cros_system_api/dbus",
 ]
diff --git a/chrome/services/cups_proxy/cups_proxy_service.cc b/chrome/services/cups_proxy/cups_proxy_service.cc
index b3558f97d..1bdab40 100644
--- a/chrome/services/cups_proxy/cups_proxy_service.cc
+++ b/chrome/services/cups_proxy/cups_proxy_service.cc
@@ -12,6 +12,7 @@
 #include "chrome/services/cups_proxy/cups_proxy_service_delegate.h"
 #include "chrome/services/cups_proxy/proxy_manager.h"
 #include "chromeos/ash/components/dbus/cups_proxy/cups_proxy_client.h"
+#include "mojo/core/configuration.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/system/invitation.h"
 #include "third_party/cros_system_api/dbus/service_constants.h"
@@ -55,6 +56,9 @@
   // Include an initial Mojo pipe in the invitation.
   mojo::ScopedMessagePipeHandle pipe = invitation.AttachMessagePipe(
       ::printing::kBootstrapMojoConnectionChannelToken);
+  if (!mojo::core::GetConfiguration().is_broker_process) {
+    invitation.set_extra_flags(MOJO_SEND_INVITATION_FLAG_SHARE_BROKER);
+  }
   mojo::OutgoingInvitation::Send(std::move(invitation),
                                  base::kNullProcessHandle,
                                  platform_channel.TakeLocalEndpoint());
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index 46b3100..87bdce9 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1020,7 +1020,6 @@
       "//chromeos/ash/components/dbus/shill",
       "//chromeos/ash/components/disks:test_support",
       "//chromeos/ash/components/nearby/common/connections_manager",
-      "//chromeos/ash/components/standalone_browser:test_support",
       "//chromeos/ash/components/system",
       "//chromeos/dbus/power",
       "//components/component_updater/ash",
@@ -1220,7 +1219,6 @@
         "//chrome/common:non_code_constants",
         "//chrome/test/base/ash/interactive:test_support",
         "//chromeos/ash/components/standalone_browser",
-        "//chromeos/ash/components/standalone_browser:test_support",
         "//google_apis",
         "//net:test_support",
         "//url",
@@ -5062,7 +5060,6 @@
         "//chromeos/ash/components/scalable_iph",
         "//chromeos/ash/components/scalable_iph:constants",
         "//chromeos/ash/components/smbfs",
-        "//chromeos/ash/components/standalone_browser:test_support",
         "//chromeos/ash/components/system",
         "//chromeos/ash/components/timezone",
         "//chromeos/ash/services/assistant:lib",
@@ -8390,8 +8387,7 @@
       "//chromeos/ash/components/proximity_auth",
       "//chromeos/ash/components/proximity_auth:test_support",
       "//chromeos/ash/components/scalable_iph:constants",
-      "//chromeos/ash/components/standalone_browser:standalone_browser",
-      "//chromeos/ash/components/standalone_browser:test_support",
+      "//chromeos/ash/components/standalone_browser",
       "//chromeos/ash/components/string_matching",
       "//chromeos/ash/components/sync_wifi",
       "//chromeos/ash/components/system",
@@ -11822,7 +11818,6 @@
         "//chromeos/ash/components/browser_context_helper",
         "//chromeos/ash/components/dbus/shill",
         "//chromeos/ash/components/standalone_browser",
-        "//chromeos/ash/components/standalone_browser:test_support",
         "//chromeos/ash/components/sync_wifi",
         "//chromeos/ash/components/sync_wifi:test_support",
         "//chromeos/printing",
diff --git a/chrome/test/data/controlled_frame/event_handlers.window.js b/chrome/test/data/controlled_frame/event_handlers.window.js
index b0153fc..3069de6 100644
--- a/chrome/test/data/controlled_frame/event_handlers.window.js
+++ b/chrome/test/data/controlled_frame/event_handlers.window.js
@@ -44,7 +44,7 @@
     name: 'contentload',
     trigger: async (controlledframe) => {
       await new Promise((resolve, reject) => {
-        controlledframe.addEventListener('loadstop', resolve);
+        controlledframe.addEventListener('loadstop', resolve, {once: true});
         controlledframe.reload();
       });
     }
@@ -57,10 +57,22 @@
     }
   },
   {
+    name: 'loadabort',
+    trigger: async (controlledframe) => {
+      await new Promise((resolve, reject) => {
+        controlledframe.addEventListener('loadabort', resolve, {once: true});
+        controlledframe.src = 'chrome://flags';
+      });
+    },
+    // Resets the <controlledframe> because this test case changes the 'src'
+    // attribute.
+    resetControlledFrameAfter: true
+  },
+  {
     name: 'loadcommit',
     trigger: async (controlledframe) => {
       await new Promise((resolve, reject) => {
-        controlledframe.addEventListener('loadstop', resolve);
+        controlledframe.addEventListener('loadstop', resolve, {once: true});
         controlledframe.reload();
       });
     }
@@ -69,7 +81,7 @@
     name: 'loadstart',
     trigger: async (controlledframe) => {
       await new Promise((resolve, reject) => {
-        controlledframe.addEventListener('loadstop', resolve);
+        controlledframe.addEventListener('loadstop', resolve, {once: true});
         controlledframe.reload();
       });
     }
@@ -78,12 +90,20 @@
     name: 'loadstop',
     trigger: async (controlledframe) => {
       await new Promise((resolve, reject) => {
-        controlledframe.addEventListener('loadstop', resolve);
+        controlledframe.addEventListener('loadstop', resolve, {once: true});
         controlledframe.reload();
       });
     }
   },
   {
+    name: 'newwindow',
+    trigger: async (controlledframe) => {
+      controlledframe.executeScript({code: 'window.open("/title2.html");'});
+      // Wait a short time for window to be dropped.
+      await new Promise((resolve) => setTimeout(resolve, 100));
+    }
+  },
+  {
     name: 'permissionrequest',
     trigger: async (controlledframe) => {
       const triggerScript = `(async () => {
@@ -92,11 +112,19 @@
       })()`;
       await executeAsyncScript(controlledframe, triggerScript);
     }
+  },
+  {
+    name: 'zoomchange',
+    trigger: async (controlledframe) => {
+      controlledframe.setZoom(0.25325);
+      // Wait a short time for zoom to apply.
+      await new Promise((resolve) => setTimeout(resolve, 50));
+    }
   }
 ];
 
 promise_test(async (test) => {
-  const controlledFrame = await createControlledFrame('/simple.html');
+  let controlledFrame = await createControlledFrame('/simple.html');
 
   for (oneEvent of AllEvents) {
     for (eventHandler of EventHandlers) {
@@ -114,7 +142,11 @@
 
       // Trigger the event, and verify that counter is increased.
       await oneEvent.trigger(controlledFrame);
-      assert_true(counter === 1);
+      assert_true(
+          counter === 1,
+          `Expected ${
+              oneEvent.name} to be triggered 1 time, but actually triggered ${
+              counter} time(s).`);
 
       // Reset the counter and unregister the handler.
       counter = 0;
@@ -123,7 +155,16 @@
 
       // Trigger the event again. Observe that the counter is not changed.
       await oneEvent.trigger(controlledFrame);
-      assert_true(counter === 0);
+      assert_true(
+          counter === 0,
+          `Expected ${
+              oneEvent.name} to be triggered 0 time, but actually triggered ${
+              counter} time(s).`);
+
+      if (oneEvent.resetControlledFrameAfter) {
+        controlledFrame.remove();
+        controlledFrame = await createControlledFrame('/simple.html');
+      }
     }
   }
 }, 'Event Handlers');
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM
index 095e6e0..5a34fe4f 100644
--- a/chromeos/CHROMEOS_LKGM
+++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@
-16123.0.0-1065326
\ No newline at end of file
+16123.0.0-1065331
\ No newline at end of file
diff --git a/chromeos/ash/components/drivefs/DEPS b/chromeos/ash/components/drivefs/DEPS
index 78bf5ddc..756aefe 100644
--- a/chromeos/ash/components/drivefs/DEPS
+++ b/chromeos/ash/components/drivefs/DEPS
@@ -8,4 +8,5 @@
   "+components/drive",
   "+components/invalidation/impl/fake_invalidation_service.h",
   "+components/signin",
+  "+mojo/core",
 ]
diff --git a/chromeos/ash/components/drivefs/drivefs_bootstrap.cc b/chromeos/ash/components/drivefs/drivefs_bootstrap.cc
index e3c6bbfb..cbe492b 100644
--- a/chromeos/ash/components/drivefs/drivefs_bootstrap.cc
+++ b/chromeos/ash/components/drivefs/drivefs_bootstrap.cc
@@ -9,6 +9,7 @@
 #include "base/functional/bind.h"
 #include "chromeos/ash/components/drivefs/mojom/drivefs.mojom.h"
 #include "chromeos/components/mojo_bootstrap/pending_connection_manager.h"
+#include "mojo/core/configuration.h"
 #include "mojo/public/cpp/bindings/receiver.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/platform/platform_channel_endpoint.h"
@@ -47,6 +48,9 @@
 }
 
 void DriveFsBootstrapListener::SendInvitationOverPipe(base::ScopedFD handle) {
+  if (!mojo::core::GetConfiguration().is_broker_process) {
+    invitation_.set_extra_flags(MOJO_SEND_INVITATION_FLAG_SHARE_BROKER);
+  }
   mojo::OutgoingInvitation::Send(
       std::move(invitation_), base::kNullProcessHandle,
       mojo::PlatformChannelEndpoint(mojo::PlatformHandle(std::move(handle))));
diff --git a/chromeos/ash/components/standalone_browser/BUILD.gn b/chromeos/ash/components/standalone_browser/BUILD.gn
index e5a472f..103996fa 100644
--- a/chromeos/ash/components/standalone_browser/BUILD.gn
+++ b/chromeos/ash/components/standalone_browser/BUILD.gn
@@ -11,8 +11,6 @@
   defines = [ "IS_CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_IMPL" ]
 
   sources = [
-    "browser_support.cc",
-    "browser_support.h",
     "channel_util.cc",
     "channel_util.h",
     "lacros_availability.cc",
@@ -49,7 +47,6 @@
 
   deps = [
     ":standalone_browser",
-    ":test_support",
     "//ash/constants:constants",
     "//base/test:test_support",
     "//components/account_id",
@@ -61,15 +58,3 @@
     "//testing/gtest:gtest",
   ]
 }
-
-source_set("test_support") {
-  testonly = true
-
-  sources = [ "feature_refs.cc" ]
-
-  deps = [
-    ":standalone_browser",
-    "//ash/constants",
-    "//base/test:test_support",
-  ]
-}
diff --git a/chromeos/ash/components/standalone_browser/browser_support.cc b/chromeos/ash/components/standalone_browser/browser_support.cc
deleted file mode 100644
index 3d30c4f..0000000
--- a/chromeos/ash/components/standalone_browser/browser_support.cc
+++ /dev/null
@@ -1,166 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/ash/components/standalone_browser/browser_support.h"
-
-#include "ash/constants/ash_switches.h"
-#include "base/check_is_test.h"
-#include "base/check_op.h"
-#include "base/command_line.h"
-#include "base/debug/dump_without_crashing.h"
-#include "base/logging.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/system/sys_info.h"
-#include "base/version_info/version_info.h"
-#include "chromeos/ash/components/standalone_browser/lacros_availability.h"
-#include "chromeos/ash/components/standalone_browser/standalone_browser_features.h"
-#include "components/user_manager/user.h"
-#include "components/user_manager/user_manager.h"
-#include "components/user_manager/user_type.h"
-
-namespace ash::standalone_browser {
-namespace {
-
-BrowserSupport* g_instance = nullptr;
-std::optional<bool> g_cpu_supported_override_ = std::nullopt;
-
-// Returns true if `kDisallowLacros` is set by command line.
-bool IsLacrosDisallowedByCommand() {
-  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
-  return cmdline->HasSwitch(ash::switches::kDisallowLacros) &&
-         !cmdline->HasSwitch(ash::switches::kDisableDisallowLacros);
-}
-
-// Some account types require features that aren't yet supported by lacros.
-// See https://crbug.com/1080693
-bool IsUserTypeAllowed(const user_manager::User& user) {
-  switch (user.GetType()) {
-    case user_manager::UserType::kRegular:
-    case user_manager::UserType::kPublicAccount:
-    // Note: Lacros will not be enabled for Guest users unless LacrosOnly
-    // flag is passed in --enable-features. See https://crbug.com/1294051#c25.
-    case user_manager::UserType::kGuest:
-      return true;
-    case user_manager::UserType::kChild:
-      return base::FeatureList::IsEnabled(features::kLacrosForSupervisedUsers);
-    case user_manager::UserType::kWebKioskApp:
-    case user_manager::UserType::kKioskApp:
-    case user_manager::UserType::kKioskIWA:
-      return false;
-  }
-}
-
-// Returns whether or not lacros is allowed for the Primary user,
-// with given LacrosAvailability policy.
-bool IsAllowedInternal(const user_manager::User* user,
-                       LacrosAvailability lacros_availability) {
-  if (IsLacrosDisallowedByCommand() || !BrowserSupport::IsCpuSupported()) {
-    // This happens when Ash is restarted in multi-user session, meaning there
-    // are more than two users logged in to the device. This will not cause an
-    // accidental removal of Lacros data because for the primary user, the fact
-    // that the device is in multi-user session means that Lacros was not
-    // enabled beforehand. And for secondary users, data removal does not happen
-    // even if Lacros is disabled.
-    return false;
-  }
-
-  if (!user) {
-    // User is not available. Practically, this is accidentally happening
-    // if related function is called before session, or in testing.
-    // TODO(crbug.com/40253772): We should limit this at least only for
-    // testing.
-    return false;
-  }
-
-  if (!IsUserTypeAllowed(*user)) {
-    return false;
-  }
-
-  switch (lacros_availability) {
-    case LacrosAvailability::kLacrosDisallowed:
-      return false;
-    case LacrosAvailability::kUserChoice:
-    case LacrosAvailability::kLacrosOnly:
-      return true;
-  }
-}
-
-}  // namespace
-
-BrowserSupport::BrowserSupport(bool is_allowed) : is_allowed_(is_allowed) {
-  DCHECK_EQ(nullptr, g_instance);
-  g_instance = this;
-}
-
-BrowserSupport::~BrowserSupport() {
-  DCHECK_EQ(this, g_instance);
-  g_instance = nullptr;
-}
-
-// static
-void BrowserSupport::InitializeForPrimaryUser(
-    const policy::PolicyMap& policy_map,
-    bool is_new_profile,
-    bool is_regular_profile) {
-  // Currently, some tests rely on initializing ProfileManager a second time.
-  // That causes this method to be called twice. Here, we take care of that
-  // case by deallocating the old instance and allocating a new one.
-  // TODO(andreaorru): remove the following code once there's no more tests
-  // that rely on it.
-  if (g_instance) {
-    CHECK_IS_TEST();
-    Shutdown();
-  }
-
-  auto* user_manager = user_manager::UserManager::Get();
-
-  auto* primary_user = user_manager->GetPrimaryUser();
-  CHECK(primary_user);
-  auto lacros_availability = GetLacrosAvailability(primary_user, policy_map);
-  auto is_allowed = IsAllowedInternal(primary_user, lacros_availability);
-
-  // Calls the constructor, which in turn takes care of tracking the newly
-  // created instance in `g_instance`, so that it's not leaked and can
-  // later be destroyed via `Shutdown()`.
-  new BrowserSupport(is_allowed);
-}
-
-// static
-void BrowserSupport::Shutdown() {
-  // Calls the destructor, which in turn takes care of setting `g_instance`
-  // to NULL, to keep track of the state.
-  delete g_instance;
-}
-
-bool BrowserSupport::IsInitializedForPrimaryUser() {
-  return !!g_instance;
-}
-
-// static
-BrowserSupport* BrowserSupport::GetForPrimaryUser() {
-  DCHECK(g_instance);
-  return g_instance;
-}
-
-// static
-bool BrowserSupport::IsCpuSupported() {
-  if (g_cpu_supported_override_.has_value()) {
-    return *g_cpu_supported_override_;
-  }
-
-#ifdef ARCH_CPU_X86_64
-  // Some very old Flex devices are not capable to support the SSE4.2
-  // instruction set. Those CPUs should not use Lacros as Lacros has only one
-  // binary for all x86-64 platforms.
-  return __builtin_cpu_supports("sse4.2");
-#else
-  return true;
-#endif
-}
-
-void BrowserSupport::SetCpuSupportedForTesting(std::optional<bool> value) {
-  g_cpu_supported_override_ = value;
-}
-
-}  // namespace ash::standalone_browser
diff --git a/chromeos/ash/components/standalone_browser/browser_support.h b/chromeos/ash/components/standalone_browser/browser_support.h
deleted file mode 100644
index 3504c70..0000000
--- a/chromeos/ash/components/standalone_browser/browser_support.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_BROWSER_SUPPORT_H_
-#define CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_BROWSER_SUPPORT_H_
-
-#include <optional>
-
-#include "base/auto_reset.h"
-#include "base/component_export.h"
-#include "chromeos/ash/components/standalone_browser/lacros_availability.h"
-
-namespace policy {
-class PolicyMap;
-}  // namespace policy
-
-namespace user_manager {
-class User;
-}  // namespace user_manager
-
-namespace ash::standalone_browser {
-
-// Class encapsulating the state of Lacros browser support.
-class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
-    BrowserSupport {
- public:
-  BrowserSupport(const BrowserSupport&) = delete;
-  BrowserSupport& operator=(const BrowserSupport&) = delete;
-
-  // Initializes the global instance of BrowserSupport for the Primary User.
-  static void InitializeForPrimaryUser(const policy::PolicyMap& policy_map,
-                                       bool is_new_profile,
-                                       bool is_regular_profile);
-
-  // Destroys the global instance of BrowserSupport.
-  static void Shutdown();
-
-  // Returns true if BrowserSupport instance is initialized for the Primary
-  // User.
-  static bool IsInitializedForPrimaryUser();
-
-  // Returns the global instance of BrowserSupport for the Primary User.
-  static BrowserSupport* GetForPrimaryUser();
-
-  // Returns whether CPU of this device is capable to run standalone browser.
-  // Can be called even before Initialize() is called.
-  static bool IsCpuSupported();
-
-  // Directly sets the value to be returned by IsCpuSupported for testing.
-  // Setting nullopt unsets the overridden behavior of IsCpuSupported.
-  static void SetCpuSupportedForTesting(std::optional<bool> value);
-
-  // Returns true if the standalone browser is allowed to be enabled.
-  bool IsAllowed() const { return is_allowed_; }
-
- private:
-  BrowserSupport(bool is_allowed);
-  ~BrowserSupport();
-
-  const bool is_allowed_;
-};
-
-}  // namespace ash::standalone_browser
-
-#endif  // CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_BROWSER_SUPPORT_H_
diff --git a/chromeos/ash/components/standalone_browser/feature_refs.cc b/chromeos/ash/components/standalone_browser/feature_refs.cc
deleted file mode 100644
index 0a3180a..0000000
--- a/chromeos/ash/components/standalone_browser/feature_refs.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
-
-#include "ash/constants/ash_features.h"
-#include "base/no_destructor.h"
-#include "chromeos/ash/components/standalone_browser/standalone_browser_features.h"
-
-namespace ash::standalone_browser {
-
-const std::vector<base::test::FeatureRef>& GetFeatureRefs() {
-  static const base::NoDestructor<std::vector<base::test::FeatureRef>> result{
-      {features::kLacrosOnly, features::kLacrosProfileMigrationForceOff}};
-  return *result;
-}
-
-}  // namespace ash::standalone_browser
diff --git a/chromeos/ash/components/standalone_browser/feature_refs.h b/chromeos/ash/components/standalone_browser/feature_refs.h
deleted file mode 100644
index ef49b6d..0000000
--- a/chromeos/ash/components/standalone_browser/feature_refs.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_FEATURE_REFS_H_
-#define CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_FEATURE_REFS_H_
-
-#include <vector>
-
-#include "base/component_export.h"
-#include "base/test/scoped_feature_list.h"
-
-namespace ash::standalone_browser {
-
-// Get the set of features that tests should enable in order to turn on Lacros.
-COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER)
-const std::vector<base::test::FeatureRef>& GetFeatureRefs();
-
-}  // namespace ash::standalone_browser
-
-#endif  // CHROMEOS_ASH_COMPONENTS_STANDALONE_BROWSER_FEATURE_REFS_H_
diff --git a/chromeos/ash/components/standalone_browser/lacros_selection_unittest.cc b/chromeos/ash/components/standalone_browser/lacros_selection_unittest.cc
index 8912815..ee70ca9a 100644
--- a/chromeos/ash/components/standalone_browser/lacros_selection_unittest.cc
+++ b/chromeos/ash/components/standalone_browser/lacros_selection_unittest.cc
@@ -10,7 +10,6 @@
 #include "ash/constants/ash_switches.h"
 #include "base/test/scoped_command_line.h"
 #include "base/values.h"
-#include "chromeos/ash/components/standalone_browser/browser_support.h"
 #include "components/account_id/account_id.h"
 #include "components/policy/core/common/policy_map.h"
 #include "components/policy/policy_constants.h"
@@ -58,13 +57,7 @@
   }
 
   void TearDown() override {
-    if (ash::standalone_browser::BrowserSupport::
-            IsInitializedForPrimaryUser()) {
-      ash::standalone_browser::BrowserSupport::Shutdown();
-    }
     fake_user_manager_.Reset();
-    ash::standalone_browser::BrowserSupport::SetCpuSupportedForTesting(
-        std::nullopt);
   }
 
   const user_manager::User* AddRegularUser(const std::string& email) {
@@ -73,8 +66,6 @@
     fake_user_manager_->UserLoggedIn(account_id, user->username_hash(),
                                      /*browser_restart=*/false,
                                      /*is_child=*/false);
-    ash::standalone_browser::BrowserSupport::InitializeForPrimaryUser(
-        policy::PolicyMap(), false, false);
     return user;
   }
 
diff --git a/chromeos/ash/services/federated/DEPS b/chromeos/ash/services/federated/DEPS
index 2e2e8d99..066e5ee 100644
--- a/chromeos/ash/services/federated/DEPS
+++ b/chromeos/ash/services/federated/DEPS
@@ -1,5 +1,5 @@
 include_rules = [
   "+chromeos/dbus",
-  "+mojo/core/embedder",
+  "+mojo/core",
   "+mojo/public",
 ]
diff --git a/chromeos/ash/services/federated/public/cpp/service_connection.cc b/chromeos/ash/services/federated/public/cpp/service_connection.cc
index 914c9f0..c25f9ba 100644
--- a/chromeos/ash/services/federated/public/cpp/service_connection.cc
+++ b/chromeos/ash/services/federated/public/cpp/service_connection.cc
@@ -11,6 +11,7 @@
 #include "base/sequence_checker.h"
 #include "chromeos/ash/components/dbus/federated/federated_client.h"
 #include "chromeos/ash/services/federated/public/mojom/federated_service.mojom.h"
+#include "mojo/core/configuration.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/system/invitation.h"
@@ -78,6 +79,9 @@
   // Include an initial Mojo pipe in the invitation.
   mojo::ScopedMessagePipeHandle pipe = invitation.AttachMessagePipe(
       ::federated::kBootstrapMojoConnectionChannelToken);
+  if (!mojo::core::GetConfiguration().is_broker_process) {
+    invitation.set_extra_flags(MOJO_SEND_INVITATION_FLAG_SHARE_BROKER);
+  }
   mojo::OutgoingInvitation::Send(std::move(invitation),
                                  base::kNullProcessHandle,
                                  platform_channel.TakeLocalEndpoint());
diff --git a/chromeos/services/machine_learning/DEPS b/chromeos/services/machine_learning/DEPS
index 2e2e8d99..066e5ee 100644
--- a/chromeos/services/machine_learning/DEPS
+++ b/chromeos/services/machine_learning/DEPS
@@ -1,5 +1,5 @@
 include_rules = [
   "+chromeos/dbus",
-  "+mojo/core/embedder",
+  "+mojo/core",
   "+mojo/public",
 ]
diff --git a/chromeos/services/machine_learning/cpp/ash/service_connection_ash.cc b/chromeos/services/machine_learning/cpp/ash/service_connection_ash.cc
index 1b9b8d5..c13f247 100644
--- a/chromeos/services/machine_learning/cpp/ash/service_connection_ash.cc
+++ b/chromeos/services/machine_learning/cpp/ash/service_connection_ash.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chromeos/services/machine_learning/public/cpp/service_connection.h"
-
 #include <utility>
 
 #include "base/component_export.h"
@@ -12,8 +10,9 @@
 #include "base/sequence_checker.h"
 #include "base/task/sequenced_task_runner.h"
 #include "chromeos/dbus/machine_learning/machine_learning_client.h"
+#include "chromeos/services/machine_learning/public/cpp/service_connection.h"
 #include "chromeos/services/machine_learning/public/mojom/machine_learning_service.mojom.h"
-#include "mojo/core/embedder/embedder.h"
+#include "mojo/core/configuration.h"
 #include "mojo/public/cpp/bindings/remote.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/system/invitation.h"
@@ -115,7 +114,7 @@
   // Include an initial Mojo pipe in the invitation.
   mojo::ScopedMessagePipeHandle pipe =
       invitation.AttachMessagePipe(ml::kBootstrapMojoConnectionChannelToken);
-  if (mojo::core::IsMojoIpczEnabled()) {
+  if (!mojo::core::GetConfiguration().is_broker_process) {
     // IPCz requires an application to explicitly opt in to broker sharing
     // and inheritance when establishing a direct connection between two
     // non-broker nodes.
diff --git a/chromeos/ui/frame/frame_header.cc b/chromeos/ui/frame/frame_header.cc
index 9161284..2f26708 100644
--- a/chromeos/ui/frame/frame_header.cc
+++ b/chromeos/ui/frame/frame_header.cc
@@ -4,9 +4,9 @@
 
 #include "chromeos/ui/frame/frame_header.h"
 
+#include <algorithm>
 #include <vector>
 
-#include "base/logging.h"  // DCHECK
 #include "chromeos/ui/frame/caption_buttons/frame_caption_button_container_view.h"
 #include "chromeos/ui/frame/caption_buttons/frame_center_button.h"
 #include "chromeos/ui/frame/frame_utils.h"
@@ -23,7 +23,9 @@
 #include "ui/gfx/canvas.h"
 #include "ui/gfx/color_utils.h"
 #include "ui/gfx/font_list.h"
+#include "ui/gfx/geometry/point.h"
 #include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/geometry/size.h"
 #include "ui/gfx/scoped_canvas.h"
 #include "ui/views/background.h"
 #include "ui/views/view.h"
@@ -297,8 +299,11 @@
     return;
   }
 
+  // If the frame header's radius is reduced, the area encompassing the
+  // curvature of both corners must be repainted.
+  view_->SchedulePaintInRect(
+      gfx::Rect(view_->width(), std::max(radius, corner_radius_)));
   corner_radius_ = radius;
-  view_->SchedulePaint();
 }
 
 void FrameHeader::SetLeftHeaderView(views::View* left_header_view) {
diff --git a/clank b/clank
index 6c91b3d..60af337 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 6c91b3d63c04c2c5907dd772e25f5bdfc70c771f
+Subproject commit 60af337f9ae927559294f121715cdc1155a86c66
diff --git a/components/app_constants/constants.h b/components/app_constants/constants.h
index 57b0680..778c03ba 100644
--- a/components/app_constants/constants.h
+++ b/components/app_constants/constants.h
@@ -16,11 +16,6 @@
 // The ID of the Chrome component application as part of ash.
 inline constexpr char kChromeAppId[] = "mgndgikekgjfcpckkfioiadnlibdjbkf";
 
-// The ID of Ash Browser for debugging.
-// Generated by: echo "ash-debug-chrome" | sha256sum | head -c32 | tr 0-9a-f a-p
-inline constexpr char kAshDebugBrowserAppId[] =
-    "nenfchlcgcabmbgfjkbcopkbodjmidhi";
-
 // The ID of the Lacros Chrome browser application that runs outside of ash.
 // Generated by: echo "lacros-chrome" | sha256sum | head -c32 | tr 0-9a-f a-p
 inline constexpr char kLacrosAppId[] = "jaimifaeiicidiikhmjedcgdimealfbh";
diff --git a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.h b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.h
index 03f8332..18d5451a 100644
--- a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.h
+++ b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.h
@@ -164,7 +164,6 @@
   UnmaskAuthFlowType current_authentication_flow_;
   bool has_logged_suggestion_with_metadata_shown_ = false;
   bool has_logged_suggestion_with_metadata_selected_ = false;
-  bool has_logged_legacy_masked_server_card_suggestion_selected_ = false;
   bool has_logged_local_card_suggestion_selected_ = false;
   bool has_logged_masked_server_card_suggestion_selected_ = false;
   bool has_logged_masked_server_card_suggestion_filled_ = false;
diff --git a/components/autofill/core/browser/payments/test_payments_autofill_client.h b/components/autofill/core/browser/payments/test_payments_autofill_client.h
index ccc13509..1e2d3e6 100644
--- a/components/autofill/core/browser/payments/test_payments_autofill_client.h
+++ b/components/autofill/core/browser/payments/test_payments_autofill_client.h
@@ -250,9 +250,11 @@
 
   std::unique_ptr<MockIbanAccessManager> mock_iban_access_manager_;
 
+#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS)
   // Populated if name fix flow was offered. True if bubble was shown, false
   // otherwise.
   bool credit_card_name_fix_flow_bubble_was_shown_ = false;
+#endif
 
   ::testing::NiceMock<MockMerchantPromoCodeManager>
       mock_merchant_promo_code_manager_;
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc
index b0b9c3d..74a582e 100644
--- a/components/autofill/core/common/autofill_payments_features.cc
+++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -291,11 +291,11 @@
 // When enabled, adds a timeout on the network request for UploadCard requests.
 BASE_FEATURE(kAutofillUploadCardRequestTimeout,
              "AutofillUploadCardRequestTimeout",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 const base::FeatureParam<int> kAutofillUploadCardRequestTimeoutMilliseconds{
     &kAutofillUploadCardRequestTimeout,
     "autofill_upload_card_request_timeout_milliseconds",
-    /*default_value=*/7000};
+    /*default_value=*/6500};
 
 // Controls offering credit card upload to Google Payments. Cannot ever be
 // ENABLED_BY_DEFAULT because the feature state depends on the user's country.
@@ -317,11 +317,11 @@
 // When enabled, adds a timeout on the network request for VcnEnroll requests.
 BASE_FEATURE(kAutofillVcnEnrollRequestTimeout,
              "AutofillVcnEnrollRequestTimeout",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 const base::FeatureParam<int> kAutofillVcnEnrollRequestTimeoutMilliseconds{
     &kAutofillVcnEnrollRequestTimeout,
     "autofill_vcn_enroll_request_timeout_milliseconds",
-    /*default_value=*/7500};
+    /*default_value=*/6500};
 
 #if BUILDFLAG(IS_ANDROID)
 // When enabled, eWallet accounts are synced from the Google Payments servers
diff --git a/components/content_settings/core/common/cookie_settings_base_unittest.cc b/components/content_settings/core/common/cookie_settings_base_unittest.cc
index 6ccbcd3..e2317b23 100644
--- a/components/content_settings/core/common/cookie_settings_base_unittest.cc
+++ b/components/content_settings/core/common/cookie_settings_base_unittest.cc
@@ -96,7 +96,6 @@
 
  private:
   GetSettingCallback callback_;
-  ContentSettingsType type_;
 };
 
 class CookieSettingsBaseTest : public testing::Test {
diff --git a/components/cross_device/logging/BUILD.gn b/components/cross_device/logging/BUILD.gn
index 38f4057..01607be 100644
--- a/components/cross_device/logging/BUILD.gn
+++ b/components/cross_device/logging/BUILD.gn
@@ -2,14 +2,17 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-source_set("logging") {
+component("logging") {
+  defines = [ "IS_COMPONENTS_CROSS_DEVICE_LOGGING_IMPL" ]
+
   sources = [
     "log_buffer.cc",
     "log_buffer.h",
     "logging.cc",
     "logging.h",
   ]
-  deps = [ "//base" ]
+
+  public_deps = [ "//base" ]
 }
 
 source_set("unit_tests") {
diff --git a/components/cross_device/logging/log_buffer.h b/components/cross_device/logging/log_buffer.h
index b4c037f..0c9a775 100644
--- a/components/cross_device/logging/log_buffer.h
+++ b/components/cross_device/logging/log_buffer.h
@@ -8,7 +8,9 @@
 #include <stddef.h>
 
 #include <list>
+#include <string>
 
+#include "base/component_export.h"
 #include "base/logging.h"
 #include "base/observer_list.h"
 #include "base/time/time.h"
@@ -23,10 +25,10 @@
 // and will discard entries in FIFO order.
 // Call CrossDeviceLogBuffer::GetInstance() to get the global
 // CrossDeviceLogBuffer instance.
-class CrossDeviceLogBuffer {
+class COMPONENT_EXPORT(COMPONENTS_CROSS_DEVICE_LOGGING) CrossDeviceLogBuffer {
  public:
   // Represents a single log entry in the log buffer.
-  struct LogMessage {
+  struct COMPONENT_EXPORT(COMPONENTS_CROSS_DEVICE_LOGGING) LogMessage {
     const std::string text;
     Feature feature;
     base::Time time;
diff --git a/components/cross_device/logging/logging.h b/components/cross_device/logging/logging.h
index 21718a2..76dec7d8 100644
--- a/components/cross_device/logging/logging.h
+++ b/components/cross_device/logging/logging.h
@@ -8,6 +8,7 @@
 #include <sstream>
 #include <string_view>
 
+#include "base/component_export.h"
 #include "base/logging.h"
 #include "components/cross_device/logging/log_buffer.h"
 
@@ -23,7 +24,8 @@
 // logging::LogMessage instance. When this object is destroyed, the message will
 // be logged with the standard logging system and also added to Nearby Sharing
 // specific log buffer.
-class CrossDeviceScopedLogMessage {
+class COMPONENT_EXPORT(COMPONENTS_CROSS_DEVICE_LOGGING)
+    CrossDeviceScopedLogMessage {
  public:
   CrossDeviceScopedLogMessage(std::string_view file,
                               int line,
diff --git a/components/endpoint_fetcher/endpoint_fetcher.cc b/components/endpoint_fetcher/endpoint_fetcher.cc
index a6ef76c..1ef0c4a 100644
--- a/components/endpoint_fetcher/endpoint_fetcher.cc
+++ b/components/endpoint_fetcher/endpoint_fetcher.cc
@@ -27,6 +27,11 @@
 constexpr base::TimeDelta kDefaultTimeOut = base::Milliseconds(30000);
 }  // namespace
 
+EndpointFetcher::RequestParams::RequestParams() = default;
+EndpointFetcher::RequestParams::RequestParams(
+    const EndpointFetcher::RequestParams& other) = default;
+EndpointFetcher::RequestParams::~RequestParams() = default;
+
 EndpointFetcher::RequestParams::Builder::Builder()
     : request_params_(std::make_unique<RequestParams>()) {}
 
@@ -264,6 +269,10 @@
   if (base::EqualsCaseInsensitiveASCII(http_method_, "POST")) {
     simple_url_loader_->AttachStringForUpload(post_data_, content_type_);
   }
+  if (!GetUploadProgressCallback().is_null()) {
+    simple_url_loader_->SetOnUploadProgressCallback(
+        GetUploadProgressCallback());
+  }
   simple_url_loader_->SetRetryOptions(GetMaxRetries(),
                                       network::SimpleURLLoader::RETRY_ON_5XX);
   simple_url_loader_->SetTimeoutDuration(timeout_);
@@ -390,6 +399,16 @@
   return request_params_.value().set_site_for_cookies.value();
 }
 
+UploadProgressCallback EndpointFetcher::GetUploadProgressCallback() {
+  if (!request_params_.has_value()) {
+    return UploadProgressCallback();
+  }
+  if (!request_params_.value().upload_progress_callback.has_value()) {
+    return UploadProgressCallback();
+  }
+  return request_params_.value().upload_progress_callback.value();
+}
+
 std::string EndpointFetcher::GetUrlForTesting() {
   return url_.spec();
 }
diff --git a/components/endpoint_fetcher/endpoint_fetcher.h b/components/endpoint_fetcher/endpoint_fetcher.h
index 1edd2ec1..9a1f291c1 100644
--- a/components/endpoint_fetcher/endpoint_fetcher.h
+++ b/components/endpoint_fetcher/endpoint_fetcher.h
@@ -64,6 +64,8 @@
 
 using EndpointFetcherCallback =
     base::OnceCallback<void(std::unique_ptr<EndpointResponse>)>;
+using UploadProgressCallback =
+    base::RepeatingCallback<void(uint64_t position, uint64_t total)>;
 
 // TODO(crbug.com/284531303) EndpointFetcher would benefit from
 // re-design/rethinking the APIs.
@@ -86,12 +88,14 @@
   // constructor does/will not scale. New parameters will be added here and
   // existing parameters will be migrated (crbug.com/357567879).
   struct RequestParams {
-    RequestParams() = default;
-    ~RequestParams() = default;
+    RequestParams();
+    RequestParams(const EndpointFetcher::RequestParams& other);
+    ~RequestParams();
 
     std::optional<CredentialsMode> credentials_mode;
     std::optional<int> max_retries;
     std::optional<bool> set_site_for_cookies;
+    std::optional<UploadProgressCallback> upload_progress_callback;
 
     class Builder final {
      public:
@@ -119,6 +123,12 @@
         return *this;
       }
 
+      Builder& SetUploadProgressCallback(
+          const UploadProgressCallback callback) {
+        request_params_->upload_progress_callback = callback;
+        return *this;
+      }
+
      private:
       std::unique_ptr<RequestParams> request_params_;
     };
@@ -225,6 +235,7 @@
   network::mojom::CredentialsMode GetCredentialsMode();
   int GetMaxRetries();
   bool GetSetSiteForCookies();
+  UploadProgressCallback GetUploadProgressCallback();
 
   enum AuthType { CHROME_API_KEY, OAUTH, NO_AUTH };
   AuthType auth_type_;
@@ -252,7 +263,6 @@
   const std::optional<signin::ConsentLevel> consent_level_;
   bool sanitize_response_;
   version_info::Channel channel_;
-
   const std::optional<RequestParams> request_params_;
 
   // Members set in Fetch
diff --git a/components/live_caption/live_caption_controller.h b/components/live_caption/live_caption_controller.h
index e073c1007..70af1fb2 100644
--- a/components/live_caption/live_caption_controller.h
+++ b/components/live_caption/live_caption_controller.h
@@ -127,8 +127,10 @@
 
   const std::string application_locale_;
 
+#if BUILDFLAG(IS_CHROMEOS_ASH)
   // Tracks whether or not Live Caption has been enabled for babel orca.
   bool enabled_for_babel_orca_ = false;
+#endif
 
   // Whether Live Caption is enabled.
   bool enabled_ = false;
diff --git a/components/omnibox/browser/omnibox_edit_model.cc b/components/omnibox/browser/omnibox_edit_model.cc
index 05c70ab..c27bd7f5 100644
--- a/components/omnibox/browser/omnibox_edit_model.cc
+++ b/components/omnibox/browser/omnibox_edit_model.cc
@@ -61,6 +61,7 @@
 #include "components/search_engines/template_url.h"
 #include "components/search_engines/template_url_prepopulate_data.h"
 #include "components/search_engines/template_url_service.h"
+#include "components/search_engines/template_url_starter_pack_data.h"
 #include "components/strings/grit/components_strings.h"
 #include "net/cookies/cookie_util.h"
 #include "third_party/icu/source/common/unicode/ubidi.h"
@@ -2036,8 +2037,11 @@
           controller_->client()->GetTemplateURLService(), false);
       std::u16string replacement_string =
           turl ? turl->short_name() : match.contents;
-      return l10n_util::GetStringFUTF16(IDS_ACC_KEYWORD_MODE,
-                                        replacement_string);
+      int message_id = (turl && turl->starter_pack_id() ==
+                                    TemplateURLStarterPackData::kGemini)
+                           ? IDS_ACC_ASK_KEYWORD_MODE
+                           : IDS_ACC_KEYWORD_MODE;
+      return l10n_util::GetStringFUTF16(message_id, replacement_string);
     }
     case OmniboxPopupSelection::FOCUSED_BUTTON_ACTION:
       // When pedal button is focused, the autocomplete suggestion isn't
diff --git a/components/omnibox_strings.grdp b/components/omnibox_strings.grdp
index 57aeb60..a2270b26a 100644
--- a/components/omnibox_strings.grdp
+++ b/components/omnibox_strings.grdp
@@ -235,6 +235,9 @@
   <message name="IDS_ACC_KEYWORD_MODE" desc="Announcement when entering keyword search mode.">
     Search <ph name="KEYWORD_SUFFIX">$1<ex>Youtube</ex>, type a query and press Enter to search</ph>
   </message>
+  <message name="IDS_ACC_ASK_KEYWORD_MODE" desc="Announcement when entering keyword mode for an engine that is suitable for asking vs. searching (e.g. Gemini).">
+    Ask <ph name="KEYWORD_SUFFIX">$1<ex>Gemini</ex>, type a question or ask it to do something and press Enter</ph>
+  </message>
 
   <!-- Accessibility labels for the omnibox thumbs up feedback button. -->
   <message name="IDS_ACC_THUMBS_UP_SUGGESTION_FOCUSED_PREFIX" desc="Announcement when thumbs up feedback button is focused.">
@@ -392,7 +395,7 @@
     Enter a word or two
   </message>
   <message name="IDS_OMNIBOX_GEMINI_SCOPE_PLACEHOLDER_TEXT" desc="The string displayed in the omnibox as placeholder text when the user input is empty and the user is in the @gemini scope.">
-    Enter your question or prompt
+    Enter a question
   </message>
 
   <!-- Strings for Android Hub Search. -->
diff --git a/components/omnibox_strings_grdp/IDS_ACC_ASK_KEYWORD_MODE.png.sha1 b/components/omnibox_strings_grdp/IDS_ACC_ASK_KEYWORD_MODE.png.sha1
new file mode 100644
index 0000000..91d674e
--- /dev/null
+++ b/components/omnibox_strings_grdp/IDS_ACC_ASK_KEYWORD_MODE.png.sha1
@@ -0,0 +1 @@
+4c479adfa16264032814eceaac2107cd4e56bc92
\ No newline at end of file
diff --git a/components/omnibox_strings_grdp/IDS_OMNIBOX_GEMINI_SCOPE_PLACEHOLDER_TEXT.png.sha1 b/components/omnibox_strings_grdp/IDS_OMNIBOX_GEMINI_SCOPE_PLACEHOLDER_TEXT.png.sha1
index 219a72b..87ddb187 100644
--- a/components/omnibox_strings_grdp/IDS_OMNIBOX_GEMINI_SCOPE_PLACEHOLDER_TEXT.png.sha1
+++ b/components/omnibox_strings_grdp/IDS_OMNIBOX_GEMINI_SCOPE_PLACEHOLDER_TEXT.png.sha1
@@ -1 +1 @@
-88e11021ac3c2d16a5461e8d72e6158388773119
\ No newline at end of file
+535e219ab7a03e3da24d1cc17515d9a254b65f81
\ No newline at end of file
diff --git a/components/optimization_guide/internal b/components/optimization_guide/internal
index 5953b2f..4381a0f 160000
--- a/components/optimization_guide/internal
+++ b/components/optimization_guide/internal
@@ -1 +1 @@
-Subproject commit 5953b2f79e0d2274f7f053f9d5ce8956a09ccfd5
+Subproject commit 4381a0f78e891579dc1e0353486886b1fc2b59e0
diff --git a/components/saved_tab_groups/internal/android/java/src/org/chromium/components/tab_group_sync/TabGroupSyncServiceImpl.java b/components/saved_tab_groups/internal/android/java/src/org/chromium/components/tab_group_sync/TabGroupSyncServiceImpl.java
index a2b00a6..9bb7b100 100644
--- a/components/saved_tab_groups/internal/android/java/src/org/chromium/components/tab_group_sync/TabGroupSyncServiceImpl.java
+++ b/components/saved_tab_groups/internal/android/java/src/org/chromium/components/tab_group_sync/TabGroupSyncServiceImpl.java
@@ -25,6 +25,7 @@
     private final ObserverList<TabGroupSyncService.Observer> mObservers = new ObserverList<>();
     private long mNativePtr;
     private boolean mInitialized;
+    private boolean mIsObservingLocalChanges;
 
     @CalledByNative
     private static TabGroupSyncServiceImpl create(long nativePtr) {
@@ -33,6 +34,7 @@
 
     private TabGroupSyncServiceImpl(long nativePtr) {
         mNativePtr = nativePtr;
+        mIsObservingLocalChanges = true;
     }
 
     @Override
@@ -182,6 +184,20 @@
     }
 
     @Override
+    public void setLocalObservationMode(boolean observeLocalChanges) {
+        if (mIsObservingLocalChanges == observeLocalChanges) return;
+        mIsObservingLocalChanges = observeLocalChanges;
+        for (Observer observer : mObservers) {
+            observer.onLocalObservationModeChanged(mIsObservingLocalChanges);
+        }
+    }
+
+    @Override
+    public boolean isObservingLocalChanges() {
+        return mIsObservingLocalChanges;
+    }
+
+    @Override
     public boolean isRemoteDevice(String syncCacheGuid) {
         if (mNativePtr == 0) return false;
         return TabGroupSyncServiceImplJni.get()
diff --git a/components/saved_tab_groups/public/android/java/src/org/chromium/components/tab_group_sync/TabGroupSyncService.java b/components/saved_tab_groups/public/android/java/src/org/chromium/components/tab_group_sync/TabGroupSyncService.java
index 159039d6..5899665 100644
--- a/components/saved_tab_groups/public/android/java/src/org/chromium/components/tab_group_sync/TabGroupSyncService.java
+++ b/components/saved_tab_groups/public/android/java/src/org/chromium/components/tab_group_sync/TabGroupSyncService.java
@@ -76,6 +76,18 @@
          */
         default void onTabGroupLocalIdChanged(
                 String syncTabGroupId, @Nullable LocalTabGroupId localTabGroupId) {}
+
+        /**
+         * Called to notify that the local observation mode has changed. If {@code
+         * observeLocalChanges} is true, the local changes should be ignored by the observer and not
+         * propagated to sync. This is typically used to ignore transient changes which are often
+         * redundant and incorrect to propagate to sync server. Note, this is a temporary solution
+         * and only available in Android until a more accurate cross-platform solution is
+         * implemented.
+         *
+         * @param observeLocalChanges Whether the local tab model changes should be observed.
+         */
+        default void onLocalObservationModeChanged(boolean observeLocalChanges) {}
     }
 
     /**
@@ -243,6 +255,20 @@
     void updateLocalTabId(LocalTabGroupId localGroupId, String syncTabId, int localTabId);
 
     /**
+     * Whether the TabGroupSyncService should observe local tab model changes. By default,
+     * TabGroupSyncService starts observing from the start. Typically called to pause / resume local
+     * observation typically during transient UI actions (such as dragging tab groups to other
+     * windows). This ensures that transient changes which are often redundant and incorrect do not
+     * propagate to sync server.
+     *
+     * @param observeLocalChanges True to observe local changes, false to pause observation.
+     */
+    void setLocalObservationMode(boolean observeLocalChanges);
+
+    /** Returns whether TabGroupSyncService is currently observing local changes. */
+    boolean isObservingLocalChanges();
+
+    /**
      * Helper method to identify whether a given sync cache guid corresponds to a remote device.
      *
      * @param syncCacheGuid A sync cache guid. Typically obtained from a tab group or tab
diff --git a/components/user_education/views/help_bubble_view.cc b/components/user_education/views/help_bubble_view.cc
index 5c943f3..a53a61e 100644
--- a/components/user_education/views/help_bubble_view.cc
+++ b/components/user_education/views/help_bubble_view.cc
@@ -15,6 +15,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/metrics/user_metrics.h"
 #include "base/notreached.h"
+#include "base/scoped_observation.h"
 #include "base/strings/string_number_conversions.h"
 #include "base/time/time.h"
 #include "components/strings/grit/components_strings.h"
@@ -68,6 +69,7 @@
 #include "ui/views/view_tracker.h"
 #include "ui/views/view_utils.h"
 #include "ui/views/widget/widget.h"
+#include "ui/views/widget/widget_observer.h"
 
 namespace user_education {
 
@@ -294,6 +296,33 @@
 DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(HelpBubbleView, kBodyTextIdForTesting);
 DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(HelpBubbleView, kTitleTextIdForTesting);
 
+// TODO(https://crbug.com/382611284): Temporarily handle the case when the
+// primary window is minimized by closing the help bubble. Remove this code when
+// the issue is solved at the Views framework level.
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
+class HelpBubbleView::PrimaryWidgetObserver : public views::WidgetObserver {
+ public:
+  explicit PrimaryWidgetObserver(HelpBubbleView& help_bubble)
+      : help_bubble_(help_bubble) {
+    observation_.Observe(help_bubble_->GetWidget()->GetPrimaryWindowWidget());
+  }
+  ~PrimaryWidgetObserver() override = default;
+
+ private:
+  void OnWidgetDestroying(views::Widget*) override { observation_.Reset(); }
+  void OnWidgetShowStateChanged(views::Widget* widget) override {
+    if (widget->IsMinimized()) {
+      help_bubble_->GetWidget()->CloseWithReason(
+          views::Widget::ClosedReason::kLostFocus);
+    }
+  }
+
+  const raw_ref<HelpBubbleView> help_bubble_;
+  base::ScopedObservation<views::Widget, views::WidgetObserver> observation_{
+      this};
+};
+#endif
+
 // Watches for the anchor view to be destroyed or removed from its widget.
 // Used in cases where the anchor element is not the same as the anchor view.
 // Prevents the help bubble from lingering after its anchor is invalid, which
@@ -743,6 +772,10 @@
     event_relay_->Init(this);
   }
 
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
+  primary_widget_observer_ = std::make_unique<PrimaryWidgetObserver>(*this);
+#endif
+
   MaybeStartAutoCloseTimer();
 }
 
diff --git a/components/user_education/views/help_bubble_view.h b/components/user_education/views/help_bubble_view.h
index 6feadf3..381d536 100644
--- a/components/user_education/views/help_bubble_view.h
+++ b/components/user_education/views/help_bubble_view.h
@@ -157,6 +157,16 @@
   // Useful when our anchor element is not the anchor view.
   std::unique_ptr<AnchorViewObserver> anchor_observer_;
 
+// TODO(https://crbug.com/382611284): On some platforms the help bubble is not
+// minimized with the window, leading to visual artifacts and errors. For now,
+// work around this problem by closing the bubble if the widget is minimized.
+// When the underlying issue is fixed at the framework level, this can be
+// removed.
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
+  class PrimaryWidgetObserver;
+  std::unique_ptr<PrimaryWidgetObserver> primary_widget_observer_;
+#endif
+
   // Auto close timeout. If the value is 0 (default), the bubble never times
   // out.
   base::TimeDelta timeout_;
diff --git a/components/user_education/views/help_bubble_view_unittest.cc b/components/user_education/views/help_bubble_view_unittest.cc
index 718f10b2..2ce25d8 100644
--- a/components/user_education/views/help_bubble_view_unittest.cc
+++ b/components/user_education/views/help_bubble_view_unittest.cc
@@ -35,6 +35,7 @@
 #include "ui/views/layout/layout_types.h"
 #include "ui/views/test/views_test_base.h"
 #include "ui/views/test/views_test_utils.h"
+#include "ui/views/test/widget_test.h"
 #include "ui/views/widget/widget.h"
 #include "ui/views/widget/widget_observer.h"
 
@@ -500,4 +501,13 @@
       help_bubble_->bubble_view()->GetAccessibleWindowTitle());
 }
 
+#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC)
+TEST_F(HelpBubbleViewsTest, MinimizeAnchorWidget) {
+  views::test::WidgetDestroyedWaiter waiter(
+      help_bubble_->bubble_view()->GetWidget());
+  widget_->Minimize();
+  waiter.Wait();
+}
+#endif
+
 }  // namespace user_education
diff --git a/components/viz/service/display/overlay_processor_delegated.h b/components/viz/service/display/overlay_processor_delegated.h
index a197bd4..6f81519 100644
--- a/components/viz/service/display/overlay_processor_delegated.h
+++ b/components/viz/service/display/overlay_processor_delegated.h
@@ -98,11 +98,7 @@
   bool BlockForCopyRequests(const AggregatedRenderPassList* render_pass_list);
 
   DelegationStatus delegated_status_ = DelegationStatus::kCompositedOther;
-  bool supports_clip_rect_ = false;
-  bool supports_out_of_window_clip_rect_ = false;
   bool needs_background_image_ = false;
-  bool supports_affine_transform_ = false;
-  bool has_transformation_fix_ = false;
   gfx::RectF unassigned_damage_;
   // Used to count the number of frames we should wait until allowing delegation
   // again.
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc
index 2998bb3..109063a 100644
--- a/components/viz/service/display/surface_aggregator.cc
+++ b/components/viz/service/display/surface_aggregator.cc
@@ -1866,6 +1866,9 @@
             .aggregation()
             .prevent_merge = true;
       }
+#else
+      // Ignore -Wunused-private-field warning.
+      (void)prevent_merging_surfaces_to_root_pass_;
 #endif
     } else if (auto* render_pass_quad =
                    quad->DynamicCast<CompositorRenderPassDrawQuad>()) {
diff --git a/content/browser/code_cache/generated_code_cache_browsertest.cc b/content/browser/code_cache/generated_code_cache_browsertest.cc
index 61c8b54b..be7a332 100644
--- a/content/browser/code_cache/generated_code_cache_browsertest.cc
+++ b/content/browser/code_cache/generated_code_cache_browsertest.cc
@@ -561,7 +561,6 @@
   const GURL url_;
   const GURL origin_;
   const size_t expected_size_;
-  size_t actual_size_ = 0;
   base::OnceClosure done_callback_;
 };
 
diff --git a/content/browser/fenced_frame/fenced_frame.cc b/content/browser/fenced_frame/fenced_frame.cc
index a27b3c8..47ce77c 100644
--- a/content/browser/fenced_frame/fenced_frame.cc
+++ b/content/browser/fenced_frame/fenced_frame.cc
@@ -358,7 +358,8 @@
   // in the browser, allowing us to use non-fixed sets of sandbox flags.
   inner_root->SetPendingFramePolicy(blink::FramePolicy(
       current_frame_policy.sandbox_flags, frame_policy.container_policy,
-      current_frame_policy.required_document_policy));
+      current_frame_policy.required_document_policy,
+      frame_policy.deferred_fetch_policy));
 }
 
 }  // namespace content
diff --git a/content/browser/preloading/prefetch/prefetch_document_manager.cc b/content/browser/preloading/prefetch/prefetch_document_manager.cc
index 7d4af18..a7da694 100644
--- a/content/browser/preloading/prefetch/prefetch_document_manager.cc
+++ b/content/browser/preloading/prefetch/prefetch_document_manager.cc
@@ -377,6 +377,36 @@
   g_prefetch_service_for_testing = prefetch_service;
 }
 
+void PrefetchDocumentManager::ResetPrefetchAheadOfPrerenderIfExist(
+    const GURL& url) {
+  auto it =
+      all_prefetches_.find(std::make_pair(url, PreloadingType::kPrerender));
+  if (it == all_prefetches_.end()) {
+    return;
+  }
+
+  base::WeakPtr<PrefetchContainer> prefetch = it->second;
+
+  if (!prefetch) {
+    return;
+  }
+
+  switch (prefetch->GetLoadState()) {
+    case PrefetchContainer::LoadState::kNotStarted:
+    case PrefetchContainer::LoadState::kEligible:
+    case PrefetchContainer::LoadState::kFailedIneligible:
+    case PrefetchContainer::LoadState::kFailedHeldback:
+      break;
+    case PrefetchContainer::LoadState::kStarted:
+      prefetch->SetPrefetchStatus(
+          PrefetchStatus::kPrefetchEvictedAfterCandidateRemoved);
+      break;
+  }
+
+  GetPrefetchService()->ResetPrefetch(prefetch);
+  all_prefetches_.erase(it);
+}
+
 PrefetchService* PrefetchDocumentManager::GetPrefetchService() const {
   if (g_prefetch_service_for_testing) {
     return g_prefetch_service_for_testing;
diff --git a/content/browser/preloading/prefetch/prefetch_document_manager.h b/content/browser/preloading/prefetch/prefetch_document_manager.h
index 0322cf9..a22e2add 100644
--- a/content/browser/preloading/prefetch/prefetch_document_manager.h
+++ b/content/browser/preloading/prefetch/prefetch_document_manager.h
@@ -120,6 +120,8 @@
 
   static void SetPrefetchServiceForTesting(PrefetchService* prefetch_service);
 
+  void ResetPrefetchAheadOfPrerenderIfExist(const GURL& url);
+
  private:
   explicit PrefetchDocumentManager(RenderFrameHost* rfh);
   friend DocumentUserData;
diff --git a/content/browser/preloading/prerenderer_impl.cc b/content/browser/preloading/prerenderer_impl.cc
index d981baa..ac4a334b 100644
--- a/content/browser/preloading/prerenderer_impl.cc
+++ b/content/browser/preloading/prerenderer_impl.cc
@@ -167,11 +167,29 @@
     started_it = equal_prerender_end;
   }
 
+  std::vector<GURL> urls;
+  for (auto ftn_id : removed_prerender_rules) {
+    if (PrerenderHost* prerender_host =
+            registry_->FindNonReservedHostById(ftn_id)) {
+      urls.push_back(prerender_host->GetInitialUrl());
+    }
+  }
   std::set<FrameTreeNodeId> canceled_prerender_rules_set =
       registry_->CancelHosts(
           removed_prerender_rules,
           PrerenderCancellationReason(
               PrerenderFinalStatus::kSpeculationRuleRemoved));
+  if (base::FeatureList::IsEnabled(
+          features::kPrerender2FallbackPrefetchSpecRules)) {
+    WebContents* web_contents =
+        WebContents::FromRenderFrameHost(&render_frame_host_.get());
+    auto* prefetch_document_manager =
+        content::PrefetchDocumentManager::GetOrCreateForCurrentDocument(
+            web_contents->GetPrimaryMainFrame());
+    for (const auto& url : urls) {
+      prefetch_document_manager->ResetPrefetchAheadOfPrerenderIfExist(url);
+    }
+  }
 
   // Canceled prerenders by kSpeculationRuleRemoved should have already been
   // removed from `started_prerenders_` via `OnCancel`.
diff --git a/content/browser/renderer_host/media/preferred_audio_output_device_manager.cc b/content/browser/renderer_host/media/preferred_audio_output_device_manager.cc
index f6bfdf2..e2fd93f 100644
--- a/content/browser/renderer_host/media/preferred_audio_output_device_manager.cc
+++ b/content/browser/renderer_host/media/preferred_audio_output_device_manager.cc
@@ -159,7 +159,11 @@
   CHECK(device_switcher);
 
   MainFramePreferredSinkIdConfig* config = FindSinkIdConfig(main_frame_id);
-  CHECK(config);
+  if (!config) {
+    // If the page refresh is done before the device switcher removal (race),
+    // then it would have no entry.
+    return;
+  }
 
   config->RemoveDeviceSwitcher(device_switcher);
 }
diff --git a/content/browser/renderer_host/media/preferred_audio_output_device_manager_unittest.cc b/content/browser/renderer_host/media/preferred_audio_output_device_manager_unittest.cc
index cb171dc..b889b49 100644
--- a/content/browser/renderer_host/media/preferred_audio_output_device_manager_unittest.cc
+++ b/content/browser/renderer_host/media/preferred_audio_output_device_manager_unittest.cc
@@ -511,4 +511,29 @@
   AddSwitcher(preferred_device_manager, sub_frame_switcher.get());
 }
 
+TEST_F(PreferredAudioOutputDeviceManagerImplTest,
+       RemoveSwitcherAfterUnregisterMainFrameDoNotCrash) {
+  // RemoveSwitcher call after unregistering main frame should not crash.
+  PreferredAudioOutputDeviceManagerImpl preferred_device_manager;
+
+  std::unique_ptr<MockAudioOutputDeviceSwitcher> main_frame_switcher =
+      CreateMockSwitcherForMainframe(preferred_device_manager);
+
+  EXPECT_CALL(*main_frame_switcher.get(),
+              SwitchAudioOutputDeviceId(
+                  media::AudioDeviceDescription::kDefaultDeviceId))
+      .Times(1);
+  EXPECT_CALL(*main_frame_switcher.get(),
+              SwitchAudioOutputDeviceId(kRawDeviceId))
+      .Times(0);
+
+  AddSwitcher(preferred_device_manager, main_frame_switcher.get());
+
+  preferred_device_manager.UnregisterMainFrameOnUIThread(main_rfh());
+  base::RunLoop().RunUntilIdle();
+
+  // It does nothing(no crash) as main frame is unregistered.
+  RemoveSwitcher(preferred_device_manager, main_frame_switcher.get());
+}
+
 }  // namespace content
diff --git a/content/browser/renderer_host/render_frame_host_manager.cc b/content/browser/renderer_host/render_frame_host_manager.cc
index a0da309..87f6718 100644
--- a/content/browser/renderer_host/render_frame_host_manager.cc
+++ b/content/browser/renderer_host/render_frame_host_manager.cc
@@ -3205,8 +3205,8 @@
     std::string* reason) {
   TRACE_EVENT("navigation",
               "RenderFrameHostManager::DetermineSiteInstanceForURL",
-              ChromeTrackEvent::kFrameTreeNodeInfo, *frame_tree_node_, "url",
-              dest_url_info.url);
+              ChromeTrackEvent::kFrameTreeNodeInfo, *frame_tree_node_,
+              "url_info", dest_url_info);
 
   // Note that this function should return a SiteInstanceDescriptor with
   // SiteInstanceRelation::UNRELATED or
diff --git a/content/browser/renderer_host/render_frame_host_permissions_policy_unittest.cc b/content/browser/renderer_host/render_frame_host_permissions_policy_unittest.cc
index a25633f..76d621ac 100644
--- a/content/browser/renderer_host/render_frame_host_permissions_policy_unittest.cc
+++ b/content/browser/renderer_host/render_frame_host_permissions_policy_unittest.cc
@@ -89,7 +89,8 @@
     static_cast<TestRenderFrameHost*>(parent)->DidChangeFramePolicy(
         frame_token, {network::mojom::WebSandboxFlags::kNone,
                       CreateFPHeader(feature, origins),
-                      {} /* required_document_policy */});
+                      {} /* required_document_policy */,
+                      blink::FramePolicy::DeferredFetchPolicy::kDisabled});
   }
 
   void SimulateNavigation(RenderFrameHost** rfh, const GURL& url) {
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index fa95a56..44b857c 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3584,6 +3584,11 @@
   unresponsive_document_javascript_call_stack_ =
       untrusted_javascript_call_stack;
   unresponsive_document_token_ = frame_token.value();
+  TRACE_EVENT1(
+      "browser",
+      "RenderProcessHostImpl::SetUnresponsiveDocumentJSCallStackAndToken",
+      "UnresponsiveJavaScriptCallStack",
+      unresponsive_document_javascript_call_stack_);
 }
 
 void RenderProcessHostImpl::InterruptJavaScriptIsolateAndCollectCallStack() {
diff --git a/content/browser/shared_storage/shared_storage_browsertest.cc b/content/browser/shared_storage/shared_storage_browsertest.cc
index 3313732..3846841 100644
--- a/content/browser/shared_storage/shared_storage_browsertest.cc
+++ b/content/browser/shared_storage/shared_storage_browsertest.cc
@@ -146,11 +146,6 @@
 
 constexpr double kSelectURLSiteBitBudget = 6.0;
 
-// kSelectURLOverallBitBudget % kSelectURLSiteBitBudget
-// TODO(https://crbug.com/378385004): As the value results in 0, the actual
-// test cases can be simplified if we assume this constant value.
-constexpr int kOverallBudgetRemaining = 0;
-
 constexpr char kGenerateURLsListScript[] = R"(
   function generateUrls(size) {
     return new Array(size).fill(0).map((e, i) => {
@@ -9939,15 +9934,6 @@
       base::StrCat({std::string(1, 'b' + num_site_limit), ".test"});
   GURL iframe_url = https_server()->GetURL(iframe_host, kSimplePagePath);
 
-  for (int j = 0; j < kOverallBudgetRemaining; j++) {
-    // Create a new iframe.
-    FrameTreeNode* iframe_node =
-        CreateIFrame(PrimaryFrameTreeNodeRoot(), iframe_url);
-
-    RunSuccessfulSelectURLInIframe(iframe_node,
-                                   /*num_urls=*/2, &console_observer);
-  }
-
   // Create a new iframe.
   FrameTreeNode* final_iframe_node =
       CreateIFrame(PrimaryFrameTreeNodeRoot(), iframe_url);
@@ -9984,31 +9970,28 @@
                      kSelectUrlBudgetStatusHistogram});
   histogram_tester_.ExpectTotalCount(
       kTimingSelectUrlExecutedInWorkletHistogram,
-      num_site_limit * (2 + per_site_input2_call_limit) +
-          kOverallBudgetRemaining + 1);
+      num_site_limit * (2 + per_site_input2_call_limit) + 1);
 
   if (LimitSelectURLCalls()) {
     histogram_tester_.ExpectBucketCount(
         kSelectUrlBudgetStatusHistogram,
         blink::SharedStorageSelectUrlBudgetStatus::kSufficientBudget,
-        num_site_limit * (1 + per_site_input2_call_limit) +
-            kOverallBudgetRemaining);
+        num_site_limit * (1 + per_site_input2_call_limit));
     histogram_tester_.ExpectBucketCount(
         kSelectUrlBudgetStatusHistogram,
         blink::SharedStorageSelectUrlBudgetStatus::
             kInsufficientSitePageloadBudget,
-        kOverallBudgetRemaining ? num_site_limit : num_site_limit - 1);
+        num_site_limit - 1);
     histogram_tester_.ExpectBucketCount(
         kSelectUrlBudgetStatusHistogram,
         blink::SharedStorageSelectUrlBudgetStatus::
             kInsufficientOverallPageloadBudget,
-        kOverallBudgetRemaining ? 1 : 2);
+        2);
   } else {
     histogram_tester_.ExpectUniqueSample(
         kSelectUrlBudgetStatusHistogram,
         blink::SharedStorageSelectUrlBudgetStatus::kSufficientBudget,
-        num_site_limit * (2 + per_site_input2_call_limit) +
-            kOverallBudgetRemaining + 1);
+        num_site_limit * (2 + per_site_input2_call_limit) + 1);
   }
 }
 
diff --git a/content/browser/site_instance_impl.cc b/content/browser/site_instance_impl.cc
index 2038d12..245f5f6 100644
--- a/content/browser/site_instance_impl.cc
+++ b/content/browser/site_instance_impl.cc
@@ -141,6 +141,8 @@
     bool is_guest,
     bool is_fenced,
     bool is_fixed_storage_partition) {
+  TRACE_EVENT("navigation", "SiteInstanceImpl::CreateForUrlInfo", "url_info",
+              url_info);
   DCHECK(url_info.is_sandboxed ||
          url_info.unique_sandbox_id == UrlInfo::kInvalidUniqueSandboxId);
   CHECK(!is_guest || url_info.storage_partition_config.has_value());
@@ -523,7 +525,7 @@
   // TODO(creis): Consider calling ShouldAssignSiteForURL internally, rather
   // than before multiple call sites.  See https://crbug.com/949220.
   TRACE_EVENT2("navigation", "SiteInstanceImpl::SetSite", "site id",
-               id_.value(), "url", url.possibly_invalid_spec());
+               id_.value(), "url_info", url_info);
   // A SiteInstance's site should not change.
   // TODO(creis): When following links or script navigations, we can currently
   // render pages from other sites in this SiteInstance.  This will eventually
@@ -804,6 +806,8 @@
 }  // namespace
 
 bool SiteInstanceImpl::IsSuitableForUrlInfo(const UrlInfo& url_info) {
+  TRACE_EVENT2("navigation", "SiteInstanceImpl::IsSuitableForUrlInfo",
+               ChromeTrackEvent::kSiteInstance, this, "url_info", url_info);
   const GURL& url = url_info.url;
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
   // If the URL to navigate to can be associated with any site instance,
diff --git a/content/browser/url_info.cc b/content/browser/url_info.cc
index 59a9189..333fa8a 100644
--- a/content/browser/url_info.cc
+++ b/content/browser/url_info.cc
@@ -76,6 +76,28 @@
           context.default_isolation_state().requires_origin_keyed_process());
 }
 
+void UrlInfo::WriteIntoTrace(perfetto::TracedProto<TraceProto> proto) const {
+  proto->set_url(url.possibly_invalid_spec());
+  if (origin.has_value()) {
+    proto->set_origin(origin->GetDebugString());
+  }
+  proto->set_is_sandboxed(is_sandboxed);
+  proto->set_is_pdf(is_pdf);
+  proto->set_is_coop_isolation_requested(is_coop_isolation_requested);
+  proto->set_origin_isolation_request(origin_isolation_request);
+  proto->set_is_prefetch_with_cross_site_contamination(
+      is_prefetch_with_cross_site_contamination);
+  if (web_exposed_isolation_info.has_value()) {
+    proto.Set(TraceProto::kWebExposedIsolationInfo,
+              *web_exposed_isolation_info);
+  }
+  if (storage_partition_config.has_value()) {
+    std::stringstream ss;
+    ss << *storage_partition_config;
+    proto->set_storage_partition_config(ss.str());
+  }
+}
+
 UrlInfoInit::UrlInfoInit(UrlInfoInit&) = default;
 
 UrlInfoInit::UrlInfoInit(const GURL& url) : url_(url) {}
diff --git a/content/browser/url_info.h b/content/browser/url_info.h
index c855547e..342687f0 100644
--- a/content/browser/url_info.h
+++ b/content/browser/url_info.h
@@ -7,10 +7,12 @@
 
 #include <optional>
 
+#include "base/tracing/protos/chrome_track_event.pbzero.h"
 #include "content/browser/agent_cluster_key.h"
 #include "content/browser/web_exposed_isolation_info.h"
 #include "content/common/content_export.h"
 #include "content/public/browser/storage_partition_config.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_proto.h"
 #include "url/gurl.h"
 #include "url/origin.h"
 
@@ -125,6 +127,9 @@
   // isolated.
   bool IsIsolated() const;
 
+  using TraceProto = perfetto::protos::pbzero::UrlInfo;
+  void WriteIntoTrace(perfetto::TracedProto<TraceProto> proto) const;
+
   GURL url;
 
   // This field indicates whether the URL is requesting additional process
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index c87953e..11063ec 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -1500,9 +1500,11 @@
         opener_rfh->active_sandbox_flags();
     if (opener_rfh->IsSandboxed(network::mojom::WebSandboxFlags::
                                     kPropagatesToAuxiliaryBrowsingContexts)) {
-      new_root->SetPendingFramePolicy({opener_flags,
-                                       {} /* container_policy */,
-                                       {} /* required_document_policy */});
+      new_root->SetPendingFramePolicy(
+          {opener_flags,
+           {} /* container_policy */,
+           {} /* required_document_policy */,
+           blink::FramePolicy::DeferredFetchPolicy::kDisabled});
     }
     new_root->SetInitialPopupURL(params.initial_popup_url);
     new_root->SetPopupCreatorOrigin(opener_rfh->GetLastCommittedOrigin());
diff --git a/content/browser/web_exposed_isolation_info.cc b/content/browser/web_exposed_isolation_info.cc
index 6c5e84e..5660dd5 100644
--- a/content/browser/web_exposed_isolation_info.cc
+++ b/content/browser/web_exposed_isolation_info.cc
@@ -109,6 +109,15 @@
   return false;
 }
 
+void WebExposedIsolationInfo::WriteIntoTrace(
+    perfetto::TracedProto<TraceProto> proto) const {
+  proto->set_is_isolated(is_isolated());
+  if (is_isolated()) {
+    proto->set_origin(origin_->GetDebugString());
+  }
+  proto->set_is_isolated_application(is_isolated_application());
+}
+
 std::ostream& operator<<(std::ostream& out,
                          const WebExposedIsolationInfo& info) {
   out << "{";
diff --git a/content/browser/web_exposed_isolation_info.h b/content/browser/web_exposed_isolation_info.h
index 6ebc634..dbe2560 100644
--- a/content/browser/web_exposed_isolation_info.h
+++ b/content/browser/web_exposed_isolation_info.h
@@ -7,7 +7,9 @@
 
 #include <optional>
 
+#include "base/tracing/protos/chrome_track_event.pbzero.h"
 #include "content/common/content_export.h"
+#include "third_party/perfetto/include/perfetto/tracing/traced_proto.h"
 #include "url/origin.h"
 
 namespace content {
@@ -92,6 +94,9 @@
   // Origin comparisons determine ordering of isolated contexts.
   bool operator<(const WebExposedIsolationInfo& b) const;
 
+  using TraceProto = perfetto::protos::pbzero::WebExposedIsolationInfo;
+  void WriteIntoTrace(perfetto::TracedProto<TraceProto> proto) const;
+
  private:
   WebExposedIsolationInfo(const std::optional<url::Origin>& origin,
                           bool isolated_application);
diff --git a/content/browser/worker_host/dedicated_worker_host.cc b/content/browser/worker_host/dedicated_worker_host.cc
index 8640dae7..7a73fe1 100644
--- a/content/browser/worker_host/dedicated_worker_host.cc
+++ b/content/browser/worker_host/dedicated_worker_host.cc
@@ -131,6 +131,14 @@
 }
 
 DedicatedWorkerHost::~DedicatedWorkerHost() {
+  // If this instance is being destroyed because its mojo connection was
+  // disconnected, then the destruction of the `service_worker_handle_` could
+  // end up causing this instance to be deleted again through
+  // RenderProcessExited, if that handle was the only thing keeping the
+  // RenderProcessHost alive. Stop observing the RenderProcessHost right away to
+  // avoid this issue. See https://crbug.com/383067308
+  scoped_process_host_observation_.Reset();
+
   // This DedicatedWorkerHost is destroyed via either the mojo disconnection
   // or RenderProcessHostObserver. This destruction should be called before
   // the observed render process host (`worker_process_host_`) is destroyed.
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc
index 236d6c4..2ca4544 100644
--- a/content/public/browser/content_browser_client.cc
+++ b/content/public/browser/content_browser_client.cc
@@ -1817,16 +1817,14 @@
     &blink::features::kLanguageDetectionAPI,
     "language_detection_local_file_model_path", ""};
 
-// Returns a singleton of `ContentLanguageDetectionDriver`. This will provide
-// the model from a flag-param path.
-language_detection::ContentLanguageDetectionDriver&
-GetContentLanguageDetectionDriver() {
-  scoped_refptr<base::SequencedTaskRunner> background_task_runner =
+// We need to initialize the provider after it is created. This should not be
+// inside `GetContentLanguageDetectionDriver` or it will be performed on every
+// call.
+language_detection::LanguageDetectionModelProvider*
+CreateLanguageDetectionModelProvider() {
+  auto* provider = new language_detection::LanguageDetectionModelProvider(
       base::ThreadPool::CreateSequencedTaskRunner(
-          {base::MayBlock(), base::TaskPriority::BEST_EFFORT});
-
-  static base::NoDestructor<language_detection::LanguageDetectionModelProvider>
-      provider(background_task_runner);
+          {base::MayBlock(), base::TaskPriority::BEST_EFFORT}));
   const std::string model_file_path =
       kLanguageDetectionLocalFileModelPath.Get();
   if (model_file_path.length()) {
@@ -1837,9 +1835,15 @@
     // a model will become available.
     provider->UnloadModelFile();
   }
+  return provider;
+}
 
+// Returns a singleton of `ContentLanguageDetectionDriver`. This will provide
+// the model from a flag-param path.
+language_detection::ContentLanguageDetectionDriver&
+GetContentLanguageDetectionDriver() {
   static base::NoDestructor<language_detection::ContentLanguageDetectionDriver>
-      driver(provider.get());
+      driver(CreateLanguageDetectionModelProvider());
   return *driver.get();
 }
 }  // namespace
diff --git a/content/public/test/navigation_handle_observer.cc b/content/public/test/navigation_handle_observer.cc
index 007461a..867c7b5 100644
--- a/content/public/test/navigation_handle_observer.cc
+++ b/content/public/test/navigation_handle_observer.cc
@@ -61,6 +61,7 @@
     if (!navigation_handle->IsErrorPage()) {
       page_transition_ = navigation_handle->GetPageTransition();
       last_committed_url_ = navigation_handle->GetURL();
+      last_initiator_origin_ = navigation_handle->GetInitiatorOrigin();
       response_headers_ = navigation_handle->GetResponseHeaders();
     } else {
       is_error_ = true;
diff --git a/content/public/test/navigation_handle_observer.h b/content/public/test/navigation_handle_observer.h
index 2ed251a..e5191aeb 100644
--- a/content/public/test/navigation_handle_observer.h
+++ b/content/public/test/navigation_handle_observer.h
@@ -46,6 +46,9 @@
   bool was_redirected() { return was_redirected_; }
   FrameTreeNodeId frame_tree_node_id() { return frame_tree_node_id_; }
   const GURL& last_committed_url() { return last_committed_url_; }
+  const std::optional<url::Origin>& last_initiator_origin() {
+    return last_initiator_origin_;
+  }
   ui::PageTransition page_transition() { return page_transition_; }
   net::Error net_error_code() { return net_error_code_; }
   int64_t navigation_id() { return navigation_id_; }
@@ -82,6 +85,8 @@
   ui::PageTransition page_transition_ = ui::PAGE_TRANSITION_LINK;
   GURL expected_start_url_;
   GURL last_committed_url_;
+  // Tracks the origin that initiated the last committed navigation.
+  std::optional<url::Origin> last_initiator_origin_;
   net::Error net_error_code_ = net::OK;
   int64_t navigation_id_ = -1;
   bool is_download_ = false;
diff --git a/content/test/test_render_frame_host.cc b/content/test/test_render_frame_host.cc
index f06815e..a4f2f06 100644
--- a/content/test/test_render_frame_host.cc
+++ b/content/test/test_render_frame_host.cc
@@ -202,7 +202,10 @@
       blink::mojom::TreeScopeType::kDocument, frame_name, frame_unique_name,
       false, blink::LocalFrameToken(), base::UnguessableToken::Create(),
       blink::DocumentToken(),
-      blink::FramePolicy({network::mojom::WebSandboxFlags::kNone, allow, {}}),
+      blink::FramePolicy({network::mojom::WebSandboxFlags::kNone,
+                          allow,
+                          {},
+                          blink::FramePolicy::DeferredFetchPolicy::kDisabled}),
       blink::mojom::FrameOwnerProperties(),
       blink::FrameOwnerElementType::kIframe, ukm::kInvalidSourceId);
   return static_cast<TestRenderFrameHost*>(
diff --git a/docs/adding_to_third_party.md b/docs/adding_to_third_party.md
index fa5f199..601fbed 100644
--- a/docs/adding_to_third_party.md
+++ b/docs/adding_to_third_party.md
@@ -313,6 +313,18 @@
 testing tools), make sure to set the "Shipped" field to "no" so that the license
 is not included in about:credits page ([more on this below](#credits)).
 
+When a dependency allows a choice of license, OWNERS should choose the least
+restrictive license that meets Chromium's needs and document only the chosen
+license(s) in the README.chromium file.
+
+Multiple licenses apply when there are dependencies bundled together, or
+different parts have different restrictions, these are inherently 'and'. This is
+very different to a project allowing multiple license options.
+
+The license field in README.chromium must use a _comma-separated list_ of licenses
+that are actively in use. Complex license expressions are not allowed or
+supported.
+
 ## Get a review
 
 All third party additions and substantive changes like re-licensing need the
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 4e14f1d..c88c44c 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -1010,8 +1010,6 @@
       "//chromeos/ash/components/dbus/upstart",
       "//chromeos/ash/components/login/login_state",
       "//chromeos/ash/components/network:test_support",
-      "//chromeos/ash/components/standalone_browser",
-      "//chromeos/ash/components/standalone_browser:test_support",
       "//chromeos/constants",
       "//chromeos/crosapi/mojom",
       "//chromeos/dbus/permission_broker",
diff --git a/extensions/browser/extension_registrar_unittest.cc b/extensions/browser/extension_registrar_unittest.cc
index a71d3ad..5ad46315 100644
--- a/extensions/browser/extension_registrar_unittest.cc
+++ b/extensions/browser/extension_registrar_unittest.cc
@@ -26,7 +26,6 @@
 #include "base/test/scoped_feature_list.h"
 #include "chrome/browser/ash/crosapi/browser_util.h"
 #include "chrome/common/pref_names.h"  // nogncheck
-#include "chromeos/ash/components/standalone_browser/feature_refs.h"
 #include "components/account_id/account_id.h"  // nogncheck
 #include "components/prefs/pref_registry_simple.h"
 #include "components/prefs/testing_pref_service.h"
diff --git a/infra/config/generated/builder-owners/~unowned.txt b/infra/config/generated/builder-owners/~unowned.txt
index cf218c3..ff89d18 100644
--- a/infra/config/generated/builder-owners/~unowned.txt
+++ b/infra/config/generated/builder-owners/~unowned.txt
@@ -17,10 +17,8 @@
 ci/Comparison ios (reclient)
 ci/Comparison ios (reclient)(CQ)
 ci/Leak Detection Linux
-ci/Linux Builder (reclient compare)
 ci/Linux Viz
 ci/Mac ASAN Release Media
-ci/Mac Builder (reclient compare)
 ci/Mac Builder Next
 ci/Mac deterministic
 ci/Mac deterministic (dbg)
@@ -28,7 +26,6 @@
 ci/Oreo Phone Tester
 ci/Site Isolation Android
 ci/Win 10 Fast Ring
-ci/Win x64 Builder (reclient compare)
 ci/Win x64 Builder (reclient)
 ci/android-11-x86-fyi-rel
 ci/android-11-x86-rel
diff --git "a/infra/config/generated/builders/ci/GPU Win x64 Builder \050dbg\051/properties.json" "b/infra/config/generated/builders/ci/GPU Win x64 Builder \050dbg\051/properties.json"
index 21f479b..f1d1883 100644
--- "a/infra/config/generated/builders/ci/GPU Win x64 Builder \050dbg\051/properties.json"
+++ "b/infra/config/generated/builders/ci/GPU Win x64 Builder \050dbg\051/properties.json"
@@ -97,7 +97,7 @@
     "enable_cloud_trace": true,
     "experiments": [],
     "project": "rbe-chromium-trusted",
-    "remote_jobs": 80
+    "remote_jobs": 250
   },
   "$recipe_engine/resultdb/test_presentation": {
     "column_keys": [],
diff --git "a/infra/config/generated/builders/ci/GPU Win x64 Builder \050dbg\051/shadow-properties.json" "b/infra/config/generated/builders/ci/GPU Win x64 Builder \050dbg\051/shadow-properties.json"
index 22e4eb0..673c7c0 100644
--- "a/infra/config/generated/builders/ci/GPU Win x64 Builder \050dbg\051/shadow-properties.json"
+++ "b/infra/config/generated/builders/ci/GPU Win x64 Builder \050dbg\051/shadow-properties.json"
@@ -12,6 +12,6 @@
     "enable_cloud_trace": true,
     "experiments": [],
     "project": "rbe-chromium-untrusted",
-    "remote_jobs": 80
+    "remote_jobs": 250
   }
 }
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/GPU Win x64 Builder/properties.json b/infra/config/generated/builders/ci/GPU Win x64 Builder/properties.json
index 8978ba61..d1adca1 100644
--- a/infra/config/generated/builders/ci/GPU Win x64 Builder/properties.json
+++ b/infra/config/generated/builders/ci/GPU Win x64 Builder/properties.json
@@ -104,7 +104,7 @@
     "enable_cloud_trace": true,
     "experiments": [],
     "project": "rbe-chromium-trusted",
-    "remote_jobs": 80
+    "remote_jobs": 250
   },
   "$recipe_engine/resultdb/test_presentation": {
     "column_keys": [],
diff --git a/infra/config/generated/builders/ci/GPU Win x64 Builder/shadow-properties.json b/infra/config/generated/builders/ci/GPU Win x64 Builder/shadow-properties.json
index 22e4eb0..673c7c0 100644
--- a/infra/config/generated/builders/ci/GPU Win x64 Builder/shadow-properties.json
+++ b/infra/config/generated/builders/ci/GPU Win x64 Builder/shadow-properties.json
@@ -12,6 +12,6 @@
     "enable_cloud_trace": true,
     "experiments": [],
     "project": "rbe-chromium-untrusted",
-    "remote_jobs": 80
+    "remote_jobs": 250
   }
 }
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/gn-args.json" "b/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/gn-args.json"
deleted file mode 100644
index e8672db..0000000
--- "a/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/gn-args.json"
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "gn_args": {
-    "dcheck_always_on": false,
-    "ffmpeg_branding": "Chrome",
-    "is_component_build": false,
-    "is_debug": false,
-    "proprietary_codecs": true,
-    "target_cpu": "x64",
-    "target_os": "linux",
-    "use_remoteexec": true,
-    "use_siso": true
-  }
-}
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/properties.json" "b/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/properties.json"
deleted file mode 100644
index 8e472c6..0000000
--- "a/infra/config/generated/builders/ci/Linux Builder \050reclient compare\051/properties.json"
+++ /dev/null
@@ -1,80 +0,0 @@
-{
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "additional_exclusions": [
-        "infra/config/generated/builders/ci/Linux Builder (reclient compare)/gn-args.json"
-      ],
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Linux Builder (reclient compare)",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "builder_group": "chromium.fyi",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "linux"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage",
-                  "chromium_with_telemetry_dependencies",
-                  "reclient_test"
-                ],
-                "config": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "Linux Builder (reclient compare)",
-          "project": "chromium"
-        }
-      ]
-    }
-  },
-  "$build/reclient": {
-    "bootstrap_env": {
-      "RBE_clang_depscan_archive": "true"
-    },
-    "ensure_verified": true,
-    "instance": "rbe-chromium-trusted-test",
-    "metrics_project": "chromium-reclient-metrics",
-    "rewrapper_env": {
-      "RBE_compare": "true",
-      "RBE_num_local_reruns": "1",
-      "RBE_num_remote_reruns": "1"
-    },
-    "scandeps_server": true
-  },
-  "$build/siso": {
-    "configs": [
-      "builder"
-    ],
-    "enable_cloud_profiler": true,
-    "enable_cloud_trace": true,
-    "experiments": [],
-    "project": "rbe-chromium-trusted-test"
-  },
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "chromium.fyi",
-  "recipe": "chromium"
-}
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/gn-args.json" "b/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/gn-args.json"
deleted file mode 100644
index c0cfa817..0000000
--- "a/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/gn-args.json"
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "gn_args": {
-    "dcheck_always_on": false,
-    "ffmpeg_branding": "Chrome",
-    "is_component_build": false,
-    "is_debug": false,
-    "proprietary_codecs": true,
-    "symbol_level": 1,
-    "target_cpu": "x64",
-    "target_os": "mac",
-    "use_remoteexec": true,
-    "use_siso": true
-  }
-}
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/properties.json" "b/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/properties.json"
deleted file mode 100644
index 659f30a..0000000
--- "a/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/properties.json"
+++ /dev/null
@@ -1,78 +0,0 @@
-{
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "additional_exclusions": [
-        "infra/config/generated/builders/ci/Mac Builder (reclient compare)/gn-args.json"
-      ],
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Mac Builder (reclient compare)",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "build_gs_bucket": "chromium-fyi-archive",
-              "builder_group": "chromium.fyi",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "mac"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage",
-                  "reclient_test"
-                ],
-                "config": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "Mac Builder (reclient compare)",
-          "project": "chromium"
-        }
-      ],
-      "targets_spec_directory": "src/infra/config/generated/builders/ci/Mac Builder (reclient compare)/targets"
-    }
-  },
-  "$build/reclient": {
-    "ensure_verified": true,
-    "instance": "rbe-chromium-trusted-test",
-    "metrics_project": "chromium-reclient-metrics",
-    "rewrapper_env": {
-      "RBE_compare": "true",
-      "RBE_num_local_reruns": "1",
-      "RBE_num_remote_reruns": "1"
-    },
-    "scandeps_server": true
-  },
-  "$build/siso": {
-    "configs": [
-      "builder"
-    ],
-    "enable_cloud_profiler": true,
-    "enable_cloud_trace": true,
-    "experiments": [],
-    "project": "rbe-chromium-trusted-test"
-  },
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "chromium.fyi",
-  "recipe": "chromium"
-}
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/targets/chromium.fyi.json" "b/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/targets/chromium.fyi.json"
deleted file mode 100644
index 1d5f45ff..0000000
--- "a/infra/config/generated/builders/ci/Mac Builder \050reclient compare\051/targets/chromium.fyi.json"
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "Mac Builder (reclient compare)": {
-    "additional_compile_targets": [
-      "chrome"
-    ],
-    "scripts": [
-      {
-        "name": "check_static_initializers",
-        "script": "check_static_initializers.py"
-      },
-      {
-        "name": "metrics_python_tests",
-        "script": "metrics_python_tests.py"
-      },
-      {
-        "name": "webkit_lint",
-        "script": "blink_lint_expectations.py"
-      }
-    ]
-  }
-}
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/gn-args.json" "b/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/gn-args.json"
deleted file mode 100644
index c78d951..0000000
--- "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/gn-args.json"
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "gn_args": {
-    "dcheck_always_on": false,
-    "ffmpeg_branding": "Chrome",
-    "is_component_build": false,
-    "is_debug": false,
-    "proprietary_codecs": true,
-    "symbol_level": 1,
-    "target_cpu": "x64",
-    "target_os": "win",
-    "use_remoteexec": true,
-    "use_siso": true
-  }
-}
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/properties.json" "b/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/properties.json"
deleted file mode 100644
index 78849b9..0000000
--- "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/properties.json"
+++ /dev/null
@@ -1,77 +0,0 @@
-{
-  "$build/chromium_tests_builder_config": {
-    "builder_config": {
-      "additional_exclusions": [
-        "infra/config/generated/builders/ci/Win x64 Builder (reclient compare)/gn-args.json"
-      ],
-      "builder_db": {
-        "entries": [
-          {
-            "builder_id": {
-              "bucket": "ci",
-              "builder": "Win x64 Builder (reclient compare)",
-              "project": "chromium"
-            },
-            "builder_spec": {
-              "builder_group": "chromium.fyi",
-              "execution_mode": "COMPILE_AND_TEST",
-              "legacy_chromium_config": {
-                "apply_configs": [
-                  "mb"
-                ],
-                "build_config": "Release",
-                "config": "chromium",
-                "target_bits": 64,
-                "target_platform": "win"
-              },
-              "legacy_gclient_config": {
-                "apply_configs": [
-                  "use_clang_coverage",
-                  "reclient_test"
-                ],
-                "config": "chromium"
-              }
-            }
-          }
-        ]
-      },
-      "builder_ids": [
-        {
-          "bucket": "ci",
-          "builder": "Win x64 Builder (reclient compare)",
-          "project": "chromium"
-        }
-      ],
-      "targets_spec_directory": "src/infra/config/generated/builders/ci/Win x64 Builder (reclient compare)/targets"
-    }
-  },
-  "$build/reclient": {
-    "ensure_verified": true,
-    "instance": "rbe-chromium-trusted-test",
-    "metrics_project": "chromium-reclient-metrics",
-    "rewrapper_env": {
-      "RBE_compare": "true",
-      "RBE_num_local_reruns": "1",
-      "RBE_num_remote_reruns": "1"
-    },
-    "scandeps_server": true
-  },
-  "$build/siso": {
-    "configs": [
-      "builder"
-    ],
-    "enable_cloud_profiler": true,
-    "enable_cloud_trace": true,
-    "experiments": [],
-    "project": "rbe-chromium-trusted-test"
-  },
-  "$recipe_engine/resultdb/test_presentation": {
-    "column_keys": [],
-    "grouping_keys": [
-      "status",
-      "v.test_suite"
-    ]
-  },
-  "builder_group": "chromium.fyi",
-  "recipe": "chromium"
-}
\ No newline at end of file
diff --git "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/targets/chromium.fyi.json" "b/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/targets/chromium.fyi.json"
deleted file mode 100644
index fbc2344..0000000
--- "a/infra/config/generated/builders/ci/Win x64 Builder \050reclient compare\051/targets/chromium.fyi.json"
+++ /dev/null
@@ -1,21 +0,0 @@
-{
-  "Win x64 Builder (reclient compare)": {
-    "additional_compile_targets": [
-      "pdf_fuzzers"
-    ],
-    "scripts": [
-      {
-        "name": "check_network_annotations",
-        "script": "check_network_annotations.py"
-      },
-      {
-        "name": "metrics_python_tests",
-        "script": "metrics_python_tests.py"
-      },
-      {
-        "name": "webkit_lint",
-        "script": "blink_lint_expectations.py"
-      }
-    ]
-  }
-}
\ No newline at end of file
diff --git a/infra/config/generated/builders/ci/android-15-x64-fyi-rel/targets/chromium.android.fyi.json b/infra/config/generated/builders/ci/android-15-x64-fyi-rel/targets/chromium.android.fyi.json
index 7e8b8163..a0c0ee2 100644
--- a/infra/config/generated/builders/ci/android-15-x64-fyi-rel/targets/chromium.android.fyi.json
+++ b/infra/config/generated/builders/ci/android-15-x64-fyi-rel/targets/chromium.android.fyi.json
@@ -127,6 +127,7 @@
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices"
         ],
+        "ci_only": true,
         "description": "Run with android_35_google_apis_x64",
         "merge": {
           "args": [
@@ -174,6 +175,55 @@
         },
         "test": "webview_trichrome_64_cts_tests",
         "test_id_prefix": "ninja://android_webview/test:webview_trichrome_64_cts_tests/"
+      },
+      {
+        "args": [
+          "--disable-field-trial-config",
+          "--emulator-debug-tags=all,-qemud,-sensors",
+          "--avd-config=../../tools/android/avd/proto/android_35_google_apis_x64.textpb",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "ci_only": true,
+        "description": "Run with android_35_google_apis_x64",
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "webview_ui_test_app_test_apk_no_field_trial"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "webview_ui_test_app_test_apk_no_field_trial",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "cores": "8",
+            "cpu": "x86-64",
+            "device_os": null,
+            "device_type": null,
+            "os": "Ubuntu-22.04",
+            "pool": "chromium.tests.avd"
+          },
+          "named_caches": [
+            {
+              "name": "android_35_google_apis_x64",
+              "path": ".android_emulator/android_35_google_apis_x64"
+            }
+          ],
+          "optional_dimensions": {
+            "60": {
+              "caches": "android_35_google_apis_x64"
+            }
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "webview_ui_test_app_test_apk",
+        "test_id_prefix": "ninja://android_webview/tools/automated_ui_tests:webview_ui_test_app_test_apk/"
       }
     ]
   }
diff --git a/infra/config/generated/builders/gn_args_locations.json b/infra/config/generated/builders/gn_args_locations.json
index 00e2548..a003a8d 100644
--- a/infra/config/generated/builders/gn_args_locations.json
+++ b/infra/config/generated/builders/gn_args_locations.json
@@ -299,15 +299,12 @@
     "Comparison Windows (8 cores) (reclient)": "ci/Comparison Windows (8 cores) (reclient)/gn-args.json",
     "Comparison Windows (reclient)": "ci/Comparison Windows (reclient)/gn-args.json",
     "Comparison ios (reclient)": "ci/Comparison ios (reclient)/gn-args.json",
-    "Linux Builder (reclient compare)": "ci/Linux Builder (reclient compare)/gn-args.json",
     "Linux Viz": "ci/Linux Viz/gn-args.json",
-    "Mac Builder (reclient compare)": "ci/Mac Builder (reclient compare)/gn-args.json",
     "Mac Builder Next": "ci/Mac Builder Next/gn-args.json",
     "Mac deterministic": "ci/Mac deterministic/gn-args.json",
     "Mac deterministic (dbg)": "ci/Mac deterministic (dbg)/gn-args.json",
     "Site Isolation Android": "ci/Site Isolation Android/gn-args.json",
     "Win 10 Fast Ring": "ci/Win 10 Fast Ring/gn-args.json",
-    "Win x64 Builder (reclient compare)": "ci/Win x64 Builder (reclient compare)/gn-args.json",
     "Win x64 Builder (reclient)": "ci/Win x64 Builder (reclient)/gn-args.json",
     "android-fieldtrial-rel": "ci/android-fieldtrial-rel/gn-args.json",
     "android-perfetto-rel": "ci/android-perfetto-rel/gn-args.json",
diff --git a/infra/config/generated/builders/try/android-15-x64-fyi-rel/targets/chromium.android.fyi.json b/infra/config/generated/builders/try/android-15-x64-fyi-rel/targets/chromium.android.fyi.json
index 7e8b8163..a0c0ee2 100644
--- a/infra/config/generated/builders/try/android-15-x64-fyi-rel/targets/chromium.android.fyi.json
+++ b/infra/config/generated/builders/try/android-15-x64-fyi-rel/targets/chromium.android.fyi.json
@@ -127,6 +127,7 @@
           "--gs-results-bucket=chromium-result-details",
           "--recover-devices"
         ],
+        "ci_only": true,
         "description": "Run with android_35_google_apis_x64",
         "merge": {
           "args": [
@@ -174,6 +175,55 @@
         },
         "test": "webview_trichrome_64_cts_tests",
         "test_id_prefix": "ninja://android_webview/test:webview_trichrome_64_cts_tests/"
+      },
+      {
+        "args": [
+          "--disable-field-trial-config",
+          "--emulator-debug-tags=all,-qemud,-sensors",
+          "--avd-config=../../tools/android/avd/proto/android_35_google_apis_x64.textpb",
+          "--gs-results-bucket=chromium-result-details",
+          "--recover-devices"
+        ],
+        "ci_only": true,
+        "description": "Run with android_35_google_apis_x64",
+        "merge": {
+          "args": [
+            "--bucket",
+            "chromium-result-details",
+            "--test-name",
+            "webview_ui_test_app_test_apk_no_field_trial"
+          ],
+          "script": "//build/android/pylib/results/presentation/test_results_presentation.py"
+        },
+        "name": "webview_ui_test_app_test_apk_no_field_trial",
+        "resultdb": {
+          "enable": true,
+          "has_native_resultdb_integration": true
+        },
+        "swarming": {
+          "dimensions": {
+            "cores": "8",
+            "cpu": "x86-64",
+            "device_os": null,
+            "device_type": null,
+            "os": "Ubuntu-22.04",
+            "pool": "chromium.tests.avd"
+          },
+          "named_caches": [
+            {
+              "name": "android_35_google_apis_x64",
+              "path": ".android_emulator/android_35_google_apis_x64"
+            }
+          ],
+          "optional_dimensions": {
+            "60": {
+              "caches": "android_35_google_apis_x64"
+            }
+          },
+          "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
+        },
+        "test": "webview_ui_test_app_test_apk",
+        "test_id_prefix": "ninja://android_webview/tools/automated_ui_tests:webview_ui_test_app_test_apk/"
       }
     ]
   }
diff --git a/infra/config/generated/health-specs/health-specs.json b/infra/config/generated/health-specs/health-specs.json
index 06ab7c5..a6a9c7b 100644
--- a/infra/config/generated/health-specs/health-specs.json
+++ b/infra/config/generated/health-specs/health-specs.json
@@ -3341,26 +3341,6 @@
           }
         ]
       },
-      "Linux Builder (reclient compare)": {
-        "problem_specs": [
-          {
-            "name": "Unhealthy",
-            "period_days": 7,
-            "score": 5,
-            "thresholds": {
-              "_default": "_default"
-            }
-          },
-          {
-            "name": "Low Value",
-            "period_days": 90,
-            "score": 1,
-            "thresholds": {
-              "_default": "_default"
-            }
-          }
-        ]
-      },
       "Linux CFI": {
         "contact_team_email": "chrome-sanitizer-builder-owners@google.com",
         "problem_specs": [
@@ -4099,26 +4079,6 @@
           }
         ]
       },
-      "Mac Builder (reclient compare)": {
-        "problem_specs": [
-          {
-            "name": "Unhealthy",
-            "period_days": 7,
-            "score": 5,
-            "thresholds": {
-              "_default": "_default"
-            }
-          },
-          {
-            "name": "Low Value",
-            "period_days": 90,
-            "score": 1,
-            "thresholds": {
-              "_default": "_default"
-            }
-          }
-        ]
-      },
       "Mac Builder Next": {
         "problem_specs": [
           {
@@ -5975,26 +5935,6 @@
           }
         ]
       },
-      "Win x64 Builder (reclient compare)": {
-        "problem_specs": [
-          {
-            "name": "Unhealthy",
-            "period_days": 7,
-            "score": 5,
-            "thresholds": {
-              "_default": "_default"
-            }
-          },
-          {
-            "name": "Low Value",
-            "period_days": 90,
-            "score": 1,
-            "thresholds": {
-              "_default": "_default"
-            }
-          }
-        ]
-      },
       "Win x64 Builder (reclient)": {
         "problem_specs": [
           {
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg
index 1f168cb..6d69845 100644
--- a/infra/config/generated/luci/cr-buildbucket.cfg
+++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -20271,115 +20271,6 @@
       }
     }
     builders {
-      name: "Linux Builder (reclient compare)"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:32"
-      dimensions: "cpu:x86-64"
-      dimensions: "free_space:standard"
-      dimensions: "os:Ubuntu-22.04"
-      dimensions: "pool:luci.chromium.ci"
-      dimensions: "ssd:0"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/ci/Linux Builder (reclient compare)/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "chromium.fyi",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 50400
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium.use_per_builder_build_dir_name"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://(chrome|content)/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)|(ninja://[^/]*headless_shell_wpt/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        dimensions: "free_space:"
-        dimensions: "pool:luci.chromium.try"
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/cached_count"
-        predicates: "has(build.output.properties.is_cached)"
-        predicates: "string(build.output.properties.is_cached) == \"true\""
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/ran_tests_retry_shard_count"
-        predicates: "has(build.output.properties.ran_tests_retry_shard)"
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/ran_tests_without_patch_count"
-        predicates: "has(build.output.properties.ran_tests_without_patch)"
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/uncached_count"
-        predicates: "has(build.output.properties.is_cached)"
-        predicates: "string(build.output.properties.is_cached) == \"false\""
-      }
-    }
-    builders {
       name: "Linux CFI"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
@@ -24445,114 +24336,6 @@
       }
     }
     builders {
-      name: "Mac Builder (reclient compare)"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cpu:arm64"
-      dimensions: "free_space:standard"
-      dimensions: "os:Mac-14"
-      dimensions: "pool:luci.chromium.ci"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/ci/Mac Builder (reclient compare)/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "chromium.fyi",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 57600
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium.use_per_builder_build_dir_name"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://(chrome|content)/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)|(ninja://[^/]*headless_shell_wpt/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "Verifies whether local and remote build artifacts are identical."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        dimensions: "free_space:"
-        dimensions: "pool:luci.chromium.try"
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/cached_count"
-        predicates: "has(build.output.properties.is_cached)"
-        predicates: "string(build.output.properties.is_cached) == \"true\""
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/ran_tests_retry_shard_count"
-        predicates: "has(build.output.properties.ran_tests_retry_shard)"
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/ran_tests_without_patch_count"
-        predicates: "has(build.output.properties.ran_tests_without_patch)"
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/uncached_count"
-        predicates: "has(build.output.properties.is_cached)"
-        predicates: "string(build.output.properties.is_cached) == \"false\""
-      }
-    }
-    builders {
       name: "Mac Builder Next"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builder:Mac Builder Next"
@@ -34237,116 +34020,6 @@
       }
     }
     builders {
-      name: "Win x64 Builder (reclient compare)"
-      swarming_host: "chromium-swarm.appspot.com"
-      dimensions: "builderless:1"
-      dimensions: "cores:16"
-      dimensions: "cpu:x86-64"
-      dimensions: "free_space:standard"
-      dimensions: "os:Windows-10"
-      dimensions: "pool:luci.chromium.ci"
-      dimensions: "ssd:1"
-      exe {
-        cipd_package: "infra/chromium/bootstrapper/${platform}"
-        cipd_version: "latest"
-        cmd: "bootstrapper"
-      }
-      properties:
-        '{'
-        '  "$bootstrap/exe": {'
-        '    "exe": {'
-        '      "cipd_package": "infra/recipe_bundles/chromium.googlesource.com/chromium/tools/build",'
-        '      "cipd_version": "refs/heads/main",'
-        '      "cmd": ['
-        '        "luciexe"'
-        '      ]'
-        '    }'
-        '  },'
-        '  "$bootstrap/properties": {'
-        '    "properties_file": "infra/config/generated/builders/ci/Win x64 Builder (reclient compare)/properties.json",'
-        '    "top_level_project": {'
-        '      "ref": "refs/heads/main",'
-        '      "repo": {'
-        '        "host": "chromium.googlesource.com",'
-        '        "project": "chromium/src"'
-        '      }'
-        '    }'
-        '  },'
-        '  "builder_group": "chromium.fyi",'
-        '  "led_builder_is_bootstrapped": true,'
-        '  "recipe": "chromium"'
-        '}'
-      priority: 35
-      execution_timeout_secs: 36000
-      build_numbers: YES
-      service_account: "chromium-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
-      experiments {
-        key: "chromium.use_per_builder_build_dir_name"
-        value: 100
-      }
-      experiments {
-        key: "luci.recipes.use_python3"
-        value: 100
-      }
-      resultdb {
-        enable: true
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "ci_test_results"
-          test_results {}
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "gpu_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "ninja://(chrome|content)/test:telemetry_gpu_integration_test[^/]*/.+"
-            }
-          }
-        }
-        bq_exports {
-          project: "chrome-luci-data"
-          dataset: "chromium"
-          table: "blink_web_tests_ci_test_results"
-          test_results {
-            predicate {
-              test_id_regexp: "(ninja://[^/]*blink_web_tests/.+)|(ninja://[^/]*_wpt_tests/.+)|(ninja://[^/]*headless_shell_wpt/.+)"
-            }
-          }
-        }
-        history_options {
-          use_invocation_timestamp: true
-        }
-      }
-      description_html: "Verifies whether local and remote build artifacts are identical."
-      shadow_builder_adjustments {
-        service_account: "chromium-try-builder@chops-service-accounts.iam.gserviceaccount.com"
-        pool: "luci.chromium.try"
-        dimensions: "free_space:"
-        dimensions: "pool:luci.chromium.try"
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/cached_count"
-        predicates: "has(build.output.properties.is_cached)"
-        predicates: "string(build.output.properties.is_cached) == \"true\""
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/ran_tests_retry_shard_count"
-        predicates: "has(build.output.properties.ran_tests_retry_shard)"
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/ran_tests_without_patch_count"
-        predicates: "has(build.output.properties.ran_tests_without_patch)"
-      }
-      custom_metric_definitions {
-        name: "/chrome/infra/browser/builds/uncached_count"
-        predicates: "has(build.output.properties.is_cached)"
-        predicates: "string(build.output.properties.is_cached) == \"false\""
-      }
-    }
-    builders {
       name: "Win x64 Builder (reclient)"
       swarming_host: "chromium-swarm.appspot.com"
       dimensions: "builderless:1"
diff --git a/infra/config/generated/luci/luci-milo.cfg b/infra/config/generated/luci/luci-milo.cfg
index 391ac59..47a6766 100644
--- a/infra/config/generated/luci/luci-milo.cfg
+++ b/infra/config/generated/luci/luci-milo.cfg
@@ -10026,11 +10026,6 @@
     short_name: "cmp"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/Mac Builder (reclient compare)"
-    category: "mac"
-    short_name: "cmp"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/Comparison Mac (reclient)(CQ)"
     category: "mac|cq"
     short_name: "cmp"
@@ -10121,11 +10116,6 @@
     short_name: "lk"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/Linux Builder (reclient compare)"
-    category: "linux"
-    short_name: "re"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/linux-rr-orchestrator-fyi"
     category: "linux"
     short_name: "rr"
@@ -10260,11 +10250,6 @@
     short_name: "re"
   }
   builders {
-    name: "buildbucket/luci.chromium.ci/Win x64 Builder (reclient compare)"
-    category: "win"
-    short_name: "re"
-  }
-  builders {
     name: "buildbucket/luci.chromium.ci/Win x64 Builder (reclient)"
     category: "win"
     short_name: "re"
diff --git a/infra/config/generated/luci/luci-scheduler.cfg b/infra/config/generated/luci/luci-scheduler.cfg
index 7ab0c36..e35c549 100644
--- a/infra/config/generated/luci/luci-scheduler.cfg
+++ b/infra/config/generated/luci/luci-scheduler.cfg
@@ -1546,15 +1546,6 @@
   }
 }
 job {
-  id: "Linux Builder (reclient compare)"
-  realm: "ci"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "Linux Builder (reclient compare)"
-  }
-}
-job {
   id: "Linux Builder reclient staging"
   realm: "reclient"
   buildbucket {
@@ -1964,16 +1955,6 @@
   }
 }
 job {
-  id: "Mac Builder (reclient compare)"
-  realm: "ci"
-  schedule: "0 */4 * * *"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "Mac Builder (reclient compare)"
-  }
-}
-job {
   id: "Mac Builder Next"
   realm: "ci"
   buildbucket {
@@ -3033,15 +3014,6 @@
   }
 }
 job {
-  id: "Win x64 Builder (reclient compare)"
-  realm: "ci"
-  buildbucket {
-    server: "cr-buildbucket.appspot.com"
-    bucket: "ci"
-    builder: "Win x64 Builder (reclient compare)"
-  }
-}
-job {
   id: "Win x64 Builder (reclient)"
   realm: "ci"
   buildbucket {
@@ -6639,7 +6611,6 @@
   triggers: "Linux Builder"
   triggers: "Linux Builder (Wayland)"
   triggers: "Linux Builder (dbg)"
-  triggers: "Linux Builder (reclient compare)"
   triggers: "Linux CFI"
   triggers: "Linux Chromium OS ASan LSan Builder"
   triggers: "Linux ChromiumOS MSan Builder"
@@ -6655,7 +6626,6 @@
   triggers: "Mac ASan 64 Builder"
   triggers: "Mac Builder"
   triggers: "Mac Builder (dbg)"
-  triggers: "Mac Builder (reclient compare)"
   triggers: "Mac Builder Next"
   triggers: "Mac deterministic"
   triggers: "Mac deterministic (dbg)"
@@ -6715,7 +6685,6 @@
   triggers: "Win Builder (dbg)"
   triggers: "Win x64 Builder"
   triggers: "Win x64 Builder (dbg)"
-  triggers: "Win x64 Builder (reclient compare)"
   triggers: "Win x64 Builder (reclient)"
   triggers: "Windows deterministic"
   triggers: "android-10-arm64-rel"
diff --git a/infra/config/generated/luci/project.cfg b/infra/config/generated/luci/project.cfg
index 132b4e92..83d9cff 100644
--- a/infra/config/generated/luci/project.cfg
+++ b/infra/config/generated/luci/project.cfg
@@ -7,7 +7,7 @@
 name: "chromium"
 access: "group:all"
 lucicfg {
-  version: "1.43.16"
+  version: "1.43.14"
   package_dir: "../.."
   config_dir: "generated/luci"
   entry_point: "main.star"
diff --git a/infra/config/generated/luci/realms.cfg b/infra/config/generated/luci/realms.cfg
index 7cc5f99..5521e00 100644
--- a/infra/config/generated/luci/realms.cfg
+++ b/infra/config/generated/luci/realms.cfg
@@ -123,7 +123,7 @@
   }
   bindings {
     role: "role/resultdb.invocationCreator"
-    principals: "user:chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com"
+    principals: "group:project-chromium-ci-task-accounts"
   }
   bindings {
     role: "role/scheduler.owner"
diff --git a/infra/config/subprojects/build/subproject.star b/infra/config/subprojects/build/subproject.star
index 04912b6..4fa7c420 100644
--- a/infra/config/subprojects/build/subproject.star
+++ b/infra/config/subprojects/build/subproject.star
@@ -7,7 +7,7 @@
         # Allow FYI builders to create invocations in their own builds.
         luci.binding(
             roles = "role/resultdb.invocationCreator",
-            users = "chromium-build-perf-ci-builder@chops-service-accounts.iam.gserviceaccount.com",
+            groups = "project-chromium-ci-task-accounts",
         ),
     ],
 )
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star
index 2b1b091..112cf5b 100644
--- a/infra/config/subprojects/chromium/ci/chromium.fyi.star
+++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -11,7 +11,6 @@
 load("//lib/consoles.star", "consoles")
 load("//lib/gn_args.star", "gn_args")
 load("//lib/html.star", "linkify", "linkify_builder")
-load("//lib/structs.star", "structs")
 load("//lib/targets.star", "targets")
 load("//lib/xcode.star", "xcode")
 
@@ -1864,49 +1863,6 @@
 )
 
 ci.builder(
-    name = "Linux Builder (reclient compare)",
-    builder_spec = builder_config.copy_from(
-        "ci/Linux Builder",
-        lambda spec: structs.evolve(
-            spec,
-            gclient_config = structs.extend(
-                spec.gclient_config,
-                apply_configs = ["reclient_test"],
-            ),
-            build_gs_bucket = None,
-        ),
-    ),
-    gn_args = gn_args.config(
-        configs = [
-            "gpu_tests",
-            "release_builder",
-            "remoteexec",
-            "linux",
-            "x64",
-        ],
-    ),
-    cores = 32,
-    os = os.LINUX_DEFAULT,
-    console_view_entry = consoles.console_view_entry(
-        category = "linux",
-        short_name = "re",
-    ),
-    execution_timeout = 14 * time.hour,
-    reclient_bootstrap_env = {
-        "RBE_clang_depscan_archive": "true",
-    },
-    reclient_ensure_verified = True,
-    reclient_rewrapper_env = {
-        "RBE_compare": "true",
-        "RBE_num_local_reruns": "1",
-        "RBE_num_remote_reruns": "1",
-    },
-    shadow_siso_project = None,
-    siso_project = siso.project.TEST_TRUSTED,
-    siso_remote_jobs = None,
-)
-
-ci.builder(
     name = "Win x64 Builder (reclient)",
     builder_spec = builder_config.builder_spec(
         gclient_config = builder_config.gclient_config(
@@ -1958,123 +1914,6 @@
     siso_remote_jobs = None,
 )
 
-ci.builder(
-    name = "Win x64 Builder (reclient compare)",
-    description_html = "Verifies whether local and remote build artifacts are identical.",
-    builder_spec = builder_config.builder_spec(
-        gclient_config = builder_config.gclient_config(
-            config = "chromium",
-            apply_configs = [
-                "use_clang_coverage",
-                "reclient_test",
-            ],
-        ),
-        chromium_config = builder_config.chromium_config(
-            config = "chromium",
-            apply_configs = ["mb"],
-            build_config = builder_config.build_config.RELEASE,
-            target_bits = 64,
-            target_platform = builder_config.target_platform.WIN,
-        ),
-    ),
-    gn_args = gn_args.config(
-        configs = [
-            "gpu_tests",
-            "release_builder",
-            "remoteexec",
-            "minimal_symbols",
-            "win",
-            "x64",
-        ],
-    ),
-    # Copied from
-    # https://source.chromium.org/chromium/chromium/src/+/7b147a6777cb32d6a12e1716c61a0ed50dc1229a:testing/buildbot/waterfalls.pyl;l=6023-6030
-    targets = targets.bundle(
-        targets = [
-            "chromium_win_scripts",
-        ],
-        additional_compile_targets = [
-            "pdf_fuzzers",
-        ],
-    ),
-    builderless = True,
-    cores = 16,
-    os = os.WINDOWS_DEFAULT,
-    ssd = True,
-    console_view_entry = consoles.console_view_entry(
-        category = "win",
-        short_name = "re",
-    ),
-    reclient_ensure_verified = True,
-    reclient_rewrapper_env = {
-        "RBE_compare": "true",
-        "RBE_num_local_reruns": "1",
-        "RBE_num_remote_reruns": "1",
-    },
-    shadow_siso_project = None,
-    siso_project = siso.project.TEST_TRUSTED,
-    siso_remote_jobs = None,
-)
-
-# TODO(crbug.com/40201781): remove this after the migration.
-fyi_mac_builder(
-    name = "Mac Builder (reclient compare)",
-    description_html = "Verifies whether local and remote build artifacts are identical.",
-    schedule = "0 */4 * * *",
-    builder_spec = builder_config.builder_spec(
-        gclient_config = builder_config.gclient_config(
-            config = "chromium",
-            apply_configs = [
-                "use_clang_coverage",
-                "reclient_test",
-            ],
-        ),
-        chromium_config = builder_config.chromium_config(
-            config = "chromium",
-            apply_configs = ["mb"],
-            build_config = builder_config.build_config.RELEASE,
-            target_bits = 64,
-            target_platform = builder_config.target_platform.MAC,
-        ),
-        build_gs_bucket = "chromium-fyi-archive",
-    ),
-    gn_args = gn_args.config(
-        configs = [
-            "gpu_tests",
-            "release_builder",
-            "remoteexec",
-            "minimal_symbols",
-            "x64",
-            "mac",
-        ],
-    ),
-    targets = targets.bundle(
-        targets = [
-            "chromium_mac_scripts",
-        ],
-        additional_compile_targets = [
-            "chrome",
-        ],
-    ),
-    builderless = True,
-    cores = None,  # crbug.com/1245114
-    cpu = cpu.ARM64,
-    console_view_entry = consoles.console_view_entry(
-        category = "mac",
-        short_name = "cmp",
-    ),
-    execution_timeout = 16 * time.hour,
-    reclient_ensure_verified = True,
-    reclient_rewrapper_env = {
-        "RBE_compare": "true",
-        "RBE_num_local_reruns": "1",
-        "RBE_num_remote_reruns": "1",
-    },
-    shadow_siso_project = None,
-    siso_project = siso.project.TEST_TRUSTED,
-    siso_remote_jobs = None,
-)
-
 fyi_ios_builder(
     name = "ios-m1-simulator",
     schedule = "0 1,5,9,13,17,21 * * *",
diff --git a/infra/config/subprojects/chromium/ci/chromium.gpu.star b/infra/config/subprojects/chromium/ci/chromium.gpu.star
index 17a04f6..1338331 100644
--- a/infra/config/subprojects/chromium/ci/chromium.gpu.star
+++ b/infra/config/subprojects/chromium/ci/chromium.gpu.star
@@ -376,7 +376,6 @@
         category = "Windows",
     ),
     cq_mirrors_console_view = "mirrors",
-    siso_remote_jobs = siso.remote_jobs.LOW_JOBS_FOR_CI,
 )
 
 ci.gpu.windows_builder(
@@ -410,7 +409,6 @@
     console_view_entry = consoles.console_view_entry(
         category = "Windows",
     ),
-    siso_remote_jobs = siso.remote_jobs.LOW_JOBS_FOR_CI,
 )
 
 ci.thin_tester(
diff --git a/infra/config/targets/bundles.star b/infra/config/targets/bundles.star
index 8a0b81e0..aa475286 100644
--- a/infra/config/targets/bundles.star
+++ b/infra/config/targets/bundles.star
@@ -221,7 +221,7 @@
                 "WEBVIEW_TRICHROME_INSTANT_CTS_TESTS",
             ],
         ),
-        "webview_trichrome_64_cts_tests_no_field_trial_suite",
+        "android_ci_only_fieldtrial_webview_tests",
     ],
 )
 
diff --git a/internal b/internal
index 6f4b9ae..64fabe2c 160000
--- a/internal
+++ b/internal
@@ -1 +1 @@
-Subproject commit 6f4b9ae57761436c222a02facc36f260e7b08ed8
+Subproject commit 64fabe2c75866b08875218107a8dc334ad0c3ecf
diff --git a/ios/third_party/earl_grey2/src b/ios/third_party/earl_grey2/src
index 56144f8..598d8e8 160000
--- a/ios/third_party/earl_grey2/src
+++ b/ios/third_party/earl_grey2/src
@@ -1 +1 @@
-Subproject commit 56144f8685227fc7f7af1ea2152d816d372d1d0a
+Subproject commit 598d8e856bc259d9632cd26e944d46d721c43071
diff --git a/ios_internal b/ios_internal
index 3f2de6e..d844ad6 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit 3f2de6eed730e6f96f37636ea84815c933f28496
+Subproject commit d844ad608bd4f17d8d82a66fd63bc1e83939e366
diff --git a/media/base/audio_buffer.cc b/media/base/audio_buffer.cc
index f94db90..e804a11 100644
--- a/media/base/audio_buffer.cc
+++ b/media/base/audio_buffer.cc
@@ -31,25 +31,6 @@
 
 namespace {
 
-// TODO(crbug.com/41258600): Use vector instructions to speed this up.
-template <class SourceSampleTypeTraits>
-void CopyConvertFromInterleaved(
-    const typename SourceSampleTypeTraits::ValueType* source_buffer,
-    int num_frames_to_write,
-    const std::vector<float*> dest) {
-  const int channels = dest.size();
-  for (int ch = 0; ch < channels; ++ch) {
-    float* dest_data = dest[ch];
-    for (int target_frame_index = 0, read_pos_in_source = ch;
-         target_frame_index < num_frames_to_write;
-         ++target_frame_index, read_pos_in_source += channels) {
-      auto source_value = source_buffer[read_pos_in_source];
-      dest_data[target_frame_index] =
-          SourceSampleTypeTraits::ToFloat(source_value);
-    }
-  }
-}
-
 class SelfOwnedMemory : public AudioBuffer::ExternalMemory {
  public:
   explicit SelfOwnedMemory(size_t size)
diff --git a/media/base/audio_limiter.cc b/media/base/audio_limiter.cc
index 0f188e54..7956eb4 100644
--- a/media/base/audio_limiter.cc
+++ b/media/base/audio_limiter.cc
@@ -215,31 +215,27 @@
   CHECK(!output_channels.empty());
   CHECK(!output_channels[0].empty());
 
+  const auto copy_float_to_channel = [](float src, base::span<uint8_t>& ch) {
+    auto [dest, remainder] = ch.split_at<sizeof(float)>();
+    dest.copy_from(base::byte_span_from_ref(src));
+    ch = remainder;
+  };
+
   if (smoothed_gain_ < 1.0) {
     // Apply gain reduction.
     for (int ch = 0; ch < channels_; ++ch) {
-      auto [dest, remainder] = output_channels[ch].split_at<4>();
-
       const float adjusted_sample = static_cast<float>(
           static_cast<double>(delayed_interleaved_input_.front()) *
           smoothed_gain_);
+      copy_float_to_channel(adjusted_sample, output_channels[ch]);
       delayed_interleaved_input_.pop_front();
-
-      dest.copy_from(base::byte_span_from_ref(adjusted_sample));
-
-      output_channels[ch] = remainder;
     }
   } else {
     // Passthrough.
     for (int ch = 0; ch < channels_; ++ch) {
-      auto [dest, remainder] = output_channels[ch].split_at<4>();
-
-      dest.copy_from(
-          base::byte_span_from_ref(delayed_interleaved_input_.front()));
-
+      copy_float_to_channel(delayed_interleaved_input_.front(),
+                            output_channels[ch]);
       delayed_interleaved_input_.pop_front();
-
-      output_channels[ch] = remainder;
     }
   }
 
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 c541964..356ba35 100644
--- a/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
+++ b/media/gpu/windows/media_foundation_video_encode_accelerator_win.cc
@@ -680,56 +680,63 @@
 
 std::vector<FramerateAndResolution> GetMaxFramerateAndResolutionsFromMFT(
     VideoCodec codec,
-    IMFTransform* encoder) {
-  ComPtr<IMFMediaType> media_type;
+    IMFTransform* encoder,
+    bool allow_set_output_type) {
   std::vector<FramerateAndResolution> framerate_and_resolutions;
-  RETURN_ON_HR_FAILURE(MFCreateMediaType(&media_type),
-                       "Create media type failed", framerate_and_resolutions);
-  RETURN_ON_HR_FAILURE(media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
-                       "Set major type failed", framerate_and_resolutions);
-  RETURN_ON_HR_FAILURE(
-      media_type->SetGUID(MF_MT_SUBTYPE, VideoCodecToMFSubtype(codec)),
-      "Set guid for sub type failed", framerate_and_resolutions);
-  RETURN_ON_HR_FAILURE(
-      MFSetAttributeSize(media_type.Get(), MF_MT_FRAME_SIZE,
-                         kDefaultMaxFramerateAndResolution.resoluion.width(),
-                         kDefaultMaxFramerateAndResolution.resoluion.height()),
-      "Set attribute size failed", framerate_and_resolutions);
-  // Frame rate,30, is dummy value for pass through.
-  RETURN_ON_HR_FAILURE(
-      MFSetAttributeRatio(
-          media_type.Get(), MF_MT_FRAME_RATE,
-          /*unNumerator=*/kDefaultMaxFramerateAndResolution.frame_rate,
-          /*unDenominator=*/1),
-      "Set attribute ratio failed", framerate_and_resolutions);
-  RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_AVG_BITRATE, 9000000),
-                       "Set avg bitrate failed", framerate_and_resolutions);
-  RETURN_ON_HR_FAILURE(
-      media_type->SetUINT32(MF_MT_INTERLACE_MODE, MFVideoInterlace_Progressive),
-      "Set interlace mode failed", framerate_and_resolutions);
+  if (allow_set_output_type) {
+    ComPtr<IMFMediaType> media_type;
 
-  if (codec != VideoCodec::kVP9) {
-    UINT32 max_level;
-    switch (codec) {
-      case VideoCodec::kH264:
-        max_level = eAVEncH264VLevel5_2;
-        break;
-      case VideoCodec::kAV1:
-        max_level = eAVEncAV1VLevel6_3;
-        break;
-      case VideoCodec::kHEVC:
-        max_level = eAVEncH265VLevel6_2;
-        break;
-      default:
-        NOTREACHED();
+    RETURN_ON_HR_FAILURE(MFCreateMediaType(&media_type),
+                         "Create media type failed", framerate_and_resolutions);
+    RETURN_ON_HR_FAILURE(
+        media_type->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
+        "Set major type failed", framerate_and_resolutions);
+    RETURN_ON_HR_FAILURE(
+        media_type->SetGUID(MF_MT_SUBTYPE, VideoCodecToMFSubtype(codec)),
+        "Set guid for sub type failed", framerate_and_resolutions);
+    RETURN_ON_HR_FAILURE(
+        MFSetAttributeSize(
+            media_type.Get(), MF_MT_FRAME_SIZE,
+            kDefaultMaxFramerateAndResolution.resoluion.width(),
+            kDefaultMaxFramerateAndResolution.resoluion.height()),
+        "Set attribute size failed", framerate_and_resolutions);
+    // Frame rate,30, is dummy value for pass through.
+    RETURN_ON_HR_FAILURE(
+        MFSetAttributeRatio(
+            media_type.Get(), MF_MT_FRAME_RATE,
+            /*unNumerator=*/kDefaultMaxFramerateAndResolution.frame_rate,
+            /*unDenominator=*/1),
+        "Set attribute ratio failed", framerate_and_resolutions);
+    RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_AVG_BITRATE, 9000000),
+                         "Set avg bitrate failed", framerate_and_resolutions);
+    RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_INTERLACE_MODE,
+                                               MFVideoInterlace_Progressive),
+                         "Set interlace mode failed",
+                         framerate_and_resolutions);
+
+    if (codec != VideoCodec::kVP9) {
+      UINT32 max_level;
+      switch (codec) {
+        case VideoCodec::kH264:
+          max_level = eAVEncH264VLevel5_2;
+          break;
+        case VideoCodec::kAV1:
+          max_level = eAVEncAV1VLevel6_3;
+          break;
+        case VideoCodec::kHEVC:
+          max_level = eAVEncH265VLevel6_2;
+          break;
+        default:
+          NOTREACHED();
+      }
+      RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_VIDEO_LEVEL, max_level),
+                           "Set video level failed", framerate_and_resolutions);
     }
-    RETURN_ON_HR_FAILURE(media_type->SetUINT32(MF_MT_VIDEO_LEVEL, max_level),
-                         "Set video level failed", framerate_and_resolutions);
-  }
 
-  RETURN_ON_HR_FAILURE(
-      encoder->SetOutputType(/*stream_id=*/0, media_type.Get(), 0),
-      "Set output type failed", framerate_and_resolutions);
+    RETURN_ON_HR_FAILURE(
+        encoder->SetOutputType(/*stream_id=*/0, media_type.Get(), 0),
+        "Set output type failed", framerate_and_resolutions);
+  }
 
   ComPtr<IMFAttributes> attributes;
   RETURN_ON_HR_FAILURE(encoder->GetAttributes(&attributes),
@@ -1107,8 +1114,8 @@
       }
 
       CHECK(encoder);
-      max_framerate_and_resolutions =
-          GetMaxFramerateAndResolutionsFromMFT(codec, encoder.Get());
+      max_framerate_and_resolutions = GetMaxFramerateAndResolutionsFromMFT(
+          codec, encoder.Get(), /*allow_set_output_type=*/true);
       min_resolution = GetMinResolution(codec, GetDriverVendor(activate));
       activate->ShutdownObject();
     }
@@ -1307,6 +1314,39 @@
     return false;
   }
 
+  // Get the max framerate and max/min resolutions of the given codec.
+  //
+  // NOTE:
+  // We use the actual encoder to retrieve max framerate and max/min
+  // resolutions. The property `MF_VIDEO_MAX_MB_PER_SEC`, which we use to
+  // calculate the resolution, is a static value stored in the encoder provided
+  // by the GPU driver. It doesn't change regardless of the parameters we set
+  // for `SetOutputType()` except for `MF_MT_MAJOR_TYPE` and `MF_MT_SUBTYPE`.
+  // So, as long as the actual encoder remains the same, the result should be
+  // unchanged.
+  //
+  // On a dual GPU system, the actual encoder selected might be different from
+  // the one used by "GetSupportedProfile". If that's the case, and if the
+  // actual encoder can't handle the incoming resolution, we can simply reject
+  // it without hesitation.
+  if (base::FeatureList::IsEnabled(kExpandMediaFoundationEncodingResolutions)) {
+    max_framerate_and_resolutions_ = GetMaxFramerateAndResolutionsFromMFT(
+        codec_, encoder_.Get(), /*allow_set_output_type=*/false);
+    min_resolution_ = GetMinResolution(codec_, vendor_);
+  } else {
+    max_framerate_and_resolutions_ = {kDefaultMaxFramerateAndResolution};
+    min_resolution_ = kDefaultMinResolution;
+  }
+  // Ideally, we should check size before `InitializeInputOutputParameters()`
+  // because it sets `MF_MT_FRAME_SIZE` when `SetOutputType()` is called.
+  // However, since we can only retrieve `MF_VIDEO_MAX_MB_PER_SEC` after calling
+  // `SetOutputType()`, we have to check the frame size at this point.
+  if (!IsFrameSizeAllowed(config.input_visible_size)) {
+    NotifyErrorStatus({EncoderStatus::Codes::kEncoderUnsupportedConfig,
+                       "Unsupported frame size"});
+    return false;
+  }
+
   encoder_info_.implementation_name = "MediaFoundationVideoEncodeAccelerator";
   // Currently, MFVEA does not support odd resolution well. The implementation
   // here reports alignment of 2 in the EncoderInfo, together with simulcast
@@ -1766,18 +1806,17 @@
 }
 
 bool MediaFoundationVideoEncodeAccelerator::IsFrameSizeAllowed(gfx::Size size) {
-  if (max_framerate_and_resolutions_.empty() || min_resolution_.IsEmpty()) {
-    DCHECK(encoder_);
-    max_framerate_and_resolutions_ =
-        GetMaxFramerateAndResolutionsFromMFT(codec_, encoder_.Get());
-    min_resolution_ = GetMinResolution(codec_, vendor_);
-  }
+  // It's possible `max_framerate_and_resolutions_` is empty when we
+  // failed to retrieve `MF_VIDEO_MAX_MB_PER_SEC`.
+  DCHECK(!min_resolution_.IsEmpty());
 
   for (auto& [frame_rate, resolution] : max_framerate_and_resolutions_) {
+    // TODO(crbug.com/365813271): Add framerate check once we can make sure
+    // WebRTC check framerate before calling `RequestEncodingParametersChange`.
     if (size.width() >= min_resolution_.width() &&
         size.height() >= min_resolution_.height() &&
         size.width() <= resolution.width() &&
-        size.height() <= resolution.height() && frame_rate_ <= frame_rate) {
+        size.height() <= resolution.height()) {
       return true;
     }
 
@@ -1786,7 +1825,7 @@
     if (size.height() >= min_resolution_.width() &&
         size.width() >= min_resolution_.height() &&
         size.width() <= resolution.width() &&
-        size.height() <= resolution.height() && frame_rate_ <= frame_rate) {
+        size.height() <= resolution.height()) {
       return true;
     }
 
diff --git a/services/webnn/webnn_graph_builder_impl.cc b/services/webnn/webnn_graph_builder_impl.cc
index 88e6d61..4d4c4ff 100644
--- a/services/webnn/webnn_graph_builder_impl.cc
+++ b/services/webnn/webnn_graph_builder_impl.cc
@@ -2961,11 +2961,19 @@
   std::tie(processed_operands, operands_to_dependent_operations) =
       *std::move(result);
 
-  // Now that all the operations have been processed we can check that the
-  // output operands are connected to the graph.
-  for (const uint64_t output : graph_outputs) {
-    if (!processed_operands.contains(output)) {
-      return std::nullopt;
+  // Now that all the operations have been processed we can check that all the
+  // operands are connected to the graph inputs and outputs.
+  for (auto& [id, operand] : graph_info.id_to_operand_map) {
+    if (operand->kind == mojom::Operand::Kind::kOutput && operand->name) {
+      // Graph outputs must be the output of some operator.
+      if (!processed_operands.contains(id)) {
+        return std::nullopt;
+      }
+    } else {
+      // All other operands must be the input to some operator.
+      if (!operands_to_dependent_operations.contains(id)) {
+        return std::nullopt;
+      }
     }
   }
 
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 5c364d4..20d8a10f 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -2560,47 +2560,6 @@
             ]
         }
     ],
-    "AutofillUploadCardRequestTimeout": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "ios",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled_6point5seconds",
-                    "params": {
-                        "autofill_upload_card_request_timeout_milliseconds": "6500"
-                    },
-                    "enable_features": [
-                        "AutofillUploadCardRequestTimeout"
-                    ]
-                },
-                {
-                    "name": "Enabled_7seconds",
-                    "params": {
-                        "autofill_upload_card_request_timeout_milliseconds": "7000"
-                    },
-                    "enable_features": [
-                        "AutofillUploadCardRequestTimeout"
-                    ]
-                },
-                {
-                    "name": "Enabled_9seconds",
-                    "params": {
-                        "autofill_upload_card_request_timeout_milliseconds": "9000"
-                    },
-                    "enable_features": [
-                        "AutofillUploadCardRequestTimeout"
-                    ]
-                }
-            ]
-        }
-    ],
     "AutofillUpstream": [
         {
             "platforms": [
@@ -2622,47 +2581,6 @@
             ]
         }
     ],
-    "AutofillVcnEnrollRequestTimeout": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "ios",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled_5seconds",
-                    "params": {
-                        "autofill_vcn_enroll_request_timeout_milliseconds": "5000"
-                    },
-                    "enable_features": [
-                        "AutofillVcnEnrollRequestTimeout"
-                    ]
-                },
-                {
-                    "name": "Enabled_7point5seconds",
-                    "params": {
-                        "autofill_vcn_enroll_request_timeout_milliseconds": "7500"
-                    },
-                    "enable_features": [
-                        "AutofillVcnEnrollRequestTimeout"
-                    ]
-                },
-                {
-                    "name": "Enabled_10seconds",
-                    "params": {
-                        "autofill_vcn_enroll_request_timeout_milliseconds": "10000"
-                    },
-                    "enable_features": [
-                        "AutofillVcnEnrollRequestTimeout"
-                    ]
-                }
-            ]
-        }
-    ],
     "AutofillVirtualViewStructureAndroid": [
         {
             "platforms": [
diff --git a/third_party/README.chromium.template b/third_party/README.chromium.template
index 5b624ce..5dc8a7f 100644
--- a/third_party/README.chromium.template
+++ b/third_party/README.chromium.template
@@ -4,7 +4,7 @@
 Version: A searchable version number for the package (if the package does not version or is versioned by date or revision this field should be "N/A" and the revision, or date should be enumerated in the appropriate field).
 Date: (OPTIONAL if Version or Revision is supplied) The date that the package was updated, in format YYYY-MM-DD.
 Revision: (REQUIRED for dependencies which have a git repository as an upstream, OPTIONAL if the upstream is not a git repository and Version or Date is supplied)
-License: The license under which the package is distributed. Standard forms are only accepted, eg MIT/X11/BSD/Apache 2.0/GPL/LGPL. See ANDROID_ALLOWED_LICENSES in PRESUBMIT.py for allowed patterns.
+License: The license/s under which the package is distributed. See ALLOWED_SPDX_LICENSES in depot_tools for the full list of allowed licenses https://source.chromium.org/chromium/chromium/tools/depot_tools/+/main:metadata/fields/custom/license_allowlist.py. If your dependency has multiple licenses, see https://chromium.googlesource.com/chromium/src/+/main/docs/adding_to_third_party.md#add-a-license-file-and-run-related-checks for guidance on how supply multiple entries or choose the best fit.
 License File: A file path from //third_party or a relative path from the README.chromium to a child directory, whichever makes more sense for your dependency. The file should contain a copy of the package's license and correspond to the License provided above. All packages should contain a valid license, regardless of whether it is shipped or not.
 Shipped: Either yes or no depending on whether this package should be included in about:credits. Anything shipped as part of a release or by component-updater should be credited.
 Security Critical: Either yes or no. Information on what classifies a package as security critical can be found at https://chromium.googlesource.com/chromium/src/+/HEAD/docs/adding_to_third_party.md#add-a-readme_chromium
diff --git a/third_party/angle b/third_party/angle
index ccf65c8..963be02f 160000
--- a/third_party/angle
+++ b/third_party/angle
@@ -1 +1 @@
-Subproject commit ccf65c8be1900e218b8df6aba22268449525d836
+Subproject commit 963be02fe0408707d8e2fcc30e294e1f361a0611
diff --git a/third_party/blink/common/frame/frame_policy.cc b/third_party/blink/common/frame/frame_policy.cc
index 1c2b94fd..784ace6 100644
--- a/third_party/blink/common/frame/frame_policy.cc
+++ b/third_party/blink/common/frame/frame_policy.cc
@@ -10,25 +10,24 @@
 FramePolicy::FramePolicy()
     : sandbox_flags(network::mojom::WebSandboxFlags::kNone),
       container_policy({}),
-      required_document_policy({}) {}
+      required_document_policy({}),
+      deferred_fetch_policy(DeferredFetchPolicy::kDisabled) {}
 
 FramePolicy::FramePolicy(
     network::mojom::WebSandboxFlags sandbox_flags,
     const ParsedPermissionsPolicy& container_policy,
-    const DocumentPolicyFeatureState& required_document_policy)
+    const DocumentPolicyFeatureState& required_document_policy,
+    DeferredFetchPolicy deferred_fetch_policy)
     : sandbox_flags(sandbox_flags),
       container_policy(container_policy),
-      required_document_policy(required_document_policy) {}
+      required_document_policy(required_document_policy),
+      deferred_fetch_policy(deferred_fetch_policy) {}
 
 FramePolicy::FramePolicy(const FramePolicy& lhs) = default;
 
 FramePolicy::~FramePolicy() = default;
 
-bool operator==(const FramePolicy& lhs, const FramePolicy& rhs) {
-  return (lhs.sandbox_flags == rhs.sandbox_flags) &&
-         (lhs.container_policy == rhs.container_policy) &&
-         (lhs.required_document_policy == rhs.required_document_policy);
-}
+bool operator==(const FramePolicy& lhs, const FramePolicy& rhs) = default;
 
 bool operator!=(const FramePolicy& lhs, const FramePolicy& rhs) {
   return !(lhs == rhs);
diff --git a/third_party/blink/public/common/frame/frame_policy.h b/third_party/blink/public/common/frame/frame_policy.h
index a041890..bb73333 100644
--- a/third_party/blink/public/common/frame/frame_policy.h
+++ b/third_party/blink/public/common/frame/frame_policy.h
@@ -25,13 +25,32 @@
 // and the pending policy, which will take effect when the frame is next
 // navigated.
 struct BLINK_COMMON_EXPORT FramePolicy {
+  // `DeferredFetchPolicy` tells how the deferred fetching feature is
+  // enabled for the subframe of an owner frame. On navigation, a value should
+  // be calculated by using the combination of the frame's inherited permissions
+  // policies of "deferred-fetch" and "deferred-fetch-minimal".
+  //
+  // See https://whatpr.org/fetch/1647.html#deferred-fetch-policy for policy
+  // definition and
+  // https://whatpr.org/fetch/1647.html#determine-subframe-deferred-fetch-policy
+  // for how to choose a value.
+  enum class DeferredFetchPolicy {
+    kDisabled,
+    kDeferredFetch,
+    kDeferredFetchMinimal,
+  };
+
   FramePolicy();
   FramePolicy(network::mojom::WebSandboxFlags sandbox_flags,
               const ParsedPermissionsPolicy& container_policy,
-              const DocumentPolicyFeatureState& required_document_policy);
+              const DocumentPolicyFeatureState& required_document_policy,
+              DeferredFetchPolicy deferred_fetch_policy);
   FramePolicy(const FramePolicy& lhs);
   ~FramePolicy();
 
+  friend bool BLINK_COMMON_EXPORT operator==(const FramePolicy& lhs,
+                                             const FramePolicy& rhs);
+
   network::mojom::WebSandboxFlags sandbox_flags;
   ParsedPermissionsPolicy container_policy;
   // |required_document_policy| is the combination of the following:
@@ -39,10 +58,10 @@
   // - 'Require-Document-Policy' http header
   // - |required_document_policy| of parent frame
   DocumentPolicyFeatureState required_document_policy;
+  // Derived from `container_policy` of the frame and the ancestor frames.
+  DeferredFetchPolicy deferred_fetch_policy;
 };
 
-bool BLINK_COMMON_EXPORT operator==(const FramePolicy& lhs,
-                                    const FramePolicy& rhs);
 bool BLINK_COMMON_EXPORT operator!=(const FramePolicy& lhs,
                                     const FramePolicy& rhs);
 
diff --git a/third_party/blink/renderer/core/animation/css_interpolation_types_map.h b/third_party/blink/renderer/core/animation/css_interpolation_types_map.h
index 47c137f..2689024 100644
--- a/third_party/blink/renderer/core/animation/css_interpolation_types_map.h
+++ b/third_party/blink/renderer/core/animation/css_interpolation_types_map.h
@@ -31,7 +31,6 @@
  private:
   const Document& document_;
   const PropertyRegistry* registry_;
-  bool allow_all_animations_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_variable_data.cc b/third_party/blink/renderer/core/css/css_variable_data.cc
index 7a232c90..cdc47f5 100644
--- a/third_party/blink/renderer/core/css/css_variable_data.cc
+++ b/third_party/blink/renderer/core/css/css_variable_data.cc
@@ -153,8 +153,7 @@
       is_8bit_(original_text.Is8Bit()),
       has_font_units_(has_font_units),
       has_root_font_units_(has_root_font_units),
-      has_line_height_units_(has_line_height_units),
-      unused_(0) {
+      has_line_height_units_(has_line_height_units) {
   if (is_8bit_) {
     base::ranges::copy(original_text.Span8(),
                        reinterpret_cast<LChar*>(this + 1));
diff --git a/third_party/blink/renderer/core/css/css_variable_data.h b/third_party/blink/renderer/core/css/css_variable_data.h
index 57ef57b..5408453 100644
--- a/third_party/blink/renderer/core/css/css_variable_data.h
+++ b/third_party/blink/renderer/core/css/css_variable_data.h
@@ -32,8 +32,7 @@
         is_8bit_(true),
         has_font_units_(false),
         has_root_font_units_(false),
-        has_line_height_units_(false),
-        unused_(0) {}
+        has_line_height_units_(false) {}
 
   using PassKey = base::PassKey<CSSVariableData>;
   CSSVariableData(PassKey,
@@ -151,7 +150,7 @@
   unsigned has_font_units_ : 1;                   // bool.
   unsigned has_root_font_units_ : 1;              // bool.
   unsigned has_line_height_units_ : 1;            // bool.
-  const unsigned unused_ : 3;
+  unsigned /* unused_ */ : 3;
 
   // The actual character data is stored after this.
 };
diff --git a/third_party/blink/renderer/core/fetch/build.gni b/third_party/blink/renderer/core/fetch/build.gni
index 74ef049..2f08cb4 100644
--- a/third_party/blink/renderer/core/fetch/build.gni
+++ b/third_party/blink/renderer/core/fetch/build.gni
@@ -19,10 +19,10 @@
   "fetch_data_loader.h",
   "fetch_header_list.cc",
   "fetch_header_list.h",
-  "fetch_later_result.cc",
-  "fetch_later_result.h",
   "fetch_later_util.cc",
   "fetch_later_util.h",
+  "fetch_later_result.cc",
+  "fetch_later_result.h",
   "fetch_manager.cc",
   "fetch_manager.h",
   "fetch_request_data.cc",
diff --git a/third_party/blink/renderer/core/fetch/fetch_later_util.cc b/third_party/blink/renderer/core/fetch/fetch_later_util.cc
index 68b9277d..621e25d7 100644
--- a/third_party/blink/renderer/core/fetch/fetch_later_util.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_later_util.cc
@@ -4,9 +4,69 @@
 
 #include "third_party/blink/renderer/core/fetch/fetch_later_util.h"
 
+#include "base/check.h"
+#include "third_party/blink/public/common/features.h"
+#include "third_party/blink/public/common/frame/frame_policy.h"
+#include "third_party/blink/public/mojom/permissions_policy/permissions_policy.mojom-blink.h"
+#include "third_party/blink/renderer/core/execution_context/security_context.h"
+#include "third_party/blink/renderer/core/fetch/fetch_header_list.h"
+#include "third_party/blink/renderer/core/fetch/fetch_request_data.h"
+#include "third_party/blink/renderer/core/frame/frame.h"
+#include "third_party/blink/renderer/core/frame/frame_owner.h"
+#include "third_party/blink/renderer/core/frame/local_dom_window.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/frame/local_frame_client.h"
+#include "third_party/blink/renderer/core/frame/location.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_request_utils.h"
+#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
 
 namespace blink {
+namespace {
+
+// Calculates "framesWithMinimalQuotaPolicy" by running Step 7 of
+// https://whatpr.org/fetch/1647.html#determine-subframe-deferred-fetch-policy
+//
+// `container_frame` is an iframe to decide deferred fetch policy for.
+// `top_level_relatives` is from executing the following for the parent of
+// `container_frame`:
+// https://whatpr.org/fetch/1647.html#available-deferred-fetching-quota
+uint32_t CountFramesWithMinimalQuotaPolicy(
+    FrameOwner* container_frame,
+    const HeapHashSet<Member<Frame>>& top_level_relatives) {
+  CHECK(container_frame);
+  uint32_t count = 0;
+
+  for (const auto& relative : top_level_relatives) {
+    //  7-2. topLevelRelatives contains navigable’s parent.
+    for (Frame* navigable = relative->FirstChild(); navigable;
+         navigable = navigable->NextSibling()) {
+      //  7-1. navigable is not container’s content navigable.
+      if (navigable == container_frame->ContentFrame()) {
+        continue;
+      }
+      // 7-3. topLevelRelatives does not contain navigable.
+      if (top_level_relatives.find(navigable) != top_level_relatives.end()) {
+        continue;
+      }
+      // 7-4. navigable’s navigable container’s deferred fetch policy is
+      // "deferred-fetch-minimal".
+      auto* navigable_container = navigable->Owner();
+      if (navigable_container &&
+          navigable_container->GetFramePolicy().deferred_fetch_policy ==
+              FramePolicy::DeferredFetchPolicy::kDeferredFetchMinimal) {
+        count++;
+      }
+    }
+  }
+  return count;
+}
+
+}  // namespace
+
+bool IsFetchLaterUseDeferredFetchPolicyEnabled() {
+  return base::GetFieldTrialParamByFeatureAsBool(
+      features::kFetchLaterAPI, "use_deferred_fetch_policy", false);
+}
 
 ResourceLoadPriority ComputeFetchLaterLoadPriority(
     const FetchParameters& params) {
@@ -21,4 +81,95 @@
   // IsSubframeDeprioritizationEnabled.
 }
 
+HeapHashSet<Member<Frame>> GetDeferredFetchQuotaSharingFrames(Frame* frame) {
+  HeapHashSet<Member<Frame>> result;
+  if (!frame) {
+    return result;
+  }
+
+  auto* top_frame = frame->Top();
+  for (auto* current_frame = top_frame; current_frame;
+       current_frame = current_frame->Tree().TraverseNext(top_frame)) {
+    if (!current_frame->IsLocalFrame()) {
+      // Skips non-local frames.
+      continue;
+    }
+    if (!frame->GetSecurityContext()->GetSecurityOrigin()->CanAccess(
+            current_frame->GetSecurityContext()->GetSecurityOrigin())) {
+      // Skips cross-origin frames.
+      continue;
+    }
+    result.insert(current_frame);
+  }
+
+  return result;
+}
+
+FramePolicy::DeferredFetchPolicy GetContainerDeferredFetchPolicyOnNavigation(
+    FrameOwner* container_frame) {
+  CHECK(container_frame);
+  // Must be called when "inherited policy" is available for container document.
+  CHECK(container_frame->ContentFrame());
+  CHECK(container_frame->ContentFrame()->IsLocalFrame());
+  // Called after committing navigation, so the frame must be local.
+  KURL to_url =
+      To<LocalFrame>(container_frame->ContentFrame())->GetDocument()->Url();
+  auto to_url_origin = SecurityOrigin::Create(to_url)->ToUrlOrigin();
+  auto* permissions_policy = container_frame->ContentFrame()
+                                 ->GetSecurityContext()
+                                 ->GetPermissionsPolicy();
+  // 1. Set container’s deferred fetch policy to disabled.
+
+  // 2. If the inherited policy for "deferred-fetch", container and
+  // originToNavigateTo is Enabled,
+  // TODO(crbug.com/40276121): and the available deferred fetching quota for
+  // container’s container document is equal or greater than 64 kibibytes,
+  if (permissions_policy->IsFeatureEnabledForOrigin(
+          mojom::blink::PermissionsPolicyFeature::kDeferredFetch,
+          to_url_origin)) {
+    // then set container’s deferred fetch policy to "deferred-fetch" and
+    // return.
+    return FramePolicy::DeferredFetchPolicy::kDeferredFetch;
+  }
+  // 3. If the inherited policy for "deferred-fetch-minimal", container and
+  // originToNavigateTo is Disabled, then set container’s deferred fetch policy
+  // to disabled and return.
+  if (!permissions_policy->IsFeatureEnabledForOrigin(
+          mojom::blink::PermissionsPolicyFeature::kDeferredFetchMinimal,
+          to_url_origin)) {
+    return FramePolicy::DeferredFetchPolicy::kDisabled;
+  }
+
+  // 4. Let topLevelRelatives be container’s container document’s deferred
+  // fetch quota-sharing navigables.
+  auto top_level_relatives = GetDeferredFetchQuotaSharingFrames(
+      container_frame->ContentFrame()->Parent());
+  // 5. If topLevelRelatives does not contain container’s node navigable’s
+  // top-level traversable, then set container’s deferred fetch policy to
+  // disabled and return.
+  if (top_level_relatives.find(container_frame->ContentFrame()->Top()) ==
+      top_level_relatives.end()) {
+    return FramePolicy::DeferredFetchPolicy::kDisabled;
+  }
+
+  // 7. For each navigable that matches the following conditions:
+  uint32_t frames_with_minimal_quota_policy =
+      CountFramesWithMinimalQuotaPolicy(container_frame, top_level_relatives);
+
+  // 8. If framesWithMinimalQuotaPolicy is less than 16, then set container’s
+  // deferred fetch policy to "deferred-fetch-minimal".
+  if (frames_with_minimal_quota_policy < 16) {
+    return FramePolicy::DeferredFetchPolicy::kDeferredFetchMinimal;
+  }
+
+  return FramePolicy::DeferredFetchPolicy::kDisabled;
+}
+
+uint32_t CountFramesWithMinimalQuotaPolicyForTesting(
+    FrameOwner* container_frame,
+    const HeapHashSet<Member<Frame>>& top_level_relatives) {
+  return CountFramesWithMinimalQuotaPolicy(container_frame,
+                                           top_level_relatives);
+}
+
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/fetch_later_util.h b/third_party/blink/renderer/core/fetch/fetch_later_util.h
index e232335..0a3deadd 100644
--- a/third_party/blink/renderer/core/fetch/fetch_later_util.h
+++ b/third_party/blink/renderer/core/fetch/fetch_later_util.h
@@ -5,20 +5,60 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_FETCH_LATER_UTIL_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_FETCH_LATER_UTIL_H_
 
+#include <stdint.h>
+
+#include "third_party/blink/public/common/frame/frame_policy.h"
 #include "third_party/blink/renderer/core/core_export.h"
+#include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h"
+#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
 #include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource.h"
 #include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h"
+#include "third_party/blink/renderer/platform/weborigin/kurl.h"
 
 namespace blink {
+class Frame;
+class FrameOwner;
 
 // The ResourceType of FetchLater requests.
 inline constexpr ResourceType kFetchLaterResourceType = ResourceType::kRaw;
 
+// 64 kibibytes.
+inline constexpr uint32_t kInitialSubframeDeferredFetchBytes = 64 * 1024;
+
+// 8 kibibytes.
+inline constexpr uint32_t kInitialSubframeDeferredFetchMinimalBytes = 8 * 1024;
+
+// Tells whether the FetchLater API should use subframe deferred fetch
+// policy to decide whether a frame show allow using the API.
+bool CORE_EXPORT IsFetchLaterUseDeferredFetchPolicyEnabled();
+
 // Computes resource loader priority for a FetchLater request.
 ResourceLoadPriority CORE_EXPORT
 ComputeFetchLaterLoadPriority(const FetchParameters& params);
 
+// Returns all frames that shares the same deferred fetch quota with `frame`,
+// i.e. all same-origin same-process frames of `frame`.
+// Note that the result includes the `frame` itself if not null.
+// https://whatpr.org/fetch/1647.html#deferred-fetch-quota-sharing-navigables
+HeapHashSet<Member<Frame>> CORE_EXPORT
+GetDeferredFetchQuotaSharingFrames(Frame* frame);
+
+// Determines the deferred fetch policy of a navigable container
+// `container_frame`, e.g. iframe, when it navigates its content to a target
+// URL, by the following algorithm:
+// https://whatpr.org/fetch/1647.html#determine-subframe-deferred-fetch-policy
+// This must be called after "inherited policy" for `container_frame` is
+// available, i.e. after `PermissionsPolicy::CreateFromParentPolicy()` is
+// already executed.
+FramePolicy::DeferredFetchPolicy CORE_EXPORT
+GetContainerDeferredFetchPolicyOnNavigation(FrameOwner* container_frame);
+
+// For testing only:
+uint32_t CORE_EXPORT CountFramesWithMinimalQuotaPolicyForTesting(
+    FrameOwner* container_frame,
+    const HeapHashSet<Member<Frame>>& top_level_relatives);
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_FETCH_LATER_UTIL_H_
diff --git a/third_party/blink/renderer/core/fetch/fetch_later_util_test.cc b/third_party/blink/renderer/core/fetch/fetch_later_util_test.cc
index 2b65e02..ede560ed 100644
--- a/third_party/blink/renderer/core/fetch/fetch_later_util_test.cc
+++ b/third_party/blink/renderer/core/fetch/fetch_later_util_test.cc
@@ -4,14 +4,30 @@
 
 #include "third_party/blink/renderer/core/fetch/fetch_later_util.h"
 
+#include <string>
+#include <utility>
+
+#include "base/strings/strcat.h"
+#include "base/strings/stringprintf.h"
+#include "base/test/scoped_feature_list.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/mojom/fetch/fetch_api_request.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
+#include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
+#include "third_party/blink/renderer/core/frame/frame.h"
+#include "third_party/blink/renderer/core/frame/frame_owner.h"
+#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_request.h"
+#include "third_party/blink/renderer/core/testing/sim/sim_test.h"
 #include "third_party/blink/renderer/platform/testing/task_environment.h"
+#include "third_party/blink/renderer/platform/testing/unit_test_helpers.h"
 #include "third_party/blink/renderer/platform/weborigin/kurl.h"
+#include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
+#include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
 namespace {
@@ -86,5 +102,401 @@
   EXPECT_EQ(computed_priority, ResourceLoadPriority::kHigh);
 }
 
+class DeferredFetchPolicyTestBase : public SimTest {
+ protected:
+  const String kMainUrl = "https://example.com/";
+  const String kCrossSubdomainUrl = "https://test.example.com/";
+  const String kCrossDomainUrl = "https://example.org/";
+
+  void SetUp() override {
+    feature_list_.InitAndEnableFeatureWithParameters(
+        features::kFetchLaterAPI, {
+                                      {"use_deferred_fetch_policy", "true"},
+                                  });
+    SimTest::SetUp();
+  }
+
+  using RequestUrlAndDataType = Vector<std::pair<const String, const String>>;
+  // Navigates to `root_url` with `html` as response.
+  // `url_and_data` provides additional responses to the requests generated by
+  // loading `html`.
+  void NavigateTo(const String& root_url,
+                  const String& html,
+                  const RequestUrlAndDataType& url_and_data = {}) {
+    // Queues all upcoming requests first.
+    SimRequest root_request(root_url, "text/html");
+    WTF::Vector<std::unique_ptr<SimRequest>> requests;
+    for (const auto& [url, _] : url_and_data) {
+      requests.emplace_back(std::make_unique<SimRequest>(url, "text/html"));
+    }
+
+    // Simulates loading the root page.
+    LoadURL(root_url);
+    root_request.Complete(String(html));
+    // Simulates loading all other requests from the root page.
+    for (size_t i = 0; i < url_and_data.size(); i++) {
+      requests[i]->Complete(url_and_data[i].second);
+    }
+
+    WaitForNavigation(root_url);
+  }
+
+  void WaitForNavigation(const String& url) {
+    Compositor().BeginFrame();
+    test::RunPendingTasks();
+    ASSERT_EQ(url, GetDocument().Url().GetString());
+  }
+
+  // Renders a series of sibling <iframe> elements with the given `iframe_urls`.
+  String RenderWithIframes(const Vector<String>& iframe_urls) {
+    StringBuilder html;
+    for (const auto& url : iframe_urls) {
+      html.Append("<iframe src=\"");
+      html.Append(url);
+      html.Append("\"></iframe>");
+    }
+    return html.ToString();
+  }
+
+  LocalFrame* GetMainFrame() { return GetDocument().GetFrame(); }
+
+ private:
+  base::test::ScopedFeatureList feature_list_;
+};
+
+using GetDeferredFetchQuotaSharingFramesTest = DeferredFetchPolicyTestBase;
+
+TEST_F(GetDeferredFetchQuotaSharingFramesTest, Null) {
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(nullptr), testing::IsEmpty());
+}
+
+// The main frame shares the deferred fetch quota with itself.
+TEST_F(GetDeferredFetchQuotaSharingFramesTest, SingleDocument) {
+  NavigateTo(kMainUrl, "");
+
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(GetMainFrame()),
+              testing::SizeIs(1));
+}
+
+// The about::blank iframe shares the deferred fetch quota with the main frame.
+TEST_F(GetDeferredFetchQuotaSharingFramesTest, SingleDocumentSingleBlankFrame) {
+  NavigateTo(kMainUrl, "<iframe></iframe>");
+
+  auto* root = GetMainFrame();
+  auto* blank_frame = root->Tree().FirstChild();
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(root), testing::SizeIs(2));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(blank_frame),
+              testing::SizeIs(2));
+}
+
+// The same-origin iframe shares the deferred fetch quota with the main frame.
+TEST_F(GetDeferredFetchQuotaSharingFramesTest,
+       SingleDocumentSingleSameOriginFrame) {
+  // The structure of the document:
+  // root -> frame_a (same-origin)
+  String root_url = kMainUrl;
+  String frame_a_url = kMainUrl + "frame-a.html";
+
+  NavigateTo(root_url, RenderWithIframes({"frame-a.html"}),
+             {{frame_a_url, ""}});
+
+  // Root and Frame A are same-origin.
+  auto* root = GetMainFrame();
+  auto* frame_a = root->Tree().FirstChild();
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(root), testing::SizeIs(2));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_a), testing::SizeIs(2));
+}
+
+// The same-origin iframe does not share the deferred fetch quota with the main
+// frame.
+TEST_F(GetDeferredFetchQuotaSharingFramesTest,
+       SingleDocumentSingleCrossOriginFrame) {
+  // The structure of the document:
+  // root -> frame_a (cross-origin)
+  String root_url = kMainUrl;
+  String frame_a_url = kCrossSubdomainUrl + "frame-a.html";
+
+  NavigateTo(root_url, RenderWithIframes({frame_a_url}), {{frame_a_url, ""}});
+
+  // Root and Frame A are cross-origin.
+  auto* root = GetMainFrame();
+  auto* frame_a = root->Tree().FirstChild();
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(root), testing::SizeIs(1));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_a), testing::SizeIs(1));
+}
+
+// The main frame and 3 cross-origin iframes don't share the same deferred
+// fetch quota.
+TEST_F(GetDeferredFetchQuotaSharingFramesTest,
+       MultipleCrossOriginSiblingFrames) {
+  // The structure of the document:
+  // root -> frame_a (cross-origin)
+  //      -> frame_b (cross-origin)
+  //      -> frame_c (cross-origin)
+  String root_url = kMainUrl;
+  String frame_a_url = kCrossSubdomainUrl + "frame-a.html";
+  String frame_b_url = kCrossSubdomainUrl + "frame-b.html";
+  String frame_c_url = kCrossSubdomainUrl + "frame-c.html";
+
+  NavigateTo(root_url,
+             RenderWithIframes({frame_a_url, frame_b_url, frame_c_url}),
+             {{frame_a_url, ""}, {frame_b_url, ""}, {frame_c_url, ""}});
+
+  auto* root = GetMainFrame();
+  auto* frame_a = root->Tree().FirstChild();
+  auto* frame_b = frame_a->Tree().NextSibling();
+  auto* frame_c = frame_b->Tree().NextSibling();
+
+  // Root is its owned origin.
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(root), testing::SizeIs(1));
+
+  // Frame A, B, and C are same-origin.
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_a), testing::SizeIs(3));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_b), testing::SizeIs(3));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_c), testing::SizeIs(3));
+}
+
+// The same-origin main frame, frame-a, frame-b are in the same frame group for
+// deferred fetch quota, while cross-origin frame-c, frame-d are in their own
+// group.
+TEST_F(GetDeferredFetchQuotaSharingFramesTest,
+       MultipleDifferentOriginSiblingFrames) {
+  // The structure of the document:
+  // root -> frame_a (same-origin)
+  //      -> frame_b (same-origin)
+  //      -> frame_c (cross-origin)
+  //      -> frame_d (cross-origin)
+  String root_url = kMainUrl;
+  String frame_a_url = kMainUrl + "frame-a.html";
+  String frame_b_url = kMainUrl + "frame-b.html";
+  String frame_c_url = kCrossSubdomainUrl + "frame-c.html";
+  String frame_d_url = kCrossSubdomainUrl + "frame-d.html";
+
+  NavigateTo(root_url,
+             RenderWithIframes(
+                 {"frame-a.html", frame_b_url, frame_c_url, frame_d_url}),
+             {{frame_a_url, ""},
+              {frame_b_url, ""},
+              {frame_c_url, ""},
+              {frame_d_url, ""}});
+
+  auto* root = GetMainFrame();
+  auto* frame_a = root->Tree().FirstChild();
+  auto* frame_b = frame_a->Tree().NextSibling();
+  auto* frame_c = frame_b->Tree().NextSibling();
+  auto* frame_d = frame_c->Tree().NextSibling();
+
+  // Root, Frame A and Frame B are same-origin.
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(root), testing::SizeIs(3));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_a), testing::SizeIs(3));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_b), testing::SizeIs(3));
+
+  // Frame C and D are same-origin.
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_c), testing::SizeIs(2));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_d), testing::SizeIs(2));
+}
+
+// The same-origin main frame, frame-a, frame-b are in the same frame group for
+// deferred fetch quota, while cross-origin frame-c, frame-d are in their own
+// group.
+TEST_F(GetDeferredFetchQuotaSharingFramesTest, MultipleLevelFrames) {
+  // The structure of the document:
+  // root -> frame_a (same-origin) -> frame_c (cross-origin)
+  //      -> frame_d (cross-origin) -> frame_b (same-origin)
+  String root_url = kMainUrl;
+  String frame_a_url = kMainUrl + "frame-a.html";
+  String frame_b_url = kMainUrl + "frame-b.html";
+  String frame_c_url = kCrossSubdomainUrl + "frame-c.html";
+  String frame_d_url = kCrossSubdomainUrl + "frame-d.html";
+
+  NavigateTo(root_url, RenderWithIframes({"frame-a.html", frame_d_url}),
+             {{frame_a_url, RenderWithIframes({frame_c_url})},
+              {frame_d_url, RenderWithIframes({frame_b_url})},
+              {frame_c_url, ""},
+              {frame_b_url, ""}});
+
+  auto* root = GetMainFrame();
+  auto* frame_a = root->Tree().FirstChild();
+  auto* frame_d = frame_a->Tree().NextSibling();
+  auto* frame_c = frame_a->Tree().FirstChild();
+  auto* frame_b = frame_d->Tree().FirstChild();
+
+  // Root, Frame A and Frame B are same-origin.
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(root), testing::SizeIs(3));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_a), testing::SizeIs(3));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_b), testing::SizeIs(3));
+
+  // Frame C and D are same-origin.
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_c), testing::SizeIs(2));
+  EXPECT_THAT(GetDeferredFetchQuotaSharingFrames(frame_d), testing::SizeIs(2));
+}
+
+class CountFramesWithMinimalQuotaPolicyTest
+    : public DeferredFetchPolicyTestBase {
+ protected:
+  [[nodiscard]] size_t CountFramesWithMinimalQuotaPolicyFor(
+      Frame* target_frame) {
+    // Should only be called by content of an iframe.
+    CHECK(target_frame->Owner());
+    // Should not be called by frame without permissions policy
+    // `deferred-fetch`.
+    CHECK(!target_frame->GetSecurityContext()
+               ->GetPermissionsPolicy()
+               ->IsFeatureEnabledForOrigin(
+                   mojom::blink::PermissionsPolicyFeature::kDeferredFetch,
+                   target_frame->GetSecurityContext()
+                       ->GetSecurityOrigin()
+                       ->ToUrlOrigin()));
+
+    // `GetDeferredFetchQuotaSharingFrames()` must be run on the
+    // `container’s container document`.
+    auto top_level_relatives =
+        GetDeferredFetchQuotaSharingFrames(target_frame->Parent());
+    return CountFramesWithMinimalQuotaPolicyForTesting(target_frame->Owner(),
+                                                       top_level_relatives);
+  }
+};
+
+// The single cross-origin iframe has default `deferred-fetch-minimal` policy
+// enabled `*`. However, there is no other cross-origin iframs share this quota
+// with it.
+TEST_F(CountFramesWithMinimalQuotaPolicyTest, SingleCrossOriginFrame) {
+  // The structure of the document:
+  // root -> frame_a (cross-origin)
+  String root_url = kMainUrl;
+  String frame_a_url = kCrossSubdomainUrl + "frame-a.html";
+  NavigateTo(root_url, RenderWithIframes({frame_a_url}), {{frame_a_url, ""}});
+
+  auto* root = GetMainFrame();
+  auto* frame_a = root->Tree().FirstChild();
+
+  // Expects no other frames share the minimal quota policy with `frame_a`.
+  EXPECT_EQ(CountFramesWithMinimalQuotaPolicyFor(frame_a), 0u);
+}
+
+TEST_F(CountFramesWithMinimalQuotaPolicyTest,
+       MultipleDifferentOriginSiblingFrames) {
+  // The structure of the document:
+  // root -> frame_a (same-origin)
+  //      -> frame_b (same-origin)
+  //      -> frame_c (cross-origin)
+  //      -> frame_d (cross-origin)
+  String root_url = kMainUrl;
+  String frame_a_url = kMainUrl + "frame-a.html";
+  String frame_b_url = kMainUrl + "frame-b.html";
+  String frame_c_url = kCrossSubdomainUrl + "frame-c.html";
+  String frame_d_url = kCrossSubdomainUrl + "frame-d.html";
+
+  NavigateTo(root_url,
+             RenderWithIframes(
+                 {"frame-a.html", frame_b_url, frame_c_url, frame_d_url}),
+             {{frame_a_url, ""},
+              {frame_b_url, ""},
+              {frame_c_url, ""},
+              {frame_d_url, ""}});
+
+  auto* root = GetMainFrame();
+  auto* frame_a = root->Tree().FirstChild();
+  auto* frame_b = frame_a->Tree().NextSibling();
+  auto* frame_c = frame_b->Tree().NextSibling();
+  auto* frame_d = frame_c->Tree().NextSibling();
+
+  // Frame A and Frame B are same-origin with root and are not counted toward
+  // minimal quota policy. Hence, they cannot be used in
+  // `CountFramesWithMinimalQuotaPolicyFor()`.
+
+  // Frame C and D are different origin with root, and shares the minimal quota
+  // policy with each other.
+  EXPECT_EQ(CountFramesWithMinimalQuotaPolicyFor(frame_c), 1u);
+  EXPECT_EQ(CountFramesWithMinimalQuotaPolicyFor(frame_d), 1u);
+}
+
+using GetContainerDeferredFetchPolicyOnNavigationTest =
+    DeferredFetchPolicyTestBase;
+
+// Tests the default behavior of a document with a same-origin iframe.
+// It should have deferred fetch policy in the owner frame set to
+// `kDeferredFetch`. The after-navigation call to
+// `GetContainerDeferredFetchPolicyOnNavigation()` should also give the same
+// result.
+TEST_F(GetContainerDeferredFetchPolicyOnNavigationTest, SingleSameOriginFrame) {
+  // The structure of the document:
+  // root -> frame_a (same-origin)
+  String root_url = kMainUrl;
+  String frame_a_url = kMainUrl + "frame-a.html";
+  NavigateTo(root_url, RenderWithIframes({"frame-a.html"}),
+             {{frame_a_url, ""}});
+  auto* root = GetMainFrame();
+  auto* frame_a = root->Tree().FirstChild();
+
+  // `GetContainerDeferredFetchPolicyOnNavigation()` should have been executed
+  // when iframe is loaded.
+  EXPECT_EQ(frame_a->Owner()->GetFramePolicy().deferred_fetch_policy,
+            FramePolicy::DeferredFetchPolicy::kDeferredFetch);
+  EXPECT_EQ(GetContainerDeferredFetchPolicyOnNavigation(frame_a->Owner()),
+            FramePolicy::DeferredFetchPolicy::kDeferredFetch);
+}
+
+// Tests the default behavior of a document with a same-origin iframe.
+// It should have deferred fetch policy in the owner frame set to
+// `kDeferredFetchMinimal`. The after-navigation call to
+// `GetContainerDeferredFetchPolicyOnNavigation()` should also give the same
+// result.
+TEST_F(GetContainerDeferredFetchPolicyOnNavigationTest,
+       SingleCrossOriginFrame) {
+  // The structure of the document:
+  // root -> frame_a (cross-origin)
+  String root_url = kMainUrl;
+  String frame_a_url = kCrossSubdomainUrl + "frame-a.html";
+  NavigateTo(root_url, RenderWithIframes({frame_a_url}), {{frame_a_url, ""}});
+
+  // Root and Frame A are cross-origin.
+  auto* root = GetMainFrame();
+  auto* frame_a = root->Tree().FirstChild();
+
+  EXPECT_EQ(GetContainerDeferredFetchPolicyOnNavigation(frame_a->Owner()),
+            FramePolicy::DeferredFetchPolicy::kDeferredFetchMinimal);
+}
+
+// Tests the default behavior of a document with 17 cross-origin sibling
+// iframes. The first 16 iframes should get kDeferredFetchMinimal as their
+// deferred fetch policy, while the last one should be kDisabled.
+TEST_F(GetContainerDeferredFetchPolicyOnNavigationTest, ManyCrossOriginFrames) {
+  // The structure of the document:
+  // root -> frame_1 (cross-origin)
+  //      -> ...
+  //      -> frame_16 (cross-origin)
+  //      -> frame_17 (cross-origin)
+  const size_t kNumCrossOriginFrames = 17;
+  String root_url = kMainUrl;
+
+  Vector<String> frame_urls;
+  RequestUrlAndDataType frame_url_and_data;
+  for (size_t i = 0; i < kNumCrossOriginFrames; i++) {
+    auto frame_id = i + 1;
+    frame_urls.emplace_back(kCrossSubdomainUrl + "frame-" +
+                            String::Number(frame_id) + ".html");
+    frame_url_and_data.emplace_back(std::make_pair(frame_urls[i], ""));
+  }
+
+  NavigateTo(root_url, RenderWithIframes(frame_urls), frame_url_and_data);
+
+  auto* root = GetMainFrame();
+  auto* frame = root->Tree().FirstChild();
+  size_t i = 0;
+  while (i < kNumCrossOriginFrames - 1 && frame) {
+    EXPECT_EQ(frame->Owner()->GetFramePolicy().deferred_fetch_policy,
+              FramePolicy::DeferredFetchPolicy::kDeferredFetchMinimal)
+        << i + 1 << "-th cross-origin iframe";
+    frame = frame->Tree().NextSibling();
+    i++;
+  }
+
+  // The last cross-origin iframe should have `kDisabled` set.
+  EXPECT_EQ(frame->Owner()->GetFramePolicy().deferred_fetch_policy,
+            FramePolicy::DeferredFetchPolicy::kDisabled)
+      << i + 1 << "-th cross-origin iframe";
+}
+
 }  // namespace
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/frame/frame_owner.h b/third_party/blink/renderer/core/frame/frame_owner.h
index 3beec2b..077469d 100644
--- a/third_party/blink/renderer/core/frame/frame_owner.h
+++ b/third_party/blink/renderer/core/frame/frame_owner.h
@@ -6,6 +6,7 @@
 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_FRAME_OWNER_H_
 
 #include "third_party/blink/public/common/frame/frame_policy.h"
+#include "third_party/blink/public/mojom/css/preferred_color_scheme.mojom-blink.h"
 #include "third_party/blink/public/mojom/frame/color_scheme.mojom-blink.h"
 #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h"
 #include "third_party/blink/public/mojom/timing/resource_timing.mojom-blink-forward.h"
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
index 7af8e16e..d379d93 100644
--- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
+++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.cc
@@ -138,8 +138,7 @@
       avoid_unnecessary_forced_layout_measurements_(
           avoid_unnecessary_forced_layout_measurements),
       should_report_uma_this_frame_(should_report_uma_this_frame),
-      is_pre_fcp_(is_pre_fcp),
-      record_ukm_for_current_frame_(record_ukm_for_current_frame) {
+      is_pre_fcp_(is_pre_fcp) {
   aggregator_->BeginForcedLayout();
 }
 
diff --git a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
index bb270fb..3d6e6d9 100644
--- a/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
+++ b/third_party/blink/renderer/core/frame/local_frame_ukm_aggregator.h
@@ -290,7 +290,6 @@
     bool avoid_unnecessary_forced_layout_measurements_;
     bool should_report_uma_this_frame_;
     bool is_pre_fcp_;
-    bool record_ukm_for_current_frame_;
   };
 
   LocalFrameUkmAggregator();
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.cc b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
index d44ddc5..bdd4bee 100644
--- a/third_party/blink/renderer/core/html/html_frame_owner_element.cc
+++ b/third_party/blink/renderer/core/html/html_frame_owner_element.cc
@@ -39,6 +39,7 @@
 #include "third_party/blink/renderer/core/events/current_input_event.h"
 #include "third_party/blink/renderer/core/execution_context/execution_context.h"
 #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
+#include "third_party/blink/renderer/core/fetch/fetch_later_util.h"
 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
 #include "third_party/blink/renderer/core/frame/local_dom_window.h"
 #include "third_party/blink/renderer/core/frame/local_frame.h"
@@ -425,6 +426,20 @@
   }
 }
 
+void HTMLFrameOwnerElement::UpdateDeferredFetchPolicy() {
+  if (!IsFetchLaterUseDeferredFetchPolicyEnabled()) {
+    return;
+  }
+  frame_policy_.deferred_fetch_policy =
+      GetContainerDeferredFetchPolicyOnNavigation(this);
+
+  if (ContentFrame()) {
+    auto* frame = GetDocument().GetFrame();
+    frame->GetLocalFrameHostRemote().DidChangeFramePolicy(
+        ContentFrame()->GetFrameToken(), frame_policy_);
+  }
+}
+
 network::mojom::blink::TrustTokenParamsPtr
 HTMLFrameOwnerElement::ConstructTrustTokenParams() const {
   return nullptr;
diff --git a/third_party/blink/renderer/core/html/html_frame_owner_element.h b/third_party/blink/renderer/core/html/html_frame_owner_element.h
index ae27aeb5..9cde43ec 100644
--- a/third_party/blink/renderer/core/html/html_frame_owner_element.h
+++ b/third_party/blink/renderer/core/html/html_frame_owner_element.h
@@ -138,6 +138,14 @@
   // For unit tests, manually trigger the UpdateContainerPolicy method.
   void UpdateContainerPolicyForTests() { UpdateContainerPolicy(); }
 
+  // Updates the deferred fetch policy and notify the frame loader client of any
+  // changes after `LoadOrRedirectSubframe()` is called and navigating to
+  // a target URL.
+  // Must be called after navigation such that "inherited policy" is available.
+  // To be precise, after `ApplyPermissionsPolicy()` is called by
+  // `DocumentLoader::CommitNavigation()`.
+  void UpdateDeferredFetchPolicy();
+
   void CancelPendingLazyLoad();
 
   void ParseAttribute(const AttributeModificationParams&) override;
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser_state.h b/third_party/blink/renderer/core/html/parser/html_document_parser_state.h
index 12f0aff..a6d8b81 100644
--- a/third_party/blink/renderer/core/html/parser/html_document_parser_state.h
+++ b/third_party/blink/renderer/core/html/parser/html_document_parser_state.h
@@ -154,7 +154,6 @@
   }
 
   DeferredParserState state_;
-  int seen_csp_counter_ = 0;
   ParserSynchronizationPolicy mode_;
   const PreloadProcessingMode preload_processing_mode_;
   unsigned end_if_delayed_forbidden_ = 0;
diff --git a/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc b/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
index 6fd9925..ed8c625 100644
--- a/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
+++ b/third_party/blink/renderer/core/html/parser/html_srcset_parser.cc
@@ -383,8 +383,17 @@
 
 static unsigned SelectionLogic(Vector<ImageCandidate*>& image_candidates,
                                float device_scale_factor) {
-  unsigned i = 0;
+  if (RuntimeEnabledFeatures::SrcsetSelectionMatchesImageSetEnabled()) {
+    unsigned i = 0;
+    for (; i < image_candidates.size() - 1; ++i) {
+      if (image_candidates[i]->Density() >= device_scale_factor) {
+        return i;
+      }
+    }
+    return i;
+  }
 
+  unsigned i = 0;
   for (; i < image_candidates.size() - 1; ++i) {
     unsigned next = i + 1;
     float next_density;
@@ -399,8 +408,9 @@
     geometric_mean = sqrt(current_density * next_density);
     if (((device_scale_factor <= 1.0) &&
          (device_scale_factor > current_density)) ||
-        (device_scale_factor >= geometric_mean))
+        (device_scale_factor >= geometric_mean)) {
       return next;
+    }
     break;
   }
   return i;
diff --git a/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc b/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc
index fa3cd315..9500963 100644
--- a/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.cc
+++ b/third_party/blink/renderer/core/html/parser/html_srcset_parser_test.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 "third_party/blink/renderer/core/html/parser/html_srcset_parser.h"
 
 #include <limits.h>
@@ -39,327 +34,380 @@
   ASSERT_EQ(candidate.SrcOrigin(), false);
 }
 
-TEST(HTMLSrcsetParserTest, Basic) {
-  test::TaskEnvironment task_environment;
-  SrcsetParserTestCase test_cases[] = {
-      {2.0, 0.5, "", "data:,a 1w, data:,b 2x", "data:,a", 2.0, 1},
-      {2.0, 1, "", "data:,a 2w, data:,b 2x", "data:,a", 2.0, 2},
-      {2.0, -1, "", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {2.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, -1, "", "1x.gif 1x 100h, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, -1, "", "1x.gif 1x 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, -1, "", "1x.gif 1x 100h 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {2.0, -1, "", "1x.gif 1x, 2x.gif -2x", "1x.gif", 1.0, -1},
-      {2.0, -1, "", "0x.gif 0x", "0x.gif", 0.0, -1},
-      {2.0, -1, "", "0x.gif -0x", "0x.gif", 0.0, -1},
-      {2.0, -1, "", "neg.gif -2x", "", 1.0, -1},
-      {2.0, -1, "", "1x.gif 1x, 2x.gif 2q", "1x.gif", 1.0, -1},
-      {2.0, -1, "", "1x.gif, 2x.gif 2q", "1x.gif", 1.0, -1},
-      {2.0, -1, "", "1x.gif  , 2x.gif 2q", "1x.gif", 1.0, -1},
-      {2.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0,
-       -1},
-      {1.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0,
-       -1},
-      {1.0, -1, "1x.gif 1x, 2x.gif 2x", "", "1x.gif 1x, 2x.gif 2x", 1.0, -1},
-      {2.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
-      {1.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
-      {2.0, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
-      {2.0, -1, "src.gif", "2x.gif 2px", "src.gif", 1.0, -1},
-      {2.0, -1, "src.gif", "2x.gif 2ex", "src.gif", 1.0, -1},
-      {10.0, -1, "src.gif", "2x.gif 2e1x", "2x.gif", 20.0, -1},
-      {2.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1},
-      {2.0, -1, "src.gif", "2x.gif +2x", "src.gif", 1.0, -1},
-      {1.5, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
-      {2.5, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
-      {2.5, -1, "src.gif", "2x.gif 2x, 3x.gif 3x", "3x.gif", 3.0, -1},
-      {2.0, -1, "", "1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
-      {2.0, -1, "", "1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
-      {2.0, -1, "", ",,1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
-      {2.0, -1, "", ",,1x,,", "1x", 1.0, -1},
-      {2.0, -1, "", ",1x,", "1x", 1.0, -1},
-      {2.0, -1, "",
-       "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 1x, 2x.gif 2x", "2x.gif",
-       2.0, -1},
-      {2.0, -1, "",
-       "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 2x, 1x.gif 1x",
-       "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg", 2.0, -1},
-      {2.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "2x.gif", 2.0, -1},
-      {4.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100h, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "2x.gif", 2.0, -1},
-      {4.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "2x.gif", 2.0, -1},
-      {1.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "1x", 1.0, -1},
-      {5.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "2x.gif", 2.0, -1},
-      {2.0, -1, "",
-       "1x.gif 1x, "
-       "data:image/"
-       "svg+xml;base64,"
-       "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGh"
-       "laWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncm"
-       "VlbiIvPgo8L3N2Zz4K 2x",
-       "data:image/"
-       "svg+xml;base64,"
-       "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGh"
-       "laWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncm"
-       "VlbiIvPgo8L3N2Zz4K",
-       2.0, -1},
-      {2.0, -1, "1x.gif",
-       "data:image/"
-       "svg+xml;base64,"
-       "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGh"
-       "laWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncm"
-       "VlbiIvPgo8L3N2Zz4K 2x",
-       "data:image/"
-       "svg+xml;base64,"
-       "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGh"
-       "laWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncm"
-       "VlbiIvPgo8L3N2Zz4K",
-       2.0, -1},
-      {2.0, -1, "1x.svg#red", "1x.svg#green 2x", "1x.svg#green", 2.0, -1},
-      {2.0, -1, "", "1x.svg#red 1x, 1x.svg#green 2x", "1x.svg#green", 2.0, -1},
-      {1.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
-      {1.0, 400, "", "400.gif 400pw, 6000.gif 6000w", "6000.gif", 15.0, 6000},
-      {1.0, 400, "fallback.gif", "400.gif 400pw", "fallback.gif", 1.0, -1},
-      {1.0, 400, "fallback.gif", "400.gif +400w", "fallback.gif", 1.0, -1},
-      {1.0, 400, "", "400.gif 400w 400h, 6000.gif 6000w", "400.gif", 1.0, 400},
-      {4.0, 400, "", "400.gif 400w, 6000.gif 6000w", "6000.gif", 15.0, 6000},
-      {3.8, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
-      {0.9, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
-      {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 400w", "1x.gif", 1.0, -1},
-      {0.9, 800, "src.gif", "1x.gif 0.6x, 400.gif 400w", "1x.gif", 0.6, -1},
-      {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 720w", "400.gif", 0.9, 720},
-      {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 719w", "1x.gif", 1.0, -1},
-      {2.0, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
-      {1.0, 400, "src.gif", "800.gif 800w", "800.gif", 2.0, 800},
-      {1.0, 400, "src.gif", "0.gif 0w, 800.gif 800w", "800.gif", 2.0, 800},
-      {1.0, 400, "src.gif", "0.gif 0w, 2x.gif 2x", "src.gif", 1.0, -1},
-      {1.0, 400, "src.gif", "800.gif 2x, 1600.gif 1600w", "800.gif", 2.0, -1},
-      {1.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
-      {2.0, 400, "", "400.gif 400w, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, 0, "", "400.gif 400w, 6000.gif 6000w", "400.gif",
-       std::numeric_limits<float>::infinity(), 400},
-      {2.0, -1, "", ", 1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, -1, "", ",1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
-      {1.0, -1, "", ",1x.gif 1.x , 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.2, -1, "", ",1x.gif 1x, 1.4x.gif 1.4x, 2x.gif 2x", "1.4x.gif", 1.4,
-       -1},
-      {1.0, -1, "", "inf.gif 0.00000000001x", "inf.gif", 1e-11, -1},
-      {1.0, -1, "", "data:,a ( , data:,b 1x, ), data:,c", "data:,c", 1.0, -1},
-      {1.0, 1, "", "data:,a 1w 1h", "data:,a", 1.0, 1},
-      {1.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x",
-       "2x.gif", 2.0, -1},
-      {2.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x",
-       "2x.gif", 2.0, -1},
-      {1.0, -1, "", "data:,a 1 w", "", 1.0, -1},
-      {1.0, -1, "", "data:,a 1  w", "", 1.0, -1},
-      {1.0, -1, "", "data:,a +1x", "", 1.0, -1},
-      {1.0, -1, "", "data:,a   +1x", "", 1.0, -1},
-      {1.0, -1, "", "data:,a 1.0x", "data:,a", 1.0, -1},
-      {1.0, -1, "", "1%20and%202.gif 1x", "1%20and%202.gif", 1.0, -1},
-      {1.0, 700, "", "data:,a 0.5x, data:,b 1400w", "data:,b", 2.0, 1400},
-      {0, 0, nullptr, nullptr, nullptr,
-       0}  // Do not remove the terminator line.
-  };
-
-  for (unsigned i = 0; test_cases[i].src_input; ++i) {
-    SrcsetParserTestCase test = test_cases[i];
-    ImageCandidate candidate = BestFitSourceForImageAttributes(
-        test.device_scale_factor, test.effective_size, test.src_input,
-        test.srcset_input);
-    ASSERT_EQ(test.output_density, candidate.Density());
-    ASSERT_EQ(test.output_resource_width, candidate.GetResourceWidth());
-    ASSERT_EQ(test.output_url, candidate.ToString().Ascii());
-  }
+void PrintTo(const SrcsetParserTestCase& test, std::ostream* os) {
+  *os << "device_scale_factor: " << test.device_scale_factor
+      << "; effective_size: " << test.effective_size << "; src_input: \""
+      << test.src_input << "\"" << "; srcset_input: \"" << test.srcset_input
+      << "\"";
 }
 
+class HTMLSrcsetParserTest
+    : public testing::TestWithParam<SrcsetParserTestCase> {};
+
+TEST_P(HTMLSrcsetParserTest, Basic) {
+  test::TaskEnvironment task_environment;
+  const SrcsetParserTestCase test = GetParam();
+  ImageCandidate candidate = BestFitSourceForImageAttributes(
+      test.device_scale_factor, test.effective_size, test.src_input,
+      test.srcset_input);
+
+  EXPECT_EQ(test.output_density, candidate.Density());
+  EXPECT_EQ(test.output_resource_width, candidate.GetResourceWidth());
+  EXPECT_EQ(test.output_url, candidate.ToString().Ascii());
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    HTMLSrcsetParserTest,
+    testing::ValuesIn(std::vector<SrcsetParserTestCase>{
+        {2.0, 0.5, "", "data:,a 1w, data:,b 2x", "data:,a", 2.0, 1},
+        {2.0, 1, "", "data:,a 2w, data:,b 2x", "data:,a", 2.0, 2},
+        {2.0, -1, "", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {2.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "", "1x.gif 1x 100h, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "", "1x.gif 1x 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "", "1x.gif 1x 100h 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {2.0, -1, "", "1x.gif 1x, 2x.gif -2x", "1x.gif", 1.0, -1},
+        {2.0, -1, "", "0x.gif 0x", "0x.gif", 0.0, -1},
+        {2.0, -1, "", "0x.gif -0x", "0x.gif", 0.0, -1},
+        {2.0, -1, "", "neg.gif -2x", "", 1.0, -1},
+        {2.0, -1, "", "1x.gif 1x, 2x.gif 2q", "1x.gif", 1.0, -1},
+        {2.0, -1, "", "1x.gif, 2x.gif 2q", "1x.gif", 1.0, -1},
+        {2.0, -1, "", "1x.gif  , 2x.gif 2q", "1x.gif", 1.0, -1},
+        {2.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0,
+         -1},
+        {1.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0,
+         -1},
+        {1.0, -1, "1x.gif 1x, 2x.gif 2x", "", "1x.gif 1x, 2x.gif 2x", 1.0, -1},
+        {2.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+        {1.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+        {2.0, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
+        {2.0, -1, "src.gif", "2x.gif 2px", "src.gif", 1.0, -1},
+        {2.0, -1, "src.gif", "2x.gif 2ex", "src.gif", 1.0, -1},
+        {10.0, -1, "src.gif", "2x.gif 2e1x", "2x.gif", 20.0, -1},
+        {2.0, -1, "src.gif", "2x.gif 2e1x", "2x.gif", 20.0, -1},
+        {2.0, -1, "src.gif", "2x.gif +2x", "src.gif", 1.0, -1},
+        {1.5, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
+        {2.5, -1, "src.gif", "2x.gif 2x", "2x.gif", 2.0, -1},
+        {2.5, -1, "src.gif", "2x.gif 2x, 3x.gif 3x", "3x.gif", 3.0, -1},
+        {2.0, -1, "", "1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
+        {2.0, -1, "", "1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
+        {2.0, -1, "", ",,1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
+        {2.0, -1, "", ",,1x,,", "1x", 1.0, -1},
+        {2.0, -1, "", ",1x,", "1x", 1.0, -1},
+        {2.0, -1, "",
+         "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 1x, 2x.gif 2x", "2x.gif",
+         2.0, -1},
+        {2.0, -1, "",
+         "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 2x, 1x.gif 1x",
+         "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg", 2.0, -1},
+        {2.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "2x.gif", 2.0, -1},
+        {4.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100h, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "2x.gif", 2.0, -1},
+        {4.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "2x.gif", 2.0, -1},
+        {1.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "1x", 1.0, -1},
+        {5.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "2x.gif", 2.0, -1},
+        {2.0, -1, "",
+         "1x.gif 1x, "
+         "data:image/"
+         "svg+xml;base64,"
+         "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiI"
+         "GhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPS"
+         "JncmVlbiIvPgo8L3N2Zz4K 2x",
+         "data:image/"
+         "svg+xml;base64,"
+         "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiI"
+         "GhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPS"
+         "JncmVlbiIvPgo8L3N2Zz4K",
+         2.0, -1},
+        {2.0, -1, "1x.gif",
+         "data:image/"
+         "svg+xml;base64,"
+         "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiI"
+         "GhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPS"
+         "JncmVlbiIvPgo8L3N2Zz4K 2x",
+         "data:image/"
+         "svg+xml;base64,"
+         "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiI"
+         "GhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPS"
+         "JncmVlbiIvPgo8L3N2Zz4K",
+         2.0, -1},
+        {2.0, -1, "1x.svg#red", "1x.svg#green 2x", "1x.svg#green", 2.0, -1},
+        {2.0, -1, "", "1x.svg#red 1x, 1x.svg#green 2x", "1x.svg#green", 2.0,
+         -1},
+        {1.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+        {1.0, 400, "", "400.gif 400pw, 6000.gif 6000w", "6000.gif", 15.0, 6000},
+        {1.0, 400, "fallback.gif", "400.gif 400pw", "fallback.gif", 1.0, -1},
+        {1.0, 400, "fallback.gif", "400.gif +400w", "fallback.gif", 1.0, -1},
+        {1.0, 400, "", "400.gif 400w 400h, 6000.gif 6000w", "400.gif", 1.0,
+         400},
+        {4.0, 400, "", "400.gif 400w, 6000.gif 6000w", "6000.gif", 15.0, 6000},
+        {3.8, 400, "", "400.gif 400w, 6000.gif 6000w", "6000.gif", 15.0, 6000},
+        {0.9, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
+        {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 400w", "1x.gif", 1.0, -1},
+        {0.9, 800, "src.gif", "1x.gif 0.6x, 400.gif 400w", "1x.gif", 0.6, -1},
+        {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 720w", "400.gif", 0.9, 720},
+        {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 719w", "1x.gif", 1.0, -1},
+        {2.0, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
+        {1.0, 400, "src.gif", "800.gif 800w", "800.gif", 2.0, 800},
+        {1.0, 400, "src.gif", "0.gif 0w, 800.gif 800w", "800.gif", 2.0, 800},
+        {1.0, 400, "src.gif", "0.gif 0w, 2x.gif 2x", "src.gif", 1.0, -1},
+        {1.0, 400, "src.gif", "800.gif 2x, 1600.gif 1600w", "800.gif", 2.0, -1},
+        {1.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
+        {2.0, 400, "", "400.gif 400w, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, 0, "", "400.gif 400w, 6000.gif 6000w", "400.gif",
+         std::numeric_limits<float>::infinity(), 400},
+        {2.0, -1, "", ", 1x.gif 1x, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "", ",1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+        {1.0, -1, "", ",1x.gif 1.x , 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.2, -1, "", ",1x.gif 1x, 1.4x.gif 1.4x, 2x.gif 2x", "1.4x.gif", 1.4,
+         -1},
+        {1.0, -1, "", "inf.gif 0.00000000001x", "inf.gif", 1e-11, -1},
+        {1.0, -1, "", "data:,a ( , data:,b 1x, ), data:,c", "data:,c", 1.0, -1},
+        {1.0, 1, "", "data:,a 1w 1h", "data:,a", 1.0, 1},
+        {1.0, -1, "",
+         ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x", "2x.gif",
+         2.0, -1},
+        {2.0, -1, "",
+         ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x", "2x.gif",
+         2.0, -1},
+        {1.0, -1, "", "data:,a 1 w", "", 1.0, -1},
+        {1.0, -1, "", "data:,a 1  w", "", 1.0, -1},
+        {1.0, -1, "", "data:,a +1x", "", 1.0, -1},
+        {1.0, -1, "", "data:,a   +1x", "", 1.0, -1},
+        {1.0, -1, "", "data:,a 1.0x", "data:,a", 1.0, -1},
+        {1.0, -1, "", "1%20and%202.gif 1x", "1%20and%202.gif", 1.0, -1},
+        {1.0, 700, "", "data:,a 0.5x, data:,b 1400w", "data:,b", 2.0, 1400},
+    }));
+
+class SaveDataHTMLSrcsetParserTest : public HTMLSrcsetParserTest {};
+
 #if (BUILDFLAG(IS_ANDROID) && defined(ADDRESS_SANITIZER))
 // https://crbug.com/1189511
 #define MAYBE_SaveDataEnabledBasic DISABLED_SaveDataEnabledBasic
 #else
 #define MAYBE_SaveDataEnabledBasic SaveDataEnabledBasic
 #endif
-TEST(HTMLSrcsetParserTest, MAYBE_SaveDataEnabledBasic) {
+TEST_P(SaveDataHTMLSrcsetParserTest, MAYBE_SaveDataEnabledBasic) {
   test::TaskEnvironment task_environment;
-  SrcsetParserTestCase test_cases[] = {
-      // 0
-      {2.0, 0.5, "", "data:,a 1w, data:,b 2x", "data:,a", 2.0, 1},
-      {2.0, 1, "", "data:,a 2w, data:,b 2x", "data:,a", 2.0, 2},
-      {2.0, -1, "", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
-      {2.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, -1, "", "1x.gif 1x 100h, 2x.gif 2x", "2x.gif", 2.0, -1},  // 5
-      {1.0, -1, "", "1x.gif 1x 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.0, -1, "", "1x.gif 1x 100h 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
-      {2.0, -1, "", "1x.gif 1x, 2x.gif -2x", "1x.gif", 1.0, -1},
-      {2.0, -1, "", "0x.gif 0x", "0x.gif", 0.0, -1},
-      {2.0, -1, "", "0x.gif -0x", "0x.gif", 0.0, -1},  // 10
-      {2.0, -1, "", "neg.gif -2x", "", 1.0, -1},
-      {2.0, -1, "", "1x.gif 1x, 2x.gif 2q", "1x.gif", 1.0, -1},
-      {2.0, -1, "", "1x.gif, 2x.gif 2q", "1x.gif", 1.0, -1},
-      {2.0, -1, "", "1x.gif  , 2x.gif 2q", "1x.gif", 1.0, -1},
-      {2.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0,
-       -1},  // 15
-      {1.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0,
-       -1},
-      {1.0, -1, "1x.gif 1x, 2x.gif 2x", "", "1x.gif 1x, 2x.gif 2x", 1.0, -1},
-      {2.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
-      {1.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
-      {1.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},  // 20
-      {2.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
-      {2.0, -1, "src.gif", "2x.gif 2px", "src.gif", 1.0, -1},
-      {2.0, -1, "src.gif", "2x.gif 2ex", "src.gif", 1.0, -1},
-      {10.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1},
-      {2.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1},  // 25
-      {2.0, -1, "src.gif", "2x.gif +2x", "src.gif", 1.0, -1},
-      {1.5, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
-      {2.5, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
-      {2.5, -1, "src.gif", "2x.gif 2x, 3x.gif 3x", "src.gif", 1.0, -1},
-      {2.0, -1, "", "1x,,  ,   x    ,2x  ", "1x", 1.0, -1},  // 30
-      {2.0, -1, "", "1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
-      {2.0, -1, "", ",,1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
-      {2.0, -1, "", ",,1x,,", "1x", 1.0, -1},
-      {2.0, -1, "", ",1x,", "1x", 1.0, -1},
-      {2.0, -1, "",
-       "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 1x, 2x.gif 2x",
-       "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg", 1.0, -1},  // 35
-      {2.0, -1, "",
-       "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 2x, 1x.gif 1x", "1x.gif",
-       1.0, -1},
-      {2.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "1x", 1.0, -1},
-      {4.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100h, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "1x", 1.0, -1},
-      {4.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "1x", 1.0, -1},
-      {1.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "1x", 1.0, -1},  // 40
-      {5.0, -1, "",
-       "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif dx, "
-       "2x.gif   2x ,",
-       "1x", 1.0, -1},
-      {2.0, -1, "",
-       "1x.gif 1x, "
-       "data:image/"
-       "svg+xml;base64,"
-       "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGh"
-       "laWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncm"
-       "VlbiIvPgo8L3N2Zz4K 2x",
-       "1x.gif", 1.0, -1},
-      {2.0, -1, "1x.gif",
-       "data:image/"
-       "svg+xml;base64,"
-       "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiIGh"
-       "laWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPSJncm"
-       "VlbiIvPgo8L3N2Zz4K 2x",
-       "1x.gif", 1.0, -1},
-      {2.0, -1, "1x.svg#red", "1x.svg#green 2x", "1x.svg#red", 1.0, -1},
-      {2.0, -1, "", "1x.svg#red 1x, 1x.svg#green 2x", "1x.svg#red", 1.0,
-       -1},  // 45
-      {1.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
-      {1.0, 400, "", "400.gif 400pw, 6000.gif 6000w", "6000.gif", 15.0, 6000},
-      {1.0, 400, "fallback.gif", "400.gif 400pw", "fallback.gif", 1.0, -1},
-      {1.0, 400, "fallback.gif", "400.gif +400w", "fallback.gif", 1.0, -1},
-      {1.0, 400, "", "400.gif 400w 400h, 6000.gif 6000w", "400.gif", 1.0,
-       400},  // 50
-      {4.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
-      {3.8, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
-      {0.9, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
-      {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 400w", "400.gif", 0.5, 400},
-      {0.9, 800, "src.gif", "1x.gif 0.6x, 400.gif 400w", "400.gif", 0.5,
-       400},  // 55
-      {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 720w", "400.gif", 0.9, 720},
-      {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 719w", "400.gif", 719.0 / 800.0,
-       719},
-      {2.0, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
-      {1.0, 400, "src.gif", "800.gif 800w", "800.gif", 2.0, 800},
-      {1.0, 400, "src.gif", "0.gif 0w, 800.gif 800w", "800.gif", 2.0,
-       800},  // 60
-      {1.0, 400, "src.gif", "0.gif 0w, 2x.gif 2x", "src.gif", 1.0, -1},
-      {1.0, 400, "src.gif", "800.gif 2x, 1600.gif 1600w", "800.gif", 2.0, -1},
-      {1.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
-      {2.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
-      {1.0, 0, "", "400.gif 400w, 6000.gif 6000w", "400.gif",
-       std::numeric_limits<float>::infinity(), 400},  // 65
-      {2.0, -1, "", ", 1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
-      {1.0, -1, "", ",1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
-      {1.0, -1, "", ",1x.gif 1.x , 2x.gif 2x", "2x.gif", 2.0, -1},
-      {1.2, -1, "", ",1x.gif 1x, 1.4x.gif 1.4x, 2x.gif 2x", "1x.gif", 1.0, -1},
-      {1.0, -1, "", "inf.gif 0.00000000001x", "inf.gif", 1e-11, -1},  // 70
-      {1.0, -1, "", "data:,a ( , data:,b 1x, ), data:,c", "data:,c", 1.0, -1},
-      {1.0, 1, "", "data:,a 1w 1h", "data:,a", 1.0, 1},
-      {1.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x",
-       "2x.gif", 2.0, -1},
-      {2.0, -1, "", ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x",
-       "2x.gif", 2.0, -1},
-      {1.0, -1, "", "data:,a 1 w", "", 1.0, -1},  // 75
-      {1.0, -1, "", "data:,a 1  w", "", 1.0, -1},
-      {1.0, -1, "", "data:,a +1x", "", 1.0, -1},
-      {1.0, -1, "", "data:,a   +1x", "", 1.0, -1},
-      {1.0, -1, "", "data:,a 1.0x", "data:,a", 1.0, -1},
-      {1.0, -1, "", "1%20and%202.gif 1x", "1%20and%202.gif", 1.0, -1},  // 80
-      {1.0, 700, "", "data:,a 0.5x, data:,b 1400w", "data:,a", 0.5, -1},
-      {0, 0, nullptr, nullptr, nullptr,
-       0}  // Do not remove the terminator line.
-  };
-
   blink::WebNetworkStateNotifier::SetSaveDataEnabled(true);
   base::test::ScopedFeatureList scoped_feature_list;
   scoped_feature_list.InitWithFeatures({blink::features::kSaveDataImgSrcset},
                                        {});
-  for (unsigned i = 0; test_cases[i].src_input; ++i) {
-    SrcsetParserTestCase test = test_cases[i];
-    ImageCandidate candidate = BestFitSourceForImageAttributes(
-        test.device_scale_factor, test.effective_size, test.src_input,
-        test.srcset_input);
-    ASSERT_EQ(test.output_density, candidate.Density());
-    ASSERT_EQ(test.output_resource_width, candidate.GetResourceWidth());
-    ASSERT_EQ(test.output_url, candidate.ToString().Ascii());
-  }
+
+  const SrcsetParserTestCase test = GetParam();
+  ImageCandidate candidate = BestFitSourceForImageAttributes(
+      test.device_scale_factor, test.effective_size, test.src_input,
+      test.srcset_input);
+
+  EXPECT_EQ(test.output_density, candidate.Density());
+  EXPECT_EQ(test.output_resource_width, candidate.GetResourceWidth());
+  EXPECT_EQ(test.output_url, candidate.ToString().Ascii());
 }
 
-TEST(HTMLSrcsetParserTest, MaxDensityEnabled) {
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    SaveDataHTMLSrcsetParserTest,
+    testing::ValuesIn(std::vector<SrcsetParserTestCase>{
+        {2.0, 0.5, "", "data:,a 1w, data:,b 2x", "data:,a", 2.0, 1},
+        {2.0, 1, "", "data:,a 2w, data:,b 2x", "data:,a", 2.0, 2},
+        {2.0, -1, "", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+        {2.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "", "1x.gif 1q, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "", "1x.gif 1x 100h, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "", "1x.gif 1x 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.0, -1, "", "1x.gif 1x 100h 100w, 2x.gif 2x", "2x.gif", 2.0, -1},
+        {2.0, -1, "", "1x.gif 1x, 2x.gif -2x", "1x.gif", 1.0, -1},
+        {2.0, -1, "", "0x.gif 0x", "0x.gif", 0.0, -1},
+        {2.0, -1, "", "0x.gif -0x", "0x.gif", 0.0, -1},
+        {2.0, -1, "", "neg.gif -2x", "", 1.0, -1},
+        {2.0, -1, "", "1x.gif 1x, 2x.gif 2q", "1x.gif", 1.0, -1},
+        {2.0, -1, "", "1x.gif, 2x.gif 2q", "1x.gif", 1.0, -1},
+        {2.0, -1, "", "1x.gif  , 2x.gif 2q", "1x.gif", 1.0, -1},
+        {2.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0,
+         -1},
+        {1.0, -1, "1x.gif 1x, 2x.gif 2x", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0,
+         -1},
+        {1.0, -1, "1x.gif 1x, 2x.gif 2x", "", "1x.gif 1x, 2x.gif 2x", 1.0, -1},
+        {2.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+        {1.0, -1, "src.gif", "1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+        {1.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+        {2.0, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+        {2.0, -1, "src.gif", "2x.gif 2px", "src.gif", 1.0, -1},
+        {2.0, -1, "src.gif", "2x.gif 2ex", "src.gif", 1.0, -1},
+        {10.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1},
+        {2.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1},
+        {2.0, -1, "src.gif", "2x.gif +2x", "src.gif", 1.0, -1},
+        {1.5, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+        {2.5, -1, "src.gif", "2x.gif 2x", "src.gif", 1.0, -1},
+        {2.5, -1, "src.gif", "2x.gif 2x, 3x.gif 3x", "src.gif", 1.0, -1},
+        {2.0, -1, "", "1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
+        {2.0, -1, "", "1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
+        {2.0, -1, "", ",,1x,,  ,   x    ,2x  ", "1x", 1.0, -1},
+        {2.0, -1, "", ",,1x,,", "1x", 1.0, -1},
+        {2.0, -1, "", ",1x,", "1x", 1.0, -1},
+        {2.0, -1, "",
+         "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 1x, 2x.gif 2x",
+         "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg", 1.0, -1},
+        {2.0, -1, "",
+         "data:image/png;base64,iVBORw0KGgoAAAANSUhEUg 2x, 1x.gif 1x", "1x.gif",
+         1.0, -1},
+        {2.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "1x", 1.0, -1},
+        {4.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100h, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "1x", 1.0, -1},
+        {4.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "1x", 1.0, -1},
+        {1.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "1x", 1.0, -1},
+        {5.0, -1, "",
+         "1x,,  ,   x    ,2x  , 1x.gif, 3x, 4x.gif 4x 100z, 5x.gif 5, dx.gif "
+         "dx, "
+         "2x.gif   2x ,",
+         "1x", 1.0, -1},
+        {2.0, -1, "",
+         "1x.gif 1x, "
+         "data:image/"
+         "svg+xml;base64,"
+         "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiI"
+         "GhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPS"
+         "JncmVlbiIvPgo8L3N2Zz4K 2x",
+         "1x.gif", 1.0, -1},
+        {2.0, -1, "1x.gif",
+         "data:image/"
+         "svg+xml;base64,"
+         "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMDAiI"
+         "GhlaWdodD0iMTAwIj4KCTxyZWN0IHdpZHRoPSIxMDAiIGhlaWdodD0iMTAwIiBmaWxsPS"
+         "JncmVlbiIvPgo8L3N2Zz4K 2x",
+         "1x.gif", 1.0, -1},
+        {2.0, -1, "1x.svg#red", "1x.svg#green 2x", "1x.svg#red", 1.0, -1},
+        {2.0, -1, "", "1x.svg#red 1x, 1x.svg#green 2x", "1x.svg#red", 1.0, -1},
+        {1.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+        {1.0, 400, "", "400.gif 400pw, 6000.gif 6000w", "6000.gif", 15.0, 6000},
+        {1.0, 400, "fallback.gif", "400.gif 400pw", "fallback.gif", 1.0, -1},
+        {1.0, 400, "fallback.gif", "400.gif +400w", "fallback.gif", 1.0, -1},
+        {1.0, 400, "", "400.gif 400w 400h, 6000.gif 6000w", "400.gif", 1.0,
+         400},
+        {4.0, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+        {3.8, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+        {0.9, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
+        {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 400w", "400.gif", 0.5, 400},
+        {0.9, 800, "src.gif", "1x.gif 0.6x, 400.gif 400w", "400.gif", 0.5, 400},
+        {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 720w", "400.gif", 0.9, 720},
+        {0.9, 800, "src.gif", "1x.gif 1x, 400.gif 719w", "400.gif",
+         719.0 / 800.0, 719},
+        {2.0, 800, "src.gif", "400.gif 400w", "400.gif", 0.5, 400},
+        {1.0, 400, "src.gif", "800.gif 800w", "800.gif", 2.0, 800},
+        {1.0, 400, "src.gif", "0.gif 0w, 800.gif 800w", "800.gif", 2.0, 800},
+        {1.0, 400, "src.gif", "0.gif 0w, 2x.gif 2x", "src.gif", 1.0, -1},
+        {1.0, 400, "src.gif", "800.gif 2x, 1600.gif 1600w", "800.gif", 2.0, -1},
+        {1.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
+        {2.0, 400, "", "400.gif 400w, 2x.gif 2x", "400.gif", 1.0, 400},
+        {1.0, 0, "", "400.gif 400w, 6000.gif 6000w", "400.gif",
+         std::numeric_limits<float>::infinity(), 400},
+        {2.0, -1, "", ", 1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+        {1.0, -1, "", ",1x.gif 1x, 2x.gif 2x", "1x.gif", 1.0, -1},
+        {1.0, -1, "", ",1x.gif 1.x , 2x.gif 2x", "2x.gif", 2.0, -1},
+        {1.2, -1, "", ",1x.gif 1x, 1.4x.gif 1.4x, 2x.gif 2x", "1x.gif", 1.0,
+         -1},
+        {1.0, -1, "", "inf.gif 0.00000000001x", "inf.gif", 1e-11, -1},
+        {1.0, -1, "", "data:,a ( , data:,b 1x, ), data:,c", "data:,c", 1.0, -1},
+        {1.0, 1, "", "data:,a 1w 1h", "data:,a", 1.0, 1},
+        {1.0, -1, "",
+         ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x", "2x.gif",
+         2.0, -1},
+        {2.0, -1, "",
+         ",1x.gif 1x future-descriptor(3x, 4h, whatever), 2x.gif 2x", "2x.gif",
+         2.0, -1},
+        {1.0, -1, "", "data:,a 1 w", "", 1.0, -1},
+        {1.0, -1, "", "data:,a 1  w", "", 1.0, -1},
+        {1.0, -1, "", "data:,a +1x", "", 1.0, -1},
+        {1.0, -1, "", "data:,a   +1x", "", 1.0, -1},
+        {1.0, -1, "", "data:,a 1.0x", "data:,a", 1.0, -1},
+        {1.0, -1, "", "1%20and%202.gif 1x", "1%20and%202.gif", 1.0, -1},
+        {1.0, 700, "", "data:,a 0.5x, data:,b 1400w", "data:,a", 0.5, -1},
+    }));
+
+class MaxDensityHTMLSrcsetParserTest : public HTMLSrcsetParserTest {};
+
+TEST_P(MaxDensityHTMLSrcsetParserTest, MaxDensityEnabled) {
   test::TaskEnvironment task_environment;
   ScopedSrcsetMaxDensityForTest srcset_max_density(true);
-  SrcsetParserTestCase test_cases[] = {
-      {10.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1},
-      {2.5, -1, "src.gif", "1.5x.gif 1.5x, 3x.gif 3x", "3x.gif", 3.0, -1},
-      {4.0, 400, "", "400.gif 400w, 1000.gif 1000w", "1000.gif", 2.5, 1000},
-      {0, 0, nullptr, nullptr, nullptr,
-       0}  // Do not remove the terminator line.
-  };
+  const SrcsetParserTestCase test = GetParam();
+  ImageCandidate candidate = BestFitSourceForImageAttributes(
+      test.device_scale_factor, test.effective_size, test.src_input,
+      test.srcset_input);
 
-  for (unsigned i = 0; test_cases[i].src_input; ++i) {
-    SrcsetParserTestCase test = test_cases[i];
-    ImageCandidate candidate = BestFitSourceForImageAttributes(
-        test.device_scale_factor, test.effective_size, test.src_input,
-        test.srcset_input);
-    ASSERT_EQ(test.output_density, candidate.Density());
-    ASSERT_EQ(test.output_resource_width, candidate.GetResourceWidth());
-    ASSERT_EQ(test.output_url, candidate.ToString().Ascii());
-  }
+  EXPECT_EQ(test.output_density, candidate.Density());
+  EXPECT_EQ(test.output_resource_width, candidate.GetResourceWidth());
+  EXPECT_EQ(test.output_url, candidate.ToString().Ascii());
 }
 
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    MaxDensityHTMLSrcsetParserTest,
+    testing::ValuesIn(std::vector<SrcsetParserTestCase>{
+        {10.0, -1, "src.gif", "2x.gif 2e1x", "2x.gif", 20.0, -1},
+        {2.5, -1, "src.gif", "1.5x.gif 1.5x, 3x.gif 3x", "3x.gif", 3.0, -1},
+        {4.0, 400, "", "400.gif 400w, 1000.gif 1000w", "1000.gif", 2.5, 1000},
+    }));
+
+class SrcsetSelectionMatchesImageSetDisabledHTMLSrcsetParserTest
+    : public HTMLSrcsetParserTest {};
+
+TEST_P(SrcsetSelectionMatchesImageSetDisabledHTMLSrcsetParserTest,
+       SrcsetSelectionMatchesImageSetDisabled) {
+  test::TaskEnvironment task_environment;
+  ScopedSrcsetSelectionMatchesImageSetForTest enabled(false);
+  const SrcsetParserTestCase test = GetParam();
+  ImageCandidate candidate = BestFitSourceForImageAttributes(
+      test.device_scale_factor, test.effective_size, test.src_input,
+      test.srcset_input);
+
+  EXPECT_EQ(test.output_density, candidate.Density());
+  EXPECT_EQ(test.output_resource_width, candidate.GetResourceWidth());
+  EXPECT_EQ(test.output_url, candidate.ToString().Ascii());
+}
+
+INSTANTIATE_TEST_SUITE_P(
+    ,
+    SrcsetSelectionMatchesImageSetDisabledHTMLSrcsetParserTest,
+    testing::ValuesIn(std::vector<SrcsetParserTestCase>{
+        {2.0, -1, "src.gif", "2x.gif 2e1x", "src.gif", 1.0, -1},
+        {3.8, 400, "", "400.gif 400w, 6000.gif 6000w", "400.gif", 1.0, 400},
+    }));
+
 }  // namespace blink
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 b18575c..5245bd4b 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
@@ -39,12 +39,45 @@
 #include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h"
 #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
 #include "third_party/blink/renderer/platform/text/writing_mode.h"
+#include "third_party/blink/renderer/platform/text/writing_mode_utils.h"
 #include "third_party/blink/renderer/platform/wtf/vector.h"
 
 namespace blink {
 
 namespace {
 
+template <typename Value>
+class PhysicalToFlex {
+  STACK_ALLOCATED();
+
+ public:
+  PhysicalToFlex(WritingDirectionMode writing_direction,
+                 bool is_column,
+                 Value top,
+                 Value right,
+                 Value bottom,
+                 Value left)
+      : logical_(writing_direction, top, right, bottom, left),
+        is_column_(is_column) {}
+
+  Value MainStart() const {
+    return is_column_ ? logical_.BlockStart() : logical_.InlineStart();
+  }
+  Value MainEnd() const {
+    return is_column_ ? logical_.BlockEnd() : logical_.InlineEnd();
+  }
+  Value CrossStart() const {
+    return is_column_ ? logical_.InlineStart() : logical_.BlockStart();
+  }
+  Value CrossEnd() const {
+    return is_column_ ? logical_.InlineEnd() : logical_.BlockEnd();
+  }
+
+ private:
+  PhysicalToLogical<Value> logical_;
+  bool is_column_;
+};
+
 class BaselineAccumulator {
   STACK_ALLOCATED();
 
@@ -603,6 +636,11 @@
         border_padding_in_child_writing_mode.ConvertToPhysical(
             child_style.GetWritingDirection()));
 
+    const unsigned main_axis_auto_margin_count =
+        is_horizontal_flow_ ? child_style.MarginLeft().IsAuto() +
+                                  child_style.MarginRight().IsAuto()
+                            : child_style.MarginTop().IsAuto() +
+                                  child_style.MarginBottom().IsAuto();
     const LayoutUnit main_axis_border_padding =
         is_horizontal_flow_ ? physical_border_padding.HorizontalSum()
                             : physical_border_padding.VerticalSum();
@@ -886,12 +924,12 @@
         /* is_parallel_context */ !is_column_, is_last_baseline,
         /* is_flipped */ is_wrap_reverse);
     algorithm_
-        .emplace_back(child.Style(), flex_base_content_size,
-                      min_max_sizes_in_main_axis_direction,
-                      main_axis_border_padding, physical_child_margins,
-                      scrollbars, baseline_writing_mode, baseline_group,
-                      is_initial_block_size_indefinite,
-                      is_used_flex_basis_indefinite, depends_on_min_max_sizes)
+        .emplace_back(
+            child.Style(), main_axis_auto_margin_count, flex_base_content_size,
+            min_max_sizes_in_main_axis_direction, main_axis_border_padding,
+            physical_child_margins, scrollbars, baseline_writing_mode,
+            baseline_group, is_initial_block_size_indefinite,
+            is_used_flex_basis_indefinite, depends_on_min_max_sizes)
         .ng_input_node_ = child;
     // Save the layout result so that we can maybe reuse it later.
     if (layout_result && !is_main_axis_inline_axis) {
@@ -1123,17 +1161,18 @@
       //    fragment)
       if (DoesItemStretch(flex_item.ng_input_node_) &&
           flex_item.layout_result_) {
-        DCHECK(!flex_item.MainAxisIsInlineAxis());
-        BoxStrut border = ComputeBorders(child_space, flex_item.ng_input_node_);
-        BoxStrut padding =
-            ComputePadding(child_space, flex_item.ng_input_node_.Style());
+        const auto& item_style = flex_item.ng_input_node_.Style();
+        DCHECK_NE(is_horizontal_flow_, item_style.IsHorizontalWritingMode());
+        const BoxStrut border_padding =
+            ComputeBorders(child_space, flex_item.ng_input_node_) +
+            ComputePadding(child_space, item_style);
         if (flex_item.ng_input_node_.IsReplaced()) {
           LogicalSize logical_border_box_size = ComputeReplacedSize(
-              flex_item.ng_input_node_, child_space, border + padding);
+              flex_item.ng_input_node_, child_space, border_padding);
           flex_item.cross_axis_size_ = logical_border_box_size.inline_size;
         } else {
           flex_item.cross_axis_size_ = ComputeInlineSizeForFragment(
-              child_space, flex_item.ng_input_node_, border + padding);
+              child_space, flex_item.ng_input_node_, border_padding);
         }
       } else if (is_computing_multiline_column_intrinsic_size) {
         flex_item.cross_axis_size_ = *flex_item.max_content_contribution_;
@@ -1155,6 +1194,8 @@
         line->remaining_free_space_;
     flex_line_outputs->back().sum_hypothetical_main_size =
         line->sum_hypothetical_main_size_;
+    flex_line_outputs->back().main_axis_auto_margin_count =
+        line->main_axis_auto_margin_count_;
     flex_line_outputs->back().line_cross_size = line->cross_axis_extent_;
     flex_line_outputs->back().major_baseline = line->max_major_ascent_;
     flex_line_outputs->back().minor_baseline = line->max_minor_ascent_;
@@ -1338,7 +1379,7 @@
   const LayoutUnit space_between_lines =
       FlexibleBoxAlgorithm::ContentDistributionSpaceBetweenChildren(
           cross_axis_free_space, align_content, num_lines);
-  LayoutUnit cross_axis_offset =
+  LayoutUnit line_cross_axis_offset =
       (is_column_ ? BorderScrollbarPadding().inline_start
                   : BorderScrollbarPadding().block_start) +
       InitialContentPositionOffset(align_content, ContentPosition::kStart,
@@ -1351,7 +1392,7 @@
   for (wtf_size_t flex_line_idx = 0; flex_line_idx < flex_line_outputs->size();
        ++flex_line_idx) {
     NGFlexLine& line_output = (*flex_line_outputs)[flex_line_idx];
-    line_output.cross_axis_offset = cross_axis_offset;
+    line_output.cross_axis_offset = line_cross_axis_offset;
 
     bool is_first_line = flex_line_idx == 0;
     bool is_last_line = flex_line_idx == flex_line_outputs->size() - 1;
@@ -1360,16 +1401,29 @@
                                           is_last_line);
     }
 
+    const bool should_apply_main_axis_auto_margin =
+        line_output.main_axis_auto_margin_count &&
+        line_output.main_axis_free_space > LayoutUnit();
+
+    const LayoutUnit main_axis_free_space =
+        should_apply_main_axis_auto_margin ? LayoutUnit()
+                                           : line_output.main_axis_free_space;
+    const LayoutUnit main_axis_auto_margin =
+        should_apply_main_axis_auto_margin
+            ? line_output.main_axis_free_space /
+                  line_output.main_axis_auto_margin_count
+            : LayoutUnit();
+
     const wtf_size_t line_items_size = line_output.line_items.size();
     const LayoutUnit space_between_items =
         FlexibleBoxAlgorithm::ContentDistributionSpaceBetweenChildren(
-            line_output.main_axis_free_space, justify_content, line_items_size);
+            main_axis_free_space, justify_content, line_items_size);
     LayoutUnit main_axis_offset =
         (is_column_ ? BorderScrollbarPadding().block_start
                     : BorderScrollbarPadding().inline_start) +
         InitialContentPositionOffset(justify_content, safe_justify_position,
-                                     line_output.main_axis_free_space,
-                                     line_items_size, is_reverse_direction);
+                                     main_axis_free_space, line_items_size,
+                                     is_reverse_direction);
 
     for (wtf_size_t flex_item_idx = 0;
          flex_item_idx < line_output.line_items.size(); ++flex_item_idx) {
@@ -1393,10 +1447,10 @@
 
       flex_item.has_descendant_that_depends_on_percentage_block_size =
           layout_result->HasDescendantThatDependsOnPercentageBlockSize();
-      flex_item.margin_block_end = item->MarginBlockEnd();
+
+      const auto& item_style = flex_item.Style();
 
       if (should_propagate_row_break_values) {
-        const auto& item_style = flex_item.Style();
         auto item_break_before = JoinFragmentainerBreakValues(
             item_style.BreakBefore(), layout_result->InitialBreakBefore());
         auto item_break_after = JoinFragmentainerBreakValues(
@@ -1438,39 +1492,78 @@
       const LayoutUnit cross_axis_size =
           is_column_ ? fragment.InlineSize() : fragment.BlockSize();
 
-      main_axis_offset += item->FlowAwareMarginStart();
-      const LayoutUnit item_cross_axis_offset =
-          cross_axis_offset +
+      PhysicalBoxStrut physical_margins = item->physical_margins_;
+      const PhysicalToFlex<LayoutUnit&> margin(
+          writing_direction, is_column_, physical_margins.top,
+          physical_margins.right, physical_margins.bottom,
+          physical_margins.left);
+
+      // Apply any auto margins.
+      {
+        const PhysicalToFlex is_margin_auto(writing_direction, is_column_,
+                                            item_style.MarginTop().IsAuto(),
+                                            item_style.MarginRight().IsAuto(),
+                                            item_style.MarginBottom().IsAuto(),
+                                            item_style.MarginLeft().IsAuto());
+
+        // Cross-axis margins are handled in the typical way.
+        const LayoutUnit margin_space =
+            (line_output.line_cross_size - margin.CrossStart() -
+             cross_axis_size - margin.CrossEnd())
+                .ClampNegativeToZero();
+        if (is_margin_auto.CrossStart() && is_margin_auto.CrossEnd()) {
+          margin.CrossStart() = margin_space / 2;
+          margin.CrossEnd() = margin_space / 2;
+        } else if (is_margin_auto.CrossStart()) {
+          margin.CrossStart() = margin_space;
+        } else if (is_margin_auto.CrossEnd()) {
+          margin.CrossEnd() = margin_space;
+        }
+
+        // Main-axis margins are distributed to evenly across the whole line.
+        if (is_margin_auto.MainStart()) {
+          margin.MainStart() = main_axis_auto_margin;
+        }
+        if (is_margin_auto.MainEnd()) {
+          margin.MainEnd() = main_axis_auto_margin;
+        }
+      }
+
+      main_axis_offset += margin.MainStart();
+      const LayoutUnit cross_axis_offset =
+          line_cross_axis_offset + margin.CrossStart() +
           item->CrossAxisOffset(line_output, cross_axis_size);
 
       const LogicalOffset offset =
-          is_column_ ? LogicalOffset(item_cross_axis_offset, main_axis_offset)
-                     : LogicalOffset(main_axis_offset, item_cross_axis_offset);
+          is_column_ ? LogicalOffset(cross_axis_offset, main_axis_offset)
+                     : LogicalOffset(main_axis_offset, cross_axis_offset);
       flex_item.offset = offset;
 
-      main_axis_offset += item->FlexedBorderBoxSize() +
-                          item->FlowAwareMarginEnd() + space_between_items +
-                          algorithm_.gap_between_items_;
+      main_axis_offset += item->FlexedBorderBoxSize() + margin.MainEnd() +
+                          space_between_items + algorithm_.gap_between_items_;
+
+      const BoxStrut logical_margins =
+          physical_margins.ConvertToLogical(writing_direction);
 
       if (!InvolvedInBlockFragmentation(container_builder_)) {
-        container_builder_.AddResult(
-            *layout_result, offset,
-            item->physical_margins_.ConvertToLogical(writing_direction));
+        container_builder_.AddResult(*layout_result, offset, logical_margins);
         baseline_accumulator.AccumulateItem(fragment, offset.block_offset,
                                             is_first_line, is_last_line);
       } else {
         flex_item.total_remaining_block_size = fragment.BlockSize();
+        flex_item.margin_block_end = logical_margins.block_end;
       }
 
       if (PropagateFlexItemInfo(item, flex_line_idx, offset,
-                                physical_fragment.Size()) ==
+                                physical_fragment.Size(), physical_margins) ==
           LayoutResult::kNeedsRelayoutWithNoChildScrollbarChanges) {
         status = LayoutResult::kNeedsRelayoutWithNoChildScrollbarChanges;
       }
     }
 
-    cross_axis_offset += line_output.line_cross_size + space_between_lines +
-                         algorithm_.gap_between_lines_;
+    line_cross_axis_offset += line_output.line_cross_size +
+                              space_between_lines +
+                              algorithm_.gap_between_lines_;
   }
 
   if (auto first_baseline = baseline_accumulator.FirstBaseline())
@@ -2031,7 +2124,8 @@
     FlexItem* flex_item,
     wtf_size_t flex_line_idx,
     LogicalOffset offset,
-    PhysicalSize fragment_size) {
+    PhysicalSize fragment_size,
+    const PhysicalBoxStrut& physical_margins) {
   DCHECK(flex_item);
   LayoutResult::EStatus status = LayoutResult::kSuccess;
 
@@ -2049,7 +2143,7 @@
         offset.ConvertToPhysical(GetConstraintSpace().GetWritingDirection(),
                                  flexbox_size, item_rect.size);
     // devtools uses margin box.
-    item_rect.Expand(flex_item->physical_margins_);
+    item_rect.Expand(physical_margins);
     DCHECK_GE(layout_info_for_devtools_->lines.size(), 1u);
     DevtoolsFlexInfo::Item item(
         item_rect, flex_item->MarginBoxAscent(
diff --git a/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.h b/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.h
index 725feb23..12c107c 100644
--- a/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/flex/flex_layout_algorithm.h
@@ -81,10 +81,12 @@
       HeapVector<NGFlexLine>* flex_line_outputs,
       Vector<EBreakBetween>* row_break_between_outputs,
       FlexBreakTokenData::FlexBreakBeforeRow* break_before_row);
-  LayoutResult::EStatus PropagateFlexItemInfo(FlexItem* flex_item,
-                                              wtf_size_t flex_line_idx,
-                                              LogicalOffset offset,
-                                              PhysicalSize fragment_size);
+  LayoutResult::EStatus PropagateFlexItemInfo(
+      FlexItem* flex_item,
+      wtf_size_t flex_line_idx,
+      LogicalOffset offset,
+      PhysicalSize fragment_size,
+      const PhysicalBoxStrut& physical_margins);
   void LayoutColumnReverse(LayoutUnit main_axis_content_size);
 
   // This is same method as FlexItem but we need that logic before FlexItem is
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 ded8887..5f53a5b 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
@@ -77,6 +77,7 @@
 
 FlexItem::FlexItem(const FlexibleBoxAlgorithm* algorithm,
                    const ComputedStyle& style,
+                   unsigned main_axis_auto_margin_count,
                    LayoutUnit flex_base_content_size,
                    MinMaxSizes min_max_main_sizes,
                    LayoutUnit main_axis_border_padding,
@@ -91,6 +92,7 @@
       style_(style),
       flex_grow_(style.ResolvedFlexGrow(algorithm_->StyleRef())),
       flex_shrink_(style.ResolvedFlexShrink(algorithm_->StyleRef())),
+      main_axis_auto_margin_count_(main_axis_auto_margin_count),
       flex_base_content_size_(flex_base_content_size),
       min_max_main_sizes_(min_max_main_sizes),
       hypothetical_main_content_size_(
@@ -109,36 +111,6 @@
       << "Use LayoutUnit::Max() for no max size";
 }
 
-bool FlexItem::MainAxisIsInlineAxis() const {
-  return algorithm_->IsHorizontalFlow() == style_->IsHorizontalWritingMode();
-}
-
-LayoutUnit FlexItem::FlowAwareMarginStart() const {
-  switch (algorithm_->MainAxisDirection()) {
-    case PhysicalDirection::kUp:
-      return physical_margins_.bottom;
-    case PhysicalDirection::kRight:
-      return physical_margins_.left;
-    case PhysicalDirection::kDown:
-      return physical_margins_.top;
-    case PhysicalDirection::kLeft:
-      return physical_margins_.right;
-  }
-}
-
-LayoutUnit FlexItem::FlowAwareMarginEnd() const {
-  switch (algorithm_->MainAxisDirection()) {
-    case PhysicalDirection::kUp:
-      return physical_margins_.top;
-    case PhysicalDirection::kRight:
-      return physical_margins_.right;
-    case PhysicalDirection::kDown:
-      return physical_margins_.bottom;
-    case PhysicalDirection::kLeft:
-      return physical_margins_.left;
-  }
-}
-
 LayoutUnit FlexItem::FlowAwareMarginBefore() const {
   switch (algorithm_->CrossAxisDirection()) {
     case PhysicalDirection::kDown:
@@ -167,12 +139,6 @@
   NOTREACHED();
 }
 
-LayoutUnit FlexItem::MarginBlockEnd() const {
-  BoxStrut margins = physical_margins_.ConvertToLogical(
-      algorithm_->Style()->GetWritingDirection());
-  return margins.block_end;
-}
-
 LayoutUnit FlexItem::MainAxisMarginExtent() const {
   return algorithm_->IsHorizontalFlow() ? physical_margins_.HorizontalSum()
                                         : physical_margins_.VerticalSum();
@@ -207,70 +173,10 @@
   return FlexibleBoxAlgorithm::AlignmentForChild(*algorithm_->Style(), *style_);
 }
 
-void FlexItem::UpdateAutoMarginsInMainAxis(LayoutUnit auto_margin_offset) {
-  DCHECK_GE(auto_margin_offset, LayoutUnit());
-
-  if (algorithm_->IsHorizontalFlow()) {
-    if (style_->MarginLeft().IsAuto()) {
-      physical_margins_.left = auto_margin_offset;
-    }
-    if (style_->MarginRight().IsAuto()) {
-      physical_margins_.right = auto_margin_offset;
-    }
-  } else {
-    if (style_->MarginTop().IsAuto()) {
-      physical_margins_.top = auto_margin_offset;
-    }
-    if (style_->MarginBottom().IsAuto()) {
-      physical_margins_.bottom = auto_margin_offset;
-    }
-  }
-}
-
-bool FlexItem::UpdateAutoMarginsInCrossAxis(
-    LayoutUnit available_alignment_space) {
-  DCHECK_GE(available_alignment_space, LayoutUnit());
-
-  bool is_horizontal = algorithm_->IsHorizontalFlow();
-  const Length& top_or_left =
-      is_horizontal ? style_->MarginTop() : style_->MarginLeft();
-  const Length& bottom_or_right =
-      is_horizontal ? style_->MarginBottom() : style_->MarginRight();
-  if (top_or_left.IsAuto() && bottom_or_right.IsAuto()) {
-    if (is_horizontal) {
-      physical_margins_.top = available_alignment_space / 2;
-      physical_margins_.bottom = available_alignment_space / 2;
-    } else {
-      physical_margins_.left = available_alignment_space / 2;
-      physical_margins_.right = available_alignment_space / 2;
-    }
-    return true;
-  }
-
-  if (top_or_left.IsAuto()) {
-    if (is_horizontal)
-      physical_margins_.top = available_alignment_space;
-    else
-      physical_margins_.left = available_alignment_space;
-    return true;
-  }
-  if (bottom_or_right.IsAuto()) {
-    if (is_horizontal)
-      physical_margins_.bottom = available_alignment_space;
-    else
-      physical_margins_.right = available_alignment_space;
-    return true;
-  }
-  return false;
-}
-
 LayoutUnit FlexItem::CrossAxisOffset(const NGFlexLine& line,
                                      LayoutUnit cross_axis_size) {
   LayoutUnit available_space =
       line.line_cross_size - (CrossAxisMarginExtent() + cross_axis_size);
-  if (UpdateAutoMarginsInCrossAxis(available_space.ClampNegativeToZero())) {
-    return FlowAwareMarginBefore();
-  }
 
   const auto* parent_style = algorithm_->Style();
   const bool is_webkit_box = parent_style->IsDeprecatedWebkitBox();
@@ -297,8 +203,7 @@
     baseline_offset =
         is_major ? baseline_delta : available_space - baseline_delta;
   }
-  return FlowAwareMarginBefore() +
-         FlexItem::AlignmentOffset(available_space, position, baseline_offset,
+  return FlexItem::AlignmentOffset(available_space, position, baseline_offset,
                                    is_wrap_reverse);
 }
 
@@ -458,35 +363,6 @@
   return !total_violation;
 }
 
-LayoutUnit FlexLine::ApplyMainAxisAutoMarginAdjustment() {
-  if (remaining_free_space_ <= LayoutUnit())
-    return LayoutUnit();
-
-  int number_of_auto_margins = 0;
-  bool is_horizontal = algorithm_->IsHorizontalFlow();
-  for (const auto& line_item : line_items_) {
-    const ComputedStyle& style = *line_item.style_;
-    if (is_horizontal) {
-      if (style.MarginLeft().IsAuto())
-        ++number_of_auto_margins;
-      if (style.MarginRight().IsAuto())
-        ++number_of_auto_margins;
-    } else {
-      if (style.MarginTop().IsAuto())
-        ++number_of_auto_margins;
-      if (style.MarginBottom().IsAuto())
-        ++number_of_auto_margins;
-    }
-  }
-  if (!number_of_auto_margins)
-    return LayoutUnit();
-
-  LayoutUnit size_of_auto_margin =
-      remaining_free_space_ / number_of_auto_margins;
-  remaining_free_space_ = LayoutUnit();
-  return size_of_auto_margin;
-}
-
 void FlexLine::ComputeLineItemsPosition() {
   const auto& style = algorithm_->StyleRef();
   const bool is_wrap_reverse = style.FlexWrap() == EFlexWrap::kWrapReverse;
@@ -500,8 +376,6 @@
       container_main_inner_size_ - total_item_size -
       (line_items_.size() - 1) * algorithm_->gap_between_items_;
 
-  const LayoutUnit auto_margin_offset = ApplyMainAxisAutoMarginAdjustment();
-
   LayoutUnit max_major_descent = LayoutUnit::Min();
   LayoutUnit max_minor_descent = LayoutUnit::Min();
 
@@ -509,8 +383,6 @@
   for (wtf_size_t i = 0; i < line_items_.size(); ++i) {
     FlexItem& flex_item = line_items_[i];
 
-    flex_item.UpdateAutoMarginsInMainAxis(auto_margin_offset);
-
     LayoutUnit child_cross_axis_margin_box_extent;
     // TODO(crbug.com/1272533): We may not have a layout-result during min/max
     // calculations. This is incorrect, and we should produce a layout-result
@@ -613,10 +485,11 @@
 
 FlexLine* FlexibleBoxAlgorithm::ComputeNextFlexLine() {
   LayoutUnit sum_flex_base_size;
+  LayoutUnit sum_hypothetical_main_size;
   double total_flex_grow = 0;
   double total_flex_shrink = 0;
   double total_weighted_flex_shrink = 0;
-  LayoutUnit sum_hypothetical_main_size;
+  unsigned main_axis_auto_margin_count = 0;
 
   bool line_has_in_flow_item = false;
 
@@ -634,12 +507,13 @@
     line_has_in_flow_item = true;
     sum_flex_base_size +=
         flex_item.FlexBaseMarginBoxSize() + gap_between_items_;
+    sum_hypothetical_main_size +=
+        flex_item.HypotheticalMainAxisMarginBoxSize() + gap_between_items_;
     total_flex_grow += flex_item.flex_grow_;
     total_flex_shrink += flex_item.flex_shrink_;
     total_weighted_flex_shrink +=
         flex_item.flex_shrink_ * flex_item.flex_base_content_size_;
-    sum_hypothetical_main_size +=
-        flex_item.HypotheticalMainAxisMarginBoxSize() + gap_between_items_;
+    main_axis_auto_margin_count += flex_item.main_axis_auto_margin_count_;
   }
   if (line_has_in_flow_item) {
     // We added a gap after every item but there shouldn't be one after the last
@@ -654,8 +528,9 @@
   if (next_item_index_ > start_index) {
     return &flex_lines_.emplace_back(
         this, FlexItemVectorView(&all_items_, start_index, next_item_index_),
-        sum_flex_base_size, total_flex_grow, total_flex_shrink,
-        total_weighted_flex_shrink, sum_hypothetical_main_size);
+        sum_flex_base_size, sum_hypothetical_main_size, total_flex_grow,
+        total_flex_shrink, total_weighted_flex_shrink,
+        main_axis_auto_margin_count);
   }
   return nullptr;
 }
@@ -717,13 +592,6 @@
   return min.HasAuto();
 }
 
-PhysicalDirection FlexibleBoxAlgorithm::MainAxisDirection() const {
-  const WritingDirectionMode writing_direction = style_->GetWritingDirection();
-  return style_->ResolvedIsColumnFlexDirection()
-             ? writing_direction.BlockEnd()
-             : writing_direction.InlineEnd();
-}
-
 PhysicalDirection FlexibleBoxAlgorithm::CrossAxisDirection() const {
   const WritingDirectionMode writing_direction = style_->GetWritingDirection();
   return style_->ResolvedIsColumnFlexDirection() ? writing_direction.InlineEnd()
@@ -846,7 +714,15 @@
                                              : logical.BlockEnd();
   }
 
-  if (align == ItemPosition::kBaseline) {
+  if (flexbox_style.FlexWrap() == EFlexWrap::kWrapReverse) {
+    if (align == ItemPosition::kFlexStart) {
+      align = ItemPosition::kFlexEnd;
+    } else if (align == ItemPosition::kFlexEnd) {
+      align = ItemPosition::kFlexStart;
+    }
+  }
+
+  if (!child_style.HasOutOfFlowPosition()) {
     if (IsHorizontalFlow(flexbox_style)) {
       if (child_style.MarginTop().IsAuto() ||
           child_style.MarginBottom().IsAuto()) {
@@ -860,13 +736,6 @@
     }
   }
 
-  if (flexbox_style.FlexWrap() == EFlexWrap::kWrapReverse) {
-    if (align == ItemPosition::kFlexStart)
-      align = ItemPosition::kFlexEnd;
-    else if (align == ItemPosition::kFlexEnd)
-      align = ItemPosition::kFlexStart;
-  }
-
   return align;
 }
 
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 507a2c35..13dc184a3 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
@@ -75,6 +75,7 @@
   //   |min_max_cross_sizes| does include cross_axis_border_padding.
   FlexItem(const FlexibleBoxAlgorithm*,
            const ComputedStyle& style,
+           unsigned main_axis_auto_margin_count,
            LayoutUnit flex_base_content_size,
            MinMaxSizes min_max_main_sizes,
            LayoutUnit main_axis_border_padding,
@@ -111,30 +112,16 @@
 
   ItemPosition Alignment() const;
 
-  bool MainAxisIsInlineAxis() const;
-
-  // Returns the main-start margin value.
-  LayoutUnit FlowAwareMarginStart() const;
-  // Returns the main-end margin value.
-  LayoutUnit FlowAwareMarginEnd() const;
   // Returns the cross-start margin value ignoring flex-wrap.
   LayoutUnit FlowAwareMarginBefore() const;
   // Returns the cross-end margin value ignoring flex-wrap.
   LayoutUnit FlowAwareMarginAfter() const;
-  // Returns the margin value on the block-end in the container writing-mode.
-  // This isn't aware of `flex-direction` and `flex-wrap`.
-  LayoutUnit MarginBlockEnd() const;
 
   LayoutUnit MainAxisMarginExtent() const;
   LayoutUnit CrossAxisMarginExtent() const;
 
   LayoutUnit MarginBoxAscent(bool is_last_baseline, bool is_wrap_reverse) const;
 
-  void UpdateAutoMarginsInMainAxis(LayoutUnit auto_margin_offset);
-
-  // Returns true if the margins were adjusted due to auto margin resolution.
-  bool UpdateAutoMarginsInCrossAxis(LayoutUnit available_alignment_space);
-
   LayoutUnit CrossAxisOffset(const NGFlexLine&, LayoutUnit cross_axis_size);
 
   static LayoutUnit AlignmentOffset(LayoutUnit available_free_space,
@@ -148,11 +135,12 @@
   Member<const ComputedStyle> style_;
   const float flex_grow_;
   const float flex_shrink_;
+  const unsigned main_axis_auto_margin_count_;
   const LayoutUnit flex_base_content_size_;
   const MinMaxSizes min_max_main_sizes_;
   const LayoutUnit hypothetical_main_content_size_;
   const LayoutUnit main_axis_border_padding_;
-  PhysicalBoxStrut physical_margins_;
+  const PhysicalBoxStrut physical_margins_;
   const BoxStrut scrollbars_;
   const WritingDirectionMode baseline_writing_direction_;
   const BaselineGroup baseline_group_;
@@ -213,17 +201,19 @@
   FlexLine(FlexibleBoxAlgorithm* algorithm,
            FlexItemVectorView line_items,
            LayoutUnit sum_flex_base_size,
+           LayoutUnit sum_hypothetical_main_size,
            double total_flex_grow,
            double total_flex_shrink,
            double total_weighted_flex_shrink,
-           LayoutUnit sum_hypothetical_main_size)
+           unsigned main_axis_auto_margin_count)
       : algorithm_(algorithm),
         line_items_(std::move(line_items)),
         sum_flex_base_size_(sum_flex_base_size),
+        sum_hypothetical_main_size_(sum_hypothetical_main_size),
         total_flex_grow_(total_flex_grow),
         total_flex_shrink_(total_flex_shrink),
         total_weighted_flex_shrink_(total_weighted_flex_shrink),
-        sum_hypothetical_main_size_(sum_hypothetical_main_size) {}
+        main_axis_auto_margin_count_(main_axis_auto_margin_count) {}
 
   FlexSign Sign() const {
     return sum_hypothetical_main_size_ < container_main_inner_size_
@@ -244,12 +234,6 @@
   // This modifies remaining_free_space.
   bool ResolveFlexibleLengths();
 
-  // Distributes remaining_free_space across the main axis auto margins
-  // of the flex items of this line and returns the amount that should be
-  // used for each auto margins. If there are no auto margins, leaves
-  // remaining_free_space unchanged.
-  LayoutUnit ApplyMainAxisAutoMarginAdjustment();
-
   // Computes & sets desired_position on the FlexItems on this line.
   // Before calling this function, the items need to be laid out with
   // flexed_content_size set as the override main axis size, and
@@ -259,13 +243,15 @@
 
   FlexibleBoxAlgorithm* algorithm_;
   FlexItemVectorView line_items_;
+
   const LayoutUnit sum_flex_base_size_;
+  const LayoutUnit sum_hypothetical_main_size_;
+
   double total_flex_grow_;
   double total_flex_shrink_;
   double total_weighted_flex_shrink_;
-  // The hypothetical main size of an item is the flex base size clamped
-  // according to its min and max main size properties
-  const LayoutUnit sum_hypothetical_main_size_;
+
+  const unsigned main_axis_auto_margin_count_;
 
   // This gets set by SetContainerMainInnerSize
   LayoutUnit container_main_inner_size_;
@@ -337,11 +323,6 @@
   bool IsMultiline() const { return style_->FlexWrap() != EFlexWrap::kNowrap; }
   static bool IsHorizontalFlow(const ComputedStyle&);
   static bool IsColumnFlow(const ComputedStyle&);
-  // Returns the physical direction of the main axis.
-  // This function is aware of `writing-mode`, `direction`, and
-  // `flex-direction`, but assumes `flex-direction:column-reverse` is same as
-  // `flex-direction:column`.
-  PhysicalDirection MainAxisDirection() const;
   // Returns the physical direction of the cross axis.
   // This function is aware of `writing-mode`, `flex-direction`, and
   // no `flex-wrap`.
diff --git a/third_party/blink/renderer/core/layout/flex/ng_flex_line.h b/third_party/blink/renderer/core/layout/flex/ng_flex_line.h
index 2f5b4ed..652f1ad 100644
--- a/third_party/blink/renderer/core/layout/flex/ng_flex_line.h
+++ b/third_party/blink/renderer/core/layout/flex/ng_flex_line.h
@@ -47,6 +47,7 @@
   void Trace(Visitor* visitor) const { visitor->Trace(line_items); }
 
   LayoutUnit main_axis_free_space;
+  unsigned main_axis_auto_margin_count;
   LayoutUnit sum_hypothetical_main_size;
   LayoutUnit line_cross_size;
   LayoutUnit cross_axis_offset;
diff --git a/third_party/blink/renderer/core/loader/document_loader.cc b/third_party/blink/renderer/core/loader/document_loader.cc
index ccc8243..204ad55 100644
--- a/third_party/blink/renderer/core/loader/document_loader.cc
+++ b/third_party/blink/renderer/core/loader/document_loader.cc
@@ -2205,6 +2205,10 @@
   if (commit_reason_ != CommitReason::kRegular)
     return;
 
+  if (auto* owner = DynamicTo<HTMLFrameOwnerElement>(frame_->Owner()); owner) {
+    owner->UpdateDeferredFetchPolicy();
+  }
+
   // When committing a new document, the FrameScheduler might need to carry over
   // the previous document's FrameScheduler's `UnreportedTaskTime()`, as that
   // value should be aggregated across all documents that ever committed in the
diff --git a/third_party/blink/renderer/core/timing/responsiveness_metrics.h b/third_party/blink/renderer/core/timing/responsiveness_metrics.h
index 12793b8..f5b2535 100644
--- a/third_party/blink/renderer/core/timing/responsiveness_metrics.h
+++ b/third_party/blink/renderer/core/timing/responsiveness_metrics.h
@@ -227,11 +227,6 @@
   HashMap<int, InteractionInfo, IntWithZeroKeyHashTraits<int>>
       key_code_to_interaction_info_map_;
 
-  // Whether we are composing or not. When we are not composing, we set
-  // interactionId for keydown and keyup events. When we are composing, we set
-  // interactionId for input events.
-  bool composition_started_ = false;
-
   enum CompositionState {
     kNonComposition,
     kCompositionContinueOngoingInteraction,
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc
index 36feedf..282a83f 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.cc
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -6476,44 +6476,6 @@
   return children_dirty_;
 }
 
-#if DCHECK_IS_ON()
-void AXObject::CheckIncludedObjectConnectedToRoot() const {
-  if (!IsIncludedInTree() || IsRoot()) {
-    return;
-  }
-
-  const AXObject* included_child = this;
-  const AXObject* ancestor = nullptr;
-  const AXObject* included_parent = nullptr;
-  for (ancestor = ParentObject(); ancestor;
-       ancestor = ancestor->ParentObject()) {
-    if (ancestor->IsIncludedInTree()) {
-      included_parent = ancestor;
-      if (included_parent->CachedChildrenIncludingIgnored().Find(
-              included_child) == kNotFound) {
-        if (AXObject* parent_for_repair = ComputeParent()) {
-          parent_for_repair->CheckIncludedObjectConnectedToRoot();
-        }
-
-        NOTREACHED() << "Cannot find included child in parents children:\n"
-                     << "\n* Child: " << included_child
-                     << "\n* Parent:  " << included_parent
-                     << "\n--------------\n"
-                     << included_parent->GetAXTreeForThis();
-      }
-      if (included_parent->IsRoot()) {
-        return;
-      }
-      included_child = included_parent;
-    }
-  }
-
-  NOTREACHED() << "Did not find included parent path to root:"
-               << "\n* Last found included parent: " << included_parent
-               << "\n* Current object in tree: " << GetAXTreeForThis();
-}
-#endif
-
 void AXObject::SetNeedsToUpdateChildren(bool update) {
   CHECK(AXObjectCache().lifecycle().StateAllowsAXObjectsToBeDirtied())
       << AXObjectCache();
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.h b/third_party/blink/renderer/modules/accessibility/ax_object.h
index 92d0d7a..9671ff1 100644
--- a/third_party/blink/renderer/modules/accessibility/ax_object.h
+++ b/third_party/blink/renderer/modules/accessibility/ax_object.h
@@ -1251,11 +1251,6 @@
   // highlighted via a "*" notation.
   std::string GetAXTreeForThis() const;
   void ShowAXTreeForThis() const;
-
-  // Starting from |this|, make sure there is an included parent path
-  // to the root, and that it's also possible to reach the included object
-  // by traversing downwards through included children.
-  void CheckIncludedObjectConnectedToRoot() const;
 #endif
 
 #if EXPENSIVE_DCHECKS_ARE_ON()
diff --git a/third_party/blink/renderer/modules/ai/ai_language_model.cc b/third_party/blink/renderer/modules/ai/ai_language_model.cc
index 1909745..2e6a6fd 100644
--- a/third_party/blink/renderer/modules/ai/ai_language_model.cc
+++ b/third_party/blink/renderer/modules/ai/ai_language_model.cc
@@ -36,9 +36,8 @@
                            AILanguageModel* language_model,
                            ScriptPromiseResolver<AILanguageModel>* resolver,
                            AbortSignal* signal,
-                           base::PassKey<AILanguageModel> pass_key)
+                           base::PassKey<AILanguageModel>)
       : AIMojoClient(script_state, language_model, resolver, signal),
-        pass_key_(pass_key),
         language_model_(language_model),
         receiver_(this, language_model->GetExecutionContext()) {
     mojo::PendingRemote<mojom::blink::AIManagerCreateLanguageModelClient>
@@ -90,7 +89,6 @@
   void ResetReceiver() override { receiver_.reset(); }
 
  private:
-  base::PassKey<AILanguageModel> pass_key_;
   Member<AILanguageModel> language_model_;
   HeapMojoReceiver<mojom::blink::AIManagerCreateLanguageModelClient,
                    CloneLanguageModelClient>
diff --git a/third_party/blink/renderer/modules/content_extraction/inner_text_builder.cc b/third_party/blink/renderer/modules/content_extraction/inner_text_builder.cc
index ed55281..e6f28fb1 100644
--- a/third_party/blink/renderer/modules/content_extraction/inner_text_builder.cc
+++ b/third_party/blink/renderer/modules/content_extraction/inner_text_builder.cc
@@ -137,7 +137,6 @@
 }
 
 InnerTextPassagesBuilder::InnerTextPassagesBuilder(
-    const mojom::blink::InnerTextParams& params)
-    : params_(params) {}
+    const mojom::blink::InnerTextParams& params) {}
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/content_extraction/inner_text_builder.h b/third_party/blink/renderer/modules/content_extraction/inner_text_builder.h
index b4218cf..6bc70e1 100644
--- a/third_party/blink/renderer/modules/content_extraction/inner_text_builder.h
+++ b/third_party/blink/renderer/modules/content_extraction/inner_text_builder.h
@@ -91,8 +91,6 @@
  private:
   explicit InnerTextPassagesBuilder(
       const mojom::blink::InnerTextParams& params);
-
-  const mojom::blink::InnerTextParams& params_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/modules/xr/xr_gpu_binding.cc b/third_party/blink/renderer/modules/xr/xr_gpu_binding.cc
index 0c6bc9c..c7750311c 100644
--- a/third_party/blink/renderer/modules/xr/xr_gpu_binding.cc
+++ b/third_party/blink/renderer/modules/xr/xr_gpu_binding.cc
@@ -85,9 +85,8 @@
 XRProjectionLayer* XRGPUBinding::createProjectionLayer(
     const XRGPUProjectionLayerInit* init,
     ExceptionState& exception_state) {
-  // TODO(crbug.com/5818595): Validate the colorFormat and depthStencilFormat.
-
-  if (!CanCreateLayer(exception_state)) {
+  if (!CanCreateLayer(exception_state) ||
+      !ValidateFormats(init, exception_state)) {
     return nullptr;
   }
 
@@ -121,7 +120,8 @@
   // Create the side-by-side color swap chain
   wgpu::TextureDescriptor color_desc = {};
   color_desc.label = "XRProjectionLayer Color";
-  color_desc.format = AsDawnEnum(init->colorFormat());
+  // TODO(crbug.com/359418629): Currently all backend images are RGBA8 format.
+  color_desc.format = wgpu::TextureFormat::RGBA8Unorm;
   color_desc.usage = static_cast<wgpu::TextureUsage>(init->textureUsage());
   color_desc.size = {static_cast<uint32_t>(texture_size.width()),
                      static_cast<uint32_t>(texture_size.height()),
@@ -142,7 +142,8 @@
   // TODO(crbug.com/359418629): Remove once array Mailboxes are available.
   XRGPUTextureArraySwapChain* wrapped_swap_chain =
       MakeGarbageCollected<XRGPUTextureArraySwapChain>(
-          device_, color_swap_chain, session()->array_texture_layers());
+          device_, color_swap_chain, AsDawnEnum(init->colorFormat()),
+          session()->array_texture_layers());
 
   // Create the depth/stencil swap chain
   XRGPUStaticSwapChain* depth_stencil_swap_chain = nullptr;
@@ -211,8 +212,9 @@
 }
 
 V8GPUTextureFormat XRGPUBinding::getPreferredColorFormat() {
-  // TODO(crbug.com/5818595): Replace with GPU::preferred_canvas_format()?
-  return FromDawnEnum(wgpu::TextureFormat::RGBA8Unorm);
+  // TODO(crbug.com/5818595): Ensure the backend swap chain format matches this.
+  // Till then the copy between formats is done in XRGPUTextureArraySwapChain.
+  return FromDawnEnum(GPU::preferred_canvas_format());
 }
 
 bool XRGPUBinding::CanCreateLayer(ExceptionState& exception_state) {
@@ -233,6 +235,41 @@
   return true;
 }
 
+bool XRGPUBinding::ValidateFormats(const XRGPUProjectionLayerInit* init,
+                                   ExceptionState& exception_state) {
+  // Is the color format supported?
+  switch (init->colorFormat().AsEnum()) {
+    case V8GPUTextureFormat::Enum::kBgra8Unorm:
+    case V8GPUTextureFormat::Enum::kRgba8Unorm:
+      // TODO(crbug.com/5818595): Support 'rgba16float'
+      break;
+    default:
+      exception_state.ThrowDOMException(
+          DOMExceptionCode::kInvalidStateError,
+          "Only 'rgba8unorm' or 'bgra8unorm' colorFormats are supported.");
+      return false;
+  }
+
+  if (init->hasDepthStencilFormat()) {
+    switch (init->depthStencilFormat().value().AsEnum()) {
+      case V8GPUTextureFormat::Enum::kStencil8:
+      case V8GPUTextureFormat::Enum::kDepth16Unorm:
+      case V8GPUTextureFormat::Enum::kDepth24Plus:
+      case V8GPUTextureFormat::Enum::kDepth24PlusStencil8:
+      case V8GPUTextureFormat::Enum::kDepth32Float:
+      case V8GPUTextureFormat::Enum::kDepth32FloatStencil8:
+        break;
+      default:
+        exception_state.ThrowDOMException(
+            DOMExceptionCode::kInvalidStateError,
+            "depthStencilFormat must be a depth and/or stencil format.");
+        return false;
+    }
+  }
+
+  return true;
+}
+
 void XRGPUBinding::Trace(Visitor* visitor) const {
   visitor->Trace(device_);
   XRGraphicsBinding::Trace(visitor);
diff --git a/third_party/blink/renderer/modules/xr/xr_gpu_binding.h b/third_party/blink/renderer/modules/xr/xr_gpu_binding.h
index 402f1582..42b05595 100644
--- a/third_party/blink/renderer/modules/xr/xr_gpu_binding.h
+++ b/third_party/blink/renderer/modules/xr/xr_gpu_binding.h
@@ -58,6 +58,8 @@
 
  private:
   bool CanCreateLayer(ExceptionState& exception_state);
+  bool ValidateFormats(const XRGPUProjectionLayerInit* init,
+                       ExceptionState& exception_state);
 
   Member<GPUDevice> device_;
 };
diff --git a/third_party/blink/renderer/modules/xr/xr_gpu_swap_chain.cc b/third_party/blink/renderer/modules/xr/xr_gpu_swap_chain.cc
index 3090b70a..213e9495 100644
--- a/third_party/blink/renderer/modules/xr/xr_gpu_swap_chain.cc
+++ b/third_party/blink/renderer/modules/xr/xr_gpu_swap_chain.cc
@@ -13,7 +13,6 @@
 
 bool IsDepthFormat(wgpu::TextureFormat format) {
   switch (format) {
-    case wgpu::TextureFormat::Stencil8:
     case wgpu::TextureFormat::Depth24Plus:
     case wgpu::TextureFormat::Depth16Unorm:
     case wgpu::TextureFormat::Depth24PlusStencil8:
diff --git a/third_party/blink/renderer/modules/xr/xr_gpu_texture_array_swap_chain.cc b/third_party/blink/renderer/modules/xr/xr_gpu_texture_array_swap_chain.cc
index 2c5d24a..c63201fb 100644
--- a/third_party/blink/renderer/modules/xr/xr_gpu_texture_array_swap_chain.cc
+++ b/third_party/blink/renderer/modules/xr/xr_gpu_texture_array_swap_chain.cc
@@ -14,6 +14,7 @@
 XRGPUTextureArraySwapChain::XRGPUTextureArraySwapChain(
     GPUDevice* device,
     XRGPUSwapChain* wrapped_swap_chain,
+    wgpu::TextureFormat format,
     uint32_t layers)
     : XRGPUSwapChain(device), wrapped_swap_chain_(wrapped_swap_chain) {
   CHECK(wrapped_swap_chain_);
@@ -23,8 +24,10 @@
   CHECK_EQ(descriptor_.size.width % layers, 0ul);
   descriptor_ = wrapped_swap_chain->descriptor();
   descriptor_.label = "XRGPUTextureArraySwapChain";
+  descriptor_.format = format;
   descriptor_.size = {descriptor_.size.width / layers, descriptor_.size.height,
                       layers};
+  descriptor_.usage |= wgpu::TextureUsage::TextureBinding;
 
   texture_internal_usage_ = {{
       .internalUsage =
@@ -52,7 +55,6 @@
     return;
   }
 
-  // Copy the texture layers into the wrapped swap chain
   GPUTexture* source_texture = GetCurrentTexture();
   GPUTexture* wrapped_texture = wrapped_swap_chain_->GetCurrentTexture();
 
@@ -61,29 +63,15 @@
   }};
   wgpu::CommandEncoderDescriptor command_encoder_desc = {
       .nextInChain = &internal_usage_desc,
-      .label = "XRGPUTextureArraySwapChain Copy",
+      .label = "XRGPUTextureArraySwapChain Direct Copy",
   };
   wgpu::CommandEncoder command_encoder =
       device()->GetHandle().CreateCommandEncoder(&command_encoder_desc);
 
-  wgpu::ImageCopyTexture source = {
-      .texture = source_texture->GetHandle(),
-      .aspect = wgpu::TextureAspect::All,
-  };
-  wgpu::ImageCopyTexture destination = {
-      .texture = wrapped_texture->GetHandle(),
-      .aspect = wgpu::TextureAspect::All,
-  };
-  wgpu::Extent3D copy_size = {
-      .width = source_texture->width(),
-      .height = source_texture->height(),
-      .depthOrArrayLayers = 1,
-  };
-
-  for (uint32_t i = 0; i < source_texture->depthOrArrayLayers(); ++i) {
-    source.origin.z = i;
-    destination.origin.x = source_texture->width() * i;
-    command_encoder.CopyTextureToTexture(&source, &destination, &copy_size);
+  if (source_texture->format() == wrapped_texture->format()) {
+    DirectCopy(command_encoder, source_texture, wrapped_texture);
+  } else {
+    RenderCopy(command_encoder, source_texture, wrapped_texture);
   }
 
   ClearCurrentTexture(command_encoder);
@@ -100,6 +88,160 @@
   // produced texture for the next frame.
 }
 
+// Copy the texture layers into the wrapped swapchain with CopyTextureToTexture.
+// This is the most efficient, but only works if the textures have the same
+// format.
+void XRGPUTextureArraySwapChain::DirectCopy(
+    wgpu::CommandEncoder command_encoder,
+    GPUTexture* source_texture,
+    GPUTexture* dest_texture) {
+  CHECK_EQ(source_texture->Format(), dest_texture->Format());
+
+  wgpu::ImageCopyTexture source = {
+      .texture = source_texture->GetHandle(),
+      .aspect = wgpu::TextureAspect::All,
+  };
+  wgpu::ImageCopyTexture destination = {
+      .texture = dest_texture->GetHandle(),
+      .aspect = wgpu::TextureAspect::All,
+  };
+  wgpu::Extent3D copy_size = {
+      .width = source_texture->width(),
+      .height = source_texture->height(),
+      .depthOrArrayLayers = 1,
+  };
+
+  for (uint32_t i = 0; i < source_texture->depthOrArrayLayers(); ++i) {
+    source.origin.z = i;
+    destination.origin.x = source_texture->width() * i;
+    command_encoder.CopyTextureToTexture(&source, &destination, &copy_size);
+  }
+}
+
+// Copy the texture layers into the wrapped swapchain with a render pass.
+// This is the less efficient, but works for textures with differing formats.
+void XRGPUTextureArraySwapChain::RenderCopy(
+    wgpu::CommandEncoder command_encoder,
+    GPUTexture* source_texture,
+    GPUTexture* dest_texture) {
+  CHECK(source_texture->Format() != dest_texture->Format());
+
+  wgpu::TextureViewDescriptor dest_view_desc = {
+      .dimension = wgpu::TextureViewDimension::e2D,
+      .baseMipLevel = 0,
+      .mipLevelCount = 1,
+      .baseArrayLayer = 0,
+      .arrayLayerCount = 1,
+  };
+  wgpu::TextureView dest_view =
+      dest_texture->GetHandle().CreateView(&dest_view_desc);
+
+  wgpu::RenderPassColorAttachment color_attachment = {
+      .view = dest_view,
+      .loadOp = wgpu::LoadOp::Clear,
+      .storeOp = wgpu::StoreOp::Store,
+      .clearValue = {0, 0, 0, 0},
+  };
+  wgpu::RenderPassDescriptor render_pass_desc = {
+      .colorAttachmentCount = 1,
+      .colorAttachments = &color_attachment,
+  };
+  wgpu::RenderPassEncoder render_pass =
+      command_encoder.BeginRenderPass(&render_pass_desc);
+
+  render_pass.SetPipeline(GetCopyPipelineForFormat(dest_texture->Format()));
+
+  // Loop through each layer of the source texture and copy it to the
+  // corresponding viewport of the destination texture.
+  for (uint32_t i = 0; i < source_texture->depthOrArrayLayers(); ++i) {
+    render_pass.SetViewport(source_texture->width() * i, 0,
+                            source_texture->width(), source_texture->height(),
+                            0, 1);
+
+    wgpu::TextureViewDescriptor source_view_desc = {
+        .dimension = wgpu::TextureViewDimension::e2D,
+        .mipLevelCount = 1,
+        .baseArrayLayer = i,
+        .arrayLayerCount = 1,
+    };
+    wgpu::TextureView source_view =
+        source_texture->GetHandle().CreateView(&source_view_desc);
+
+    wgpu::BindGroupEntry source_binding = {
+        .binding = 0,
+        .textureView = source_view,
+    };
+    wgpu::BindGroupDescriptor source_bind_group_desc = {
+        .layout = copy_pipeline_.GetBindGroupLayout(0),
+        .entryCount = 1,
+        .entries = &source_binding,
+    };
+    wgpu::BindGroup source_bind_group =
+        device()->GetHandle().CreateBindGroup(&source_bind_group_desc);
+    render_pass.SetBindGroup(0, source_bind_group);
+
+    // Draw 3 vertices, comprising a triangle that covers the entire viewport.
+    render_pass.Draw(3);
+  }
+
+  render_pass.End();
+}
+
+wgpu::RenderPipeline XRGPUTextureArraySwapChain::GetCopyPipelineForFormat(
+    wgpu::TextureFormat format) {
+  // Check to see if we have a copy pipeline for the appropriate format. If not,
+  // create one.
+  if (copy_pipeline_format_ != format) {
+    wgpu::ShaderSourceWGSL wgsl_desc = {};
+    wgsl_desc.code = R"(
+      // Internal shader used to copy between two textures
+      @group(0) @binding(0) var source: texture_2d<f32>;
+
+      struct VertexOut {
+        @builtin(position) pos: vec4f,
+        @location(0) uv: vec2f,
+      }
+
+      @vertex fn vert_main(@builtin(vertex_index) vertexIndex : u32) -> VertexOut {
+          var pos = array<vec2f, 3>(
+              vec2f(-1.0, -1.0),
+              vec2f( 3.0, -1.0),
+              vec2f(-1.0,  3.0));
+          return VertexOut(
+            vec4f(pos[vertexIndex], 0.0, 1.0),
+            vec2f(pos[vertexIndex].xy * vec2f(0.5, -0.5) + 0.5)
+          );
+      }
+
+      @fragment fn frag_main(in: VertexOut) -> @location(0) vec4<f32> {
+          let uv = vec2u(in.uv.xy * vec2f(textureDimensions(source)));
+          return textureLoad(source, uv, 0);
+      }
+    )";
+    wgpu::ShaderModuleDescriptor shader_module_desc = {.nextInChain =
+                                                           &wgsl_desc};
+    wgpu::ShaderModule shader_module =
+        device()->GetHandle().CreateShaderModule(&shader_module_desc);
+
+    wgpu::ColorTargetState color_target = {.format = format};
+    wgpu::FragmentState fragment = {
+        .module = shader_module,
+        .targetCount = 1,
+        .targets = &color_target,
+    };
+    wgpu::RenderPipelineDescriptor copy_pipeline_desc = {
+        .vertex = {.module = shader_module},
+        .fragment = &fragment,
+    };
+
+    copy_pipeline_ =
+        device()->GetHandle().CreateRenderPipeline(&copy_pipeline_desc);
+    copy_pipeline_format_ = format;
+  }
+
+  return copy_pipeline_;
+}
+
 void XRGPUTextureArraySwapChain::Trace(Visitor* visitor) const {
   visitor->Trace(wrapped_swap_chain_);
   XRGPUSwapChain::Trace(visitor);
diff --git a/third_party/blink/renderer/modules/xr/xr_gpu_texture_array_swap_chain.h b/third_party/blink/renderer/modules/xr/xr_gpu_texture_array_swap_chain.h
index c0249fc..addf336 100644
--- a/third_party/blink/renderer/modules/xr/xr_gpu_texture_array_swap_chain.h
+++ b/third_party/blink/renderer/modules/xr/xr_gpu_texture_array_swap_chain.h
@@ -20,6 +20,7 @@
  public:
   XRGPUTextureArraySwapChain(GPUDevice* device,
                              XRGPUSwapChain* wrapped_swap_chain,
+                             wgpu::TextureFormat format,
                              uint32_t layers);
   ~XRGPUTextureArraySwapChain() override = default;
 
@@ -37,9 +38,20 @@
   void Trace(Visitor* visitor) const override;
 
  private:
+  void DirectCopy(wgpu::CommandEncoder command_encoder,
+                  GPUTexture* source_texture,
+                  GPUTexture* dest_texture);
+  void RenderCopy(wgpu::CommandEncoder command_encoder,
+                  GPUTexture* source_texture,
+                  GPUTexture* dest_texture);
+
+  wgpu::RenderPipeline GetCopyPipelineForFormat(wgpu::TextureFormat format);
+
   Member<XRGPUSwapChain> wrapped_swap_chain_;
   wgpu::TextureDescriptor descriptor_;
   wgpu::DawnTextureInternalUsageDescriptor texture_internal_usage_;
+  wgpu::RenderPipeline copy_pipeline_;
+  wgpu::TextureFormat copy_pipeline_format_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 560d7a9e..cf358c85 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1326,11 +1326,9 @@
       // customizable.
       name: "CustomizableSelect",
       status: "experimental",
-      // :open is used in the UA stylesheet for CustomizableSelect, so this feature
-      // will not work properly without CSSPseudoOpen.
       // SelectParserRelaxation is needed to allow more content in <select>
       // than just <option>s etc.
-      depends_on: ["CSSPseudoOpen", "SelectParserRelaxation"],
+      depends_on: ["SelectParserRelaxation"],
     },
     {
       name: "Database",
@@ -4007,6 +4005,11 @@
     {
       name: "SrcsetMaxDensity",
     },
+    // Kill switch for change to unify image-set and srcset selection logic.
+    {
+      name: "SrcsetSelectionMatchesImageSet",
+      status: "stable",
+    },
     // Used as argument in attribute of stable-release functions/interfaces
     // where a runtime-enabled feature name is required for correct IDL syntax.
     // This is a global flag; do not change its status.
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py b/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
index ce5170c..6d0a2d9 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_manifest.py
@@ -19,11 +19,13 @@
 from typing import (
     Any,
     Dict,
+    Iterator,
     List,
     Literal,
     NamedTuple,
     Optional,
     Sequence,
+    Set,
     Tuple,
 )
 
@@ -148,7 +150,7 @@
     def __init__(self,
                  raw_dict,
                  wpt_dir: str,
-                 test_types: Optional[Sequence[str]] = None,
+                 test_types: Optional[Sequence[TestType]] = None,
                  exclude_jsshell: bool = True):
         self._raw_dict = raw_dict
         self.wpt_dir = wpt_dir
@@ -164,10 +166,16 @@
 
         items = self._raw_dict.get('items', {})
         for test_type in self.test_types:
-            self._map_tests(test_type, items.get(test_type, {}))
+            for url, test in self._items_in_trie(test_type,
+                                                 items.get(test_type, {})):
+                assert url not in self._tests_by_url, f'duplicate URL {url!r}'
+                self._tests_by_url[url] = test
 
-    def _map_tests(self, test_type: str, trie, path: str = ''):
-        """Record tests present in a trie for some test type.
+    def _items_in_trie(self,
+                       test_type: TestType,
+                       trie,
+                       path: str = '') -> Iterator[Tuple[str, _Test]]:
+        """Get tests present in a trie for some test type.
 
         Arguments:
             test_type: The WPT test type.
@@ -187,7 +195,7 @@
                 # URLs always use `/` for path separators. Don't add a leading
                 # `/`, since that's the convention in `blinkpy` for test paths.
                 child_path = f'{path}/{component}' if path else component
-                self._map_tests(test_type, child, child_path)
+                yield from self._items_in_trie(test_type, child, child_path)
             return
 
         assert len(trie) >= 2, f'{trie!r} must contain at least one test'
@@ -204,9 +212,8 @@
                 test = _Test(path, test_type, refs, extras)
             else:
                 url, test = path, _Test(None, test_type, refs, extras)
-            assert url not in self._tests_by_url, f'duplicate URL {url!r}'
             if not self._exclude_jsshell or not test.jsshell:
-                self._tests_by_url[url] = test
+                yield url, test
 
     @classmethod
     def from_file(cls,
@@ -226,33 +233,63 @@
         """Returns a set of the URLs for all items in the manifest."""
         return frozenset(self._tests_by_url)
 
-    def get_test_type(self, url: str) -> Optional[str]:
+    def get_test_type(self, url: str) -> Optional[TestType]:
         """Returns the test type of the given test file path."""
         assert not url.startswith('/')
         test = self._tests_by_url.get(url)
         return test and test.test_type
 
+    def tests_under_path(self, file_path: str) -> Set[str]:
+        """Get all test URLs under a test file or directory.
+
+        This is similar to inverting `file_path_for_test_url()`.
+        """
+        assert not file_path.startswith('/')
+        components = file_path.split('/')
+        assert components, file_path
+        tries_by_type = self._raw_dict.get('items', {})
+        tests = set()
+        for test_type in self.test_types:
+            trie_for_type = tries_by_type.get(test_type, {})
+            if trie_for_path := self._lookup_path(trie_for_type, components):
+                tests.update(url for url, _ in self._items_in_trie(
+                    test_type, trie_for_path, file_path))
+        return tests
+
     def is_test_file(self, file_path: str) -> bool:
         """Checks if file_path is a test file according to the manifest."""
         assert not file_path.startswith('/')
         components = file_path.split('/')
         assert components, file_path
         tries_by_type = self._raw_dict.get('items', {})
-        return any(
-            self._contains_file(tries_by_type.get(test_type, {}), components)
-            for test_type in self.test_types)
+        test_files = (self._lookup_path(tries_by_type.get(test_type, {}),
+                                        components)
+                      for test_type in self.test_types)
+        return any(isinstance(maybe_file, list) for maybe_file in test_files)
 
-    def _contains_file(self, trie, components: Sequence[str]) -> bool:
-        """Determine if a test trie contains a test file."""
-        if isinstance(trie, list):
-            # Not a test file if there are still components at a leaf.
-            return not bool(components)
+    def _lookup_path(self, trie, components: Sequence[str]):
+        """Lookup an entry in a trie of test items.
+
+        Arguments:
+            trie: See above for format. One of:
+              * A test file (`list`) with a test type-dependent format.
+              * A test directory (`dict`) mapping names to subdirectories or
+                files.
+            components: Path components to the target file/directory.
+
+        Returns:
+            Either `None` for invalid paths, or a test file or directory.
+        """
         if not components:
-            # This is a test directory, not a test file.
-            return False
+            return trie
+        elif isinstance(trie, list):
+            # Path doesn't exist because there are still more path components to
+            # look up at a leaf.
+            return None
         next_component, *rest = components
-        child = trie.get(next_component)
-        return bool(child) and self._contains_file(child, rest)
+        if (child := trie.get(next_component)) is not None:
+            return self._lookup_path(child, rest)
+        return None
 
     def is_test_url(self, url):
         """Checks if url is a valid test in the manifest."""
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py b/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
index ef01475..1f08f46 100644
--- a/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
+++ b/third_party/blink/tools/blinkpy/w3c/wpt_manifest_unittest.py
@@ -209,6 +209,58 @@
             manifest.file_path_for_test_url('test.any.worker.html'),
             'test.any.js')
 
+    def test_tests_under_path_file(self):
+        raw_manifest = {
+            'items': {
+                'testharness': {
+                    'a': {
+                        'b.html': [
+                            'd23fbb8',
+                            ['a/b.html?c', {}],
+                            ['a/b.html?d', {}],
+                        ],
+                        'e.html': ['f23fbb8', [None, {}]],
+                    },
+                },
+            },
+        }
+        manifest = WPTManifest(raw_manifest, 'external/wpt')
+        self.assertEqual(manifest.tests_under_path('a/b.html'),
+                         {'a/b.html?c', 'a/b.html?d'})
+        self.assertEqual(manifest.tests_under_path('a/e.html'), {'a/e.html'})
+        self.assertEqual(manifest.tests_under_path('a/does-not-exist.html'),
+                         set())
+
+    def test_tests_under_path_directory(self):
+        raw_manifest = {
+            'items': {
+                'testharness': {
+                    'a': {
+                        'b': {
+                            'c.html': [
+                                'd23fbb8',
+                                ['a/b/c.html?d', {}],
+                                ['a/b/c.html?e', {}],
+                            ],
+                        },
+                    },
+                },
+                'crashtest': {
+                    'a': {
+                        'f.html': ['f23fbb8', [None, {}]],
+                    },
+                    'do-not-include': {
+                        'g.html': ['023fbb8', [None, {}]],
+                    },
+                },
+            },
+        }
+        manifest = WPTManifest(raw_manifest, 'external/wpt')
+        self.assertEqual(manifest.tests_under_path('a/b'),
+                         {'a/b/c.html?d', 'a/b/c.html?e'})
+        self.assertEqual(manifest.tests_under_path('a'),
+                         {'a/b/c.html?d', 'a/b/c.html?e', 'a/f.html'})
+
     def test_crash_tests(self):
         # Test that the manifest recognizes crash tests and that is_crash_test
         # correctly identifies only crash tests in the manifest.
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index d5e898c..9d1b93a 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -2689,6 +2689,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/383200044 [ Win10.20h2 ] external/wpt/png/apng/fdAT-16bit.html [ Failure ]
+crbug.com/383194996 [ Mac13 ] external/wpt/webrtc/RTCPeerConnection-setLocalDescription-pranswer.html [ Timeout ]
 crbug.com/382988706 external/wpt/css/css-rhythm/replaced-elements/block-level-canvas-margins-affected-by-block-step-size.html [ Failure ]
 crbug.com/382988706 external/wpt/css/css-rhythm/replaced-elements/block-level-embed-margins-affected-by-block-step-size.html [ Failure ]
 crbug.com/382988706 external/wpt/css/css-rhythm/replaced-elements/block-level-iframe-margins-affected-by-block-step-size.html [ Failure ]
@@ -2943,8 +2945,10 @@
 crbug.com/371233767 [ Mac14 ] external/wpt/webrtc/RTCConfiguration-rtcpMuxPolicy.html [ Timeout ]
 crbug.com/371233767 [ Mac15 ] external/wpt/webrtc/RTCConfiguration-rtcpMuxPolicy.html [ Timeout ]
 crbug.com/371233767 [ Mac13 ] external/wpt/webrtc/RTCPeerConnection-canTrickleIceCandidates.html [ Timeout ]
+crbug.com/371233767 [ Mac15 ] external/wpt/webrtc/RTCPeerConnection-canTrickleIceCandidates.html [ Timeout ]
 crbug.com/371233767 [ Mac13 ] external/wpt/webrtc/RTCRtpSender.https.html [ Timeout ]
 crbug.com/371233767 [ Mac14 ] external/wpt/webrtc/RTCRtpSender.https.html [ Timeout ]
+crbug.com/371233767 [ Mac15 ] external/wpt/webrtc/RTCRtpSender.https.html [ Timeout ]
 crbug.com/371233767 [ Mac13 ] external/wpt/webrtc/back-forward-cache-with-closed-webrtc-connection.https.window.html [ Timeout ]
 crbug.com/371233767 [ Mac15 ] external/wpt/webrtc/back-forward-cache-with-closed-webrtc-connection.https.window.html [ Timeout ]
 crbug.com/371068262 [ Mac14 ] external/wpt/media-capabilities/encodingInfo.webrtc.html [ Timeout ]
@@ -6445,6 +6449,7 @@
 crbug.com/1385905 [ Win ] external/wpt/editing/run/caret-navigation-around-line-break.html [ Skip Timeout ]
 crbug.com/1385881 [ Mac12 ] external/wpt/fetch/metadata/generated/audioworklet.https.sub.html [ Timeout ]
 crbug.com/1385881 [ Mac13 ] external/wpt/fetch/metadata/generated/audioworklet.https.sub.html [ Timeout ]
+crbug.com/1385881 [ Mac13-arm64 ] external/wpt/fetch/metadata/generated/audioworklet.https.sub.html [ Timeout ]
 crbug.com/1385881 [ Mac14 ] external/wpt/fetch/metadata/generated/audioworklet.https.sub.html [ Timeout ]
 crbug.com/1385881 [ Mac15 ] external/wpt/fetch/metadata/generated/audioworklet.https.sub.html [ Timeout ]
 crbug.com/1385881 [ Mac15-arm64 ] external/wpt/fetch/metadata/generated/audioworklet.https.sub.html [ Timeout ]
@@ -8011,6 +8016,7 @@
 crbug.com/356930166 [ Mac14 ] external/wpt/webrtc/legacy/simplecall_callbacks.https.html [ Timeout ]
 crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/legacy/simplecall_callbacks.https.html [ Timeout ]
 crbug.com/356930166 [ Mac13 ] external/wpt/webrtc/no-media-call.html [ Timeout ]
+crbug.com/356930166 [ Mac14 ] external/wpt/webrtc/no-media-call.html [ Timeout ]
 crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/no-media-call.html [ Timeout ]
 crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/promises-call.html [ Timeout ]
 crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/protocol/additional-codecs.html [ Skip Timeout ]
@@ -8071,6 +8077,7 @@
 crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/RTCSctpTransport-maxChannels.html [ Timeout ]
 crbug.com/356930166 [ Mac13 ] external/wpt/webrtc/simplecall-no-ssrcs.https.html [ Timeout ]
 crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/simplecall-no-ssrcs.https.html [ Timeout ]
+crbug.com/356930166 [ Mac14 ] external/wpt/webrtc/simplecall.https.html [ Timeout ]
 crbug.com/356930166 [ Mac15 ] external/wpt/webrtc/simplecall.https.html [ Timeout ]
 crbug.com/356930166 [ Mac15-arm64 ] external/wpt/webrtc-encoded-transform/tentative/RTCPeerConnection-insertable-streams-errors.https.html [ Timeout ]
 crbug.com/356930166 [ Mac15-arm64 ] external/wpt/webrtc-extensions/RTCRtpSynchronizationSource-captureTimestamp.html [ Skip Timeout ]
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 235c623..3c8ae75 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
@@ -5418,6 +5418,13 @@
        {}
       ]
      ],
+     "empty-render-target-crash.html": [
+      "38c32b1efb870059b286bde904ff84de68351fc3",
+      [
+       null,
+       {}
+      ]
+     ],
      "get-computed-style-crash.html": [
       "38cd5af7f83d60976f9712e446a55d11fe07160e",
       [
@@ -381759,7 +381766,7 @@
         []
        ],
        "text.yaml": [
-        "38630509bf2f79eda68ae6c5de82c1050b98f7c4",
+        "42bf9a3c93964c4bc0ea575ce36d6892fba01bc0",
         []
        ],
        "the-canvas-state.yaml": [
@@ -387194,10 +387201,6 @@
        ]
       }
      },
-     "dimension-attributes-expected.txt": [
-      "291e645f241409c89fc804ed2ec5949351bf1b13",
-      []
-     ],
      "interactive-media": {
       "links-forms-and-navigation": {
        "original-id.json": [
@@ -467596,14 +467599,14 @@
       ]
      ],
      "position-try-order-basic.html": [
-      "c7705a71bbb5fe0a8833604a2edc8bcf43639636",
+      "f54ce44f72333a3b09f2445d81ac0d69d0b6f740",
       [
        null,
        {}
       ]
      ],
      "position-try-order-position-area.html": [
-      "3b7a3475c759d0910b770e89c9df6adf0ac0e62a",
+      "4ffbbd0b71ded8991b89b8ae69ac68383560da15",
       [
        null,
        {}
@@ -477606,7 +477609,21 @@
         ]
        ],
        "gap-decorations-style-computed.html": [
-        "379fb89c071774c9864a670dd220d2c2cf462e63",
+        "60600bdb8a7fdfa01c2826f578f4a51a9b713dc5",
+        [
+         null,
+         {}
+        ]
+       ],
+       "gap-decorations-style-invalid.html": [
+        "d2a11f6c0d3220559778c784164bcbc82cd4b0f2",
+        [
+         null,
+         {}
+        ]
+       ],
+       "gap-decorations-style-valid.html": [
+        "74d243bd6da188c761c84e0cdb4fc96969c6b8a6",
         [
          null,
          {}
@@ -585165,27 +585182,6 @@
          {}
         ]
        ],
-       "2d.text.measure.caret-position-edge-cases.tentative.html": [
-        "6628c9394683bf20394a94b3ca952453d18be7b1",
-        [
-         null,
-         {}
-        ]
-       ],
-       "2d.text.measure.caret-position-edges.tentative.html": [
-        "cd56e20bb980a67543b361004990ee12d3c060bd",
-        [
-         null,
-         {}
-        ]
-       ],
-       "2d.text.measure.caret-position.tentative.html": [
-        "4b223c8a0a356833ef0d8ad51e8cb3a915a328eb",
-        [
-         null,
-         {}
-        ]
-       ],
        "2d.text.measure.emHeights-low-ascent.html": [
         "8eb49ff8adda5be92719defaaf4a97844c6b7d82",
         [
@@ -585256,6 +585252,27 @@
          {}
         ]
        ],
+       "2d.text.measure.index-from-offset-edge-cases.tentative.html": [
+        "b7a327aeaae1997a6b70dc6ad4224911ce4b806d",
+        [
+         null,
+         {}
+        ]
+       ],
+       "2d.text.measure.index-from-offset-edges.tentative.html": [
+        "842f50857cca530b130dd85f9e5a57204113875f",
+        [
+         null,
+         {}
+        ]
+       ],
+       "2d.text.measure.index-from-offset.tentative.html": [
+        "9893fcdc4c293dbbdcac9795beb1e18b8f433bfc",
+        [
+         null,
+         {}
+        ]
+       ],
        "2d.text.measure.selection-rects-baselines.tentative.html": [
         "8ef5e83199c395d1de79b7730b47c2c9342d074e",
         [
@@ -585298,6 +585315,13 @@
          {}
         ]
        ],
+       "2d.text.measure.text-clusters-rendering-options.tentative.html": [
+        "10a433cc61bd029e3c05a686c7b4f2c256e877e7",
+        [
+         null,
+         {}
+        ]
+       ],
        "2d.text.measure.text-clusters-split.tentative.html": [
         "63c7cce72be7c1ede567c2f00001d7a57addadbc",
         [
@@ -598784,41 +598808,6 @@
          {}
         ]
        ],
-       "2d.text.measure.caret-position-edge-cases.tentative.html": [
-        "a9bf8b4de5990da8da9eb33a35cc5f6a0af5476c",
-        [
-         null,
-         {}
-        ]
-       ],
-       "2d.text.measure.caret-position-edge-cases.tentative.worker.js": [
-        "835392228363b63c175f6d9e17bd247bbe67dffe",
-        [
-         "html/canvas/offscreen/text/2d.text.measure.caret-position-edge-cases.tentative.worker.html",
-         {}
-        ]
-       ],
-       "2d.text.measure.caret-position-edges.tentative.html": [
-        "a6e45274c7300aa9f407c605e41108559f92f6c8",
-        [
-         null,
-         {}
-        ]
-       ],
-       "2d.text.measure.caret-position-edges.tentative.worker.js": [
-        "2cef8432d2a2eb6fa9057d6a593cc7e2f0a2ae3f",
-        [
-         "html/canvas/offscreen/text/2d.text.measure.caret-position-edges.tentative.worker.html",
-         {}
-        ]
-       ],
-       "2d.text.measure.caret-position.tentative.html": [
-        "3c1873aaf1f27b17da19860c693b0ce006cc6da2",
-        [
-         null,
-         {}
-        ]
-       ],
        "2d.text.measure.emHeights-low-ascent.html": [
         "229f558bf2d4b07a9fd0b29a54067ceb4f0a3367",
         [
@@ -598959,6 +598948,41 @@
          {}
         ]
        ],
+       "2d.text.measure.index-from-offset-edge-cases.tentative.html": [
+        "5f0236bfa87e5af74939bcaa8bfb0832e306206f",
+        [
+         null,
+         {}
+        ]
+       ],
+       "2d.text.measure.index-from-offset-edge-cases.tentative.worker.js": [
+        "ae08c78d07a2adfe5f80457373b8b589589ab3f3",
+        [
+         "html/canvas/offscreen/text/2d.text.measure.index-from-offset-edge-cases.tentative.worker.html",
+         {}
+        ]
+       ],
+       "2d.text.measure.index-from-offset-edges.tentative.html": [
+        "fbefdd5804cd3fe3ad6cf9a94f68ad89767ac5e4",
+        [
+         null,
+         {}
+        ]
+       ],
+       "2d.text.measure.index-from-offset-edges.tentative.worker.js": [
+        "2ec89e84b516f9515f8e68a3e6fcd39733b018b2",
+        [
+         "html/canvas/offscreen/text/2d.text.measure.index-from-offset-edges.tentative.worker.html",
+         {}
+        ]
+       ],
+       "2d.text.measure.index-from-offset.tentative.html": [
+        "18e42aff3c385f747d63e580ed3929d34e8bf9e2",
+        [
+         null,
+         {}
+        ]
+       ],
        "2d.text.measure.selection-rects-baselines.tentative.html": [
         "fc1683bcce17a948e3580a64357da5a7927ce289",
         [
@@ -599036,6 +599060,20 @@
          {}
         ]
        ],
+       "2d.text.measure.text-clusters-rendering-options.tentative.html": [
+        "645013528e81734cffba84f4231a1ce293152892",
+        [
+         null,
+         {}
+        ]
+       ],
+       "2d.text.measure.text-clusters-rendering-options.tentative.worker.js": [
+        "f55d2c4655641d1c05bc14b9f210889f247c49e3",
+        [
+         "html/canvas/offscreen/text/2d.text.measure.text-clusters-rendering-options.tentative.worker.html",
+         {}
+        ]
+       ],
        "2d.text.measure.text-clusters-split.tentative.html": [
         "6a5fd475795e140ff8b8533b8d070baf97f0ebfe",
         [
@@ -616059,6 +616097,20 @@
          {}
         ]
        ],
+       "button-click-resets-with-commandfor.tentative.html": [
+        "a1e3669717e90c16d93b11cde663a73495c852a5",
+        [
+         null,
+         {}
+        ]
+       ],
+       "button-click-submits-with-commandfor.tentative.html": [
+        "ced0d9ef152d82920fee888947bba0484335585b",
+        [
+         null,
+         {}
+        ]
+       ],
        "button-click-submits.html": [
         "86b92402e46896917748c792d14ec1989fc1a4b8",
         [
@@ -618491,7 +618543,7 @@
         ]
        ],
        "dialog-requestclose.tentative.html": [
-        "eb2270b861c75e8318760b1ee6ce5398c780d780",
+        "18486f791b4a6c6e2f23f4c9f1c566f9f3dbf8a1",
         [
          null,
          {
@@ -618903,7 +618955,7 @@
        ]
       ],
       "invoketarget-button-event-dispatch.tentative.html": [
-       "ef870627a066f5dd85f29ce6ea664581ea0259fc",
+       "74148caa2107d3e99acc4f9223c19eaad9de4ec1",
        [
         null,
         {
@@ -619650,10 +619702,12 @@
        ]
       ],
       "popover-minimum-role.html": [
-       "8606f983969b9fc94e2684073a4946e9358e3507",
+       "b46ca81fb526d828ce15806850999d002cc01ab0",
        [
         null,
-        {}
+        {
+         "testdriver": true
+        }
        ]
       ],
       "popover-move-documents.html": [
@@ -630556,6 +630610,13 @@
       {}
      ]
     ],
+    "external-import-map-errors.html": [
+     "ea2a1c058755deb0646505ed3b4909a4a123cb25",
+     [
+      null,
+      {}
+     ]
+    ],
     "http-url-like-specifiers.sub.html": [
      "ba5182354cbcdda4386eea7730701a45460c443c",
      [
@@ -632217,6 +632278,13 @@
       }
      ]
     ],
+    "input-events-range-exceptions.tentative.html": [
+     "d2a2b66bea9fd9a852cf816ea2de107fd0014cc9",
+     [
+      null,
+      {}
+     ]
+    ],
     "input-events-spin-button-click-on-number-input-delete-document.html": [
      "fb3655398dbd1bdde84f032df392b6352b7fcafe",
      [
@@ -644824,7 +644892,7 @@
      ]
     ],
     "nav2-test-timing-persistent.html": [
-     "d0fc8c073bfdcb057b0f6a1adda08763f8bb71c4",
+     "4a590b8fbb5ddcca30626913541d965e26066183",
      [
       null,
       {}
@@ -668872,6 +668940,13 @@
        {}
       ]
      ],
+     "animation-range-scroll-timeline.html": [
+      "a1ff45e2a2f671bf4a84abc68044b6b133f320a4",
+      [
+       null,
+       {}
+      ]
+     ],
      "animation-shorthand.html": [
       "144fc5773fd5c75af30d74775a75ec9e7e478396",
       [
diff --git a/third_party/blink/web_tests/external/wpt/import-maps/external-import-map-errors.html b/third_party/blink/web_tests/external/wpt/import-maps/external-import-map-errors.html
new file mode 100644
index 0000000..ea2a1c0
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/import-maps/external-import-map-errors.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+  window.markupErrored = false;
+  window.markupLoaded = false;
+</script>
+<script src="/import-maps/resources/empty.js" type="importmap"
+ onload="window.markupLoaded = true;" onerror="window.markupErrored = true;">
+</script>
+<script>
+  promise_test(async () => {
+    await new Promise((resolve, reject) => {
+      const element = document.createElement("script");
+      element.onload = () => { reject("Got an unexpected load event"); };
+      element.onerror = () => { resolve("Got an error event"); };
+      element.src = "/import-maps/resources/empty.js";
+      element.type = "importmap";
+      document.head.appendChild(element);
+    })
+  }, "Test that an external import map fires an error event");
+
+  promise_test(async () => {
+    await new Promise((resolve, reject) => {
+      const element = document.createElement("script");
+      element.type = "importmap";
+      element.onload = () => { reject("Got an unexpected load event"); };
+      element.onerror = () => { resolve("Got an error event"); };
+      element.src = "/import-maps/resources/empty.js";
+      document.head.appendChild(element);
+    })
+  }, "Test that an external import map fires an error event, regardless of attribute order");
+
+  promise_test(async () => {
+    assert_true(window.markupErrored, "error");
+    assert_false(window.markupLoaded, "load");
+  }, "Test that an external import map in markup fires an error event");
+</script>
+</head>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-range-scroll-timeline.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-range-scroll-timeline.html
new file mode 100644
index 0000000..a1ff45e
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-range-scroll-timeline.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="help" src="https://drafts.csswg.org/scroll-animations-1/#named-range-animation-declaration">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/scroll-animations/scroll-timelines/testcommon.js"></script>
+<title>The animation-range-* CSS properties for an animation associated with a scroll timeline</title>
+</head>
+<style>
+
+  @keyframes anim {
+    from { opacity: 0 }
+  }
+
+  #scroller {
+    overflow-y: scroll;
+    width: 100px;
+    height: 100px;
+  }
+
+  #target {
+    width: 100%;
+    height: 200%;
+
+    animation: anim auto linear;
+    animation-timeline: scroll();
+    animation-range-start: 10px;
+    animation-range-end: 80px;
+  }
+</style>
+<body>
+  <div id="scroller">
+    <div id="target"></div>
+  </div>
+</body>
+<script>
+
+const animation = document.getAnimations()[0];
+
+test(t => {
+  assert_equals(animation.rangeStart.offset.value, 10);
+  assert_equals(animation.rangeStart.offset.unit, "px");
+}, "The animation-range-start CSS property maps to Animation's 'rangeStart' property");
+
+test(t => {
+    assert_equals(animation.rangeEnd.offset.value, 80);
+    assert_equals(animation.rangeEnd.offset.unit, "px");
+}, "The animation-range-end CSS property maps to Animation's 'rangeEnd' property");
+
+promise_test(async t => {
+  await animation.ready;
+  assert_percents_equal(animation.startTime, 10);
+}, "The auto-aligned start time accounts for the animation-range-start property");
+
+promise_test(async t => {
+  await animation.ready;
+  assert_percents_equal(animation.effect.getComputedTiming().duration, 70);
+}, "The effect duration accounts for the animation-range-* properties");
+
+</script>
diff --git a/third_party/boringssl/src b/third_party/boringssl/src
index 470d9b0..57f525e 160000
--- a/third_party/boringssl/src
+++ b/third_party/boringssl/src
@@ -1 +1 @@
-Subproject commit 470d9b07dd07353b7b0880f5b843f489ca24330e
+Subproject commit 57f525e425a95e7c89fa2df926fa93273bd47311
diff --git a/third_party/catapult b/third_party/catapult
index 350ba7c..40c51c5 160000
--- a/third_party/catapult
+++ b/third_party/catapult
@@ -1 +1 @@
-Subproject commit 350ba7c712c9e1af86954eea7db34d2a6fad294c
+Subproject commit 40c51c5d3e7e1a69ebc277adb03c78d0058151b2
diff --git a/third_party/chromite b/third_party/chromite
index 825cf77..d8cadf1 160000
--- a/third_party/chromite
+++ b/third_party/chromite
@@ -1 +1 @@
-Subproject commit 825cf77f9079c0f6882fc45913e471b1407d6ef8
+Subproject commit d8cadf19e5362d8d204ff96dcda6644dedbe9029
diff --git a/third_party/crossbench b/third_party/crossbench
index 93a7369..4c64713 160000
--- a/third_party/crossbench
+++ b/third_party/crossbench
@@ -1 +1 @@
-Subproject commit 93a7369e66a419ceede2a0124d95d42243533832
+Subproject commit 4c647135c01c82af0907269c326346cc24f334e3
diff --git a/third_party/d3/README.chromium b/third_party/d3/README.chromium
index 0a2315da..5a6db67 100644
--- a/third_party/d3/README.chromium
+++ b/third_party/d3/README.chromium
@@ -5,7 +5,7 @@
 CPEPrefix: cpe:/a:d3.js_project:d3.js:7.8.4::~~~node.js~~
 Date: 2023-03-31
 Revision: 37b1960e0af52d12bc7bbea2ed932ea954c36d14
-License: BSD 3-Clause
+License: ISC
 License File: src/LICENSE
 Security Critical: Yes
 Shipped: yes
diff --git a/third_party/dawn b/third_party/dawn
index bb1dbd8..67e21d0 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit bb1dbd8ad562999d1e142b519d49075ae9bc0253
+Subproject commit 67e21d0f9ae8c7e2db7ba7bb3d8b89687714e2a8
diff --git a/third_party/depot_tools b/third_party/depot_tools
index c30219e..25fede4 160000
--- a/third_party/depot_tools
+++ b/third_party/depot_tools
@@ -1 +1 @@
-Subproject commit c30219e4a720a4f91f66983fdb11c5a665da63ac
+Subproject commit 25fede45b3488984d27555820e823644697e748e
diff --git a/third_party/devtools-frontend-internal b/third_party/devtools-frontend-internal
index 2534d7d..b6bd78d 160000
--- a/third_party/devtools-frontend-internal
+++ b/third_party/devtools-frontend-internal
@@ -1 +1 @@
-Subproject commit 2534d7deee0d3f46def3299aced0f4866ac978de
+Subproject commit b6bd78d495c40d4370348a7c9f4c5b9351f1dde7
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src
index 3c18d9b..2e1b6ce 160000
--- a/third_party/devtools-frontend/src
+++ b/third_party/devtools-frontend/src
@@ -1 +1 @@
-Subproject commit 3c18d9b9ab9158565e4378e9899f66b020030b63
+Subproject commit 2e1b6ce3712118681e7919265bf9fe135dd77d6b
diff --git a/third_party/dom_distiller_js/README.chromium b/third_party/dom_distiller_js/README.chromium
index 6b86decd..f8fe8c89d 100644
--- a/third_party/dom_distiller_js/README.chromium
+++ b/third_party/dom_distiller_js/README.chromium
@@ -1,7 +1,7 @@
 Name: dom-distiller-js
 URL: https://github.com/chromium/dom-distiller
 Version: 36c7178512
-License: BSD
+License: BSD-3-Clause, Apache-2.0
 License File: LICENSE
 Security Critical: yes
 Shipped: yes
diff --git a/third_party/fdlibm/README.chromium b/third_party/fdlibm/README.chromium
index 3e45ceaf..cbda8fe7 100644
--- a/third_party/fdlibm/README.chromium
+++ b/third_party/fdlibm/README.chromium
@@ -4,7 +4,7 @@
 Version: N/A
 Security Critical: yes
 Shipped: yes
-License: fdlibm license
+License: SunPro
 License File: LICENSE
 License Android Compatible: yes
 
diff --git a/third_party/libaom/README.chromium b/third_party/libaom/README.chromium
index 9143070..de60ebd 100644
--- a/third_party/libaom/README.chromium
+++ b/third_party/libaom/README.chromium
@@ -2,7 +2,7 @@
 Short Name: libaom
 URL: https://aomedia.googlesource.com/aom/
 Version: N/A
-Revision: ff9badefdf0f98f758ec22fc5bf3816ebdeafd61
+Revision: 0063380307ea8f388d24ddf824724418a8f2237d
 CPEPrefix: cpe:/a:aomedia:aomedia:3.11.0
 License: BSD-2-Clause, Patent
 License File: source/libaom/LICENSE, source/libaom/PATENTS
diff --git a/third_party/libaom/libaom_test_srcs.gni b/third_party/libaom/libaom_test_srcs.gni
index 5e3075e4..b3ec400 100644
--- a/third_party/libaom/libaom_test_srcs.gni
+++ b/third_party/libaom/libaom_test_srcs.gni
@@ -84,6 +84,7 @@
   "//third_party/libaom/source/libaom/test/metadata_test.cc",
   "//third_party/libaom/source/libaom/test/minmax_test.cc",
   "//third_party/libaom/source/libaom/test/monochrome_test.cc",
+  "//third_party/libaom/source/libaom/test/multilayer_metadata_test.cc",
   "//third_party/libaom/source/libaom/test/mv_cost_test.cc",
   "//third_party/libaom/source/libaom/test/reconinter_test.cc",
   "//third_party/libaom/source/libaom/test/resize_test.cc",
diff --git a/third_party/libaom/source/config/config/aom_version.h b/third_party/libaom/source/config/config/aom_version.h
index 1cb4c654..d1ba051 100644
--- a/third_party/libaom/source/config/config/aom_version.h
+++ b/third_party/libaom/source/config/config/aom_version.h
@@ -14,9 +14,9 @@
 #define VERSION_MAJOR 3
 #define VERSION_MINOR 11
 #define VERSION_PATCH 0
-#define VERSION_EXTRA "116-gff9badefdf"
+#define VERSION_EXTRA "126-g0063380307"
 #define VERSION_PACKED \
   ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH))
-#define VERSION_STRING_NOSP "3.11.0-116-gff9badefdf"
-#define VERSION_STRING " 3.11.0-116-gff9badefdf"
+#define VERSION_STRING_NOSP "3.11.0-126-g0063380307"
+#define VERSION_STRING " 3.11.0-126-g0063380307"
 #endif  // AOM_VERSION_H_
diff --git a/third_party/libaom/source/libaom b/third_party/libaom/source/libaom
index ff9bade..0063380 160000
--- a/third_party/libaom/source/libaom
+++ b/third_party/libaom/source/libaom
@@ -1 +1 @@
-Subproject commit ff9badefdf0f98f758ec22fc5bf3816ebdeafd61
+Subproject commit 0063380307ea8f388d24ddf824724418a8f2237d
diff --git a/third_party/libavif/README.chromium b/third_party/libavif/README.chromium
index a139d5f..a12b1e3 100644
--- a/third_party/libavif/README.chromium
+++ b/third_party/libavif/README.chromium
@@ -3,7 +3,7 @@
 URL: https://github.com/AOMediaCodec/libavif
 Version: N/A
 Revision: DEPS
-License: 2-Clause BSD
+License: BSD-2-Clause, MIT
 License File: LICENSE
 Security Critical: yes
 Shipped: yes
diff --git a/third_party/libei/README.chromium b/third_party/libei/README.chromium
index 7e97b9e..1940b1c 100644
--- a/third_party/libei/README.chromium
+++ b/third_party/libei/README.chromium
@@ -2,7 +2,7 @@
 URL: https://gitlab.freedesktop.org/libinput/libei
 Version: f9d691e98b515b544fb803a3c0c387621fd2d332
 Revision: f9d691e98b515b544fb803a3c0c387621fd2d332
-License: BSD
+License: MIT
 License File: LICENSE
 Security Critical: yes
 Shipped: yes
diff --git a/third_party/libxcb-keysyms/README.chromium b/third_party/libxcb-keysyms/README.chromium
index 153e2ccd..dc70c8c 100644
--- a/third_party/libxcb-keysyms/README.chromium
+++ b/third_party/libxcb-keysyms/README.chromium
@@ -3,7 +3,7 @@
 URL: https://gitlab.freedesktop.org/xorg/lib/libxcb-keysyms
 Version: 691515491a4a3c119adc6c769c29de264b3f3806
 Revision: 691515491a4a3c119adc6c769c29de264b3f3806
-License: MIT
+License: X11
 License File: LICENSE
 Security Critical: no
 Shipped: yes
diff --git a/third_party/libxslt/README.chromium b/third_party/libxslt/README.chromium
index a2a1ed5303..fa70f731 100644
--- a/third_party/libxslt/README.chromium
+++ b/third_party/libxslt/README.chromium
@@ -5,7 +5,7 @@
 CPEPrefix: cpe:/a:xmlsoft:libxslt:1.1.42
 Security Critical: yes
 Shipped: yes
-License: MIT
+License: X11
 License File: src/Copyright
 
 Description:
diff --git a/third_party/llvm-libc/src b/third_party/llvm-libc/src
index ab2f32b..de6fc6c 160000
--- a/third_party/llvm-libc/src
+++ b/third_party/llvm-libc/src
@@ -1 +1 @@
-Subproject commit ab2f32b66014843f072d32d72c560b7dd229c0f3
+Subproject commit de6fc6ccb31619c9ba67ba849d4572835229f270
diff --git a/third_party/openxr/README.chromium b/third_party/openxr/README.chromium
index 2fe5944..1fa3d29 100644
--- a/third_party/openxr/README.chromium
+++ b/third_party/openxr/README.chromium
@@ -3,7 +3,7 @@
 URL: https://github.com/KhronosGroup/OpenXR-SDK
 Version: 1.1.43
 Revision: 781f2eab3698d653c804ecbd11e0aed47eaad1c6
-License: Apache 2.0
+License: Apache-2.0
 License File: src/LICENSE
 Security Critical: yes
 Shipped: yes
@@ -63,7 +63,7 @@
 URL: https://gitlab.freedesktop.org/monado/utilities/android-jni-wrappers
 Version: N/A
 Date: 2023-12-13
-License: Apache 2.0
+License: Apache-2.0
 License File: src/LICENSES/Apache-2.0.txt
 Security Critical: yes
 Shipped: yes
diff --git a/third_party/perfetto b/third_party/perfetto
index b4c1dfa..b5c4a75 160000
--- a/third_party/perfetto
+++ b/third_party/perfetto
@@ -1 +1 @@
-Subproject commit b4c1dfa24715ef5600fd068b646447707cb9ee08
+Subproject commit b5c4a751ca8d5736accf47a9cdfc1a58ff2ef814
diff --git a/third_party/rust/adler2/v2/README.chromium b/third_party/rust/adler2/v2/README.chromium
index 3002c9c..a0a9ea4 100644
--- a/third_party/rust/adler2/v2/README.chromium
+++ b/third_party/rust/adler2/v2/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/adler2
 Version: 2.0.0
 Revision: 8f1f7897870fae9825a92c578a5adbd02f09830e
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/adler2-2.0.0/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/anstyle/v1/README.chromium b/third_party/rust/anstyle/v1/README.chromium
index d2829629..2cde3b1 100644
--- a/third_party/rust/anstyle/v1/README.chromium
+++ b/third_party/rust/anstyle/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/anstyle
 Version: 1.0.10
 Revision: 9ce373f0202db52eea0ba3167fd1c6300a0a17b6
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/anstyle-1.0.10/LICENSE-APACHE
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/anyhow/v1/README.chromium b/third_party/rust/anyhow/v1/README.chromium
index 6114d00..50da0b72 100644
--- a/third_party/rust/anyhow/v1/README.chromium
+++ b/third_party/rust/anyhow/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/anyhow
 Version: 1.0.94
 Revision: 8ceb5e988fcae18270745e291efb8bd716c25bf0
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/anyhow-1.0.94/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/base64/v0_13/README.chromium b/third_party/rust/base64/v0_13/README.chromium
index 23244086..ceaf145 100644
--- a/third_party/rust/base64/v0_13/README.chromium
+++ b/third_party/rust/base64/v0_13/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/base64
 Version: 0.13.1
 Revision: efb0b531c79581978aec5c410d0ae866b21f8aac
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/base64-0.13.1/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/bitflags/v1/README.chromium b/third_party/rust/bitflags/v1/README.chromium
index fc60016..9aa2d77a 100644
--- a/third_party/rust/bitflags/v1/README.chromium
+++ b/third_party/rust/bitflags/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/bitflags
 Version: 1.3.2
 Revision: ed185cfb1c447c1b4bd6ac021c9ec3bb02c9e2f2
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/bitflags-1.3.2/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/bitflags/v2/README.chromium b/third_party/rust/bitflags/v2/README.chromium
index a57abf5..5ff28e04 100644
--- a/third_party/rust/bitflags/v2/README.chromium
+++ b/third_party/rust/bitflags/v2/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/bitflags
 Version: 2.6.0
 Revision: 13513699141432af1dea2a6208e99e7bf21958db
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/bitflags-2.6.0/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/bstr/v1/README.chromium b/third_party/rust/bstr/v1/README.chromium
index 3f836e9e..ffe55d7 100644
--- a/third_party/rust/bstr/v1/README.chromium
+++ b/third_party/rust/bstr/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/bstr
 Version: 1.11.0
 Revision: 41f8bdb9ec08912a38a1b2da704fcf0a19fcea45
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/bstr-1.11.0/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/bytemuck/v1/README.chromium b/third_party/rust/bytemuck/v1/README.chromium
index 0f65dd4..ae61361 100644
--- a/third_party/rust/bytemuck/v1/README.chromium
+++ b/third_party/rust/bytemuck/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/bytemuck
 Version: 1.19.0
 Revision: 7b98ff1cec8df2be270410f2c42c655f5abd66b2
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/bytemuck-1.19.0/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/bytemuck_derive/v1/README.chromium b/third_party/rust/bytemuck_derive/v1/README.chromium
index 02d798d..c353c353 100644
--- a/third_party/rust/bytemuck_derive/v1/README.chromium
+++ b/third_party/rust/bytemuck_derive/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/bytemuck_derive
 Version: 1.8.0
 Revision: 48952a0246ffb54b8cdea1c6adc561ee430420a3
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/bytemuck_derive-1.8.0/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/cfg_if/v1/README.chromium b/third_party/rust/cfg_if/v1/README.chromium
index 1cbf5b0..4d3e0778 100644
--- a/third_party/rust/cfg_if/v1/README.chromium
+++ b/third_party/rust/cfg_if/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/cfg-if
 Version: 1.0.0
 Revision: e60fa1efeab0ec6e90c50d93ec526e1410459c23
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/cfg-if-1.0.0/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/clap/v4/README.chromium b/third_party/rust/clap/v4/README.chromium
index 0ef91f6..18f7c1d 100644
--- a/third_party/rust/clap/v4/README.chromium
+++ b/third_party/rust/clap/v4/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/clap
 Version: 4.5.21
 Revision: 2920fb082c987acb72ed1d1f47991c4d157e380d
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/clap-4.5.21/LICENSE-APACHE
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/clap_builder/v4/README.chromium b/third_party/rust/clap_builder/v4/README.chromium
index d6aae12..7b34197 100644
--- a/third_party/rust/clap_builder/v4/README.chromium
+++ b/third_party/rust/clap_builder/v4/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/clap_builder
 Version: 4.5.21
 Revision: 2920fb082c987acb72ed1d1f47991c4d157e380d
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/clap_builder-4.5.21/LICENSE-APACHE
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/clap_lex/v0_7/README.chromium b/third_party/rust/clap_lex/v0_7/README.chromium
index b212860..019d93d 100644
--- a/third_party/rust/clap_lex/v0_7/README.chromium
+++ b/third_party/rust/clap_lex/v0_7/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/clap_lex
 Version: 0.7.3
 Revision: 2920fb082c987acb72ed1d1f47991c4d157e380d
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/clap_lex-0.7.3/LICENSE-APACHE
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/codespan_reporting/v0_11/README.chromium b/third_party/rust/codespan_reporting/v0_11/README.chromium
index b10578b..81972a59 100644
--- a/third_party/rust/codespan_reporting/v0_11/README.chromium
+++ b/third_party/rust/codespan_reporting/v0_11/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/codespan-reporting
 Version: 0.11.1
 Revision: fd389a13f5bb6d625b71e2e4694b26e127f393f9
-License: Apache 2.0
+License: Apache-2.0
 License File:
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/crc32fast/v1/README.chromium b/third_party/rust/crc32fast/v1/README.chromium
index 63fb39e4..d833b9a 100644
--- a/third_party/rust/crc32fast/v1/README.chromium
+++ b/third_party/rust/crc32fast/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/crc32fast
 Version: 1.4.2
 Revision: b0899ffddc050eca040c4fc23a37a058d3017ce9
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/crc32fast-1.4.2/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/cxx/v1/README.chromium b/third_party/rust/cxx/v1/README.chromium
index 4ea7cd5..e2ea7e9 100644
--- a/third_party/rust/cxx/v1/README.chromium
+++ b/third_party/rust/cxx/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/cxx
 Version: 1.0.131
 Revision: 3c5cf5c485ddf8200058d041bb539875a483d427
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/cxx-1.0.131/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/cxxbridge_cmd/v1/README.chromium b/third_party/rust/cxxbridge_cmd/v1/README.chromium
index 09c6f43..dacefa7 100644
--- a/third_party/rust/cxxbridge_cmd/v1/README.chromium
+++ b/third_party/rust/cxxbridge_cmd/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/cxxbridge-cmd
 Version: 1.0.131
 Revision: 3c5cf5c485ddf8200058d041bb539875a483d427
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/cxxbridge-cmd-1.0.131/LICENSE-APACHE
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/cxxbridge_flags/v1/README.chromium b/third_party/rust/cxxbridge_flags/v1/README.chromium
index 2199f01..00f7b67a 100644
--- a/third_party/rust/cxxbridge_flags/v1/README.chromium
+++ b/third_party/rust/cxxbridge_flags/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/cxxbridge-flags
 Version: 1.0.131
 Revision: 3c5cf5c485ddf8200058d041bb539875a483d427
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/cxxbridge-flags-1.0.131/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/cxxbridge_macro/v1/README.chromium b/third_party/rust/cxxbridge_macro/v1/README.chromium
index a06a2693..9a69f6b 100644
--- a/third_party/rust/cxxbridge_macro/v1/README.chromium
+++ b/third_party/rust/cxxbridge_macro/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/cxxbridge-macro
 Version: 1.0.131
 Revision: 3c5cf5c485ddf8200058d041bb539875a483d427
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/cxxbridge-macro-1.0.131/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/either/v1/README.chromium b/third_party/rust/either/v1/README.chromium
index dfd1662..514a9345 100644
--- a/third_party/rust/either/v1/README.chromium
+++ b/third_party/rust/either/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/either
 Version: 1.13.0
 Revision: e3ec2506f97ab27df3fbb284a3459280cb692c97
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/either-1.13.0/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/fdeflate/v0_3/README.chromium b/third_party/rust/fdeflate/v0_3/README.chromium
index 408d8d4..6d091be 100644
--- a/third_party/rust/fdeflate/v0_3/README.chromium
+++ b/third_party/rust/fdeflate/v0_3/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/fdeflate
 Version: 0.3.7
 Revision: c365c7e6ffa81feb2e1fb762eed7299f05c9b0ca
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/fdeflate-0.3.7/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/flate2/v1/README.chromium b/third_party/rust/flate2/v1/README.chromium
index 5ee7bd1..378ff6d 100644
--- a/third_party/rust/flate2/v1/README.chromium
+++ b/third_party/rust/flate2/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/flate2
 Version: 1.0.35
 Revision: 14aec222af2b85485bd3df4578d8d510eca46af7
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/flate2-1.0.35/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/font_types/v0_7/README.chromium b/third_party/rust/font_types/v0_7/README.chromium
index 978df84..5fd2c4ba 100644
--- a/third_party/rust/font_types/v0_7/README.chromium
+++ b/third_party/rust/font_types/v0_7/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/font-types
 Version: 0.7.3
 Revision: 25d04d8205455be59155d8a14aa25f182012ae5c
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/font-types-0.7.3/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/getrandom/v0_2/README.chromium b/third_party/rust/getrandom/v0_2/README.chromium
index fecbfad..26c6394 100644
--- a/third_party/rust/getrandom/v0_2/README.chromium
+++ b/third_party/rust/getrandom/v0_2/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/getrandom
 Version: 0.2.15
 Revision: cf65e83f9df8954df101320de86f80dccfc6b68a
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/getrandom-0.2.15/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/glob/v0_3/README.chromium b/third_party/rust/glob/v0_3/README.chromium
index 3efc11e..446f28f 100644
--- a/third_party/rust/glob/v0_3/README.chromium
+++ b/third_party/rust/glob/v0_3/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/glob
 Version: 0.3.1
 Revision: 408e579f74830c2073180a7e4e214a2677d38a49
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/glob-0.3.1/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/heck/v0_4/README.chromium b/third_party/rust/heck/v0_4/README.chromium
index 7401e7b..efc124c 100644
--- a/third_party/rust/heck/v0_4/README.chromium
+++ b/third_party/rust/heck/v0_4/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/heck
 Version: 0.4.1
 Revision: 76a8274f948fbe3551413dc09026b733aca71995
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/heck-0.4.1/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/hex/v0_4/README.chromium b/third_party/rust/hex/v0_4/README.chromium
index 1f12518..7de0be2e 100644
--- a/third_party/rust/hex/v0_4/README.chromium
+++ b/third_party/rust/hex/v0_4/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/hex
 Version: 0.4.3
 Revision: b2b4370b5bf021b98ee7adc92233e8de3f2de792
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/hex-0.4.3/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/hex_literal/v0_4/README.chromium b/third_party/rust/hex_literal/v0_4/README.chromium
index 59d2e369..2b68aa1 100644
--- a/third_party/rust/hex_literal/v0_4/README.chromium
+++ b/third_party/rust/hex_literal/v0_4/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/hex-literal
 Version: 0.4.1
 Revision: b8bd42f441f8e2987ded60fbaa809e7bf9d17a8e
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/hex-literal-0.4.1/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/itertools/v0_11/README.chromium b/third_party/rust/itertools/v0_11/README.chromium
index 058e82e..e9d14fdd 100644
--- a/third_party/rust/itertools/v0_11/README.chromium
+++ b/third_party/rust/itertools/v0_11/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/itertools
 Version: 0.11.0
 Revision: 62a6401afd6d45e1c2aea94c05cb5c70076b2ca4
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/itertools-0.11.0/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/itoa/v1/README.chromium b/third_party/rust/itoa/v1/README.chromium
index 5fe608f..6100f4c 100644
--- a/third_party/rust/itoa/v1/README.chromium
+++ b/third_party/rust/itoa/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/itoa
 Version: 1.0.14
 Revision: 7e6b2580b1ac3ad7d6f25887af01a09686c0ea5c
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/itoa-1.0.14/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/lazy_static/v1/README.chromium b/third_party/rust/lazy_static/v1/README.chromium
index 5a793999..2013661 100644
--- a/third_party/rust/lazy_static/v1/README.chromium
+++ b/third_party/rust/lazy_static/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/lazy_static
 Version: 1.5.0
 Revision: be7c1c43f264699f956b70ce8e29941bd1e61bde
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/lazy_static-1.5.0/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/libc/v0_2/README.chromium b/third_party/rust/libc/v0_2/README.chromium
index 5e70ce5..1e4de862 100644
--- a/third_party/rust/libc/v0_2/README.chromium
+++ b/third_party/rust/libc/v0_2/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/libc
 Version: 0.2.167
 Revision: 3831e59feb28cdf00a80b2c5ca85af47b1659fb3
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/libc-0.2.167/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/log/v0_4/README.chromium b/third_party/rust/log/v0_4/README.chromium
index c2f6a5ef4..e9dd25ef 100644
--- a/third_party/rust/log/v0_4/README.chromium
+++ b/third_party/rust/log/v0_4/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/log
 Version: 0.4.22
 Revision: d5ba2cfee9b3b4ca1fcad911b7f59dc79eeee022
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/log-0.4.22/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/miniz_oxide/v0_8/README.chromium b/third_party/rust/miniz_oxide/v0_8/README.chromium
index f641feea..1127e124 100644
--- a/third_party/rust/miniz_oxide/v0_8/README.chromium
+++ b/third_party/rust/miniz_oxide/v0_8/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/miniz_oxide
 Version: 0.8.0
 Revision: 58cf901875b2a5b3c9eeb844bd534f6cee54f847
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/miniz_oxide-0.8.0/LICENSE,//third_party/rust/chromium_crates_io/vendor/miniz_oxide-0.8.0/LICENSE-APACHE.md
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/png/v0_17/README.chromium b/third_party/rust/png/v0_17/README.chromium
index 6644c98b..c2a4ec1 100644
--- a/third_party/rust/png/v0_17/README.chromium
+++ b/third_party/rust/png/v0_17/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/png
 Version: 0.17.15
 Revision: 10644dbff4d5b5614199cbc81145838abdafd98c
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/png-0.17.15/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/ppv_lite86/v0_2/README.chromium b/third_party/rust/ppv_lite86/v0_2/README.chromium
index b9565e7..07e80b99 100644
--- a/third_party/rust/ppv_lite86/v0_2/README.chromium
+++ b/third_party/rust/ppv_lite86/v0_2/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/ppv-lite86
 Version: 0.2.20
 Revision: 16e2fe894fc39944c2625d735fff3d697d052e42
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/ppv-lite86-0.2.20/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/proc_macro2/v1/README.chromium b/third_party/rust/proc_macro2/v1/README.chromium
index 4053ce3..ae58e8b 100644
--- a/third_party/rust/proc_macro2/v1/README.chromium
+++ b/third_party/rust/proc_macro2/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/proc-macro2
 Version: 1.0.89
 Revision: 671d87da32779e3a5c4cecacd8a9234e0e27630c
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/proc-macro2-1.0.89/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/prost/v0_13/README.chromium b/third_party/rust/prost/v0_13/README.chromium
index 169e1afb..1df0665 100644
--- a/third_party/rust/prost/v0_13/README.chromium
+++ b/third_party/rust/prost/v0_13/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/prost
 Version: 0.13.3
 Revision: 9ed944eb633480079037dfceeee61aac6cd0c94f
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/prost-0.13.3/LICENSE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/prost_derive/v0_13/README.chromium b/third_party/rust/prost_derive/v0_13/README.chromium
index ba9304e..143e1db 100644
--- a/third_party/rust/prost_derive/v0_13/README.chromium
+++ b/third_party/rust/prost_derive/v0_13/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/prost-derive
 Version: 0.13.3
 Revision: 9ed944eb633480079037dfceeee61aac6cd0c94f
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/prost-derive-0.13.3/LICENSE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/qr_code/v2/README.chromium b/third_party/rust/qr_code/v2/README.chromium
index 5eb8384..8a5ca2bfe 100644
--- a/third_party/rust/qr_code/v2/README.chromium
+++ b/third_party/rust/qr_code/v2/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/qr_code
 Version: 2.0.0
 Revision: 341f62be3a91ecb05e6e0870e61f763308eaf2ff
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/qr_code-2.0.0/LICENSE-APACHE.txt
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/quote/v1/README.chromium b/third_party/rust/quote/v1/README.chromium
index e257a10..618395b 100644
--- a/third_party/rust/quote/v1/README.chromium
+++ b/third_party/rust/quote/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/quote
 Version: 1.0.37
 Revision: b1ebffa035363a430862e033aa3268e8cb17affa
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/quote-1.0.37/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/rand/v0_8/README.chromium b/third_party/rust/rand/v0_8/README.chromium
index 90967ef..39835ffd 100644
--- a/third_party/rust/rand/v0_8/README.chromium
+++ b/third_party/rust/rand/v0_8/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rand
 Version: 0.8.5
 Revision: 937320cbfeebd4352a23086d9c6e68f067f74644
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rand-0.8.5/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/rand_chacha/v0_3/README.chromium b/third_party/rust/rand_chacha/v0_3/README.chromium
index b718f5d6..a3e716a 100644
--- a/third_party/rust/rand_chacha/v0_3/README.chromium
+++ b/third_party/rust/rand_chacha/v0_3/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rand_chacha
 Version: 0.3.1
 Revision: 98a0339f99ecfe0467b2829c329bd8b7525a1c21
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rand_chacha-0.3.1/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/rand_core/v0_6/README.chromium b/third_party/rust/rand_core/v0_6/README.chromium
index 92a1bd3e..9de9bdd2 100644
--- a/third_party/rust/rand_core/v0_6/README.chromium
+++ b/third_party/rust/rand_core/v0_6/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rand_core
 Version: 0.6.4
 Revision: 89a1336b934c68ddce548127c6f8afd910b35a18
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rand_core-0.6.4/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/rand_pcg/v0_3/README.chromium b/third_party/rust/rand_pcg/v0_3/README.chromium
index 77e78fff..62f5c52 100644
--- a/third_party/rust/rand_pcg/v0_3/README.chromium
+++ b/third_party/rust/rand_pcg/v0_3/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rand_pcg
 Version: 0.3.1
 Revision: 8792268dfe57e49bb4518190bf4fe66176759a44
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rand_pcg-0.3.1/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/read_fonts/v0_23/README.chromium b/third_party/rust/read_fonts/v0_23/README.chromium
index 23a0ca25..de9f2a0 100644
--- a/third_party/rust/read_fonts/v0_23/README.chromium
+++ b/third_party/rust/read_fonts/v0_23/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/read-fonts
 Version: 0.23.2
 Revision: 25d04d8205455be59155d8a14aa25f182012ae5c
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/read-fonts-0.23.2/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/regex/v1/README.chromium b/third_party/rust/regex/v1/README.chromium
index f2ac41d..8bffb9981 100644
--- a/third_party/rust/regex/v1/README.chromium
+++ b/third_party/rust/regex/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/regex
 Version: 1.11.1
 Revision: 9870c06e6c772daaad7ab612faab29130753e41c
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/regex-1.11.1/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/regex_automata/v0_4/README.chromium b/third_party/rust/regex_automata/v0_4/README.chromium
index 9b14b5a3..cf14174 100644
--- a/third_party/rust/regex_automata/v0_4/README.chromium
+++ b/third_party/rust/regex_automata/v0_4/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/regex-automata
 Version: 0.4.9
 Revision: 1a069b9232c607b34c4937122361aa075ef573fa
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/regex-automata-0.4.9/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/regex_syntax/v0_8/README.chromium b/third_party/rust/regex_syntax/v0_8/README.chromium
index 2619e33..6fd11493 100644
--- a/third_party/rust/regex_syntax/v0_8/README.chromium
+++ b/third_party/rust/regex_syntax/v0_8/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/regex-syntax
 Version: 0.8.5
 Revision: cba0fbc0194456f644040d7558ae6ed261d57cc2
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/regex-syntax-0.8.5/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/relative_path/v1/README.chromium b/third_party/rust/relative_path/v1/README.chromium
index 606ec77..2cb7ed1 100644
--- a/third_party/rust/relative_path/v1/README.chromium
+++ b/third_party/rust/relative_path/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/relative-path
 Version: 1.9.3
 Revision: 6d267fbd85b257e4416c9f020131c6da168e1d3d
-License: Apache 2.0
+License: Apache-2.0
 License File:
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/rstest/v0_22/README.chromium b/third_party/rust/rstest/v0_22/README.chromium
index 91a8a88..e187402 100644
--- a/third_party/rust/rstest/v0_22/README.chromium
+++ b/third_party/rust/rstest/v0_22/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rstest
 Version: 0.22.0
 Revision: 62134281cf451fc2bea69f9d2a16805a9ad03fef
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rstest-0.22.0/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/rstest_macros/v0_22/README.chromium b/third_party/rust/rstest_macros/v0_22/README.chromium
index 3f7833b..df88d22e 100644
--- a/third_party/rust/rstest_macros/v0_22/README.chromium
+++ b/third_party/rust/rstest_macros/v0_22/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rstest_macros
 Version: 0.22.0
 Revision: 62134281cf451fc2bea69f9d2a16805a9ad03fef
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rstest_macros-0.22.0/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/rstest_reuse/v0_7/README.chromium b/third_party/rust/rstest_reuse/v0_7/README.chromium
index 5659dc7..202988f5 100644
--- a/third_party/rust/rstest_reuse/v0_7/README.chromium
+++ b/third_party/rust/rstest_reuse/v0_7/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rstest_reuse
 Version: 0.7.0
 Revision: 5112bf74303f91f181736127321add94592e275f
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rstest_reuse-0.7.0/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/rustc_demangle/v0_1/README.chromium b/third_party/rust/rustc_demangle/v0_1/README.chromium
index c45e4ae..2261289 100644
--- a/third_party/rust/rustc_demangle/v0_1/README.chromium
+++ b/third_party/rust/rustc_demangle/v0_1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rustc-demangle
 Version: 0.1.24
 Revision: d43f6d58562319e93a492ac8ceb3fe258beefaf4
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rustc-demangle-0.1.24/LICENSE-APACHE
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/rustc_demangle_capi/v0_1/README.chromium b/third_party/rust/rustc_demangle_capi/v0_1/README.chromium
index 80994762..7d8e952f 100644
--- a/third_party/rust/rustc_demangle_capi/v0_1/README.chromium
+++ b/third_party/rust/rustc_demangle_capi/v0_1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rustc-demangle-capi
 Version: 0.1.0
 Revision: f540792067ab84d0f47164b29d7db5c7ba3b367d
-License: Apache 2.0
+License: Apache-2.0
 License File:
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/rustc_version/v0_4/README.chromium b/third_party/rust/rustc_version/v0_4/README.chromium
index f819ed46..d157d0ae 100644
--- a/third_party/rust/rustc_version/v0_4/README.chromium
+++ b/third_party/rust/rustc_version/v0_4/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rustc_version
 Version: 0.4.1
 Revision: eeca449cca83e24150e46739e797aa82e9142809
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rustc_version-0.4.1/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/rustversion/v1/README.chromium b/third_party/rust/rustversion/v1/README.chromium
index 5c656aa..ad3ce82 100644
--- a/third_party/rust/rustversion/v1/README.chromium
+++ b/third_party/rust/rustversion/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/rustversion
 Version: 1.0.18
 Revision: 04f18461f03f7586b32238529b3e6c4731e63db5
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/rustversion-1.0.18/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/ryu/v1/README.chromium b/third_party/rust/ryu/v1/README.chromium
index 2e390cb9..863e804 100644
--- a/third_party/rust/ryu/v1/README.chromium
+++ b/third_party/rust/ryu/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/ryu
 Version: 1.0.18
 Revision: 12746aa88cc51a6f1fc97f92b8d36d991c2d966e
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/ryu-1.0.18/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/semver/v1/README.chromium b/third_party/rust/semver/v1/README.chromium
index 2e8837f..90df049 100644
--- a/third_party/rust/semver/v1/README.chromium
+++ b/third_party/rust/semver/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/semver
 Version: 1.0.23
 Revision: 69efd3cc770ead273a06ad1788477b3092996d29
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/semver-1.0.23/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/serde/v1/README.chromium b/third_party/rust/serde/v1/README.chromium
index 0473adf..c03dc8b 100644
--- a/third_party/rust/serde/v1/README.chromium
+++ b/third_party/rust/serde/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/serde
 Version: 1.0.215
 Revision: 8939af48fecb965eb3ff04dc8969146d5af5ca0f
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/serde-1.0.215/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/serde_derive/v1/README.chromium b/third_party/rust/serde_derive/v1/README.chromium
index 7c34c3c..f8c0c31 100644
--- a/third_party/rust/serde_derive/v1/README.chromium
+++ b/third_party/rust/serde_derive/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/serde_derive
 Version: 1.0.215
 Revision: 8939af48fecb965eb3ff04dc8969146d5af5ca0f
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/serde_derive-1.0.215/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/serde_json/v1/README.chromium b/third_party/rust/serde_json/v1/README.chromium
index 80969ad..a145dbe8 100644
--- a/third_party/rust/serde_json/v1/README.chromium
+++ b/third_party/rust/serde_json/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/serde_json
 Version: 1.0.133
 Revision: 0903de449c52c1b4a2271e909b7afb18909dc379
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/serde_json-1.0.133/LICENSE-APACHE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/serde_json_lenient/v0_2/README.chromium b/third_party/rust/serde_json_lenient/v0_2/README.chromium
index 1d076987..778ea7c 100644
--- a/third_party/rust/serde_json_lenient/v0_2/README.chromium
+++ b/third_party/rust/serde_json_lenient/v0_2/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/serde_json_lenient
 Version: 0.2.3
 Revision: 422da85272805a597368a17a01d477e153a8913e
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/serde_json_lenient-0.2.3/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/skrifa/v0_24/README.chromium b/third_party/rust/skrifa/v0_24/README.chromium
index 7887428..1118ce1 100644
--- a/third_party/rust/skrifa/v0_24/README.chromium
+++ b/third_party/rust/skrifa/v0_24/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/skrifa
 Version: 0.24.1
 Revision: 25d04d8205455be59155d8a14aa25f182012ae5c
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/skrifa-0.24.1/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/small_ctor/v0_1/README.chromium b/third_party/rust/small_ctor/v0_1/README.chromium
index 99fc6484..6904089 100644
--- a/third_party/rust/small_ctor/v0_1/README.chromium
+++ b/third_party/rust/small_ctor/v0_1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/small_ctor
 Version: 0.1.2
 Revision: 81ca7a1ff7c309f784a4c20eb99a3aeea43b80ca
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/small_ctor-0.1.2/LICENSE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/static_assertions/v1/README.chromium b/third_party/rust/static_assertions/v1/README.chromium
index 6b93daa..5f159487 100644
--- a/third_party/rust/static_assertions/v1/README.chromium
+++ b/third_party/rust/static_assertions/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/static_assertions
 Version: 1.1.0
 Revision: 18bc65a094d890fe1faa5d3ccb70f12b89eabf56
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/static_assertions-1.1.0/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/syn/v2/README.chromium b/third_party/rust/syn/v2/README.chromium
index 285a8db2..4254f44f 100644
--- a/third_party/rust/syn/v2/README.chromium
+++ b/third_party/rust/syn/v2/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/syn
 Version: 2.0.87
 Revision: a777cff00528f270b43f40b0a58c5c26fc85a2bd
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/syn-2.0.87/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/tinyvec/v1/README.chromium b/third_party/rust/tinyvec/v1/README.chromium
index 51e7930..b6042e0 100644
--- a/third_party/rust/tinyvec/v1/README.chromium
+++ b/third_party/rust/tinyvec/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/tinyvec
 Version: 1.8.0
 Revision: 4afac90195d3032eee7f1651111c0e78dd5b99a3
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/tinyvec-1.8.0/LICENSE-APACHE.md
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/unicode_ident/v1/README.chromium b/third_party/rust/unicode_ident/v1/README.chromium
index 9e0ddb6..910d5b31 100644
--- a/third_party/rust/unicode_ident/v1/README.chromium
+++ b/third_party/rust/unicode_ident/v1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/unicode-ident
 Version: 1.0.13
 Revision: e34a369149a64064013c29f6c36e8f2bbc450656
-License: Apache 2.0 AND Unicode License Agreement - Data Files and Software (2016)
+License: Apache-2.0, Unicode-DFS-2016
 License File: //third_party/rust/chromium_crates_io/vendor/unicode-ident-1.0.13/LICENSE-APACHE,//third_party/rust/chromium_crates_io/vendor/unicode-ident-1.0.13/LICENSE-UNICODE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/unicode_linebreak/v0_1/README.chromium b/third_party/rust/unicode_linebreak/v0_1/README.chromium
index dd06004..1d046e4 100644
--- a/third_party/rust/unicode_linebreak/v0_1/README.chromium
+++ b/third_party/rust/unicode_linebreak/v0_1/README.chromium
@@ -1,7 +1,7 @@
 Name: unicode-linebreak
 URL: https://crates.io/crates/unicode-linebreak
 Version: 0.1.5
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/unicode-linebreak-0.1.5/LICENSE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/unicode_width/v0_1/README.chromium b/third_party/rust/unicode_width/v0_1/README.chromium
index c41bb05..476a68a 100644
--- a/third_party/rust/unicode_width/v0_1/README.chromium
+++ b/third_party/rust/unicode_width/v0_1/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/unicode-width
 Version: 0.1.14
 Revision: 9eaafa5f91b737bb5958d46f9647aa11104c6f25
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/unicode-width-0.1.14/LICENSE-APACHE
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/windows_aarch64_msvc/v0_52/README.chromium b/third_party/rust/windows_aarch64_msvc/v0_52/README.chromium
index 9fbee714..530b277c 100644
--- a/third_party/rust/windows_aarch64_msvc/v0_52/README.chromium
+++ b/third_party/rust/windows_aarch64_msvc/v0_52/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/windows_aarch64_msvc
 Version: 0.52.6
 Revision: db06b51c2ebb743efb544d40e3064efa49f28d38
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/windows_aarch64_msvc-0.52.6/license-apache-2.0
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/windows_i686_msvc/v0_52/README.chromium b/third_party/rust/windows_i686_msvc/v0_52/README.chromium
index 66bf0b4..1da909b 100644
--- a/third_party/rust/windows_i686_msvc/v0_52/README.chromium
+++ b/third_party/rust/windows_i686_msvc/v0_52/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/windows_i686_msvc
 Version: 0.52.6
 Revision: db06b51c2ebb743efb544d40e3064efa49f28d38
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/windows_i686_msvc-0.52.6/license-apache-2.0
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/windows_sys/v0_52/README.chromium b/third_party/rust/windows_sys/v0_52/README.chromium
index 59430bd..b65a1975 100644
--- a/third_party/rust/windows_sys/v0_52/README.chromium
+++ b/third_party/rust/windows_sys/v0_52/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/windows-sys
 Version: 0.52.0
 Revision: 3a605cba064b26f2a198ac58085f8c8836f47c38
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/windows-sys-0.52.0/license-apache-2.0
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/windows_targets/v0_52/README.chromium b/third_party/rust/windows_targets/v0_52/README.chromium
index c83ec7d5..d4019b17 100644
--- a/third_party/rust/windows_targets/v0_52/README.chromium
+++ b/third_party/rust/windows_targets/v0_52/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/windows-targets
 Version: 0.52.6
 Revision: db06b51c2ebb743efb544d40e3064efa49f28d38
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/windows-targets-0.52.6/license-apache-2.0
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/windows_x86_64_msvc/v0_52/README.chromium b/third_party/rust/windows_x86_64_msvc/v0_52/README.chromium
index 9c9f5fa..44473934 100644
--- a/third_party/rust/windows_x86_64_msvc/v0_52/README.chromium
+++ b/third_party/rust/windows_x86_64_msvc/v0_52/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/windows_x86_64_msvc
 Version: 0.52.6
 Revision: db06b51c2ebb743efb544d40e3064efa49f28d38
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/windows_x86_64_msvc-0.52.6/license-apache-2.0
 Shipped: no
 Security Critical: yes
diff --git a/third_party/rust/wycheproof/v0_4/README.chromium b/third_party/rust/wycheproof/v0_4/README.chromium
index 6186b5f..54c0f63 100644
--- a/third_party/rust/wycheproof/v0_4/README.chromium
+++ b/third_party/rust/wycheproof/v0_4/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/wycheproof
 Version: 0.4.0
 Revision: be067ecfc83ab2630c16081a1aa454a0135c86f5
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/wycheproof-0.4.0/LICENSE
 Shipped: no
 Security Critical: no
diff --git a/third_party/rust/zerocopy/v0_7/README.chromium b/third_party/rust/zerocopy/v0_7/README.chromium
index ba1f724..be199780a 100644
--- a/third_party/rust/zerocopy/v0_7/README.chromium
+++ b/third_party/rust/zerocopy/v0_7/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/zerocopy
 Version: 0.7.35
 Revision: 727de668608f2d16e151c42e344d172c0931b1e9
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/zerocopy-0.7.35/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/rust/zerocopy_derive/v0_7/README.chromium b/third_party/rust/zerocopy_derive/v0_7/README.chromium
index 1decdea2..554b8b2 100644
--- a/third_party/rust/zerocopy_derive/v0_7/README.chromium
+++ b/third_party/rust/zerocopy_derive/v0_7/README.chromium
@@ -2,7 +2,7 @@
 URL: https://crates.io/crates/zerocopy-derive
 Version: 0.7.35
 Revision: 727de668608f2d16e151c42e344d172c0931b1e9
-License: Apache 2.0
+License: Apache-2.0
 License File: //third_party/rust/chromium_crates_io/vendor/zerocopy-derive-0.7.35/LICENSE-APACHE
 Shipped: yes
 Security Critical: yes
diff --git a/third_party/skia b/third_party/skia
index 4c5f736b..9495576 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit 4c5f736b89157519dcdad75c9801c1af9d765f8f
+Subproject commit 9495576979226fc3eac8acb6b29aaef09ffd9da2
diff --git a/third_party/utf/README.chromium b/third_party/utf/README.chromium
index ec718dab..1de12f1f 100644
--- a/third_party/utf/README.chromium
+++ b/third_party/utf/README.chromium
@@ -4,7 +4,7 @@
 Version: ee5074db68f498a5c802dc9f1645f396c219938a
 Revision: ee5074db68f498a5c802dc9f1645f396c219938a
 Date: 2021-01-05
-License: MIT License
+License: Unicode-DFS-2015, MIT
 License File: LICENSE
 Security Critical: Yes
 Shipped: yes
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src
index 3ed497b..58d5109 160000
--- a/third_party/webgpu-cts/src
+++ b/third_party/webgpu-cts/src
@@ -1 +1 @@
-Subproject commit 3ed497b59345978f8460b5e375e7cd18f3b98872
+Subproject commit 58d51090746647c523ddda207a5ecd5cc3cc1d58
diff --git a/third_party/webrtc b/third_party/webrtc
index 8d5b344..a2c84a7 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit 8d5b344b05e2415be08d31a21c09f89c1d220741
+Subproject commit a2c84a713ff9bda1add0c1c1f7a03983fe110b15
diff --git a/third_party/xcbproto/README.chromium b/third_party/xcbproto/README.chromium
index c795d76..c48b4b1c 100644
--- a/third_party/xcbproto/README.chromium
+++ b/third_party/xcbproto/README.chromium
@@ -6,7 +6,7 @@
 CPEPrefix: unknown
 Security Critical: no
 Shipped: no
-License: MIT
+License: X11
 License File: src/COPYING
 
 Description:
diff --git a/tools/crates/gnrt/lib/readme.rs b/tools/crates/gnrt/lib/readme.rs
index f38a03e6..7f4851b 100644
--- a/tools/crates/gnrt/lib/readme.rs
+++ b/tools/crates/gnrt/lib/readme.rs
@@ -211,54 +211,54 @@
 // crates.io, and the format to write to README.chromium.
 static ALLOWED_LICENSES: [(&str, &str); 22] = [
     // ("Cargo.toml string", "License for README.chromium")
-    ("Apache-2.0", "Apache 2.0"),
-    ("MIT OR Apache-2.0", "Apache 2.0"),
-    ("MIT/Apache-2.0", "Apache 2.0"),
-    ("MIT / Apache-2.0", "Apache 2.0"),
-    ("Apache-2.0 / MIT", "Apache 2.0"),
-    ("Apache-2.0 OR MIT", "Apache 2.0"),
-    ("Apache-2.0/MIT", "Apache 2.0"),
-    ("(Apache-2.0 OR MIT) AND BSD-3-Clause", "Apache 2.0 | BSD 3-Clause"),
-    ("MIT OR Apache-2.0 OR Zlib", "Apache 2.0"),
+    ("Apache-2.0", "Apache-2.0"),
+    ("MIT OR Apache-2.0", "Apache-2.0"),
+    ("MIT/Apache-2.0", "Apache-2.0"),
+    ("MIT / Apache-2.0", "Apache-2.0"),
+    ("Apache-2.0 / MIT", "Apache-2.0"),
+    ("Apache-2.0 OR MIT", "Apache-2.0"),
+    ("Apache-2.0/MIT", "Apache-2.0"),
+    ("(Apache-2.0 OR MIT) AND BSD-3-Clause", "Apache-2.0, BSD-3-Clause"),
+    ("MIT OR Apache-2.0 OR Zlib", "Apache-2.0"),
     ("MIT", "MIT"),
     ("Unlicense OR MIT", "MIT"),
     ("Unlicense/MIT", "MIT"),
-    ("Apache-2.0 OR BSL-1.0", "Apache 2.0"),
-    ("BSD-3-Clause", "BSD 3-Clause"),
+    ("Apache-2.0 OR BSL-1.0", "Apache-2.0"),
+    ("BSD-3-Clause", "BSD-3-Clause"),
     ("ISC", "ISC"),
-    ("MIT OR Zlib OR Apache-2.0", "Apache 2.0"),
-    ("Zlib OR Apache-2.0 OR MIT", "Apache 2.0"),
-    ("0BSD OR MIT OR Apache-2.0", "Apache 2.0"),
+    ("MIT OR Zlib OR Apache-2.0", "Apache-2.0"),
+    ("Zlib OR Apache-2.0 OR MIT", "Apache-2.0"),
+    ("0BSD OR MIT OR Apache-2.0", "Apache-2.0"),
     (
         "(MIT OR Apache-2.0) AND Unicode-DFS-2016",
-        "Apache 2.0 AND Unicode License Agreement - Data Files and Software (2016)",
+        "Apache-2.0, Unicode-DFS-2016",
     ),
-    ("Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "Apache 2.0"),
-    ("BSD-2-Clause OR Apache-2.0 OR MIT", "Apache 2.0"),
+    ("Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT", "Apache-2.0"),
+    ("BSD-2-Clause OR Apache-2.0 OR MIT", "Apache-2.0"),
     ("Zlib", "Zlib"),
 ];
 
 static EXPECTED_LICENSE_FILE: [(&str, &str); 22] = [
-    ("Apache 2.0", "LICENSE"),
-    ("Apache 2.0", "LICENSE-APACHE"),
-    ("Apache 2.0", "LICENSE-APACHE.md"),
-    ("Apache 2.0", "LICENSE-APACHE.txt"),
-    ("Apache 2.0", "LICENSE.md"),
-    ("Apache 2.0", "license-apache-2.0"),
+    ("Apache-2.0", "LICENSE"),
+    ("Apache-2.0", "LICENSE-APACHE"),
+    ("Apache-2.0", "LICENSE-APACHE.md"),
+    ("Apache-2.0", "LICENSE-APACHE.txt"),
+    ("Apache-2.0", "LICENSE.md"),
+    ("Apache-2.0", "license-apache-2.0"),
     ("MIT", "LICENSE"),
     ("MIT", "LICENSE.md"),
     ("MIT", "LICENSE-MIT"),
     ("MIT", "LICENSE-MIT.txt"),
     ("MIT", "LICENSE-MIT.md"),
-    ("BSD 3-Clause", "LICENSE"),
-    ("BSD 3-Clause", "LICENSE.md"),
-    ("BSD 3-Clause", "LICENSE-BSD"),
-    ("BSD 3-Clause", "LICENSE-BSD.txt"),
-    ("BSD 3-Clause", "LICENSE-BSD.md"),
+    ("BSD-3-Clause", "LICENSE"),
+    ("BSD-3-Clause", "LICENSE.md"),
+    ("BSD-3-Clause", "LICENSE-BSD"),
+    ("BSD-3-Clause", "LICENSE-BSD.txt"),
+    ("BSD-3-Clause", "LICENSE-BSD.md"),
     ("ISC", "LICENSE"),
     ("ISC", "LICENSE.md"),
     ("ISC", "LICENSE-ISC"),
-    ("Apache 2.0 | BSD 3-Clause", "LICENSE"),
-    ("Apache 2.0 | BSD 3-Clause", "LICENSE.md"),
+    ("Apache-2.0, BSD-3-Clause", "LICENSE"),
+    ("Apache-2.0, BSD-3-Clause", "LICENSE.md"),
     ("Zlib", "LICENSE"),
 ];
diff --git a/tools/metrics/histograms/metadata/extensions/histograms.xml b/tools/metrics/histograms/metadata/extensions/histograms.xml
index 64c941d..151c721e 100644
--- a/tools/metrics/histograms/metadata/extensions/histograms.xml
+++ b/tools/metrics/histograms/metadata/extensions/histograms.xml
@@ -3953,8 +3953,8 @@
     It is permuted by channel type (message type). {ChannelType}.
   </summary>
   <token key="DispatchTarget">
-    <variant name="ForFrame" summary="frame"/>
-    <variant name="ForWorker" summary="worker"/>
+    <variant name=".ForFrame" summary="frame"/>
+    <variant name=".ForWorker" summary="worker"/>
   </token>
   <token key="ChannelType" variants="ChannelType"/>
 </histogram>
diff --git a/tools/metrics/histograms/metadata/fingerprint/enums.xml b/tools/metrics/histograms/metadata/fingerprint/enums.xml
index 4ca1baf9..cc2837f9 100644
--- a/tools/metrics/histograms/metadata/fingerprint/enums.xml
+++ b/tools/metrics/histograms/metadata/fingerprint/enums.xml
@@ -204,6 +204,31 @@
   <int value="5" label="Set enroll mode failed"/>
 </enum>
 
+<enum name="UploadTemplateResStatus">
+  <int value="-1" label="Command failed"/>
+  <int value="0" label="Success"/>
+  <int value="1" label="Invalid command"/>
+  <int value="2" label="Error"/>
+  <int value="3" label="Invalid parameter"/>
+  <int value="4" label="Access denied"/>
+  <int value="5" label="Invalid response"/>
+  <int value="6" label="Invalid version"/>
+  <int value="7" label="Invalid checksum"/>
+  <int value="8" label="In progress"/>
+  <int value="9" label="Unavailable"/>
+  <int value="10" label="Timeout"/>
+  <int value="11" label="Overflow"/>
+  <int value="12" label="Invalid header"/>
+  <int value="13" label="Request truncated"/>
+  <int value="14" label="Response too big"/>
+  <int value="15" label="Bus error"/>
+  <int value="16" label="Busy"/>
+  <int value="17" label="Invalid header version"/>
+  <int value="18" label="Invalid header crc"/>
+  <int value="19" label="Invalid data crc"/>
+  <int value="20" label="DUP unavailable"/>
+</enum>
+
 </enums>
 
 </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/fingerprint/histograms.xml b/tools/metrics/histograms/metadata/fingerprint/histograms.xml
index b77a428..77b10e12 100644
--- a/tools/metrics/histograms/metadata/fingerprint/histograms.xml
+++ b/tools/metrics/histograms/metadata/fingerprint/histograms.xml
@@ -480,6 +480,18 @@
   </token>
 </histogram>
 
+<histogram name="Fingerprint.UploadTemplate.Success"
+    enum="UploadTemplateResStatus" expires_after="2025-12-09">
+  <owner>fsammoura@google.com</owner>
+  <owner>chromeos-fingerprint@google.com</owner>
+  <summary>
+    Reports the result of uploading a fingerprint template to the Fingerprint
+    Microcontroller (FPMCU). Returns an EC result code with the following
+    possible values: -1: Command failure; 0: Success; 1 to 20: Specific error
+    codes (see EC result code documentation for details).
+  </summary>
+</histogram>
+
 <histogram name="Fingerprint.{ContextFunction}" enum="FingerprintSensorMode"
     expires_after="2025-05-29">
   <owner>tomhughes@chromium.org</owner>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json
index c9316bde..ab04a39 100644
--- a/tools/perf/core/perfetto_binary_roller/binary_deps.json
+++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@
             "full_remote_path": "perfetto-luci-artifacts/65d6491a008cb4d626effb25f72219dc179188d8/linux-arm64/trace_processor_shell"
         },
         "win": {
-            "hash": "a4bbc9119dc6e1f028f8ca470160f548cc8f2e13",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/1a0d053d2f0d440bd8cfd1fc6421bccd63dd4041/trace_processor_shell.exe"
+            "hash": "65a389507ac41af859ffe276f4d2b38f69e3e22e",
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/b5c4a751ca8d5736accf47a9cdfc1a58ff2ef814/trace_processor_shell.exe"
         },
         "linux_arm": {
             "hash": "8d23f6f07e4b3472196a878035fc304903813da3",
@@ -22,7 +22,7 @@
         },
         "linux": {
             "hash": "2fe306598e3d339e35c99f5d51be57b05e9c5984",
-            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/b4c1dfa24715ef5600fd068b646447707cb9ee08/trace_processor_shell"
+            "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/b5c4a751ca8d5736accf47a9cdfc1a58ff2ef814/trace_processor_shell"
         }
     },
     "power_profile.sql": {
diff --git a/ui/compositor/test/direct_layer_tree_frame_sink.cc b/ui/compositor/test/direct_layer_tree_frame_sink.cc
index 9922e6a9..e99e4f36 100644
--- a/ui/compositor/test/direct_layer_tree_frame_sink.cc
+++ b/ui/compositor/test/direct_layer_tree_frame_sink.cc
@@ -176,6 +176,8 @@
     DLOG(WARNING) << "Received frame for non-existent widget.";
   }
 #else
+  // Suppress -Wunused-private-field warning.
+  (void)widget_;
   NOTREACHED();
 #endif
 }
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.cc b/ui/views/controls/tabbed_pane/tabbed_pane.cc
index f9c716e..ff1c7b8 100644
--- a/ui/views/controls/tabbed_pane/tabbed_pane.cc
+++ b/ui/views/controls/tabbed_pane/tabbed_pane.cc
@@ -66,22 +66,21 @@
 
 }  // namespace
 
-TabbedPaneTab::TabbedPaneTab(TabbedPane* tabbed_pane,
+TabbedPaneTab::TabbedPaneTab(TabbedPaneTabStrip* tab_strip,
                              const std::u16string& title,
-                             View* contents,
                              const gfx::VectorIcon* tab_icon)
-    : icon_for_tab_(tab_icon), tabbed_pane_(tabbed_pane), contents_(contents) {
+    : tab_strip_(tab_strip), icon_for_tab_(tab_icon) {
   // Calculate the size while the font list is bold.
   auto title_label = std::make_unique<Label>(title, style::CONTEXT_LABEL,
                                              style::STYLE_TAB_ACTIVE);
   title_ = title_label.get();
   UpdatePreferredTitleWidth();
 
-  if (tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kVertical) {
+  if (tab_strip_->GetOrientation() == TabbedPane::Orientation::kVertical) {
     title_label->SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT);
 
     const bool is_highlight_style =
-        tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight;
+        tab_strip_->GetStyle() == TabbedPane::TabStripStyle::kHighlight;
     constexpr auto kTabPadding = gfx::Insets::VH(5, 10);
     constexpr auto kTabPaddingHighlight = gfx::Insets::TLBR(8, 32, 8, 0);
     SetBorder(CreateEmptyBorder(is_highlight_style ? kTabPaddingHighlight
@@ -94,7 +93,7 @@
   SetState(State::kInactive);
 
   // Create an icon if the style requests one.
-  if (tabbed_pane_->HasIconStyle()) {
+  if (tab_strip_->HasIconStyle()) {
     auto icon = std::make_unique<views::ImageView>(
         GetImageModelForTab(GetIconTitleColor()));
     icon->SetProperty(views::kMarginsKey,
@@ -109,7 +108,7 @@
   // Therefore, for a single child, FillLayout is okay. However when multiple
   // elements are present (e.g. icon + text), we need to use a BoxLayout to
   // arrange them correctly.
-  if (tabbed_pane_->HasIconStyle()) {
+  if (tab_strip_->HasIconStyle()) {
     auto box_layout = std::make_unique<BoxLayout>();
     box_layout->set_main_axis_alignment(
         views::BoxLayout::MainAxisAlignment::kCenter);
@@ -136,8 +135,7 @@
 TabbedPaneTab::~TabbedPaneTab() = default;
 
 void TabbedPaneTab::SetSelected(bool selected) {
-  contents_->SetVisible(selected);
-  contents_->parent()->InvalidateLayout();
+  selected_ = selected;
   SetState(selected ? State::kActive : State::kInactive);
 #if BUILDFLAG(IS_MAC)
   SetFocusBehavior(selected ? FocusBehavior::ACCESSIBLE_ONLY
@@ -159,7 +157,7 @@
 
 bool TabbedPaneTab::OnMousePressed(const ui::MouseEvent& event) {
   if (GetEnabled() && event.IsOnlyLeftMouseButton())
-    tabbed_pane_->SelectTab(this);
+    tab_strip_->SelectTab(this);
   return true;
 }
 
@@ -176,7 +174,7 @@
     case ui::EventType::kGestureTapDown:
     case ui::EventType::kGestureTap:
       // SelectTab also sets the right tab color.
-      tabbed_pane_->SelectTab(this);
+      tab_strip_->SelectTab(this);
       break;
     case ui::EventType::kGestureTapCancel:
       SetState(selected() ? State::kActive : State::kInactive);
@@ -193,13 +191,13 @@
 
   // An icon is only present in kCompactWithIcon or kWithIcon styles, in a
   // horizontal orientation.
-  if (tabbed_pane_->HasIconStyle() &&
-      tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kHorizontal) {
+  if (tab_strip_->HasIconStyle() &&
+      tab_strip_->GetOrientation() == TabbedPane::Orientation::kHorizontal) {
     width += icon_view_->GetPreferredSize({}).width() + kIconRightMargin;
   }
 
-  if (tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight &&
-      tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kVertical) {
+  if (tab_strip_->GetStyle() == TabbedPane::TabStripStyle::kHighlight &&
+      tab_strip_->GetOrientation() == TabbedPane::Orientation::kVertical) {
     width = std::max(width, 192);
   }
 
@@ -218,7 +216,7 @@
 
 void TabbedPaneTab::OnFocus() {
   // Do not draw focus ring in kHighlight mode.
-  if (tabbed_pane_->GetStyle() != TabbedPane::TabStripStyle::kHighlight) {
+  if (tab_strip_->GetStyle() != TabbedPane::TabStripStyle::kHighlight) {
     // Maintain the current Insets with CreatePaddedBorder.
     int border_size = 2;
     SetBorder(CreatePaddedBorder(
@@ -232,25 +230,26 @@
 
 void TabbedPaneTab::OnBlur() {
   // Do not draw focus ring in kHighlight mode.
-  if (tabbed_pane_->GetStyle() != TabbedPane::TabStripStyle::kHighlight)
+  if (tab_strip_->GetStyle() != TabbedPane::TabStripStyle::kHighlight) {
     SetBorder(CreateEmptyBorder(GetInsets()));
+  }
   SchedulePaint();
 }
 
 bool TabbedPaneTab::OnKeyPressed(const ui::KeyEvent& event) {
   const ui::KeyboardCode key = event.key_code();
-  if (tabbed_pane_->GetOrientation() == TabbedPane::Orientation::kHorizontal) {
+  if (tab_strip_->GetOrientation() == TabbedPane::Orientation::kHorizontal) {
     // Use left and right arrows to navigate tabs in horizontal orientation.
     int delta = key == ui::VKEY_RIGHT ? 1 : -1;
     if (base::i18n::IsRTL()) {
       delta = key == ui::VKEY_RIGHT ? -1 : 1;
     }
     return (key == ui::VKEY_LEFT || key == ui::VKEY_RIGHT) &&
-           tabbed_pane_->MoveSelectionBy(delta);
+           tab_strip_->MoveSelectionBy(delta);
   }
   // Use up and down arrows to navigate tabs in vertical orientation.
   return (key == ui::VKEY_UP || key == ui::VKEY_DOWN) &&
-         tabbed_pane_->MoveSelectionBy(key == ui::VKEY_DOWN ? 1 : -1);
+         tab_strip_->MoveSelectionBy(key == ui::VKEY_DOWN ? 1 : -1);
 }
 
 void TabbedPaneTab::OnThemeChanged() {
@@ -276,7 +275,7 @@
 
   // TabbedPaneTab design spec dictates special handling of font weight for
   // the windows platform when dealing with border style tabs.
-  if (tabbed_pane_->GetStyle() == TabbedPane::TabStripStyle::kHighlight) {
+  if (tab_strip_->GetStyle() == TabbedPane::TabStripStyle::kHighlight) {
     // Notify assistive tools to update this tab's selected status. The way
     // ChromeOS accessibility is implemented right now, firing almost any event
     // will work, we just need to trigger its state to be refreshed.
@@ -310,8 +309,8 @@
 
   // Paints the active tab for the vertical highlighted tabbed pane.
   if (!selected() ||
-      tabbed_pane_->GetOrientation() != TabbedPane::Orientation::kVertical ||
-      tabbed_pane_->GetStyle() != TabbedPane::TabStripStyle::kHighlight) {
+      tab_strip_->GetOrientation() != TabbedPane::Orientation::kVertical ||
+      tab_strip_->GetStyle() != TabbedPane::TabStripStyle::kHighlight) {
     return;
   }
   constexpr SkScalar kRadius = SkIntToScalar(32);
@@ -364,7 +363,7 @@
     GetViewAccessibility().SetName(title_->GetText(),
                                    ax::mojom::NameFrom::kContents);
   }
-  tabbed_pane_->UpdateAccessibleName();
+  tab_strip_->UpdateAccessibleName();
 }
 
 void TabbedPaneTab::UpdateAccessibleSelection() {
@@ -388,8 +387,9 @@
 constexpr size_t TabbedPaneTabStrip::kNoSelectedTab;
 
 TabbedPaneTabStrip::TabbedPaneTabStrip(TabbedPane::Orientation orientation,
-                                       TabbedPane::TabStripStyle style)
-    : orientation_(orientation), style_(style) {
+                                       TabbedPane::TabStripStyle style,
+                                       raw_ptr<TabbedPane> tabbed_pane)
+    : orientation_(orientation), style_(style), tabbed_pane_(tabbed_pane) {
   std::unique_ptr<BoxLayout> layout;
   if (orientation == TabbedPane::Orientation::kHorizontal) {
     layout = std::make_unique<BoxLayout>(BoxLayout::Orientation::kHorizontal);
@@ -407,7 +407,20 @@
   }
   SetLayoutManager(std::move(layout));
 
-  GetViewAccessibility().SetRole(ax::mojom::Role::kNone);
+  // Support navigating tabs by Ctrl+Tab and Ctrl+Shift+Tab.
+  AddAccelerator(
+      ui::Accelerator(ui::VKEY_TAB, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN));
+  AddAccelerator(ui::Accelerator(ui::VKEY_TAB, ui::EF_CONTROL_DOWN));
+
+  // If the component is part of a parent TabbedPane, there is no accessibility
+  // that needs to be set for this component.
+  if (tabbed_pane) {
+    GetViewAccessibility().SetRole(ax::mojom::Role::kNone);
+  } else {
+    // Otherwise, it's a standalone component so set the accessibility role.
+    GetViewAccessibility().SetRole(ax::mojom::Role::kTabList);
+    UpdateAccessibleName();
+  }
 
   // These durations are taken from the Paper Tabs source:
   // https://github.com/PolymerElements/paper-tabs/blob/master/paper-tabs.html
@@ -418,6 +431,23 @@
 
 TabbedPaneTabStrip::~TabbedPaneTabStrip() = default;
 
+void TabbedPaneTabStrip::AddTab(const std::u16string& title,
+                                const gfx::VectorIcon* tab_icon) {
+  AddTabAt(title, tab_icon, GetTabCount());
+
+  // Always select the first tab.
+  if (!GetSelectedTab()) {
+    SelectTab(GetTabAtIndex(0));
+  }
+}
+
+void TabbedPaneTabStrip::AddTabAt(const std::u16string& title,
+                                  const gfx::VectorIcon* tab_icon,
+                                  size_t index) {
+  AddChildViewAt(std::make_unique<TabbedPaneTab>(this, title, tab_icon), index);
+  PreferredSizeChanged();
+}
+
 void TabbedPaneTabStrip::AnimationProgressed(const gfx::Animation* animation) {
   SchedulePaint();
 }
@@ -450,6 +480,13 @@
   return {starting_x, ending_x};
 }
 
+bool TabbedPaneTabStrip::AcceleratorPressed(
+    const ui::Accelerator& accelerator) {
+  // Handle Ctrl+Tab and Ctrl+Shift+Tab navigation of pages.
+  DCHECK(accelerator.key_code() == ui::VKEY_TAB && accelerator.IsCtrlDown());
+  return MoveSelectionBy(accelerator.IsShiftDown() ? -1 : 1);
+}
+
 void TabbedPaneTabStrip::OnSelectedTabChanged(TabbedPaneTab* from_tab,
                                               TabbedPaneTab* to_tab,
                                               bool animate) {
@@ -488,6 +525,72 @@
   expand_animation_->Start();
 }
 
+bool TabbedPaneTabStrip::SelectTab(TabbedPaneTab* new_selected_tab,
+                                   bool animate) {
+  TabbedPaneTab* old_selected_tab = GetSelectedTab();
+  if (old_selected_tab == new_selected_tab) {
+    return false;
+  }
+
+  const size_t new_selected_tab_idx = GetIndexForTab(new_selected_tab);
+
+  new_selected_tab->SetSelected(true);
+  MaybeUpdateTabContentVisibility(new_selected_tab_idx, true);
+
+  if (old_selected_tab) {
+    if (old_selected_tab->HasFocus()) {
+      new_selected_tab->RequestFocus();
+    }
+    old_selected_tab->SetSelected(false);
+    MaybeUpdateTabContentVisibility(GetIndexForTab(old_selected_tab), false);
+    OnSelectedTabChanged(old_selected_tab, new_selected_tab, animate);
+
+    NotifyNewAccessibilityEvent(ax::mojom::Event::kSelectedChildrenChanged,
+                                true);
+  }
+
+  UpdateAccessibleName();
+  SchedulePaint();
+
+  if (tabbed_pane_) {
+    tabbed_pane_->MaybeSetFocusedView(new_selected_tab_idx);
+  }
+
+  if (listener()) {
+    listener()->TabSelectedAt(base::checked_cast<int>(new_selected_tab_idx));
+  }
+
+  return true;
+}
+
+void TabbedPaneTabStrip::MaybeUpdateTabContentVisibility(size_t tab_index,
+                                                         bool visible) {
+  if (tabbed_pane_) {
+    tabbed_pane_->SetTabContentVisibility(tab_index, visible);
+  }
+}
+
+void TabbedPaneTabStrip::NotifyNewAccessibilityEvent(
+    ax::mojom::Event event_type,
+    bool send_native_event) {
+  // If this component is part of a TabbedPane, then forward the accessibility
+  // event to the parent.
+  if (tabbed_pane_) {
+    tabbed_pane_->GetViewAccessibility().NotifyEvent(event_type,
+                                                     send_native_event);
+  } else {
+    // Otherwise, make the call ourselves.
+    GetViewAccessibility().NotifyEvent(event_type, send_native_event);
+  }
+}
+
+bool TabbedPaneTabStrip::MoveSelectionBy(int delta) {
+  if (children().size() <= 1) {
+    return false;
+  }
+  return SelectTab(GetTabAtDeltaFromSelected(delta));
+}
+
 TabbedPaneTab* TabbedPaneTabStrip::GetSelectedTab() const {
   size_t index = GetSelectedTabIndex();
   return index == kNoSelectedTab ? nullptr : GetTabAtIndex(index);
@@ -510,6 +613,13 @@
   return static_cast<TabbedPaneTab*>(children()[index]);
 }
 
+size_t TabbedPaneTabStrip::GetIndexForTab(TabbedPaneTab* tab) const {
+  CHECK(tab);
+  const auto it = std::ranges::find(children(), tab);
+  CHECK(it != children().end());
+  return static_cast<size_t>(it - children().begin());
+}
+
 size_t TabbedPaneTabStrip::GetSelectedTabIndex() const {
   for (size_t i = 0; i < children().size(); ++i)
     if (GetTabAtIndex(i)->selected()) {
@@ -518,6 +628,14 @@
   return kNoSelectedTab;
 }
 
+size_t TabbedPaneTabStrip::GetTabCount() const {
+  return children().size();
+}
+
+void TabbedPaneTabStrip::SetDefaultFlex(int flex) {
+  static_cast<BoxLayout*>(GetLayoutManager())->SetDefaultFlex(flex);
+}
+
 TabbedPane::Orientation TabbedPaneTabStrip::GetOrientation() const {
   return orientation_;
 }
@@ -526,6 +644,28 @@
   return style_;
 }
 
+bool TabbedPaneTabStrip::HasIconStyle() const {
+  return GetStyle() == TabbedPane::TabStripStyle::kCompactWithIcon ||
+         GetStyle() == TabbedPane::TabStripStyle::kWithIcon;
+}
+
+void TabbedPaneTabStrip::UpdateAccessibleName() {
+  // Update parent's accessible name, if its parent exists.
+  if (tabbed_pane_) {
+    tabbed_pane_->UpdateAccessibleName();
+    return;
+  }
+
+  // Otherwise, the TabbedPaneTabStrip is a standalone View, so update
+  // ourselves.
+  const TabbedPaneTab* const selected_tab = GetSelectedTab();
+  if (selected_tab) {
+    GetViewAccessibility().SetName(selected_tab->GetTitleText());
+  } else {
+    GetViewAccessibility().RemoveName();
+  }
+}
+
 void TabbedPaneTabStrip::OnPaintBorder(gfx::Canvas* canvas) {
   // Do not draw border line in kHighlight mode.
   if (GetStyle() == TabbedPane::TabStripStyle::kHighlight) {
@@ -648,7 +788,8 @@
   if (orientation == TabbedPane::Orientation::kHorizontal)
     SetOrientation(views::LayoutOrientation::kVertical);
 
-  auto tab_strip = std::make_unique<TabbedPaneTabStrip>(orientation, style);
+  auto tab_strip =
+      std::make_unique<TabbedPaneTabStrip>(orientation, style, this);
   if (scrollable) {
     scroll_view_ = AddChildView(
         std::make_unique<ScrollView>(ScrollView::ScrollWithLayers::kEnabled));
@@ -665,16 +806,20 @@
                                views::MaximumFlexSizeRule::kUnbounded));
   contents_->SetLayoutManager(std::make_unique<views::FillLayout>());
 
-  // Support navigating tabs by Ctrl+TabbedPaneTab and Ctrl+Shift+TabbedPaneTab.
-  AddAccelerator(
-      ui::Accelerator(ui::VKEY_TAB, ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN));
-  AddAccelerator(ui::Accelerator(ui::VKEY_TAB, ui::EF_CONTROL_DOWN));
   GetViewAccessibility().SetRole(ax::mojom::Role::kTabList);
   UpdateAccessibleName();
 }
 
 TabbedPane::~TabbedPane() = default;
 
+TabbedPaneListener* TabbedPane::GetListener() const {
+  return tab_strip_->listener();
+}
+
+void TabbedPane::SetListener(TabbedPaneListener* listener) {
+  tab_strip_->set_listener(listener);
+}
+
 size_t TabbedPane::GetSelectedTabIndex() const {
   return tab_strip_->GetSelectedTabIndex();
 }
@@ -696,9 +841,7 @@
                                              ax::mojom::NameFrom::kAttribute);
   }
 
-  tab_strip_->AddChildViewAt(
-      std::make_unique<TabbedPaneTab>(this, title, contents.get(), tab_icon),
-      index);
+  tab_strip_->AddTabAt(title, tab_icon, index);
   contents_->AddChildViewAt(std::move(contents), index);
   if (!GetSelectedTab()) {
     SelectTabAt(index);
@@ -707,45 +850,30 @@
   PreferredSizeChanged();
 }
 
-void TabbedPane::SelectTab(TabbedPaneTab* new_selected_tab, bool animate) {
-  TabbedPaneTab* old_selected_tab = tab_strip_->GetSelectedTab();
-  if (old_selected_tab == new_selected_tab) {
-    return;
-  }
-
-  new_selected_tab->SetSelected(true);
-  if (old_selected_tab) {
-    if (old_selected_tab->HasFocus()) {
-      new_selected_tab->RequestFocus();
-    }
-    old_selected_tab->SetSelected(false);
-    tab_strip_->OnSelectedTabChanged(old_selected_tab, new_selected_tab,
-                                     animate);
-
-    NotifyAccessibilityEvent(ax::mojom::Event::kSelectedChildrenChanged, true);
-  }
-
-  UpdateAccessibleName();
-  tab_strip_->SchedulePaint();
-
-  FocusManager* focus_manager = new_selected_tab->contents()->GetFocusManager();
-  if (focus_manager) {
-    const View* focused_view = focus_manager->GetFocusedView();
-    if (focused_view && contents_->Contains(focused_view) &&
-        !new_selected_tab->contents()->Contains(focused_view))
-      focus_manager->SetFocusedView(new_selected_tab->contents());
-  }
-
-  if (listener()) {
-    listener()->TabSelectedAt(base::checked_cast<int>(
-        tab_strip_->GetIndexOf(new_selected_tab).value()));
-  }
-}
-
 void TabbedPane::SelectTabAt(size_t index, bool animate) {
   TabbedPaneTab* tab = tab_strip_->GetTabAtIndex(index);
   if (tab) {
-    SelectTab(tab, animate);
+    tab_strip_->SelectTab(tab, animate);
+  }
+}
+
+void TabbedPane::SetTabContentVisibility(size_t tab_index, bool visible) {
+  CHECK_LT(tab_index, GetTabCount());
+  contents_->children()[tab_index]->SetVisible(visible);
+  contents_->InvalidateLayout();
+}
+
+void TabbedPane::MaybeSetFocusedView(size_t tab_index) {
+  const auto tab_contents = contents_->children()[tab_index];
+  FocusManager* focus_manager = tab_contents->GetFocusManager();
+  if (!focus_manager) {
+    return;
+  }
+
+  if (const View* focused_view = focus_manager->GetFocusedView();
+      focused_view && contents_->Contains(focused_view) &&
+      !tab_contents->Contains(focused_view)) {
+    focus_manager->SetFocusedView(tab_contents);
   }
 }
 
@@ -765,27 +893,28 @@
   return tab_strip_->GetTabAtIndex(index);
 }
 
+const views::View* TabbedPane::GetTabContents(size_t index) const {
+  CHECK_LT(index, GetTabCount());
+  return contents_->children()[index];
+}
+
+views::View* TabbedPane::GetTabContentsForTesting(size_t index) {
+  CHECK_LT(index, GetTabCount());
+  return contents_->children()[index];
+}
+
+void TabbedPane::UpdateAccessibleName() {
+  if (const TabbedPaneTab* const selected_tab = GetSelectedTab()) {
+    GetViewAccessibility().SetName(selected_tab->GetTitleText());
+  } else {
+    GetViewAccessibility().RemoveName();
+  }
+}
+
 TabbedPaneTab* TabbedPane::GetSelectedTab() {
   return tab_strip_->GetSelectedTab();
 }
 
-View* TabbedPane::GetSelectedTabContentView() {
-  return GetSelectedTab() ? GetSelectedTab()->contents() : nullptr;
-}
-
-bool TabbedPane::MoveSelectionBy(int delta) {
-  if (contents_->children().size() <= 1) {
-    return false;
-  }
-  SelectTab(tab_strip_->GetTabAtDeltaFromSelected(delta));
-  return true;
-}
-
-bool TabbedPane::HasIconStyle() const {
-  return GetStyle() == TabStripStyle::kCompactWithIcon ||
-         GetStyle() == TabStripStyle::kWithIcon;
-}
-
 gfx::Size TabbedPane::CalculatePreferredSize(
     const SizeBounds& available_size) const {
   // In horizontal mode, use the preferred size as determined by the largest
@@ -802,22 +931,6 @@
   return gfx::Size(size.width(), contents_->GetHeightForWidth(size.width()));
 }
 
-bool TabbedPane::AcceleratorPressed(const ui::Accelerator& accelerator) {
-  // Handle Ctrl+TabbedPaneTab and Ctrl+Shift+TabbedPaneTab navigation of pages.
-  DCHECK(accelerator.key_code() == ui::VKEY_TAB && accelerator.IsCtrlDown());
-  return MoveSelectionBy(accelerator.IsShiftDown() ? -1 : 1);
-}
-
-void TabbedPane::UpdateAccessibleName() {
-  const TabbedPaneTab* const selected_tab = GetSelectedTab();
-
-  if (selected_tab) {
-    GetViewAccessibility().SetName(selected_tab->GetTitleText());
-  } else {
-    GetViewAccessibility().RemoveName();
-  }
-}
-
 BEGIN_METADATA(TabbedPane)
 END_METADATA
 
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane.h b/ui/views/controls/tabbed_pane/tabbed_pane.h
index eaf5298..31d5409 100644
--- a/ui/views/controls/tabbed_pane/tabbed_pane.h
+++ b/ui/views/controls/tabbed_pane/tabbed_pane.h
@@ -62,8 +62,8 @@
 
   ~TabbedPane() override;
 
-  TabbedPaneListener* listener() const { return listener_; }
-  void set_listener(TabbedPaneListener* listener) { listener_ = listener; }
+  TabbedPaneListener* GetListener() const;
+  void SetListener(TabbedPaneListener* listener);
 
   // Returns the index of the currently selected tab, or
   // TabStrip::kNoSelectedTab if no tab is selected.
@@ -99,7 +99,11 @@
   void SelectTabAt(size_t index, bool animate = true);
 
   // Selects |tab| (the tabstrip view, not its content) if it is valid.
-  void SelectTab(TabbedPaneTab* tab, bool animate = true);
+  void SetTabContentVisibility(size_t tab_index, bool visible);
+
+  // Calls the FocusManager (if it exists), and gives focus to the view at
+  // |tab_index|.
+  void MaybeSetFocusedView(size_t tab_index);
 
   // Gets the scroll view containing the tab strip, if it exists
   ScrollView* GetScrollView();
@@ -110,12 +114,17 @@
   // Gets the style of the tab strip.
   TabStripStyle GetStyle() const;
 
-  // Returns whether an Icon should be rendered for the TabbedPaneTab children.
-  bool HasIconStyle() const;
-
   // Returns the tab at the given index.
   TabbedPaneTab* GetTabAt(size_t index);
 
+  // Returns the View associated with a specific tab.
+  const views::View* GetTabContents(size_t index) const;
+  views::View* GetTabContentsForTesting(size_t index);
+
+  // Updates the view's accessible name based on the currently selected tab's
+  // title.
+  void UpdateAccessibleName();
+
  private:
   friend class FocusTraversalTest;
   friend class TabbedPaneTab;
@@ -135,24 +144,9 @@
   // index.
   TabbedPaneTab* GetSelectedTab();
 
-  // Returns the content View of the currently selected TabbedPaneTab.
-  View* GetSelectedTabContentView();
-
-  // Moves the selection by |delta| tabs, where negative delta means leftwards
-  // and positive delta means rightwards. Returns whether the selection could be
-  // moved by that amount; the only way this can fail is if there is only one
-  // tab.
-  bool MoveSelectionBy(int delta);
-
   // View:
   gfx::Size CalculatePreferredSize(
       const SizeBounds& available_size) const override;
-  bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
-
-  void UpdateAccessibleName();
-
-  // A listener notified when tab selection changes. Weak, not owned.
-  raw_ptr<TabbedPaneListener> listener_ = nullptr;
 
   // The tab strip and contents container. The child indices of these members
   // correspond to match each TabbedPaneTab with its respective content View.
@@ -169,9 +163,8 @@
   METADATA_HEADER(TabbedPaneTab, View)
 
  public:
-  TabbedPaneTab(TabbedPane* tabbed_pane,
+  TabbedPaneTab(TabbedPaneTabStrip* tab_strip,
                 const std::u16string& title,
-                View* contents,
                 const gfx::VectorIcon* tab_icon);
 
   TabbedPaneTab(const TabbedPaneTab&) = delete;
@@ -179,9 +172,7 @@
 
   ~TabbedPaneTab() override;
 
-  View* contents() const { return contents_; }
-
-  bool selected() const { return contents_->GetVisible(); }
+  bool selected() const { return selected_; }
   void SetSelected(bool selected);
 
   const std::u16string& GetTitleText() const;
@@ -229,22 +220,22 @@
   ui::ImageModel GetImageModelForTab(ui::ColorId color_id) const;
   ui::ColorId GetIconTitleColor() const;
 
+  raw_ptr<TabbedPaneTabStrip> tab_strip_;
   raw_ptr<const gfx::VectorIcon> icon_for_tab_;
-  raw_ptr<TabbedPane> tabbed_pane_;
   raw_ptr<ImageView> icon_view_ = nullptr;
   raw_ptr<Label> title_ = nullptr;
   // The preferred title width is the maximum width between inactive and active
   // states (font changes). See UpdatePreferredTitleWidth() for more details.
   int preferred_title_width_;
   State state_ = State::kActive;
-  // The content view associated with this tab.
-  raw_ptr<View> contents_;
+  bool selected_ = false;
 
   base::CallbackListSubscription title_text_changed_callback_;
 };
 
 // The tab strip shown above/left of the tab contents.
-class TabbedPaneTabStrip : public View, public gfx::AnimationDelegate {
+class VIEWS_EXPORT TabbedPaneTabStrip : public View,
+                                        public gfx::AnimationDelegate {
   METADATA_HEADER(TabbedPaneTabStrip, View)
 
  public:
@@ -252,13 +243,24 @@
   static constexpr size_t kNoSelectedTab = static_cast<size_t>(-1);
 
   TabbedPaneTabStrip(TabbedPane::Orientation orientation,
-                     TabbedPane::TabStripStyle style);
+                     TabbedPane::TabStripStyle style,
+                     raw_ptr<TabbedPane> tabbed_pane);
 
   TabbedPaneTabStrip(const TabbedPaneTabStrip&) = delete;
   TabbedPaneTabStrip& operator=(const TabbedPaneTabStrip&) = delete;
 
   ~TabbedPaneTabStrip() override;
 
+  TabbedPaneListener* listener() { return listener_; }
+  void set_listener(TabbedPaneListener* listener) { listener_ = listener; }
+
+  // Adds a new TabbedPaneTab as a child of this View. This method should only
+  // be used when TabbedPaneTabStrip is instantiated as a standalone component.
+  void AddTab(const std::u16string& title, const gfx::VectorIcon* tab_icon);
+  void AddTabAt(const std::u16string& title,
+                const gfx::VectorIcon* tab_icon,
+                size_t index);
+
   // AnimationDelegate:
   void AnimationProgressed(const gfx::Animation* animation) override;
   void AnimationEnded(const gfx::Animation* animation) override;
@@ -270,15 +272,46 @@
                             TabbedPaneTab* to_tab,
                             bool animate = true);
 
+  // Attempts to select the provided tab. Returns true if the new tab was
+  // selected, or false if no work was done (i.e., |new_selected_tab| is the
+  // currently selected tab).
+  bool SelectTab(TabbedPaneTab* new_selected_tab, bool animate = true);
+
+  // Updates the visibility of the content associated with the tab at
+  // |tab_index| if there is a |tabbed_pane_| parented to this view.
+  void MaybeUpdateTabContentVisibility(size_t tab_index, bool visible);
+
+  // Dispatches an accessibility event to the parent |tabbed_pane_| if it
+  // exists, otherwise the event is dispatched on behalf of this View.
+  void NotifyNewAccessibilityEvent(ax::mojom::Event event_type,
+                                   bool send_native_event);
+
+  // Moves the selection by |delta| tabs, where negative delta means leftwards
+  // and positive delta means rightwards. Returns whether the move was
+  // performed. This only fails if the delta results in currently selected tab.
+  bool MoveSelectionBy(int delta);
+
   TabbedPaneTab* GetSelectedTab() const;
   TabbedPaneTab* GetTabAtDeltaFromSelected(int delta) const;
   TabbedPaneTab* GetTabAtIndex(size_t index) const;
+  size_t GetIndexForTab(TabbedPaneTab* index) const;
   size_t GetSelectedTabIndex() const;
+  size_t GetTabCount() const;
+
+  // Sets the default flex of the tab strip. Useful for adding custom padding
+  // instead of expecting the tab strip to stretch across its parent container.
+  void SetDefaultFlex(int flex);
 
   TabbedPane::Orientation GetOrientation() const;
-
   TabbedPane::TabStripStyle GetStyle() const;
 
+  // Returns whether an Icon should be rendered for the TabbedPaneTab children.
+  bool HasIconStyle() const;
+
+  // Updates its own accessible name, and also calls TabbedPane's
+  // UpdateAccessibleName method if |tabbed_pane_| is defined.
+  void UpdateAccessibleName();
+
  protected:
   // View:
   void OnPaintBorder(gfx::Canvas* canvas) override;
@@ -296,6 +329,9 @@
   // -------end-----------------^
   Coordinates GetIconLabelStartEndingX(TabbedPaneTab* tab);
 
+  // view::View
+  bool AcceleratorPressed(const ui::Accelerator& accelerator) override;
+
   // The orientation of the tab alignment.
   const TabbedPane::Orientation orientation_;
 
@@ -315,6 +351,13 @@
   // The x-coordinate ranges of the old selection and the new selection.
   Coordinates animating_from_;
   Coordinates animating_to_;
+
+  // A listener notified when tab selection changes. Weak, not owned.
+  raw_ptr<TabbedPaneListener> listener_ = nullptr;
+
+  // An optional parent container which connects Tabs in the TabStrip to
+  // content views.
+  raw_ptr<TabbedPane> tabbed_pane_;
 };
 
 BEGIN_VIEW_BUILDER(VIEWS_EXPORT, TabbedPane, FlexLayoutView)
diff --git a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
index 9fd33ce..7e34987 100644
--- a/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
+++ b/ui/views/controls/tabbed_pane/tabbed_pane_unittest.cc
@@ -170,7 +170,8 @@
   }
 
   View* GetSelectedTabContentView() {
-    return tabbed_pane_->GetSelectedTabContentView();
+    return tabbed_pane_->GetTabContentsForTesting(
+        tabbed_pane_->GetSelectedTabIndex());
   }
 
   void SendKeyPressToSelectedTab(ui::KeyboardCode keyboard_code) {
diff --git a/ui/views/examples/examples_window.cc b/ui/views/examples/examples_window.cc
index be98177b..b7f90b9 100644
--- a/ui/views/examples/examples_window.cc
+++ b/ui/views/examples/examples_window.cc
@@ -121,7 +121,7 @@
 
     status_label_ = AddChildView(std::make_unique<Label>());
     status_label_->SetVisible(false);
-    tabbed_pane_->set_listener(this);
+    tabbed_pane_->SetListener(this);
     instance_ = this;
   }
 
@@ -152,9 +152,9 @@
       const SizeBounds& /*available_size*/) const override {
     gfx::Size size(800, 300);
     for (size_t i = 0; i < tabbed_pane_->GetTabCount(); ++i) {
-      size.set_height(std::max(
-          size.height(),
-          tabbed_pane_->GetTabAt(i)->contents()->GetHeightForWidth(800)));
+      size.set_height(
+          std::max(size.height(),
+                   tabbed_pane_->GetTabContents(i)->GetHeightForWidth(800)));
     }
     return size;
   }
diff --git a/ui/views/examples/tabbed_pane_example.cc b/ui/views/examples/tabbed_pane_example.cc
index be19a341..72bc280 100644
--- a/ui/views/examples/tabbed_pane_example.cc
+++ b/ui/views/examples/tabbed_pane_example.cc
@@ -29,7 +29,7 @@
 
 TabbedPaneExample::~TabbedPaneExample() {
   if (tabbed_pane_) {
-    tabbed_pane_->set_listener(nullptr);
+    tabbed_pane_->SetListener(nullptr);
   }
 }
 
@@ -84,7 +84,7 @@
 
   tabbed_pane_ = container->AddChildViewAt(
       std::make_unique<TabbedPane>(orientation, style), 0);
-  tabbed_pane_->set_listener(this);
+  tabbed_pane_->SetListener(this);
   toggle_highlighted_->SetEnabled(orientation ==
                                   TabbedPane::Orientation::kVertical);
   const auto full_flex = FlexSpecification(MinimumFlexSizeRule::kScaleToZero,
diff --git a/ui/views/focus/focus_manager_unittest.cc b/ui/views/focus/focus_manager_unittest.cc
index 78a7568..54e5774 100644
--- a/ui/views/focus/focus_manager_unittest.cc
+++ b/ui/views/focus/focus_manager_unittest.cc
@@ -619,8 +619,6 @@
  private:
   // Restores the locale to default when the destructor is called.
   base::test::ScopedRestoreICUDefaultLocale restore_locale_;
-
-  bool previous_arrow_key_traversal_enabled_ = false;
 };
 
 // Instantiate the Boolean which is used to toggle RTL in
diff --git a/ui/views/focus/focus_traversal_unittest.cc b/ui/views/focus/focus_traversal_unittest.cc
index 06aadef8..13a17de 100644
--- a/ui/views/focus/focus_traversal_unittest.cc
+++ b/ui/views/focus/focus_traversal_unittest.cc
@@ -216,7 +216,9 @@
     if (view)
       return view;
     if (style_tab_)
-      view = style_tab_->GetSelectedTabContentView()->GetViewByID(id);
+      view = style_tab_
+                 ->GetTabContentsForTesting(style_tab_->GetSelectedTabIndex())
+                 ->GetViewByID(id);
     if (view)
       return view;
     view = search_border_view_->GetContentsRootView()->GetViewByID(id);
@@ -335,9 +337,9 @@
   //   NativeButton        * OK_BUTTON_ID
   //   NativeButton        * CANCEL_BUTTON_ID
   //   NativeButton        * HELP_BUTTON_ID
-  //   TabbedPane          * STYLE_CONTAINER_ID
+  //   TabbedPane
   //     TabStrip
-  //       Tab ("Style")
+  //       Tab ("Style")   * STYLE_CONTAINER_ID
   //       Tab ("Other")
   //     View
   //       View
diff --git a/ui/views/interaction/interactive_views_test_unittest.cc b/ui/views/interaction/interactive_views_test_unittest.cc
index 7527ab9..3cf42c1 100644
--- a/ui/views/interaction/interactive_views_test_unittest.cc
+++ b/ui/views/interaction/interactive_views_test_unittest.cc
@@ -336,7 +336,7 @@
       SelectTab(kTabbedPaneId, 1U, InputType::kTouch),
       NameViewRelative(kTabbedPaneId, kViewName,
                        base::BindRepeating([&](TabbedPane* tabs) {
-                         return tabs->GetTabAt(1U)->contents();
+                         return tabs->GetTabContentsForTesting(1);
                        })),
       WithElement(kViewName,
                   base::BindLambdaForTesting([&](ui::TrackedElement* el) {