diff --git a/DEPS b/DEPS
index 271ac07..8240292 100644
--- a/DEPS
+++ b/DEPS
@@ -253,7 +253,7 @@
   'screen_ai_windows_386': 'version:127.9',
 
   # siso CIPD package version.
-  'siso_version': 'git_revision:67a8780a72f407b3dffe9e338c368f0b799d004b',
+  'siso_version': 'git_revision:0721be7440a7c67f8369fcce1ca01932638641bb',
 
   # download libaom test data
   'download_libaom_testdata': False,
@@ -280,7 +280,7 @@
   # 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': 'ffd7fec8b6c5df912dbd7e382f7a0d7c1f51937d',
+  'skia_revision': 'dac808134f758c75b52cd53a4c93f84dea22803a',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -352,7 +352,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling chromium_variations
   # and whatever else without interference from each other.
-  'chromium_variations_revision': '60f815f521c36d4b0a6d54e7fb30a103cfc32738',
+  'chromium_variations_revision': 'd66e3e79647b84e230bec45ffea13c456f4c01e3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling CrossBench
   # and whatever else without interference from each other.
@@ -396,11 +396,11 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': '571eea1e9b33486148be3257d49588f190956454',
+  'dawn_revision': '4585c9495dd4c1958890921fa2abacd8546d088d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'quiche_revision': '41e68574090ab56109ca785bba9c6a611ab99dce',
+  'quiche_revision': '16535679768274d3061f1b991082a6a0c8fd1aac',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ink
   # and whatever else without interference from each other.
@@ -1439,7 +1439,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '2a03afbec2cf5258224406339ab653a9899927a0',
+    '82f68d0ac4e31a5198d219842a3873b82b3ab1cd',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -2809,7 +2809,7 @@
     Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'),
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '1305eb90832d17fc5edf2e8fb2e71dab5b689820',
+    Var('webrtc_git') + '/src.git' + '@' + '9aeeb6123d2a4fc868626a9ee8f45b268d223c03',
 
   # 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.
@@ -2883,7 +2883,7 @@
       'packages': [
         {
           'package': 'skia/tools/goldctl/mac-amd64',
-          'version': 'aGSV8FRvSVFoQndmtzdgxKhvRR5fHzqV4Out1xJ8IdQC',
+          'version': 'i1pCGOButmwiJERJNRCcVJvvq5eJVXmgn6naqj5pIUwC',
         },
       ],
       'dep_type': 'cipd',
@@ -2946,7 +2946,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/help_app/app',
-        'version': 'BEgsMF48qQZ4D5S5i5wA-usVOZnBfsd1jo454wou_ygC',
+        'version': 'uMy7vOfonOvlppmthaEbPS0Hk5Fu-VCTlEycHHlHY6IC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -2957,7 +2957,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/media_app/app',
-        'version': 'R86nCLtnx23yNHB-78b6PnoH9fdnl63Pol42oZXRv08C',
+        'version': 'CqrRs-8NaEMyLsBk1WrbKynksiwxfaMLnT2fKqSH8PYC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -2990,7 +2990,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'CIGnQNBH2QDBmNqa9W8HAvGCNzi7-9VcuRvoVcFeYgIC',
+        'version': 'I6qYL1WbVeH_3Cp8TM4r42OxK6gcYxPqjIS2IkvTFdwC',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4350,7 +4350,7 @@
     'packages' : [
       {
         'package': 'chromeos_internal/inputs/orca',
-        'version': 'Wzh-xjWvzQ4sxJ83qNnnr0RIF5dy95fqpG-is0Y_aRQC'
+        'version': 'u9vK3nIWSWZ0y9DalJGOfXqsbdZOBq4nZCLO3fc6tc0C'
       }
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -4538,7 +4538,7 @@
 
   'src/ios_internal':  {
       'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' +
-        'b4752700af4d89c303eea80d0088c07fb7a5cb21',
+        '67d2600839370d13a8f8f962d74803d2d129b267',
       'condition': 'checkout_ios and checkout_src_internal',
   },
 
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index 3b5f0bc..ce13f59 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1256,8 +1256,6 @@
     "scanner/scanner_session.h",
     "scanner/scanner_text.cc",
     "scanner/scanner_text.h",
-    "scanner/scanner_unpopulated_action.cc",
-    "scanner/scanner_unpopulated_action.h",
     "user_education/user_education_class_properties.cc",
     "user_education/user_education_class_properties.h",
     "user_education/user_education_controller.cc",
@@ -4069,7 +4067,6 @@
     "scanner/scanner_metrics_unittest.cc",
     "scanner/scanner_session_unittest.cc",
     "scanner/scanner_text_unittest.cc",
-    "scanner/scanner_unpopulated_action_unittest.cc",
     "screen_util_unittest.cc",
     "sensor_info/sensor_provider_unittest.cc",
     "session/fullscreen_controller_unittest.cc",
diff --git a/ash/capture_mode/action_button_view.cc b/ash/capture_mode/action_button_view.cc
index ffff28c..7012dd4 100644
--- a/ash/capture_mode/action_button_view.cc
+++ b/ash/capture_mode/action_button_view.cc
@@ -8,6 +8,7 @@
 #include <string>
 #include <utility>
 
+#include "ash/capture_mode/capture_mode_session_focus_cycler.h"
 #include "ash/capture_mode/capture_mode_types.h"
 #include "ash/capture_mode/capture_mode_util.h"
 #include "ash/style/ash_color_id.h"
@@ -93,6 +94,7 @@
   label_ = AddChildView(std::make_unique<views::Label>(text));
   TypographyProvider::Get()->StyleLabel(TypographyToken::kCrosButton2, *label_);
 
+  CaptureModeSessionFocusCycler::HighlightHelper::Install(this);
   SetAccessibleName(text);
 }
 
diff --git a/ash/capture_mode/capture_mode_session.cc b/ash/capture_mode/capture_mode_session.cc
index ad4b4a9..ba5d64d 100644
--- a/ash/capture_mode/capture_mode_session.cc
+++ b/ash/capture_mode/capture_mode_session.cc
@@ -1418,7 +1418,6 @@
   ActionButtonView* action_button = action_container_view_->AddActionButton(
       std::move(callback), text, icon, rank, id);
   CHECK(action_button);
-  CaptureModeSessionFocusCycler::HighlightHelper::Install(action_button);
 
   UpdateActionContainerWidget();
 
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index b969d99..3532775 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -1708,7 +1708,7 @@
 // Enables lobster feedback form.
 BASE_FEATURE(kLobsterFeedback,
              "LobsterFeedback",
-             base::FEATURE_DISABLED_BY_DEFAULT);
+             base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Enables lobster feedback form.
 BASE_FEATURE(kLobsterFileNamingImprovement,
@@ -2307,7 +2307,7 @@
              base::FEATURE_ENABLED_BY_DEFAULT);
 
 // Enables GIF search in Picker.
-BASE_FEATURE(kPickerGifs, "PickerGifs", base::FEATURE_DISABLED_BY_DEFAULT);
+BASE_FEATURE(kPickerGifs, "PickerGifs", base::FEATURE_ENABLED_BY_DEFAULT);
 
 BASE_FEATURE(kPipDoubleTapToResize,
              "PipDoubleTapToResize",
diff --git a/ash/scanner/scanner_action_view_model.cc b/ash/scanner/scanner_action_view_model.cc
index aa91bb9..5a530e6 100644
--- a/ash/scanner/scanner_action_view_model.cc
+++ b/ash/scanner/scanner_action_view_model.cc
@@ -8,188 +8,21 @@
 #include <utility>
 
 #include "ash/resources/vector_icons/vector_icons.h"
-#include "ash/scanner/scanner_action_handler.h"
-#include "ash/scanner/scanner_command_delegate.h"
-#include "ash/scanner/scanner_metrics.h"
-#include "ash/scanner/scanner_unpopulated_action.h"
 #include "ash/strings/grit/ash_strings.h"
-#include "base/functional/bind.h"
-#include "base/functional/callback.h"
-#include "base/memory/weak_ptr.h"
-#include "base/metrics/histogram_functions.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/notreached.h"
-#include "base/time/time.h"
 #include "chromeos/ui/vector_icons/vector_icons.h"
 #include "components/manta/proto/scanner.pb.h"
 #include "ui/base/l10n/l10n_util.h"
 
 namespace ash {
 
-namespace {
-
-using enum ScannerFeatureUserState;
-
-void RecordExecutePopulatedActionTimer(
-    manta::proto::ScannerAction::ActionCase action_case,
-    base::TimeTicks execute_start_time) {
-  // TODO(b/363101363): Add tests once scanner action view model tests are set
-  // up.
-  std::string_view variant_name;
-  switch (action_case) {
-    case manta::proto::ScannerAction::kNewEvent:
-      variant_name = kScannerFeatureTimerExecutePopulatedNewCalendarEventAction;
-      break;
-    case manta::proto::ScannerAction::kNewContact:
-      variant_name = kScannerFeatureTimerExecutePopulatedNewContactAction;
-      break;
-    case manta::proto::ScannerAction::kNewGoogleDoc:
-      variant_name = kScannerFeatureTimerExecutePopulatedNewGoogleDocAction;
-      break;
-    case manta::proto::ScannerAction::kNewGoogleSheet:
-      variant_name = kScannerFeatureTimerExecutePopulatedNewGoogleSheetAction;
-      break;
-    case manta::proto::ScannerAction::kCopyToClipboard:
-      variant_name =
-          kScannerFeatureTimerExecutePopulatedNewCopyToClipboardAction;
-      break;
-    case manta::proto::ScannerAction::ACTION_NOT_SET:
-      break;
-  }
-  if (variant_name.empty()) {
-    return;
-  }
-  base::UmaHistogramMediumTimes(variant_name,
-                                base::TimeTicks::Now() - execute_start_time);
-}
-
-void RecordPopulateActionTimer(
-    manta::proto::ScannerAction::ActionCase action_case,
-    base::TimeTicks request_start_time) {
-  // TODO(b/363101363): Add tests once scanner action view model tests are set
-  // up.
-  std::string_view variant_name;
-  switch (action_case) {
-    case manta::proto::ScannerAction::kNewEvent:
-      variant_name = kScannerFeatureTimerPopulateNewCalendarEventAction;
-      break;
-    case manta::proto::ScannerAction::kNewContact:
-      variant_name = kScannerFeatureTimerPopulateNewContactAction;
-      break;
-    case manta::proto::ScannerAction::kNewGoogleDoc:
-      variant_name = kScannerFeatureTimerPopulateNewGoogleDocAction;
-      break;
-    case manta::proto::ScannerAction::kNewGoogleSheet:
-      variant_name = kScannerFeatureTimerPopulateNewGoogleSheetAction;
-      break;
-    case manta::proto::ScannerAction::kCopyToClipboard:
-      variant_name = kScannerFeatureTimerPopulateNewCopyToClipboardAction;
-      break;
-    case manta::proto::ScannerAction::ACTION_NOT_SET:
-      break;
-  }
-  if (variant_name.empty()) {
-    return;
-  }
-  base::UmaHistogramMediumTimes(variant_name,
-                                base::TimeTicks::Now() - request_start_time);
-}
-
-void RecordPopulateActionFailure(
-    manta::proto::ScannerAction::ActionCase action_case) {
-  // TODO(b/363101363): Add tests once scanner action view model tests are set
-  // up.
-  switch (action_case) {
-    case manta::proto::ScannerAction::kNewEvent:
-      RecordScannerFeatureUserState(kNewCalendarEventActionPopulationFailed);
-      return;
-    case manta::proto::ScannerAction::kNewContact:
-      RecordScannerFeatureUserState(kNewContactActionPopulationFailed);
-      return;
-    case manta::proto::ScannerAction::kNewGoogleDoc:
-      RecordScannerFeatureUserState(kNewGoogleDocActionPopulationFailed);
-      return;
-    case manta::proto::ScannerAction::kNewGoogleSheet:
-      RecordScannerFeatureUserState(kNewGoogleSheetActionPopulationFailed);
-      return;
-    case manta::proto::ScannerAction::kCopyToClipboard:
-      RecordScannerFeatureUserState(kCopyToClipboardActionPopulationFailed);
-      return;
-    case manta::proto::ScannerAction::ACTION_NOT_SET:
-      return;
-  }
-}
-
-void RecordActionExecutionAndRun(
-    manta::proto::ScannerAction::ActionCase action_case,
-    base::TimeTicks execute_start_time,
-    ScannerCommandCallback action_finished_callback,
-    bool success) {
-  // TODO(b/363101363): Add tests once scanner action view model tests are set
-  // up.
-  switch (action_case) {
-    case manta::proto::ScannerAction::kNewEvent:
-      RecordScannerFeatureUserState(
-          success ? kNewCalendarEventActionFinishedSuccessfully
-                  : kNewCalendarEventPopulatedActionExecutionFailed);
-      break;
-    case manta::proto::ScannerAction::kNewContact:
-      RecordScannerFeatureUserState(
-          success ? kNewContactActionFinishedSuccessfully
-                  : kNewContactPopulatedActionExecutionFailed);
-      break;
-    case manta::proto::ScannerAction::kNewGoogleDoc:
-      RecordScannerFeatureUserState(
-          success ? kNewGoogleDocActionFinishedSuccessfully
-                  : kNewGoogleDocPopulatedActionExecutionFailed);
-      break;
-    case manta::proto::ScannerAction::kNewGoogleSheet:
-      RecordScannerFeatureUserState(
-          success ? kNewGoogleSheetActionFinishedSuccessfully
-                  : kNewGoogleSheetPopulatedActionExecutionFailed);
-      break;
-    case manta::proto::ScannerAction::kCopyToClipboard:
-      RecordScannerFeatureUserState(
-          success ? kCopyToClipboardActionFinishedSuccessfully
-                  : kCopyToClipboardPopulatedActionExecutionFailed);
-      break;
-    case manta::proto::ScannerAction::ACTION_NOT_SET:
-      break;
-  }
-  RecordExecutePopulatedActionTimer(action_case, execute_start_time);
-  std::move(action_finished_callback).Run(success);
-}
-
-// Executes the populated action, if it exists, calling
-// `action_finished_callback` with the result of the execution.
-void ExecutePopulatedAction(manta::proto::ScannerAction::ActionCase action_case,
-                            base::TimeTicks request_start_time,
-                            base::WeakPtr<ScannerCommandDelegate> delegate,
-                            ScannerCommandCallback action_finished_callback,
-                            manta::proto::ScannerAction populated_action) {
-  RecordPopulateActionTimer(action_case, request_start_time);
-  if (populated_action.action_case() ==
-      manta::proto::ScannerAction::ACTION_NOT_SET) {
-    RecordPopulateActionFailure(action_case);
-    std::move(action_finished_callback).Run(false);
-    return;
-  }
-
-  ScannerCommandCallback record_metrics_callback = base::BindOnce(
-      &RecordActionExecutionAndRun, action_case, base::TimeTicks::Now(),
-      std::move(action_finished_callback));
-
-  HandleScannerCommand(std::move(delegate),
-                       ScannerActionToCommand(std::move(populated_action)),
-                       std::move(record_metrics_callback));
-}
-
-}  // namespace
-
 ScannerActionViewModel::ScannerActionViewModel(
-    ScannerUnpopulatedAction unpopulated_action,
-    base::WeakPtr<ScannerCommandDelegate> delegate)
+    manta::proto::ScannerAction unpopulated_action,
+    scoped_refptr<base::RefCountedMemory> downscaled_jpeg_bytes)
     : unpopulated_action_(std::move(unpopulated_action)),
-      delegate_(std::move(delegate)) {}
+      downscaled_jpeg_bytes_(std::move(downscaled_jpeg_bytes)) {}
 
 ScannerActionViewModel::ScannerActionViewModel(const ScannerActionViewModel&) =
     default;
@@ -256,11 +89,4 @@
   return unpopulated_action_.action_case();
 }
 
-void ScannerActionViewModel::ExecuteAction(
-    ScannerCommandCallback action_finished_callback) const {
-  unpopulated_action_.Populate(base::BindOnce(
-      &ExecutePopulatedAction, unpopulated_action_.action_case(),
-      base::TimeTicks::Now(), delegate_, std::move(action_finished_callback)));
-}
-
 }  // namespace ash
diff --git a/ash/scanner/scanner_action_view_model.h b/ash/scanner/scanner_action_view_model.h
index c6e7c87..48ccca8e 100644
--- a/ash/scanner/scanner_action_view_model.h
+++ b/ash/scanner/scanner_action_view_model.h
@@ -8,10 +8,9 @@
 #include <string>
 
 #include "ash/ash_export.h"
-#include "ash/scanner/scanner_action_handler.h"
-#include "ash/scanner/scanner_unpopulated_action.h"
 #include "base/functional/callback_helpers.h"
-#include "base/memory/weak_ptr.h"
+#include "base/memory/ref_counted_memory.h"
+#include "base/memory/scoped_refptr.h"
 #include "components/manta/proto/scanner.pb.h"
 
 namespace gfx {
@@ -20,15 +19,13 @@
 
 namespace ash {
 
-class ScannerCommandDelegate;
-
 // A view model wrapper around a `ScannerUnpopulatedAction`, which handles the
 // conversion to a user-facing text string, icon, and a callback.
 class ASH_EXPORT ScannerActionViewModel {
  public:
   explicit ScannerActionViewModel(
-      ScannerUnpopulatedAction unpopulated_action,
-      base::WeakPtr<ScannerCommandDelegate> delegate);
+      manta::proto::ScannerAction unpopulated_action,
+      scoped_refptr<base::RefCountedMemory> downscaled_jpeg_bytes);
   ScannerActionViewModel(const ScannerActionViewModel&);
   ScannerActionViewModel& operator=(const ScannerActionViewModel&);
   ScannerActionViewModel(ScannerActionViewModel&&);
@@ -41,13 +38,16 @@
   const gfx::VectorIcon& GetIcon() const;
   manta::proto::ScannerAction::ActionCase GetActionCase() const;
 
-  // Executes this action, running the provided callback with a success value
-  // when the execution finishes.
-  void ExecuteAction(ScannerCommandCallback action_finished_callback) const;
+  const manta::proto::ScannerAction& unpopulated_action() const {
+    return unpopulated_action_;
+  }
+  const scoped_refptr<base::RefCountedMemory>& downscaled_jpeg_bytes() const {
+    return downscaled_jpeg_bytes_;
+  }
 
  private:
-  ScannerUnpopulatedAction unpopulated_action_;
-  base::WeakPtr<ScannerCommandDelegate> delegate_;
+  manta::proto::ScannerAction unpopulated_action_;
+  scoped_refptr<base::RefCountedMemory> downscaled_jpeg_bytes_;
 };
 
 }  // namespace ash
diff --git a/ash/scanner/scanner_controller.cc b/ash/scanner/scanner_controller.cc
index eb801e32..4e12519 100644
--- a/ash/scanner/scanner_controller.cc
+++ b/ash/scanner/scanner_controller.cc
@@ -7,6 +7,7 @@
 #include <memory>
 #include <optional>
 #include <string>
+#include <string_view>
 #include <utility>
 #include <vector>
 
@@ -19,19 +20,25 @@
 #include "ash/public/cpp/system/toast_data.h"
 #include "ash/public/cpp/system/toast_manager.h"
 #include "ash/resources/vector_icons/vector_icons.h"
+#include "ash/scanner/scanner_action_handler.h"
 #include "ash/scanner/scanner_command_delegate_impl.h"
 #include "ash/scanner/scanner_feedback.h"
+#include "ash/scanner/scanner_metrics.h"
 #include "ash/scanner/scanner_session.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/shell_delegate.h"
 #include "base/check.h"
+#include "base/check_is_test.h"
 #include "base/containers/span.h"
 #include "base/functional/bind.h"
 #include "base/json/json_writer.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/memory/scoped_refptr.h"
+#include "base/memory/weak_ptr.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/strings/strcat.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "components/account_id/account_id.h"
 #include "components/feedback/feedback_constants.h"
@@ -44,6 +51,8 @@
 
 namespace {
 
+using enum ScannerFeatureUserState;
+
 constexpr char kScannerActionNotificationId[] = "scanner_action_notification";
 constexpr char kScannerNotifierId[] = "ash.scanner";
 
@@ -78,31 +87,154 @@
       message_center::SystemNotificationWarningLevel::NORMAL));
 }
 
-// Should be called when an action finishes execution.
-void OnActionFinished(manta::proto::ScannerAction::ActionCase action_case,
-                      bool success) {
-  // Remove the action progress notification.
-  message_center::MessageCenter::Get()->RemoveNotification(
-      kScannerActionNotificationId,
-      /*by_user=*/false);
-
-  if (success) {
-    // TODO: crbug.com/375967525 - Finalize the action toast string.
-    if (action_case == manta::proto::ScannerAction::kCopyToClipboard) {
-      ToastManager::Get()->Show(ToastData(
-          kScannerActionSuccessToastId, ToastCatalogName::kScannerActionSuccess,
-          u"Text copied to clipboard"));
-    }
-    // TODO: crbug.com/383925780 - We should also show a toast for other action
-    // cases once the feedback mechanism is ready.
-  } else {
-    // TODO: crbug.com/383926250 - The action failure text should depend on the
-    // type of action attempted.
-    constexpr char16_t kPlaceholderActionFailureText[] = u"Action Failed";
-    ToastManager::Get()->Show(ToastData(kScannerActionFailureToastId,
-                                        ToastCatalogName::kScannerActionFailure,
-                                        kPlaceholderActionFailureText));
+void RecordExecutePopulatedActionTimer(
+    manta::proto::ScannerAction::ActionCase action_case,
+    base::TimeTicks execute_start_time) {
+  // TODO(b/363101363): Add tests.
+  std::string_view variant_name;
+  switch (action_case) {
+    case manta::proto::ScannerAction::kNewEvent:
+      variant_name = kScannerFeatureTimerExecutePopulatedNewCalendarEventAction;
+      break;
+    case manta::proto::ScannerAction::kNewContact:
+      variant_name = kScannerFeatureTimerExecutePopulatedNewContactAction;
+      break;
+    case manta::proto::ScannerAction::kNewGoogleDoc:
+      variant_name = kScannerFeatureTimerExecutePopulatedNewGoogleDocAction;
+      break;
+    case manta::proto::ScannerAction::kNewGoogleSheet:
+      variant_name = kScannerFeatureTimerExecutePopulatedNewGoogleSheetAction;
+      break;
+    case manta::proto::ScannerAction::kCopyToClipboard:
+      variant_name =
+          kScannerFeatureTimerExecutePopulatedNewCopyToClipboardAction;
+      break;
+    case manta::proto::ScannerAction::ACTION_NOT_SET:
+      break;
   }
+  if (variant_name.empty()) {
+    return;
+  }
+  base::UmaHistogramMediumTimes(variant_name,
+                                base::TimeTicks::Now() - execute_start_time);
+}
+
+void RecordPopulateActionTimer(
+    manta::proto::ScannerAction::ActionCase action_case,
+    base::TimeTicks request_start_time) {
+  // TODO(b/363101363): Add tests.
+  std::string_view variant_name;
+  switch (action_case) {
+    case manta::proto::ScannerAction::kNewEvent:
+      variant_name = kScannerFeatureTimerPopulateNewCalendarEventAction;
+      break;
+    case manta::proto::ScannerAction::kNewContact:
+      variant_name = kScannerFeatureTimerPopulateNewContactAction;
+      break;
+    case manta::proto::ScannerAction::kNewGoogleDoc:
+      variant_name = kScannerFeatureTimerPopulateNewGoogleDocAction;
+      break;
+    case manta::proto::ScannerAction::kNewGoogleSheet:
+      variant_name = kScannerFeatureTimerPopulateNewGoogleSheetAction;
+      break;
+    case manta::proto::ScannerAction::kCopyToClipboard:
+      variant_name = kScannerFeatureTimerPopulateNewCopyToClipboardAction;
+      break;
+    case manta::proto::ScannerAction::ACTION_NOT_SET:
+      break;
+  }
+  if (variant_name.empty()) {
+    return;
+  }
+  base::UmaHistogramMediumTimes(variant_name,
+                                base::TimeTicks::Now() - request_start_time);
+}
+
+void RecordPopulateActionFailure(
+    manta::proto::ScannerAction::ActionCase action_case) {
+  // TODO(b/363101363): Add tests.
+  switch (action_case) {
+    case manta::proto::ScannerAction::kNewEvent:
+      RecordScannerFeatureUserState(kNewCalendarEventActionPopulationFailed);
+      return;
+    case manta::proto::ScannerAction::kNewContact:
+      RecordScannerFeatureUserState(kNewContactActionPopulationFailed);
+      return;
+    case manta::proto::ScannerAction::kNewGoogleDoc:
+      RecordScannerFeatureUserState(kNewGoogleDocActionPopulationFailed);
+      return;
+    case manta::proto::ScannerAction::kNewGoogleSheet:
+      RecordScannerFeatureUserState(kNewGoogleSheetActionPopulationFailed);
+      return;
+    case manta::proto::ScannerAction::kCopyToClipboard:
+      RecordScannerFeatureUserState(kCopyToClipboardActionPopulationFailed);
+      return;
+    case manta::proto::ScannerAction::ACTION_NOT_SET:
+      return;
+  }
+}
+
+void RecordActionExecutionAndRun(
+    manta::proto::ScannerAction::ActionCase action_case,
+    base::TimeTicks execute_start_time,
+    ScannerCommandCallback action_finished_callback,
+    bool success) {
+  // TODO(b/363101363): Add tests.
+  switch (action_case) {
+    case manta::proto::ScannerAction::kNewEvent:
+      RecordScannerFeatureUserState(
+          success ? kNewCalendarEventActionFinishedSuccessfully
+                  : kNewCalendarEventPopulatedActionExecutionFailed);
+      break;
+    case manta::proto::ScannerAction::kNewContact:
+      RecordScannerFeatureUserState(
+          success ? kNewContactActionFinishedSuccessfully
+                  : kNewContactPopulatedActionExecutionFailed);
+      break;
+    case manta::proto::ScannerAction::kNewGoogleDoc:
+      RecordScannerFeatureUserState(
+          success ? kNewGoogleDocActionFinishedSuccessfully
+                  : kNewGoogleDocPopulatedActionExecutionFailed);
+      break;
+    case manta::proto::ScannerAction::kNewGoogleSheet:
+      RecordScannerFeatureUserState(
+          success ? kNewGoogleSheetActionFinishedSuccessfully
+                  : kNewGoogleSheetPopulatedActionExecutionFailed);
+      break;
+    case manta::proto::ScannerAction::kCopyToClipboard:
+      RecordScannerFeatureUserState(
+          success ? kCopyToClipboardActionFinishedSuccessfully
+                  : kCopyToClipboardPopulatedActionExecutionFailed);
+      break;
+    case manta::proto::ScannerAction::ACTION_NOT_SET:
+      break;
+  }
+  RecordExecutePopulatedActionTimer(action_case, execute_start_time);
+  std::move(action_finished_callback).Run(success);
+}
+
+// Executes the populated action, if it exists, calling
+// `action_finished_callback` with the result of the execution.
+void ExecutePopulatedAction(manta::proto::ScannerAction::ActionCase action_case,
+                            base::TimeTicks request_start_time,
+                            base::WeakPtr<ScannerCommandDelegate> delegate,
+                            ScannerCommandCallback action_finished_callback,
+                            manta::proto::ScannerAction populated_action) {
+  RecordPopulateActionTimer(action_case, request_start_time);
+  if (populated_action.action_case() ==
+      manta::proto::ScannerAction::ACTION_NOT_SET) {
+    RecordPopulateActionFailure(action_case);
+    std::move(action_finished_callback).Run(false);
+    return;
+  }
+
+  ScannerCommandCallback record_metrics_callback = base::BindOnce(
+      &RecordActionExecutionAndRun, action_case, base::TimeTicks::Now(),
+      std::move(action_finished_callback));
+
+  HandleScannerCommand(std::move(delegate),
+                       ScannerActionToCommand(std::move(populated_action)),
+                       std::move(record_metrics_callback));
 }
 
 void OnFeedbackFormSendButtonClicked(const AccountId& account_id,
@@ -150,16 +282,8 @@
   // (to avoid subtle issues from having simultaneously existing sessions).
   scanner_session_ = nullptr;
   if (CanStartSession()) {
-    ScannerProfileScopedDelegate* profile_scoped_delegate =
-        delegate_->GetProfileScopedDelegate();
-    // Keep the existing `command_delegate_` if there is one, to allow commands
-    // from previous sessions to continue in the background if needed.
-    if (command_delegate_ == nullptr) {
-      command_delegate_ =
-          std::make_unique<ScannerCommandDelegateImpl>(profile_scoped_delegate);
-    }
-    scanner_session_ = std::make_unique<ScannerSession>(
-        profile_scoped_delegate, command_delegate_.get());
+    scanner_session_ =
+        std::make_unique<ScannerSession>(delegate_->GetProfileScopedDelegate());
   }
   return scanner_session_.get();
 }
@@ -180,9 +304,25 @@
 
 void ScannerController::ExecuteAction(
     const ScannerActionViewModel& scanner_action) {
+  if (!scanner_session_) {
+    return;
+  }
+  // Keep the existing `command_delegate_` if there is one, to allow commands
+  // from previous sessions to continue in the background if needed.
+  if (!command_delegate_) {
+    command_delegate_ = std::make_unique<ScannerCommandDelegateImpl>(
+        delegate_->GetProfileScopedDelegate());
+  }
   const manta::proto::ScannerAction::ActionCase action_case =
       scanner_action.GetActionCase();
-  scanner_action.ExecuteAction(base::BindOnce(&OnActionFinished, action_case));
+  scanner_session_->PopulateAction(
+      scanner_action.downscaled_jpeg_bytes(),
+      scanner_action.unpopulated_action(),
+      base::BindOnce(
+          &ExecutePopulatedAction, action_case, base::TimeTicks::Now(),
+          command_delegate_->GetWeakPtr(),
+          base::BindOnce(&ScannerController::OnActionFinished,
+                         weak_ptr_factory_.GetWeakPtr(), action_case)));
   ShowActionProgressNotification(action_case);
 }
 
@@ -208,8 +348,45 @@
       base::BindOnce(&OnFeedbackFormSendButtonClicked, account_id));
 }
 
+void ScannerController::SetOnActionFinishedForTesting(
+    OnActionFinishedCallback callback) {
+  on_action_finished_for_testing_ = std::move(callback);
+}
+
 bool ScannerController::HasActiveSessionForTesting() const {
   return !!scanner_session_;
 }
 
+void ScannerController::OnActionFinished(
+    manta::proto::ScannerAction::ActionCase action_case,
+    bool success) {
+  // Remove the action progress notification.
+  message_center::MessageCenter::Get()->RemoveNotification(
+      kScannerActionNotificationId,
+      /*by_user=*/false);
+
+  if (success) {
+    // TODO: crbug.com/375967525 - Finalize the action toast string.
+    if (action_case == manta::proto::ScannerAction::kCopyToClipboard) {
+      ToastManager::Get()->Show(ToastData(
+          kScannerActionSuccessToastId, ToastCatalogName::kScannerActionSuccess,
+          u"Text copied to clipboard"));
+    }
+    // TODO: crbug.com/383925780 - We should also show a toast for other action
+    // cases once the feedback mechanism is ready.
+  } else {
+    // TODO: crbug.com/383926250 - The action failure text should depend on the
+    // type of action attempted.
+    constexpr char16_t kPlaceholderActionFailureText[] = u"Action Failed";
+    ToastManager::Get()->Show(ToastData(kScannerActionFailureToastId,
+                                        ToastCatalogName::kScannerActionFailure,
+                                        kPlaceholderActionFailureText));
+  }
+
+  if (!on_action_finished_for_testing_.is_null()) {
+    CHECK_IS_TEST();
+    std::move(on_action_finished_for_testing_).Run(success);
+  }
+}
+
 }  // namespace ash
diff --git a/ash/scanner/scanner_controller.h b/ash/scanner/scanner_controller.h
index 09444a47..f4248cfb 100644
--- a/ash/scanner/scanner_controller.h
+++ b/ash/scanner/scanner_controller.h
@@ -6,10 +6,12 @@
 #define ASH_SCANNER_SCANNER_CONTROLLER_H_
 
 #include <memory>
+#include <utility>
 
 #include "ash/ash_export.h"
 #include "ash/public/cpp/session/session_observer.h"
 #include "ash/scanner/scanner_session.h"
+#include "base/functional/callback.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
@@ -27,6 +29,8 @@
 // between Scanner and any consuming features.
 class ASH_EXPORT ScannerController : public SessionObserver {
  public:
+  using OnActionFinishedCallback = base::OnceCallback<void(bool success)>;
+
   explicit ScannerController(std::unique_ptr<ScannerDelegate> delegate);
   ScannerController(const ScannerController&) = delete;
   ScannerController& operator=(const ScannerController&) = delete;
@@ -70,7 +74,13 @@
 
   ScannerDelegate* delegate_for_testing() { return delegate_.get(); }
 
+  void SetOnActionFinishedForTesting(OnActionFinishedCallback callback);
+
  private:
+  // Should be called when an action finishes execution.
+  void OnActionFinished(manta::proto::ScannerAction::ActionCase action_case,
+                        bool success);
+
   std::unique_ptr<ScannerDelegate> delegate_;
 
   // Delegate to handle Scanner commands for actions fetched during a session.
@@ -81,6 +91,8 @@
   // May hold an active Scanner session, to allow access to the Scanner feature.
   std::unique_ptr<ScannerSession> scanner_session_;
 
+  OnActionFinishedCallback on_action_finished_for_testing_;
+
   ScopedSessionObserver session_observer_{this};
 
   base::WeakPtrFactory<ScannerController> weak_ptr_factory_{this};
diff --git a/ash/scanner/scanner_controller_unittest.cc b/ash/scanner/scanner_controller_unittest.cc
index f4b55e9..67b2398 100644
--- a/ash/scanner/scanner_controller_unittest.cc
+++ b/ash/scanner/scanner_controller_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "ash/scanner/scanner_controller.h"
 
+#include <cstdint>
 #include <memory>
 #include <optional>
 #include <string>
@@ -16,30 +17,43 @@
 #include "ash/public/cpp/scanner/scanner_enums.h"
 #include "ash/public/cpp/scanner/scanner_feedback_info.h"
 #include "ash/public/cpp/system/toast_manager.h"
+#include "ash/public/cpp/test/test_new_window_delegate.h"
 #include "ash/scanner/fake_scanner_delegate.h"
 #include "ash/scanner/fake_scanner_profile_scoped_delegate.h"
 #include "ash/scanner/scanner_action_view_model.h"
+#include "ash/scanner/scanner_session.h"
 #include "ash/session/session_controller_impl.h"
 #include "ash/shell.h"
 #include "ash/test/ash_test_base.h"
 #include "ash/test_shell_delegate.h"
+#include "base/check.h"
 #include "base/containers/span.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/strings/string_split.h"
 #include "base/test/gmock_callback_support.h"
 #include "base/test/mock_callback.h"
+#include "base/test/protobuf_matchers.h"
 #include "base/test/scoped_feature_list.h"
+#include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "base/test/values_test_util.h"
 #include "chromeos/ash/components/specialized_features/feature_access_checker.h"
 #include "components/feedback/feedback_constants.h"
 #include "components/manta/manta_status.h"
 #include "components/manta/proto/scanner.pb.h"
+#include "components/manta/scanner_provider.h"
 #include "google_apis/gaia/gaia_id.h"
+#include "net/http/http_status_code.h"
+#include "net/test/embedded_test_server/embedded_test_server.h"
+#include "net/test/embedded_test_server/http_response.h"
 #include "testing/gmock/include/gmock/gmock-matchers.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "ui/gfx/codec/jpeg_codec.h"
+#include "ui/gfx/image/image_skia.h"
+#include "ui/gfx/image/image_unittest_util.h"
+#include "ui/message_center/fake_message_center.h"
 #include "ui/message_center/message_center.h"
 #include "url/gurl.h"
 
@@ -47,6 +61,7 @@
 
 namespace {
 
+using ::base::test::EqualsProto;
 using ::base::test::InvokeFuture;
 using ::base::test::IsJson;
 using ::base::test::RunOnceCallback;
@@ -56,6 +71,7 @@
 using ::testing::Eq;
 using ::testing::IsEmpty;
 using ::testing::Optional;
+using ::testing::Property;
 using ::testing::Return;
 using ::testing::SizeIs;
 using ::testing::StartsWith;
@@ -76,6 +92,23 @@
       scanner_controller.delegate_for_testing()->GetProfileScopedDelegate());
 }
 
+scoped_refptr<base::RefCountedMemory> MakeJpegBytes(int width = 100,
+                                                    int height = 100) {
+  gfx::ImageSkia img = gfx::test::CreateImageSkia(width, height);
+  std::optional<std::vector<uint8_t>> data =
+      gfx::JPEGCodec::Encode(*img.bitmap(), /*quality=*/90);
+  CHECK(data.has_value());
+  return base::MakeRefCounted<base::RefCountedBytes>(std::move(*data));
+}
+
+class MockNewWindowDelegate : public TestNewWindowDelegate {
+ public:
+  MOCK_METHOD(void,
+              OpenUrl,
+              (const GURL& url, OpenUrlFrom from, Disposition disposition),
+              (override));
+};
+
 class ScannerControllerTest : public AshTestBase {
  public:
   ScannerControllerTest() = default;
@@ -96,10 +129,15 @@
     return mock_send_specialized_feature_feedback_;
   }
 
+  MockNewWindowDelegate& mock_new_window_delegate() {
+    return mock_new_window_delegate_;
+  }
+
  private:
   testing::StrictMock<base::MockCallback<
       TestShellDelegate::SendSpecializedFeatureFeedbackCallback>>
       mock_send_specialized_feature_feedback_;
+  MockNewWindowDelegate mock_new_window_delegate_;
   base::test::ScopedFeatureList scoped_feature_list_{features::kScannerUpdate};
 };
 
@@ -401,6 +439,327 @@
       .Run(std::move(feedback_dialog_info), "user description");
 }
 
+TEST_F(ScannerControllerTest, RunningActionFailsIfActionDetailsFails) {
+  ScannerController* scanner_controller = Shell::Get()->scanner_controller();
+  ASSERT_TRUE(scanner_controller);
+  ScannerSession* session = scanner_controller->StartNewSession();
+  ASSERT_TRUE(session);
+  FakeScannerProfileScopedDelegate& delegate =
+      *GetFakeScannerProfileScopedDelegate(*scanner_controller);
+  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
+  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
+  EXPECT_CALL(delegate, FetchActionsForImage)
+      .WillOnce(RunOnceCallback<1>(
+          std::move(unpopulated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+  EXPECT_CALL(delegate, FetchActionDetailsForImage)
+      .WillOnce(RunOnceCallback<2>(
+          nullptr, manta::MantaStatus{
+                       .status_code = manta::MantaStatusCode::kInvalidInput}));
+
+  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
+  session->FetchActionsForImage(nullptr, future.GetCallback());
+  std::vector<ScannerActionViewModel> actions = future.Take();
+  ASSERT_THAT(actions, SizeIs(1));
+  base::test::TestFuture<bool> action_finished_future;
+  scanner_controller->SetOnActionFinishedForTesting(
+      action_finished_future.GetCallback());
+  scanner_controller->ExecuteAction(actions[0]);
+
+  EXPECT_FALSE(action_finished_future.Get());
+}
+
+TEST_F(ScannerControllerTest,
+       RunningActionFailsIfActionDetailsHaveMultipleObjects) {
+  ScannerController* scanner_controller = Shell::Get()->scanner_controller();
+  ASSERT_TRUE(scanner_controller);
+  ScannerSession* session = scanner_controller->StartNewSession();
+  ASSERT_TRUE(session);
+  FakeScannerProfileScopedDelegate& delegate =
+      *GetFakeScannerProfileScopedDelegate(*scanner_controller);
+  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
+  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
+  auto output_with_multiple_objects =
+      std::make_unique<manta::proto::ScannerOutput>();
+  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
+  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
+  EXPECT_CALL(delegate, FetchActionsForImage)
+      .WillOnce(RunOnceCallback<1>(
+          std::move(unpopulated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+  EXPECT_CALL(delegate, FetchActionDetailsForImage)
+      .WillOnce(RunOnceCallback<2>(
+          std::move(output_with_multiple_objects),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+
+  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
+  session->FetchActionsForImage(nullptr, future.GetCallback());
+  std::vector<ScannerActionViewModel> actions = future.Take();
+  ASSERT_THAT(actions, SizeIs(1));
+  base::test::TestFuture<bool> action_finished_future;
+  scanner_controller->SetOnActionFinishedForTesting(
+      action_finished_future.GetCallback());
+  scanner_controller->ExecuteAction(actions[0]);
+
+  EXPECT_FALSE(action_finished_future.Get());
+}
+
+TEST_F(ScannerControllerTest,
+       RunningActionFailsIfActionDetailsHaveMultipleActions) {
+  ScannerController* scanner_controller = Shell::Get()->scanner_controller();
+  ASSERT_TRUE(scanner_controller);
+  ScannerSession* session = scanner_controller->StartNewSession();
+  ASSERT_TRUE(session);
+  FakeScannerProfileScopedDelegate& delegate =
+      *GetFakeScannerProfileScopedDelegate(*scanner_controller);
+  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
+  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
+  auto output_with_multiple_actions =
+      std::make_unique<manta::proto::ScannerOutput>();
+  manta::proto::ScannerObject& object = *unpopulated_output->add_objects();
+  object.add_actions()->mutable_new_event();
+  object.add_actions()->mutable_new_event();
+  EXPECT_CALL(delegate, FetchActionsForImage)
+      .WillOnce(RunOnceCallback<1>(
+          std::move(unpopulated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+  EXPECT_CALL(delegate, FetchActionDetailsForImage)
+      .WillOnce(RunOnceCallback<2>(
+          std::move(output_with_multiple_actions),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+
+  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
+  session->FetchActionsForImage(nullptr, future.GetCallback());
+  std::vector<ScannerActionViewModel> actions = future.Take();
+  ASSERT_THAT(actions, SizeIs(1));
+  base::test::TestFuture<bool> action_finished_future;
+  scanner_controller->SetOnActionFinishedForTesting(
+      action_finished_future.GetCallback());
+  scanner_controller->ExecuteAction(actions[0]);
+
+  EXPECT_FALSE(action_finished_future.Get());
+}
+
+TEST_F(ScannerControllerTest,
+       RunningActionFailsIfActionDetailsHaveDifferentActionCase) {
+  ScannerController* scanner_controller = Shell::Get()->scanner_controller();
+  ASSERT_TRUE(scanner_controller);
+  ScannerSession* session = scanner_controller->StartNewSession();
+  ASSERT_TRUE(session);
+  FakeScannerProfileScopedDelegate& delegate =
+      *GetFakeScannerProfileScopedDelegate(*scanner_controller);
+  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
+  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
+  auto output_with_different_action =
+      std::make_unique<manta::proto::ScannerOutput>();
+  manta::proto::ScannerObject& object = *unpopulated_output->add_objects();
+  object.add_actions()->mutable_new_contact();
+  EXPECT_CALL(delegate, FetchActionsForImage)
+      .WillOnce(RunOnceCallback<1>(
+          std::move(unpopulated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+  EXPECT_CALL(delegate, FetchActionDetailsForImage)
+      .WillOnce(RunOnceCallback<2>(
+          std::move(output_with_different_action),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+
+  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
+  session->FetchActionsForImage(nullptr, future.GetCallback());
+  std::vector<ScannerActionViewModel> actions = future.Take();
+  ASSERT_THAT(actions, SizeIs(1));
+  base::test::TestFuture<bool> action_finished_future;
+  scanner_controller->SetOnActionFinishedForTesting(
+      action_finished_future.GetCallback());
+  scanner_controller->ExecuteAction(actions[0]);
+
+  EXPECT_FALSE(action_finished_future.Get());
+}
+
+TEST_F(ScannerControllerTest,
+       RunningActionsCallsFetchActionDetailsForImageWithResizedImage) {
+  scoped_refptr<base::RefCountedMemory> jpeg_bytes =
+      MakeJpegBytes(/*width=*/2300, /*height=*/23000);
+  ScannerController* scanner_controller = Shell::Get()->scanner_controller();
+  ASSERT_TRUE(scanner_controller);
+  ScannerSession* session = scanner_controller->StartNewSession();
+  ASSERT_TRUE(session);
+  FakeScannerProfileScopedDelegate& delegate =
+      *GetFakeScannerProfileScopedDelegate(*scanner_controller);
+  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
+  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
+  EXPECT_CALL(delegate, FetchActionsForImage)
+      .WillOnce(RunOnceCallback<1>(
+          std::move(unpopulated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+  EXPECT_CALL(delegate, FetchActionDetailsForImage(
+                            Pointee(ResultOf(
+                                "decoding JPEG",
+                                [](const base::RefCountedMemory& bytes) {
+                                  return gfx::JPEGCodec::Decode(bytes);
+                                },
+                                AllOf(Property(&SkBitmap::width, 230),
+                                      Property(&SkBitmap::height, 2300)))),
+                            _, _))
+      .WillOnce(RunOnceCallback<2>(
+          nullptr, manta::MantaStatus{
+                       .status_code = manta::MantaStatusCode::kInvalidInput}));
+
+  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
+  session->FetchActionsForImage(jpeg_bytes, future.GetCallback());
+  std::vector<ScannerActionViewModel> actions = future.Take();
+  ASSERT_THAT(actions, SizeIs(1));
+  base::test::TestFuture<bool> action_finished_future;
+  scanner_controller->SetOnActionFinishedForTesting(
+      action_finished_future.GetCallback());
+  scanner_controller->ExecuteAction(actions[0]);
+  ASSERT_TRUE(action_finished_future.IsReady());
+}
+
+TEST_F(ScannerControllerTest,
+       RunningActionsCallsFetchActionDetailsForImageWithUnpopulatedAction) {
+  ScannerController* scanner_controller = Shell::Get()->scanner_controller();
+  ASSERT_TRUE(scanner_controller);
+  ScannerSession* session = scanner_controller->StartNewSession();
+  ASSERT_TRUE(session);
+  FakeScannerProfileScopedDelegate& delegate =
+      *GetFakeScannerProfileScopedDelegate(*scanner_controller);
+  manta::proto::ScannerAction unpopulated_action;
+  unpopulated_action.mutable_new_event()->set_title("Unpopulated event");
+  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
+  *unpopulated_output->add_objects()->add_actions() = unpopulated_action;
+  EXPECT_CALL(delegate, FetchActionsForImage)
+      .WillOnce(RunOnceCallback<1>(
+          std::move(unpopulated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+  EXPECT_CALL(delegate,
+              FetchActionDetailsForImage(_, EqualsProto(unpopulated_action), _))
+      .WillOnce(RunOnceCallback<2>(
+          nullptr, manta::MantaStatus{
+                       .status_code = manta::MantaStatusCode::kInvalidInput}));
+
+  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
+  session->FetchActionsForImage(nullptr, future.GetCallback());
+  std::vector<ScannerActionViewModel> actions = future.Take();
+  ASSERT_THAT(actions, SizeIs(1));
+  base::test::TestFuture<bool> action_finished_future;
+  scanner_controller->SetOnActionFinishedForTesting(
+      action_finished_future.GetCallback());
+  scanner_controller->ExecuteAction(actions[0]);
+  ASSERT_TRUE(action_finished_future.IsReady());
+}
+
+TEST_F(ScannerControllerTest, RunningNewEventActionOpensUrl) {
+  EXPECT_CALL(mock_new_window_delegate(),
+              OpenUrl(Property("spec", &GURL::spec,
+                               "https://calendar.google.com/calendar/render"
+                               "?action=TEMPLATE"
+                               "&text=%F0%9F%8C%8F"
+                               "&details=formerly+%22Geo+Sync%22"
+                               "&dates=20241014T160000%2F20241014T161500"
+                               "&location=Wonderland"),
+                      _, _))
+      .Times(1);
+  ScannerController* scanner_controller = Shell::Get()->scanner_controller();
+  ASSERT_TRUE(scanner_controller);
+  ScannerSession* session = scanner_controller->StartNewSession();
+  ASSERT_TRUE(session);
+  FakeScannerProfileScopedDelegate& delegate =
+      *GetFakeScannerProfileScopedDelegate(*scanner_controller);
+  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
+  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
+  manta::proto::NewEventAction event_action;
+  event_action.set_title("🌏");
+  event_action.set_description("formerly \"Geo Sync\"");
+  event_action.set_dates("20241014T160000/20241014T161500");
+  event_action.set_location("Wonderland");
+  auto populated_output = std::make_unique<manta::proto::ScannerOutput>();
+  *populated_output->add_objects()->add_actions()->mutable_new_event() =
+      std::move(event_action);
+  EXPECT_CALL(delegate, FetchActionsForImage)
+      .WillOnce(RunOnceCallback<1>(
+          std::move(unpopulated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+  EXPECT_CALL(delegate, FetchActionDetailsForImage)
+      .WillOnce(RunOnceCallback<2>(
+          std::move(populated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+
+  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
+  session->FetchActionsForImage(nullptr, future.GetCallback());
+  std::vector<ScannerActionViewModel> actions = future.Take();
+  ASSERT_THAT(actions, SizeIs(1));
+  base::test::TestFuture<bool> action_finished_future;
+  scanner_controller->SetOnActionFinishedForTesting(
+      action_finished_future.GetCallback());
+  scanner_controller->ExecuteAction(actions[0]);
+
+  EXPECT_TRUE(action_finished_future.Get());
+}
+
+// This test cannot use AshTestBase as it requires an IO thread.
+TEST(ScannerControllerNoFixtureTest, RunningNewContactActionOpensUrl) {
+  // ScannerController dependencies:
+  // A task environment with an IO thread to use `TestSharedURLLoaderFactory`.
+  base::test::TaskEnvironment task_environment(
+      base::test::TaskEnvironment::MainThreadType::IO);
+  // A session controller for `ScopedSessionObserver`.
+  SessionControllerImpl session_controller;
+  // A message center for showing notifications.
+  message_center::MessageCenter::Initialize();
+  // A new window delegate for opening the URL in test.
+  MockNewWindowDelegate mock_new_window_delegate;
+  EXPECT_CALL(mock_new_window_delegate,
+              OpenUrl(Property("spec", &GURL::spec,
+                               "https://contacts.google.com/person/c1?edit=1"),
+                      _, _))
+      .Times(1);
+  ScannerController scanner_controller(std::make_unique<FakeScannerDelegate>());
+  ScannerSession* session = scanner_controller.StartNewSession();
+  ASSERT_TRUE(session);
+  FakeScannerProfileScopedDelegate& delegate =
+      *GetFakeScannerProfileScopedDelegate(scanner_controller);
+  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
+  unpopulated_output->add_objects()->add_actions()->mutable_new_contact();
+  manta::proto::NewContactAction contact_action;
+  contact_action.set_given_name("André");
+  contact_action.set_family_name("François");
+  contact_action.set_email("afrancois@example.com");
+  contact_action.set_phone("+61400000000");
+  auto populated_output = std::make_unique<manta::proto::ScannerOutput>();
+  *populated_output->add_objects()->add_actions()->mutable_new_contact() =
+      std::move(contact_action);
+  EXPECT_CALL(delegate, FetchActionsForImage)
+      .WillOnce(RunOnceCallback<1>(
+          std::move(unpopulated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+  EXPECT_CALL(delegate, FetchActionDetailsForImage)
+      .WillOnce(RunOnceCallback<2>(
+          std::move(populated_output),
+          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
+  base::MockCallback<
+      net::test_server::EmbeddedTestServer::HandleRequestCallback>
+      request_callback;
+  auto response = std::make_unique<net::test_server::BasicHttpResponse>();
+  response->set_code(net::HttpStatusCode::HTTP_OK);
+  response->set_content(R"json({"resourceName": "people/c1"})json");
+  response->set_content_type("application/json");
+  EXPECT_CALL(request_callback, Run).WillOnce(Return(std::move(response)));
+  delegate.SetRequestCallback(request_callback.Get());
+
+  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
+  session->FetchActionsForImage(nullptr, future.GetCallback());
+  std::vector<ScannerActionViewModel> actions = future.Take();
+  ASSERT_THAT(actions, SizeIs(1));
+  base::test::TestFuture<bool> action_finished_future;
+  scanner_controller.SetOnActionFinishedForTesting(
+      action_finished_future.GetCallback());
+  scanner_controller.ExecuteAction(actions[0]);
+
+  EXPECT_TRUE(action_finished_future.Get());
+
+  message_center::MessageCenter::Shutdown();
+}
+
 }  // namespace
 
 }  // namespace ash
diff --git a/ash/scanner/scanner_session.cc b/ash/scanner/scanner_session.cc
index 0d5e963..43041d5b 100644
--- a/ash/scanner/scanner_session.cc
+++ b/ash/scanner/scanner_session.cc
@@ -13,9 +13,7 @@
 
 #include "ash/public/cpp/scanner/scanner_profile_scoped_delegate.h"
 #include "ash/scanner/scanner_action_view_model.h"
-#include "ash/scanner/scanner_command_delegate.h"
 #include "ash/scanner/scanner_metrics.h"
-#include "ash/scanner/scanner_unpopulated_action.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/memory/ref_counted_memory.h"
@@ -95,10 +93,9 @@
 
 // Runs the callback with the populated proto from the response of a call to
 // `FetchActionDetailsForImage`.
-void OnActionPopulated(
-    ScannerUnpopulatedAction::PopulatedActionCallback callback,
-    std::unique_ptr<manta::proto::ScannerOutput> output,
-    manta::MantaStatus status) {
+void OnActionPopulated(ScannerSession::PopulateActionCallback callback,
+                       std::unique_ptr<manta::proto::ScannerOutput> output,
+                       manta::MantaStatus status) {
   if (output == nullptr) {
     // TODO(b/363100868): Handle error case
     std::move(callback).Run(manta::proto::ScannerAction());
@@ -170,9 +167,8 @@
 
 }  // namespace
 
-ScannerSession::ScannerSession(ScannerProfileScopedDelegate* delegate,
-                               ScannerCommandDelegate* command_delegate)
-    : delegate_(delegate), command_delegate_(command_delegate) {}
+ScannerSession::ScannerSession(ScannerProfileScopedDelegate* delegate)
+    : delegate_(delegate) {}
 
 ScannerSession::~ScannerSession() = default;
 
@@ -212,19 +208,12 @@
 
   std::vector<ScannerActionViewModel> action_view_models;
 
-  ScannerUnpopulatedAction::PopulateCallback populate_to_proto_callback =
-      base::BindRepeating(&ScannerSession::PopulateAction,
-                          weak_ptr_factory_.GetWeakPtr(),
-                          downscaled_jpeg_bytes);
-
   for (manta::proto::ScannerAction& proto_action :
        *output->mutable_objects(0)->mutable_actions()) {
-    std::optional<ScannerUnpopulatedAction> unpopulated_action_ =
-        ScannerUnpopulatedAction::FromProto(std::move(proto_action),
-                                            populate_to_proto_callback);
-    if (unpopulated_action_.has_value()) {
-      action_view_models.emplace_back(std::move(*unpopulated_action_),
-                                      command_delegate_->GetWeakPtr());
+    if (proto_action.action_case() !=
+        manta::proto::ScannerAction::ACTION_NOT_SET) {
+      action_view_models.emplace_back(std::move(proto_action),
+                                      downscaled_jpeg_bytes);
     }
   }
 
@@ -234,7 +223,7 @@
 void ScannerSession::PopulateAction(
     scoped_refptr<base::RefCountedMemory> downscaled_jpeg_bytes,
     manta::proto::ScannerAction unpopulated_action,
-    ScannerUnpopulatedAction::PopulatedActionCallback callback) {
+    PopulateActionCallback callback) {
   delegate_->FetchActionDetailsForImage(
       std::move(downscaled_jpeg_bytes), std::move(unpopulated_action),
       base::BindOnce(&OnActionPopulated, std::move(callback)));
diff --git a/ash/scanner/scanner_session.h b/ash/scanner/scanner_session.h
index f76262b..28fef09 100644
--- a/ash/scanner/scanner_session.h
+++ b/ash/scanner/scanner_session.h
@@ -10,7 +10,6 @@
 
 #include "ash/ash_export.h"
 #include "ash/scanner/scanner_action_view_model.h"
-#include "ash/scanner/scanner_unpopulated_action.h"
 #include "base/functional/callback.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/ref_counted_memory.h"
@@ -22,7 +21,6 @@
 
 namespace ash {
 
-class ScannerCommandDelegate;
 class ScannerProfileScopedDelegate;
 
 // A ScannerSession represents a single "use" of the Scanner feature. A session
@@ -36,9 +34,10 @@
   // Callback used to receive the actions returned from a FetchActions call.
   using FetchActionsCallback =
       base::OnceCallback<void(std::vector<ScannerActionViewModel> actions)>;
+  using PopulateActionCallback =
+      base::OnceCallback<void(manta::proto::ScannerAction action)>;
 
-  ScannerSession(ScannerProfileScopedDelegate* delegate,
-                 ScannerCommandDelegate* command_delegate);
+  explicit ScannerSession(ScannerProfileScopedDelegate* delegate);
   ScannerSession(const ScannerSession&) = delete;
   ScannerSession& operator=(const ScannerSession&) = delete;
   ~ScannerSession();
@@ -48,6 +47,13 @@
   void FetchActionsForImage(scoped_refptr<base::RefCountedMemory> jpeg_bytes,
                             FetchActionsCallback callback);
 
+  // Populates the selected action based on the contents of
+  // `downscaled_jpeg_bytes`.
+  void PopulateAction(
+      scoped_refptr<base::RefCountedMemory> downscaled_jpeg_bytes,
+      manta::proto::ScannerAction unpopulated_action,
+      PopulateActionCallback callback);
+
  private:
   void OnActionsReturned(
       scoped_refptr<base::RefCountedMemory> downscaled_jpeg_bytes,
@@ -56,20 +62,8 @@
       std::unique_ptr<manta::proto::ScannerOutput> output,
       manta::MantaStatus status);
 
-  // Populates the selected action. Used as a
-  // `ScannerUnpopulatedAction::PopulateToProtoCallback` once bound with the
-  // possibly-downscaled JPEG bytes.
-  void PopulateAction(
-      scoped_refptr<base::RefCountedMemory> downscaled_jpeg_bytes,
-      manta::proto::ScannerAction unpopulated_action,
-      ScannerUnpopulatedAction::PopulatedActionCallback callback);
-
   const raw_ptr<ScannerProfileScopedDelegate> delegate_;
 
-  // Delegate for performing relevant commands after an action is fetched.
-  // Should outlive `this`.
-  const raw_ptr<ScannerCommandDelegate> command_delegate_;
-
   base::WeakPtrFactory<ScannerSession> weak_ptr_factory_{this};
 };
 
diff --git a/ash/scanner/scanner_session_unittest.cc b/ash/scanner/scanner_session_unittest.cc
index cedc614..552dbdfe 100644
--- a/ash/scanner/scanner_session_unittest.cc
+++ b/ash/scanner/scanner_session_unittest.cc
@@ -9,47 +9,31 @@
 #include <utility>
 #include <vector>
 
-#include "ash/public/cpp/test/test_new_window_delegate.h"
 #include "ash/scanner/fake_scanner_profile_scoped_delegate.h"
 #include "ash/scanner/scanner_action_view_model.h"
-#include "ash/scanner/scanner_command_delegate_impl.h"
 #include "ash/scanner/scanner_metrics.h"
 #include "base/memory/ref_counted_memory.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/test/gmock_callback_support.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "base/test/mock_callback.h"
-#include "base/test/protobuf_matchers.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "components/manta/manta_status.h"
 #include "components/manta/proto/scanner.pb.h"
 #include "components/manta/scanner_provider.h"
-#include "net/http/http_status_code.h"
-#include "net/test/embedded_test_server/embedded_test_server.h"
-#include "net/test/embedded_test_server/http_response.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/codec/jpeg_codec.h"
 #include "ui/gfx/image/image_skia.h"
 #include "ui/gfx/image/image_unittest_util.h"
-#include "url/gurl.h"
 
 namespace ash {
 namespace {
 
-using ::base::test::EqualsProto;
 using ::base::test::InvokeFuture;
 using ::base::test::RunOnceCallback;
-using ::testing::_;
-using ::testing::AllOf;
-using ::testing::DoAll;
 using ::testing::IsEmpty;
-using ::testing::Pointee;
-using ::testing::Property;
-using ::testing::ResultOf;
-using ::testing::Return;
 using ::testing::SizeIs;
 
 constexpr std::string_view kScannerFeatureUserStateHistogram =
@@ -68,22 +52,13 @@
   return base::MakeRefCounted<base::RefCountedBytes>(std::move(*data));
 }
 
-class MockNewWindowDelegate : public TestNewWindowDelegate {
- public:
-  MOCK_METHOD(void,
-              OpenUrl,
-              (const GURL& url, OpenUrlFrom from, Disposition disposition),
-              (override));
-};
-
 TEST(ScannerSessionTest, FetchActionsForImageReturnsEmptyWhenDelegateErrors) {
   FakeScannerProfileScopedDelegate delegate;
   EXPECT_CALL(delegate, FetchActionsForImage)
       .WillOnce(RunOnceCallback<1>(
           nullptr, manta::MantaStatus{
                        .status_code = manta::MantaStatusCode::kInvalidInput}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
 
   base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
   session.FetchActionsForImage(nullptr, future.GetCallback());
@@ -98,8 +73,7 @@
       .WillOnce(RunOnceCallback<1>(
           std::make_unique<manta::proto::ScannerOutput>(),
           manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
 
   base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
   session.FetchActionsForImage(nullptr, future.GetCallback());
@@ -122,8 +96,7 @@
       .WillOnce(RunOnceCallback<1>(
           std::move(output),
           manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
   session.FetchActionsForImage(nullptr, base::DoNothing());
 
   histogram_tester.ExpectBucketCount(
@@ -151,8 +124,7 @@
       .WillOnce(RunOnceCallback<1>(
           std::move(output),
           manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
   session.FetchActionsForImage(nullptr, base::DoNothing());
 
   histogram_tester.ExpectBucketCount(
@@ -167,9 +139,7 @@
   FetchActionsForImageFuture future;
   FakeScannerProfileScopedDelegate delegate;
   EXPECT_CALL(delegate, FetchActionsForImage).WillOnce(InvokeFuture(future));
-
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
   session.FetchActionsForImage(nullptr, base::DoNothing());
   task_environment.FastForwardBy(base::Milliseconds(500));
   auto output = std::make_unique<manta::proto::ScannerOutput>();
@@ -195,8 +165,7 @@
       .WillOnce(RunOnceCallback<1>(
           std::move(output),
           manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
 
   base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
   session.FetchActionsForImage(nullptr, future.GetCallback());
@@ -204,283 +173,11 @@
   EXPECT_THAT(future.Take(), SizeIs(3));
 }
 
-TEST(ScannerSessionTest, RunningActionFailsIfActionDetailsFails) {
-  FakeScannerProfileScopedDelegate delegate;
-  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
-  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
-  EXPECT_CALL(delegate, FetchActionsForImage)
-      .WillOnce(RunOnceCallback<1>(
-          std::move(unpopulated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  EXPECT_CALL(delegate, FetchActionDetailsForImage)
-      .WillOnce(RunOnceCallback<2>(
-          nullptr, manta::MantaStatus{
-                       .status_code = manta::MantaStatusCode::kInvalidInput}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
-
-  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
-  session.FetchActionsForImage(nullptr, future.GetCallback());
-  std::vector<ScannerActionViewModel> actions = future.Take();
-  ASSERT_THAT(actions, SizeIs(1));
-  base::test::TestFuture<bool> action_finished_future;
-  actions.front().ExecuteAction(action_finished_future.GetCallback());
-
-  EXPECT_FALSE(action_finished_future.Get());
-}
-
-TEST(ScannerSessionTest, RunningActionFailsIfActionDetailsHaveMultipleObjects) {
-  FakeScannerProfileScopedDelegate delegate;
-  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
-  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
-  auto output_with_multiple_objects =
-      std::make_unique<manta::proto::ScannerOutput>();
-  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
-  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
-  EXPECT_CALL(delegate, FetchActionsForImage)
-      .WillOnce(RunOnceCallback<1>(
-          std::move(unpopulated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  EXPECT_CALL(delegate, FetchActionDetailsForImage)
-      .WillOnce(RunOnceCallback<2>(
-          std::move(output_with_multiple_objects),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
-
-  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
-  session.FetchActionsForImage(nullptr, future.GetCallback());
-  std::vector<ScannerActionViewModel> actions = future.Take();
-  ASSERT_THAT(actions, SizeIs(1));
-  base::test::TestFuture<bool> action_finished_future;
-  actions.front().ExecuteAction(action_finished_future.GetCallback());
-
-  EXPECT_FALSE(action_finished_future.Get());
-}
-
-TEST(ScannerSessionTest, RunningActionFailsIfActionDetailsHaveMultipleActions) {
-  FakeScannerProfileScopedDelegate delegate;
-  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
-  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
-  auto output_with_multiple_actions =
-      std::make_unique<manta::proto::ScannerOutput>();
-  manta::proto::ScannerObject& object = *unpopulated_output->add_objects();
-  object.add_actions()->mutable_new_event();
-  object.add_actions()->mutable_new_event();
-  EXPECT_CALL(delegate, FetchActionsForImage)
-      .WillOnce(RunOnceCallback<1>(
-          std::move(unpopulated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  EXPECT_CALL(delegate, FetchActionDetailsForImage)
-      .WillOnce(RunOnceCallback<2>(
-          std::move(output_with_multiple_actions),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
-
-  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
-  session.FetchActionsForImage(nullptr, future.GetCallback());
-  std::vector<ScannerActionViewModel> actions = future.Take();
-  ASSERT_THAT(actions, SizeIs(1));
-  base::test::TestFuture<bool> action_finished_future;
-  actions.front().ExecuteAction(action_finished_future.GetCallback());
-
-  EXPECT_FALSE(action_finished_future.Get());
-}
-
-TEST(ScannerSessionTest,
-     RunningActionFailsIfActionDetailsHaveDifferentActionCase) {
-  FakeScannerProfileScopedDelegate delegate;
-  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
-  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
-  auto output_with_different_action =
-      std::make_unique<manta::proto::ScannerOutput>();
-  manta::proto::ScannerObject& object = *unpopulated_output->add_objects();
-  object.add_actions()->mutable_new_contact();
-  EXPECT_CALL(delegate, FetchActionsForImage)
-      .WillOnce(RunOnceCallback<1>(
-          std::move(unpopulated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  EXPECT_CALL(delegate, FetchActionDetailsForImage)
-      .WillOnce(RunOnceCallback<2>(
-          std::move(output_with_different_action),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
-
-  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
-  session.FetchActionsForImage(nullptr, future.GetCallback());
-  std::vector<ScannerActionViewModel> actions = future.Take();
-  ASSERT_THAT(actions, SizeIs(1));
-  base::test::TestFuture<bool> action_finished_future;
-  actions.front().ExecuteAction(action_finished_future.GetCallback());
-
-  EXPECT_FALSE(action_finished_future.Get());
-}
-
-TEST(ScannerSessionTest,
-     RunningActionsCallsFetchActionDetailsForImageWithResizedImage) {
-  scoped_refptr<base::RefCountedMemory> jpeg_bytes =
-      MakeJpegBytes(/*width=*/2300, /*height=*/23000);
-  FakeScannerProfileScopedDelegate delegate;
-  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
-  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
-  EXPECT_CALL(delegate, FetchActionsForImage)
-      .WillOnce(RunOnceCallback<1>(
-          std::move(unpopulated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  EXPECT_CALL(delegate, FetchActionDetailsForImage(
-                            Pointee(ResultOf(
-                                "decoding JPEG",
-                                [](const base::RefCountedMemory& bytes) {
-                                  return gfx::JPEGCodec::Decode(bytes);
-                                },
-                                AllOf(Property(&SkBitmap::width, 230),
-                                      Property(&SkBitmap::height, 2300)))),
-                            _, _))
-      .WillOnce(RunOnceCallback<2>(
-          nullptr, manta::MantaStatus{
-                       .status_code = manta::MantaStatusCode::kInvalidInput}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
-
-  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
-  session.FetchActionsForImage(jpeg_bytes, future.GetCallback());
-  std::vector<ScannerActionViewModel> actions = future.Take();
-  ASSERT_THAT(actions, SizeIs(1));
-  base::test::TestFuture<bool> action_finished_future;
-  actions.front().ExecuteAction(action_finished_future.GetCallback());
-  ASSERT_TRUE(action_finished_future.IsReady());
-}
-
-TEST(ScannerSessionTest,
-     RunningActionsCallsFetchActionDetailsForImageWithUnpopulatedAction) {
-  FakeScannerProfileScopedDelegate delegate;
-  manta::proto::ScannerAction unpopulated_action;
-  unpopulated_action.mutable_new_event()->set_title("Unpopulated event");
-  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
-  *unpopulated_output->add_objects()->add_actions() = unpopulated_action;
-  EXPECT_CALL(delegate, FetchActionsForImage)
-      .WillOnce(RunOnceCallback<1>(
-          std::move(unpopulated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  EXPECT_CALL(delegate,
-              FetchActionDetailsForImage(_, EqualsProto(unpopulated_action), _))
-      .WillOnce(RunOnceCallback<2>(
-          nullptr, manta::MantaStatus{
-                       .status_code = manta::MantaStatusCode::kInvalidInput}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
-
-  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
-  session.FetchActionsForImage(nullptr, future.GetCallback());
-  std::vector<ScannerActionViewModel> actions = future.Take();
-  ASSERT_THAT(actions, SizeIs(1));
-  base::test::TestFuture<bool> action_finished_future;
-  actions.front().ExecuteAction(action_finished_future.GetCallback());
-  ASSERT_TRUE(action_finished_future.IsReady());
-}
-
-TEST(ScannerSessionTest, RunningNewEventActionOpensUrl) {
-  MockNewWindowDelegate new_window_delegate;
-  EXPECT_CALL(new_window_delegate,
-              OpenUrl(Property("spec", &GURL::spec,
-                               "https://calendar.google.com/calendar/render"
-                               "?action=TEMPLATE"
-                               "&text=%F0%9F%8C%8F"
-                               "&details=formerly+%22Geo+Sync%22"
-                               "&dates=20241014T160000%2F20241014T161500"
-                               "&location=Wonderland"),
-                      _, _))
-      .Times(1);
-  FakeScannerProfileScopedDelegate delegate;
-  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
-  unpopulated_output->add_objects()->add_actions()->mutable_new_event();
-  manta::proto::NewEventAction event_action;
-  event_action.set_title("🌏");
-  event_action.set_description("formerly \"Geo Sync\"");
-  event_action.set_dates("20241014T160000/20241014T161500");
-  event_action.set_location("Wonderland");
-  auto populated_output = std::make_unique<manta::proto::ScannerOutput>();
-  *populated_output->add_objects()->add_actions()->mutable_new_event() =
-      std::move(event_action);
-  EXPECT_CALL(delegate, FetchActionsForImage)
-      .WillOnce(RunOnceCallback<1>(
-          std::move(unpopulated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  EXPECT_CALL(delegate, FetchActionDetailsForImage)
-      .WillOnce(RunOnceCallback<2>(
-          std::move(populated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
-
-  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
-  session.FetchActionsForImage(nullptr, future.GetCallback());
-  std::vector<ScannerActionViewModel> actions = future.Take();
-  ASSERT_THAT(actions, SizeIs(1));
-  base::test::TestFuture<bool> action_finished_future;
-  actions.front().ExecuteAction(action_finished_future.GetCallback());
-
-  EXPECT_TRUE(action_finished_future.Get());
-}
-
-TEST(ScannerSessionTest, RunningNewContactActionOpensUrl) {
-  base::test::TaskEnvironment task_environment(
-      base::test::TaskEnvironment::MainThreadType::IO);
-  MockNewWindowDelegate new_window_delegate;
-  EXPECT_CALL(new_window_delegate,
-              OpenUrl(Property("spec", &GURL::spec,
-                               "https://contacts.google.com/person/c1?edit=1"),
-                      _, _))
-      .Times(1);
-  FakeScannerProfileScopedDelegate delegate;
-  auto unpopulated_output = std::make_unique<manta::proto::ScannerOutput>();
-  unpopulated_output->add_objects()->add_actions()->mutable_new_contact();
-  manta::proto::NewContactAction contact_action;
-  contact_action.set_given_name("André");
-  contact_action.set_family_name("François");
-  contact_action.set_email("afrancois@example.com");
-  contact_action.set_phone("+61400000000");
-  auto populated_output = std::make_unique<manta::proto::ScannerOutput>();
-  *populated_output->add_objects()->add_actions()->mutable_new_contact() =
-      std::move(contact_action);
-  EXPECT_CALL(delegate, FetchActionsForImage)
-      .WillOnce(RunOnceCallback<1>(
-          std::move(unpopulated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  EXPECT_CALL(delegate, FetchActionDetailsForImage)
-      .WillOnce(RunOnceCallback<2>(
-          std::move(populated_output),
-          manta::MantaStatus{.status_code = manta::MantaStatusCode::kOk}));
-  base::MockCallback<
-      net::test_server::EmbeddedTestServer::HandleRequestCallback>
-      request_callback;
-  auto response = std::make_unique<net::test_server::BasicHttpResponse>();
-  response->set_code(net::HttpStatusCode::HTTP_OK);
-  response->set_content(R"json({"resourceName": "people/c1"})json");
-  response->set_content_type("application/json");
-  EXPECT_CALL(request_callback, Run).WillOnce(Return(std::move(response)));
-  delegate.SetRequestCallback(request_callback.Get());
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
-
-  base::test::TestFuture<std::vector<ScannerActionViewModel>> future;
-  session.FetchActionsForImage(nullptr, future.GetCallback());
-  std::vector<ScannerActionViewModel> actions = future.Take();
-  ASSERT_THAT(actions, SizeIs(1));
-  base::test::TestFuture<bool> action_finished_future;
-  actions.front().ExecuteAction(action_finished_future.GetCallback());
-
-  EXPECT_TRUE(action_finished_future.Get());
-}
-
 TEST(ScannerSessionTest, ResizesImageHeightToMaxEdge) {
   FakeScannerProfileScopedDelegate delegate;
   FetchActionsForImageFuture future;
   EXPECT_CALL(delegate, FetchActionsForImage).WillOnce(InvokeFuture(future));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
 
   scoped_refptr<base::RefCountedMemory> bytes =
       MakeJpegBytes(/*width=*/2300, /*height=*/23000);
@@ -498,8 +195,7 @@
   FakeScannerProfileScopedDelegate delegate;
   FetchActionsForImageFuture future;
   EXPECT_CALL(delegate, FetchActionsForImage).WillOnce(InvokeFuture(future));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
 
   scoped_refptr<base::RefCountedMemory> bytes =
       MakeJpegBytes(/*width=*/23000, /*height=*/2300);
@@ -517,8 +213,7 @@
   FakeScannerProfileScopedDelegate delegate;
   FetchActionsForImageFuture future;
   EXPECT_CALL(delegate, FetchActionsForImage).WillOnce(InvokeFuture(future));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
 
   scoped_refptr<base::RefCountedMemory> bytes =
       MakeJpegBytes(/*width=*/1000, /*height=*/1000);
@@ -533,8 +228,7 @@
   FakeScannerProfileScopedDelegate delegate;
   FetchActionsForImageFuture future;
   EXPECT_CALL(delegate, FetchActionsForImage).WillOnce(InvokeFuture(future));
-  ScannerCommandDelegateImpl command_delegate(&delegate);
-  ScannerSession session(&delegate, &command_delegate);
+  ScannerSession session(&delegate);
 
   scoped_refptr<base::RefCountedMemory> bytes =
       MakeJpegBytes(/*width=*/4600, /*height=*/1100);
diff --git a/ash/scanner/scanner_unpopulated_action.cc b/ash/scanner/scanner_unpopulated_action.cc
deleted file mode 100644
index 4f7ab4c..0000000
--- a/ash/scanner/scanner_unpopulated_action.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/scanner/scanner_unpopulated_action.h"
-
-#include <optional>
-#include <utility>
-
-#include "base/check_op.h"
-#include "components/manta/proto/scanner.pb.h"
-
-namespace ash {
-
-ScannerUnpopulatedAction::ScannerUnpopulatedAction(
-    manta::proto::ScannerAction unpopulated_action,
-    PopulateCallback populate_to_proto_callback)
-    : unpopulated_action_(std::move(unpopulated_action)),
-      populate_callback_(std::move(populate_to_proto_callback)) {}
-
-std::optional<ScannerUnpopulatedAction> ScannerUnpopulatedAction::FromProto(
-    manta::proto::ScannerAction unpopulated_action,
-    PopulateCallback populate_to_proto_callback) {
-  if (unpopulated_action.action_case() ==
-      manta::proto::ScannerAction::ACTION_NOT_SET) {
-    return std::nullopt;
-  }
-
-  return ScannerUnpopulatedAction(std::move(unpopulated_action),
-                                  std::move(populate_to_proto_callback));
-}
-
-ScannerUnpopulatedAction::ScannerUnpopulatedAction(
-    const ScannerUnpopulatedAction&) = default;
-ScannerUnpopulatedAction& ScannerUnpopulatedAction::operator=(
-    const ScannerUnpopulatedAction&) = default;
-ScannerUnpopulatedAction::ScannerUnpopulatedAction(ScannerUnpopulatedAction&&) =
-    default;
-ScannerUnpopulatedAction& ScannerUnpopulatedAction::operator=(
-    ScannerUnpopulatedAction&&) = default;
-
-ScannerUnpopulatedAction::~ScannerUnpopulatedAction() = default;
-
-void ScannerUnpopulatedAction::Populate(
-    PopulatedActionCallback callback) const& {
-  manta::proto::ScannerAction::ActionCase unpopulated_action_case =
-      unpopulated_action_.action_case();
-  // This should never occur unless the action has been previously moved.
-  CHECK_NE(unpopulated_action_case,
-           manta::proto::ScannerAction::ACTION_NOT_SET);
-
-  // This causes a copy of the unpopulated action to be made.
-  populate_callback_.Run(unpopulated_action_, std::move(callback));
-}
-
-}  // namespace ash
diff --git a/ash/scanner/scanner_unpopulated_action.h b/ash/scanner/scanner_unpopulated_action.h
deleted file mode 100644
index f940719..0000000
--- a/ash/scanner/scanner_unpopulated_action.h
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_SCANNER_SCANNER_UNPOPULATED_ACTION_H_
-#define ASH_SCANNER_SCANNER_UNPOPULATED_ACTION_H_
-
-#include <optional>
-
-#include "ash/ash_export.h"
-#include "base/functional/callback.h"
-#include "components/manta/proto/scanner.pb.h"
-
-namespace ash {
-
-// Represents a `manta::proto::ScannerAction` from an initial response from the
-// Scanner service, which is expected to be "unpopulated".
-//
-// Takes in a `PopulateCallback` which should return a "populated"
-// `manta::proto::ScannerAction`, or one with no action case if there is an
-// error. Provides methods to populate this to a `ScannerAction`.
-class ASH_EXPORT ScannerUnpopulatedAction {
- public:
-  using PopulatedActionCallback =
-      base::OnceCallback<void(manta::proto::ScannerAction populated_action)>;
-  using PopulateCallback = base::RepeatingCallback<void(
-      manta::proto::ScannerAction unpopulated_action,
-      PopulatedActionCallback callback)>;
-
-  // Returns nullopt iff `unpopulated_action.action_case() == ACTION_NOT_SET`.
-  static std::optional<ScannerUnpopulatedAction> FromProto(
-      manta::proto::ScannerAction unpopulated_action,
-      PopulateCallback populate_to_proto_callback);
-
-  ScannerUnpopulatedAction(const ScannerUnpopulatedAction&);
-  ScannerUnpopulatedAction& operator=(const ScannerUnpopulatedAction&);
-  ScannerUnpopulatedAction(ScannerUnpopulatedAction&&);
-  ScannerUnpopulatedAction& operator=(ScannerUnpopulatedAction&&);
-
-  ~ScannerUnpopulatedAction();
-
-  // If this has not been previously moved, this will never return
-  // `ACTION_NOT_SET` and should always be a known enum value.
-  manta::proto::ScannerAction::ActionCase action_case() const {
-    return unpopulated_action_.action_case();
-  }
-
-  // Calls the provided `PopulatedActionCallback` and asynchronously returns a
-  // `ScannerAction`. If any errors occur, such as `callback` returning a
-  // different type of action to this action, an empty action is returned.
-  // This method will crash if this has been previously moved.
-  void Populate(PopulatedActionCallback callback) const&;
-
- private:
-  ScannerUnpopulatedAction(manta::proto::ScannerAction unpopulated_action,
-                           PopulateCallback populate_to_proto_callback);
-
-  // Guaranteed to have `action_case()` to be set to a known value.
-  manta::proto::ScannerAction unpopulated_action_;
-  PopulateCallback populate_callback_;
-};
-
-}  // namespace ash
-
-#endif  // ASH_SCANNER_SCANNER_UNPOPULATED_ACTION_H_
diff --git a/ash/scanner/scanner_unpopulated_action_unittest.cc b/ash/scanner/scanner_unpopulated_action_unittest.cc
deleted file mode 100644
index 5db8173..0000000
--- a/ash/scanner/scanner_unpopulated_action_unittest.cc
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2024 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/scanner/scanner_unpopulated_action.h"
-
-#include <optional>
-
-#include "base/functional/callback_helpers.h"
-#include "base/test/gmock_callback_support.h"
-#include "base/test/mock_callback.h"
-#include "base/test/protobuf_matchers.h"
-#include "base/test/test_future.h"
-#include "components/manta/proto/scanner.pb.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace ash {
-namespace {
-
-using ::base::test::EqualsProto;
-using ::base::test::RunOnceCallback;
-using ::base::test::RunOnceCallbackRepeatedly;
-using ::testing::_;
-using ::testing::Property;
-
-struct TestCase {
-  manta::proto::ScannerAction unpopulated_proto;
-  manta::proto::ScannerAction populated_proto;
-  manta::proto::ScannerAction different_proto;
-};
-
-class ScannerUnpopulatedActionTestWithParam
-    : public ::testing::TestWithParam<TestCase> {};
-
-INSTANTIATE_TEST_SUITE_P(
-    ,
-    ScannerUnpopulatedActionTestWithParam,
-    testing::Values(
-        []() {
-          TestCase test_case;
-          manta::proto::ScannerAction action;
-          manta::proto::NewEventAction& event_action =
-              *action.mutable_new_event();
-          test_case.unpopulated_proto = action;
-
-          event_action.set_title("🌏");
-          event_action.set_description("formerly \"Geo Sync\"");
-          event_action.set_dates("20241014T160000/20241014T161500");
-          event_action.set_location("Wonderland");
-          test_case.populated_proto = action;
-
-          test_case.different_proto.mutable_new_contact();
-
-          return test_case;
-        }(),
-        []() {
-          TestCase test_case;
-          manta::proto::ScannerAction action;
-          manta::proto::NewContactAction& contact_action =
-              *action.mutable_new_contact();
-          test_case.unpopulated_proto = action;
-
-          contact_action.set_given_name("André");
-          contact_action.set_family_name("François");
-          contact_action.set_email("afrancois@example.com");
-          contact_action.set_phone("+61400000000");
-          test_case.populated_proto = action;
-
-          test_case.different_proto.mutable_new_event();
-
-          return test_case;
-        }(),
-        []() {
-          TestCase test_case;
-          manta::proto::ScannerAction action;
-          manta::proto::NewGoogleDocAction& doc_action =
-              *action.mutable_new_google_doc();
-          test_case.unpopulated_proto = action;
-
-          doc_action.set_title("Doc Title");
-          doc_action.set_html_contents("<span>Contents</span>");
-          test_case.populated_proto = action;
-
-          test_case.different_proto.mutable_new_event();
-
-          return test_case;
-        }(),
-        []() {
-          TestCase test_case;
-          manta::proto::ScannerAction action;
-          manta::proto::NewGoogleSheetAction& sheet_action =
-              *action.mutable_new_google_sheet();
-          test_case.unpopulated_proto = action;
-
-          sheet_action.set_title("Sheet Title");
-          sheet_action.set_csv_contents("a,b\n1,2");
-          test_case.populated_proto = action;
-
-          test_case.different_proto.mutable_new_event();
-
-          return test_case;
-        }(),
-        []() {
-          TestCase test_case;
-          manta::proto::ScannerAction action;
-          manta::proto::CopyToClipboardAction& copy_action =
-              *action.mutable_copy_to_clipboard();
-          test_case.unpopulated_proto = action;
-
-          copy_action.set_plain_text("Hello");
-          copy_action.set_html_text("<b>Hello</b>");
-          test_case.populated_proto = action;
-
-          test_case.different_proto.mutable_new_event();
-
-          return test_case;
-        }()));
-
-TEST(ScannerUnpopulatedActionTest, FromUnsetProtoReturnsNullopt) {
-  manta::proto::ScannerAction unpopulated_proto;
-
-  std::optional<ScannerUnpopulatedAction> unpopulated_action =
-      ScannerUnpopulatedAction::FromProto(
-          unpopulated_proto, /*populate_to_proto_callback=*/base::DoNothing());
-
-  EXPECT_FALSE(unpopulated_action.has_value());
-}
-
-TEST_P(ScannerUnpopulatedActionTestWithParam, FromValidProtoReturnsValue) {
-  manta::proto::ScannerAction unpopulated_proto = GetParam().unpopulated_proto;
-
-  std::optional<ScannerUnpopulatedAction> unpopulated_action =
-      ScannerUnpopulatedAction::FromProto(
-          unpopulated_proto, /*populate_to_proto_callback=*/base::DoNothing());
-
-  EXPECT_TRUE(unpopulated_action.has_value());
-}
-
-TEST_P(ScannerUnpopulatedActionTestWithParam, ActionCaseReturnsSameAsInput) {
-  manta::proto::ScannerAction unpopulated_proto = GetParam().unpopulated_proto;
-
-  std::optional<ScannerUnpopulatedAction> unpopulated_action =
-      ScannerUnpopulatedAction::FromProto(
-          unpopulated_proto, /*populate_to_proto_callback=*/base::DoNothing());
-
-  EXPECT_THAT(
-      unpopulated_action,
-      Optional(Property("action_case", &ScannerUnpopulatedAction::action_case,
-                        unpopulated_proto.action_case())));
-}
-
-TEST_P(ScannerUnpopulatedActionTestWithParam,
-       PopulateCallsPopulateCallbackWithUnpopulatedProto) {
-  manta::proto::ScannerAction unpopulated_proto = GetParam().unpopulated_proto;
-  testing::StrictMock<
-      base::MockCallback<ScannerUnpopulatedAction::PopulateCallback>>
-      populate_callback;
-  EXPECT_CALL(populate_callback, Run(EqualsProto(unpopulated_proto), _))
-      .Times(1);
-  std::optional<ScannerUnpopulatedAction> unpopulated_action =
-      ScannerUnpopulatedAction::FromProto(unpopulated_proto,
-                                          populate_callback.Get());
-  ASSERT_TRUE(unpopulated_action.has_value());
-
-  unpopulated_action->Populate(base::DoNothing());
-}
-
-TEST_P(ScannerUnpopulatedActionTestWithParam,
-       PopulateRepeatedlyCallsPopulateCallbackWithUnpopulatedProto) {
-  manta::proto::ScannerAction unpopulated_proto = GetParam().unpopulated_proto;
-  testing::StrictMock<
-      base::MockCallback<ScannerUnpopulatedAction::PopulateCallback>>
-      populate_callback;
-  EXPECT_CALL(populate_callback, Run(EqualsProto(unpopulated_proto), _))
-      .Times(3);
-  std::optional<ScannerUnpopulatedAction> unpopulated_action =
-      ScannerUnpopulatedAction::FromProto(unpopulated_proto,
-                                          populate_callback.Get());
-  ASSERT_TRUE(unpopulated_action.has_value());
-
-  unpopulated_action->Populate(base::DoNothing());
-  unpopulated_action->Populate(base::DoNothing());
-  unpopulated_action->Populate(base::DoNothing());
-}
-
-TEST_P(ScannerUnpopulatedActionTestWithParam, PopulateReturnsPopulated) {
-  manta::proto::ScannerAction unpopulated_proto = GetParam().unpopulated_proto;
-  testing::StrictMock<
-      base::MockCallback<ScannerUnpopulatedAction::PopulateCallback>>
-      populate_to_proto_callback;
-  EXPECT_CALL(populate_to_proto_callback, Run)
-      .WillOnce(RunOnceCallback<1>(GetParam().populated_proto));
-  std::optional<ScannerUnpopulatedAction> unpopulated_action =
-      ScannerUnpopulatedAction::FromProto(unpopulated_proto,
-                                          populate_to_proto_callback.Get());
-  ASSERT_TRUE(unpopulated_action.has_value());
-
-  base::test::TestFuture<manta::proto::ScannerAction> future;
-  unpopulated_action->Populate(future.GetCallback());
-
-  EXPECT_THAT(future.Take(), EqualsProto(GetParam().populated_proto));
-}
-
-TEST_P(ScannerUnpopulatedActionTestWithParam,
-       PopulateRepeatedlyReturnsPopulatedVariant) {
-  manta::proto::ScannerAction unpopulated_proto = GetParam().unpopulated_proto;
-  testing::StrictMock<
-      base::MockCallback<ScannerUnpopulatedAction::PopulateCallback>>
-      populate_to_proto_callback;
-  EXPECT_CALL(populate_to_proto_callback, Run)
-      .Times(3)
-      .WillRepeatedly(RunOnceCallbackRepeatedly<1>(GetParam().populated_proto));
-  std::optional<ScannerUnpopulatedAction> unpopulated_action =
-      ScannerUnpopulatedAction::FromProto(unpopulated_proto,
-                                          populate_to_proto_callback.Get());
-  ASSERT_TRUE(unpopulated_action.has_value());
-
-  base::test::TestFuture<manta::proto::ScannerAction> future;
-  unpopulated_action->Populate(future.GetCallback());
-  EXPECT_THAT(future.Take(), EqualsProto(GetParam().populated_proto));
-
-  unpopulated_action->Populate(future.GetCallback());
-  EXPECT_THAT(future.Take(), EqualsProto(GetParam().populated_proto));
-
-  unpopulated_action->Populate(future.GetCallback());
-  EXPECT_THAT(future.Take(), EqualsProto(GetParam().populated_proto));
-}
-
-}  // namespace
-}  // namespace ash
diff --git a/ash/strings/ash_strings_ar.xtb b/ash/strings/ash_strings_ar.xtb
index 872d3c3..224c0c7 100644
--- a/ash/strings/ash_strings_ar.xtb
+++ b/ash/strings/ash_strings_ar.xtb
@@ -140,6 +140,7 @@
 <translation id="1415846719612499304">عرض قائمة الشبكات: <ph name="STATE_TEXT" /></translation>
 <translation id="1419738280318246476">فتح قفل الجهاز لتنفيذ إجراء الإشعارات</translation>
 <translation id="1420408895951708260">يمكنك تبديل "الإضاءة الليلية". <ph name="STATE_TEXT" /></translation>
+<translation id="1421166164855200062">المجموعة المقترَحة</translation>
 <translation id="1426410128494586442">نعم</translation>
 <translation id="1435537621343861112">يتعذّر بدء الإملاء بسبب إيقاف الميكروفون.</translation>
 <translation id="1445031758921122223">‏تم تنزيل ملفات التحكّم في ميزة FaceGaze</translation>
@@ -244,12 +245,14 @@
 <translation id="17722141032474077">عمليات حسابية</translation>
 <translation id="1774796056689732716">التقويم، <ph name="CURRENT_MONTH_YEAR" />، التاريخ المُحدّد حاليًا هو <ph name="DATE" />.</translation>
 <translation id="178347895271755507">إعداد ميزة عرض الصور والوسائط والإشعارات الحديثة في هاتفك</translation>
+<translation id="1785317913592722944">إزالة العنصر من المجموعة المقترَحة</translation>
 <translation id="1786487376942610288">التبديل بين الحد الأقصى أو الحجم الحالي للنافذة المفتوحة بميزة "نافذة ضمن النافذة"</translation>
 <translation id="1787955149152357925">غير مُفعَّل</translation>
 <translation id="1796561540704213354">المواقع الإلكترونية بما في ذلك الصفحات التي سبقَت زيارتها والصفحات المفتوحة الآن</translation>
 <translation id="179842970735685253">‏بنود خدمة Google</translation>
 <translation id="1805407494113167797">تعذَّر تشغيل المقاطع الصوتية التي تساعد على التركيز</translation>
 <translation id="181103072419391116">قوة الإشارة <ph name="SIGNAL_STRENGTH" />، يديرها المشرف</translation>
+<translation id="1815039896005206046">يؤدي النقر على رمز عدم الإعجاب إلى إرسال ملاحظات بأنّ هذه المجموعة المقترَحة لا تعجبك</translation>
 <translation id="1816896987747843206">يتيح هذا الإجراء إمكانية الوصول إلى الكاميرا من التطبيقات والمواقع الإلكترونية التي لديها هذا الإذن.</translation>
 <translation id="1823873187264960516">الإيثرنت: <ph name="ADDRESS" /></translation>
 <translation id="1824922790784036530">تفعيل إذن الوصول إلى بيانات الموقع الجغرافي</translation>
@@ -391,6 +394,7 @@
 <translation id="2369165858548251131">"مرحبًا" باللغة الصينية</translation>
 <translation id="2370971919968699910">قد يتم تحصيل رسوم منك مقابل ذلك.
 عدد الأجهزة المتصلة <ph name="DEVICECOUNT" />.</translation>
+<translation id="2383521554963939360">مجموعات التطبيقات وعلامات التبويب</translation>
 <translation id="2386292613071805067">اختيار كل محتوى الصفحة</translation>
 <translation id="2389423187722941333">‏تفعيل Gemini أو إيقافه</translation>
 <translation id="2392659840443812875">لا تتوفّر نقطة اتصال. يجب تفعيل البلوتوث ووضع جهازك بالقرب منك.</translation>
@@ -918,6 +922,7 @@
 <translation id="4151054805501931758">تحسين صورة الوجه</translation>
 <translation id="4156293514828496577">‏يتبقّى ‎<ph name="PERCENTAGE" />% من شحن البطارية (حوالي <ph name="TIME_LEFT" />).
 لإطالة عمر البطارية، تم حصر وظائف بعض الميزات.</translation>
+<translation id="4158003972857765638">تنظيم الملفات في سطح مكتب جديد</translation>
 <translation id="4160919062868802509">تم رصد مصادر صوتية متعددة</translation>
 <translation id="416245495747357243">أحسنت!</translation>
 <translation id="4165275524535002941">قد يكون الكابل غير متوافق مع الشاشات</translation>
@@ -982,6 +987,7 @@
 <translation id="4322742403972824594">‏تم تغيير اختصارات لوحة المفاتيح "Ctrl + Alt + السهم المتّجه للأعلى". لاستخدام مفتاح Home، اضغط على المفتاحَين "<ph name="LAUNCHER_KEY_NAME" /> + السهم المتّجه لليسار".</translation>
 <translation id="4324840740119394760">يتيح هذا الإجراء إمكانية الوصول إلى الكاميرا من "<ph name="APP_NAME" />" وجميع التطبيقات والمواقع الإلكترونية التي لديها هذا الإذن.</translation>
 <translation id="4327147325944669226">تسجيل اللعبة</translation>
+<translation id="4329076911374908740">تم بلوغ الحد الأقصى لعدد المجموعات المحفوظة.</translation>
 <translation id="4338109981321384717">العدسة المكبرة</translation>
 <translation id="4348580496249286403">‫<ph name="VOLUME_LEVEL" />، الصوت مكتوم</translation>
 <translation id="4351244548802238354">إغلاق مربع الحوار</translation>
@@ -1938,6 +1944,7 @@
 <translation id="7524043547948122239">‏مهام Google</translation>
 <translation id="7525067979554623046">إنشاء</translation>
 <translation id="7526573455193969409">قد تكون الشبكة خاضعة للمراقبة</translation>
+<translation id="7534543072325030705">يؤدي النقر على رمز الإعجاب إلى إرسال ملاحظات بأنّ هذه المجموعة المقترَحة تعجبك</translation>
 <translation id="7536035074519304529">‏عنوان IP: ‏<ph name="ADDRESS" /></translation>
 <translation id="7536832381700852123">تعديل النافذة اليمنى</translation>
 <translation id="7543399541175347147">‏تطبيقات Linux ونوافذ التصفّح المتخفي غير متوافقة حاليًا، ولكن سيتم حفظ التطبيقات الأخرى.</translation>
@@ -2102,6 +2109,7 @@
 <translation id="8004512796067398576">زيادة</translation>
 <translation id="8005527720597583355">بدء جلسة "وضع التركيز"</translation>
 <translation id="8015361438441228492">تعذَّر تعديل المهمة.</translation>
+<translation id="8027187124910699148">استئناف المجموعة المقترَحة</translation>
 <translation id="802782383769312836">سطح المكتب السابق: <ph name="DESK_NAME" />. سطح المكتب <ph name="DESK_INDEX" /> من <ph name="DESK_COUNT" />.</translation>
 <translation id="8029247720646289474">تعذّر الاتصال بالإنترنت عبر نقطة الاتصال</translation>
 <translation id="8029629653277878342">يجب إدخال رقم التعريف الشخصي أو كلمة المرور لمزيد من الأمان.</translation>
@@ -2210,6 +2218,7 @@
 <translation id="8426708595819210923">مساء الخير <ph name="GIVEN_NAME" />،</translation>
 <translation id="8428213095426709021">الإعدادات</translation>
 <translation id="8428810263141909179">‏‫‎<ph name="MODIFIER_ONE" /><ph name="MODIFIER_TWO" /><ph name="DELIMITER" /> من <ph name="KEY_ONE" /> إلى <ph name="KEY_TWO" /></translation>
+<translation id="8429547770382807369">حفظ المجموعة لوقت لاحق</translation>
 <translation id="8433186206711564395">إعدادات الشبكة</translation>
 <translation id="8433977262951327081">تم تغيير اختصار عرض الفقاعة التفسيرية لقائمة خيارات الإدخال في الرف. يُرجى استخدام <ph name="NEW_SHORTCUT" /> بدلاً من <ph name="OLD_SHORTCUT" />.</translation>
 <translation id="8437311513256731931">فتح أداة "تعليقات"</translation>
@@ -2218,6 +2227,7 @@
 <translation id="8446884382197647889">مزيد من المعلومات</translation>
 <translation id="8456543082656546101"><ph name="SHORTCUT_KEY_NAME" /> + V</translation>
 <translation id="8462305545768648477">إيقاف ميزة "سماع الاختيار"</translation>
+<translation id="8466665972451889002">إظهار العناصر في "<ph name="GROUP_NAME" />"</translation>
 <translation id="8468806060683421065">‏الموعد المحدّد للتسليم: ‎<ph name="DUE_DATE_AND_TIME" /></translation>
 <translation id="847056008324733326">عرض إعدادات المقياس</translation>
 <translation id="8473301994082929012">الميزة <ph name="FEATURE_NAME" /> حالتها <ph name="FEATURE_STATE" /> في <ph name="ORGANIZATION_NAME" />.</translation>
@@ -2240,6 +2250,7 @@
 <translation id="8551588720239073785">إعدادات التاريخ والوقت</translation>
 <translation id="8553395910833293175">سبقَ نقل المحتوى المرئي إلى جميع أسطح المكتب.</translation>
 <translation id="8555757996376137129">إزالة سطح المكتب الحالي</translation>
+<translation id="8558521694042102707">قد ترتكب تكنولوجيا الذكاء الاصطناعي التوليدي أخطاء، بما فيها تلك المتعلّقة بالأشخاص، لذا يُنصَح بالتحقّق من ردودها.</translation>
 <translation id="8559845965695780508">تم تعديله من قِبل "<ph name="USER" />"</translation>
 <translation id="8569146227972631631">درجة فهرنهايت</translation>
 <translation id="8569751806372591456">إليك بعض الاقتراحات للتجربة:</translation>
@@ -2262,6 +2273,7 @@
 <translation id="8637598503828012618">حالة الاتصال <ph name="CONNECTION_STATUS" />، قوة الإشارة <ph name="SIGNAL_STRENGTH" />، يديرها المشرف</translation>
 <translation id="8638637208069328956">تفعيل/إيقاف الميكروفون</translation>
 <translation id="8639760480004882931">يتبقى <ph name="PERCENTAGE" /></translation>
+<translation id="8640470573049727749">إخفاء جميع اقتراحات المجموعات</translation>
 <translation id="8641510901370802679">جارٍ عرض معلومات <ph name="ANSWER_TYPE" /></translation>
 <translation id="8646417893960517480">موقّت <ph name="TOTAL_TIME" /></translation>
 <translation id="8647931990447795414">‏لإضافة شخص، يُرجى إدخال رمز الدخول المخصّص للوالدَين في Family Link.</translation>
@@ -2344,6 +2356,7 @@
 <translation id="8905919797434099235">(بلا عنوان)</translation>
 <translation id="890616557918890486">تغيير المصدر</translation>
 <translation id="8909138438987180327">مستوى طاقة البطارية عند <ph name="PERCENTAGE" /> في المئة.</translation>
+<translation id="8916866375277139011">إخفاء العناصر في "<ph name="GROUP_NAME" />"</translation>
 <translation id="8921554779039049422">H+‎</translation>
 <translation id="8921624153894383499">‏لا يتحدث مساعد Google هذه اللغة.</translation>
 <translation id="8926951137623668982">إخفاء الرف دائمًا</translation>
diff --git a/ash/strings/ash_strings_fa.xtb b/ash/strings/ash_strings_fa.xtb
index 93671d1..681136d 100644
--- a/ash/strings/ash_strings_fa.xtb
+++ b/ash/strings/ash_strings_fa.xtb
@@ -140,6 +140,7 @@
 <translation id="1415846719612499304">نمایش فهرست شبکه. <ph name="STATE_TEXT" />.</translation>
 <translation id="1419738280318246476">برای اجرای کنش اعلان، قفل دستگاه را باز کنید</translation>
 <translation id="1420408895951708260">روشن/خاموش کردن «نور شب». <ph name="STATE_TEXT" /></translation>
+<translation id="1421166164855200062">گروه پیشنهادی</translation>
 <translation id="1426410128494586442">بله</translation>
 <translation id="1435537621343861112">دیکته شروع نشد. میکروفون خاموش است.</translation>
 <translation id="1445031758921122223">فایل‌های کنترل چهره بارگیری شد</translation>
@@ -243,12 +244,14 @@
 <translation id="17722141032474077">محاسبات</translation>
 <translation id="1774796056689732716">تقویم، <ph name="CURRENT_MONTH_YEAR" />، درحال‌حاضر <ph name="DATE" /> انتخاب شده است.</translation>
 <translation id="178347895271755507">راه‌اندازی مشاهده عکس‌ها، رسانه‌ها، و اعلان‌های جدید تلفن</translation>
+<translation id="1785317913592722944">برداشتن مورد از گروه پیشنهادی</translation>
 <translation id="1786487376942610288">جابه‌جایی بین اندازه بیشینه یا اندازه فعلی پنجره تصویر در تصویر</translation>
 <translation id="1787955149152357925">خاموش</translation>
 <translation id="1796561540704213354">وب‌سایت‌ها شامل صفحه‌های که از آن‌ها بازدید کرده‌اید و صفحه‌های باز می‌شود</translation>
 <translation id="179842970735685253">‏شرایط خدمات Google</translation>
 <translation id="1805407494113167797">«صداهای تمرکز» پخش نشد</translation>
 <translation id="181103072419391116">قدرت سیگنال <ph name="SIGNAL_STRENGTH" />، تحت‌مدیریت سرپرست</translation>
+<translation id="1815039896005206046">«رأی مخالف» بازخوردی با این معنا ارسال می‌کند که شما این گروه پیشنهادی را نمی‌پسندید</translation>
 <translation id="1816896987747843206">با این کار، دسترسی به دوربین برای همه برنامه‌ها و وب‌سایت‌های دارای اجازه دوربین مجاز می‌شود</translation>
 <translation id="1823873187264960516">اترنت: <ph name="ADDRESS" /></translation>
 <translation id="1824922790784036530">روشن کردن دسترسی به مکان</translation>
@@ -390,6 +393,7 @@
 <translation id="2369165858548251131">‏‎«Hello»‎ in Chinese (سلام به زبان چینی)</translation>
 <translation id="2370971919968699910">ممکن است هزینه داده دربر داشته باشد.
 ‫<ph name="DEVICECOUNT" /> دستگاه متصل است.</translation>
+<translation id="2383521554963939360">گروه‌های برگه و برنامه</translation>
 <translation id="2386292613071805067">انتخاب همه‌چیز در صفحه</translation>
 <translation id="2389423187722941333">‏روشن/خاموش کردن Gemini</translation>
 <translation id="2392659840443812875">نقطه اتصالی دردسترس نیست. دستگاهتان باید همین اطراف باشد و بلوتوث آن روشن باشد.</translation>
@@ -920,6 +924,7 @@
 <translation id="4151054805501931758">رتوش چهره</translation>
 <translation id="4156293514828496577">‫<ph name="PERCENTAGE" />٪ از شارژ باتری باقی مانده است (حدود <ph name="TIME_LEFT" />).
 برخی‌از ویژگی‌ها برای افزایش عمر باتری محدود شده‌اند.</translation>
+<translation id="4158003972857765638">سازمان‌دهی در میزکار جدید</translation>
 <translation id="4160919062868802509">چند منبع صوتی شناسایی شد</translation>
 <translation id="416245495747357243">بهتر از این نمی‌شود!</translation>
 <translation id="4165275524535002941">کابل از نمایشگر پشتیبانی نمی‌کند</translation>
@@ -984,6 +989,7 @@
 <translation id="4322742403972824594">میان‌بر صفحه‌کلید «مهار + دگرساز + جهت‌نمای بالا» تغییر کرده است. برای استفاده از کلید «صفحه اصلی»، کلید «<ph name="LAUNCHER_KEY_NAME" /> + جهت‌نمای چپ» را فشار دهید.</translation>
 <translation id="4324840740119394760">با این کار، دسترسی به دوربین برای <ph name="APP_NAME" /> و همه برنامه‌ها و وب‌سایت‌های دارای اجازه دوربین مجاز می‌شود</translation>
 <translation id="4327147325944669226">ضبط کردن بازی</translation>
+<translation id="4329076911374908740">به حداکثر تعداد گروه‌های ذخیره‌شده رسیده‌اید.</translation>
 <translation id="4338109981321384717">ذره‌بین</translation>
 <translation id="4348580496249286403">‫<ph name="VOLUME_LEVEL" />، بی‌صدا است</translation>
 <translation id="4351244548802238354">بستن کادر گفتگو</translation>
@@ -1939,6 +1945,7 @@
 <translation id="7524043547948122239">Google Tasks</translation>
 <translation id="7525067979554623046">ایجاد</translation>
 <translation id="7526573455193969409">ممکن است شبکه پایش شود</translation>
+<translation id="7534543072325030705">«رأی موافق» بازخوردی با این معنا ارسال می‌کند که شما این گروه پیشنهادی را می‌پسندید</translation>
 <translation id="7536035074519304529">‏نشانی IP: <ph name="ADDRESS" /></translation>
 <translation id="7536832381700852123">به‌روزرسانی پنجره چپ</translation>
 <translation id="7543399541175347147">‏درحال‌حاضر از برنامه‌های Linux و پنجره‌های «ناشناس» پشتیبانی نمی‌شود. برنامه‌های دیگر ذخیره خواهد شد.</translation>
@@ -2103,6 +2110,7 @@
 <translation id="8004512796067398576">افزایش</translation>
 <translation id="8005527720597583355">شروع جلسه «تمرکز»</translation>
 <translation id="8015361438441228492">تکلیف ویرایش نشد.</translation>
+<translation id="8027187124910699148">ازسر گرفتن گروه پیشنهادی</translation>
 <translation id="802782383769312836">میز کار قبلی: <ph name="DESK_NAME" />. میز کار <ph name="DESK_INDEX" /> از <ph name="DESK_COUNT" />.</translation>
 <translation id="8029247720646289474">نقطه اتصال متصل نشد</translation>
 <translation id="8029629653277878342">برای ایمنی بیشتر به پین یا گذرواژه نیاز است</translation>
@@ -2211,6 +2219,7 @@
 <translation id="8426708595819210923">عصر به‌خیر <ph name="GIVEN_NAME" />،</translation>
 <translation id="8428213095426709021">تنظیمات</translation>
 <translation id="8428810263141909179"><ph name="MODIFIER_ONE" /><ph name="MODIFIER_TWO" /><ph name="DELIMITER" /><ph name="KEY_ONE" /> تا <ph name="KEY_TWO" /></translation>
+<translation id="8429547770382807369">ذخیره کردن گروه برای زمانی دیگر</translation>
 <translation id="8433186206711564395">تنظیمات شبکه</translation>
 <translation id="8433977262951327081">میان‌بر نمایش حبابک گزینه‌های ورودی در قفسه تغییر کرده است. لطفاً به‌جای <ph name="OLD_SHORTCUT" /> از <ph name="NEW_SHORTCUT" /> استفاده کنید.</translation>
 <translation id="8437311513256731931">باز کردن ابزار بازخورد</translation>
@@ -2219,6 +2228,7 @@
 <translation id="8446884382197647889">بیشتر بدانید</translation>
 <translation id="8456543082656546101"><ph name="SHORTCUT_KEY_NAME" /> + ر</translation>
 <translation id="8462305545768648477">بستن «انتخاب برای شنیدن»</translation>
+<translation id="8466665972451889002">نمایش موارد موجود در <ph name="GROUP_NAME" /></translation>
 <translation id="8468806060683421065">تاریخ سررسید: <ph name="DUE_DATE_AND_TIME" /></translation>
 <translation id="847056008324733326">تنظیمات مقیاس نمایش</translation>
 <translation id="8473301994082929012"><ph name="ORGANIZATION_NAME" /> <ph name="FEATURE_STATE" /> <ph name="FEATURE_NAME" /> دارد.</translation>
@@ -2241,6 +2251,7 @@
 <translation id="8551588720239073785">تنظیمات ساعت و تاریخ</translation>
 <translation id="8553395910833293175">قبلاً به همه میزکارها اختصاص داده شده است.</translation>
 <translation id="8555757996376137129">حذف میز کار کنونی</translation>
+<translation id="8558521694042102707">هوش مصنوعی زایا ممکن است اشتباه کند (ازجمله درباره افراد)، بنابراین پاسخ‌ها را دوباره‌سنجی کنید.</translation>
 <translation id="8559845965695780508"><ph name="USER" /> ویرایش کرد</translation>
 <translation id="8569146227972631631">درجه فارنهایت</translation>
 <translation id="8569751806372591456">چند پیشنهاد برای امتحان کردن:</translation>
@@ -2263,6 +2274,7 @@
 <translation id="8637598503828012618"><ph name="CONNECTION_STATUS" />، قدرت سیگنال <ph name="SIGNAL_STRENGTH" />، تحت‌مدیریت سرپرست</translation>
 <translation id="8638637208069328956">روشن/ خاموش کردن میکروفون</translation>
 <translation id="8639760480004882931"><ph name="PERCENTAGE" /> باقی‌مانده</translation>
+<translation id="8640470573049727749">پنهان کردن همه پیشنهادهای گروه</translation>
 <translation id="8641510901370802679">درحال نمایش اطلاعات <ph name="ANSWER_TYPE" /></translation>
 <translation id="8646417893960517480">زمان‌سنج <ph name="TOTAL_TIME" /></translation>
 <translation id="8647931990447795414">‏برای افزودن فرد، کد دسترسی ولی Family Link خود را وارد کنید</translation>
@@ -2344,6 +2356,7 @@
 <translation id="8905919797434099235">(بی‌عنوان)</translation>
 <translation id="890616557918890486">تغییر منبع</translation>
 <translation id="8909138438987180327">شارژ باتری <ph name="PERCENTAGE" /> درصد است.</translation>
+<translation id="8916866375277139011">پنهان کردن موارد موجود در <ph name="GROUP_NAME" /></translation>
 <translation id="8921554779039049422">H+‎</translation>
 <translation id="8921624153894383499">‏«دستیار Google» به این زبان صحبت نمی‌کند.</translation>
 <translation id="8926951137623668982">قفسه همیشه پنهان می‌شود</translation>
diff --git a/ash/strings/ash_strings_mn.xtb b/ash/strings/ash_strings_mn.xtb
index 0e2afb1e..6645c0f9 100644
--- a/ash/strings/ash_strings_mn.xtb
+++ b/ash/strings/ash_strings_mn.xtb
@@ -140,6 +140,7 @@
 <translation id="1415846719612499304">Сүлжээний жагсаалтыг харуулна уу. <ph name="STATE_TEXT" />.</translation>
 <translation id="1419738280318246476">Мэдэгдлийн үйлдлийг гүйцэтгэхийн тулд төхөөрөмжийн түгжээг тайлна уу</translation>
 <translation id="1420408895951708260">Шөнийн гэрлийг асаах/унтраах. <ph name="STATE_TEXT" /></translation>
+<translation id="1421166164855200062">Санал болгосон бүлэг</translation>
 <translation id="1426410128494586442">Тийм</translation>
 <translation id="1435537621343861112">Дуу хоолойгоор бичихийг эхлүүлэх боломжгүй. Таны микрофон унтраалттай байна.</translation>
 <translation id="1445031758921122223">Царайн хяналтын файлыг татсан</translation>
@@ -243,12 +244,14 @@
 <translation id="17722141032474077">Тооцоолол</translation>
 <translation id="1774796056689732716">Календарь, <ph name="CURRENT_MONTH_YEAR" />, одоогоор <ph name="DATE" />-г сонгосон.</translation>
 <translation id="178347895271755507">Утасныхаа саяхны зураг, медиа болон мэдэгдлүүдийг харахыг тохируулах</translation>
+<translation id="1785317913592722944">Санал болгосон бүлгээс зүйл хасах</translation>
 <translation id="1786487376942610288">Дэлгэц доторх дэлгэц цонхны дээд эсвэл одоогийн хэмжээний хооронд сэлгэх</translation>
 <translation id="1787955149152357925">Унтраалттай</translation>
 <translation id="1796561540704213354">Таны зочилсон хуудас болон нээлттэй хуудаснуудыг оруулсан вебсайтууд</translation>
 <translation id="179842970735685253">Google-н үйлчилгээний нөхцөл</translation>
 <translation id="1805407494113167797">Төвлөрөх дуу чимээг тоглуулж чадсангүй</translation>
 <translation id="181103072419391116">Дохионы хүч <ph name="SIGNAL_STRENGTH" />, таны администратор удирддаг</translation>
+<translation id="1815039896005206046">Муу тэмдэглэгээ нь танд энэ санал болгосон бүлэг таалагдаагүй гэсэн санал хүсэлтийг илгээнэ</translation>
 <translation id="1816896987747843206">Энэ нь камерын зөвшөөрөлтэй бүх апп болон вебсайтад камерын хандалтыг зөвшөөрнө</translation>
 <translation id="1823873187264960516">Этернет: <ph name="ADDRESS" /></translation>
 <translation id="1824922790784036530">Байршлын хандалтыг асаах</translation>
@@ -390,6 +393,7 @@
 <translation id="2369165858548251131">"Сайн байна уу?"-г хятад хэлээр</translation>
 <translation id="2370971919968699910">Энэ нь дата ашиглалтын зардал гаргаж магадгүй.
 <ph name="DEVICECOUNT" /> төхөөрөмж холбогдсон.</translation>
+<translation id="2383521554963939360">Апп, табын бүлэг</translation>
 <translation id="2386292613071805067">Хуудсан дээрх бүх зүйлийг сонгох</translation>
 <translation id="2389423187722941333">Gemini-г асаах/унтраах</translation>
 <translation id="2392659840443812875">Боломжтой ямар ч сүлжээний цэг байхгүй. Таны төхөөрөмж ойролцоо бөгөөд Bluetooth-г асаасан эсэхийг шалгана уу.</translation>
@@ -921,6 +925,7 @@
 <translation id="4151054805501931758">Хөрөг засвар</translation>
 <translation id="4156293514828496577"><ph name="PERCENTAGE" />% батарей үлдсэн (ойролцоогоор <ph name="TIME_LEFT" />).
 Зарим онцлогийг батарейн ажиллах хугацааг ихэсгэхээр хязгаарласан.</translation>
+<translation id="4158003972857765638">Шинэ дэлгэцэд зохион байгуулах</translation>
 <translation id="4160919062868802509">Олон аудио эх сурвалж илэрлээ</translation>
 <translation id="416245495747357243">Болчихлоо!</translation>
 <translation id="4165275524535002941">Кабель нь дэлгэцүүдийг дэмжихгүй байж магадгүй</translation>
@@ -985,6 +990,7 @@
 <translation id="4322742403972824594">Ctrl + Alt + Дээш сумны товчлуурын шууд холбоосыг өөрчилсөн байна. Home товчлуурыг ашиглахын тулд <ph name="LAUNCHER_KEY_NAME" /> товчлуур + Зүүн сумыг дарна уу.</translation>
 <translation id="4324840740119394760">Энэ нь <ph name="APP_NAME" /> болон камерын зөвшөөрөлтэй бүх апп болон вебсайтад камерын хандалтыг зөвшөөрнө</translation>
 <translation id="4327147325944669226">Тоглоомыг бичих</translation>
+<translation id="4329076911374908740">Хадгалсан бүлгийн дээд тоонд хүрлээ.</translation>
 <translation id="4338109981321384717">Томруулдаг шил</translation>
 <translation id="4348580496249286403"><ph name="VOLUME_LEVEL" />, Дууг хаасан</translation>
 <translation id="4351244548802238354">Харилцах цонхыг хаах</translation>
@@ -1940,6 +1946,7 @@
 <translation id="7524043547948122239">Google Tasks</translation>
 <translation id="7525067979554623046">Үүсгэх</translation>
 <translation id="7526573455193969409">Сүлжээг хянаж байж болзошгүй</translation>
+<translation id="7534543072325030705">Сайн тэмдэглэгээ нь танд энэ санал болгосон бүлэг таалагдсан гэсэн санал хүсэлтийг илгээнэ</translation>
 <translation id="7536035074519304529">IP хаяг: <ph name="ADDRESS" /></translation>
 <translation id="7536832381700852123">Зүүн талын цонхыг шинэчлэх</translation>
 <translation id="7543399541175347147">Linux аппууд болон Нууцлалтай цонхнуудыг одоогоор дэмждэггүй. Бусад аппыг хадгална.</translation>
@@ -2104,6 +2111,7 @@
 <translation id="8004512796067398576">Тоон өсөлт</translation>
 <translation id="8005527720597583355">Төвлөрөх горимын харилцан үйлдлийг эхлүүлэх</translation>
 <translation id="8015361438441228492">Ажлыг засаж чадсангүй.</translation>
+<translation id="8027187124910699148">Санал болгосон бүлгийг үргэлжлүүлэх</translation>
 <translation id="802782383769312836">Өмнөх дэлгэц: <ph name="DESK_NAME" />. <ph name="DESK_COUNT" />-н <ph name="DESK_INDEX" />-р дэлгэц.</translation>
 <translation id="8029247720646289474">Сүлжээний цэгийн холболт амжилтгүй боллоо</translation>
 <translation id="8029629653277878342">Нэмэлт аюулгүй байдлын үүднээс ПИН эсвэл нууц үг шаардлагатай</translation>
@@ -2212,6 +2220,7 @@
 <translation id="8426708595819210923">Оройн мэнд <ph name="GIVEN_NAME" />,</translation>
 <translation id="8428213095426709021">Тохиргоо</translation>
 <translation id="8428810263141909179"><ph name="MODIFIER_ONE" /><ph name="MODIFIER_TWO" /><ph name="DELIMITER" /><ph name="KEY_ONE" />-с <ph name="KEY_TWO" /></translation>
+<translation id="8429547770382807369">Дараа ашиглахаар бүлгийг хадгалах</translation>
 <translation id="8433186206711564395">Сүлжээний тохиргоо</translation>
 <translation id="8433977262951327081">Тавиурын оролтын сонголт цэсийг харуулдаг товчлолыг өөрчилсөн.
 <ph name="OLD_SHORTCUT" />-н оронд <ph name="NEW_SHORTCUT" />-г ашиглана уу.</translation>
@@ -2221,6 +2230,7 @@
 <translation id="8446884382197647889">Дэлгэрэнгүй мэдээлэл</translation>
 <translation id="8456543082656546101"><ph name="SHORTCUT_KEY_NAME" /> + V</translation>
 <translation id="8462305545768648477">Ярихаар сонгох онцлогийг хаах</translation>
+<translation id="8466665972451889002"><ph name="GROUP_NAME" /> дахь зүйлсийг харуулах</translation>
 <translation id="8468806060683421065">хугацаа нь <ph name="DUE_DATE_AND_TIME" />-д дуусна</translation>
 <translation id="847056008324733326">Дэлгэцийн хэмжээсийн тохиргоо</translation>
 <translation id="8473301994082929012"><ph name="ORGANIZATION_NAME" /> нь <ph name="FEATURE_STATE" /> <ph name="FEATURE_NAME" />-тай байна.</translation>
@@ -2243,6 +2253,7 @@
 <translation id="8551588720239073785">Огноо болон цагийн тохиргоо</translation>
 <translation id="8553395910833293175">Бүх дэлгэц дээр аль хэдийн оноосон.</translation>
 <translation id="8555757996376137129">Одоогийн цонхыг хасах</translation>
+<translation id="8558521694042102707">Үүсгэгч ХОУ хүмүүсийн талаар буруу мэдээлэл үүсгэх зэрэг алдаа гаргаж болох тул хариултыг дахин шалгана уу.</translation>
 <translation id="8559845965695780508"><ph name="USER" /> зассан</translation>
 <translation id="8569146227972631631">°F</translation>
 <translation id="8569751806372591456">Оролдож үзэх цөөн хэдэн зөвлөмж энд байна</translation>
@@ -2265,6 +2276,7 @@
 <translation id="8637598503828012618"><ph name="CONNECTION_STATUS" />, дохионы хүч <ph name="SIGNAL_STRENGTH" />, таны администратор удирддаг</translation>
 <translation id="8638637208069328956">Микрофоныг асаах/унтраах</translation>
 <translation id="8639760480004882931"><ph name="PERCENTAGE" /> үлдсэн</translation>
+<translation id="8640470573049727749">Бүх бүлгийн зөвлөмжийг нуух</translation>
 <translation id="8641510901370802679"><ph name="ANSWER_TYPE" />-н мэдээллийг харуулж байна</translation>
 <translation id="8646417893960517480"><ph name="TOTAL_TIME" /> цаг хэмжигч</translation>
 <translation id="8647931990447795414">Хүн нэмэхийн тулд Family Link-н эцэг эхийн хандалтын кодоо оруулна уу</translation>
@@ -2347,6 +2359,7 @@
 <translation id="8905919797434099235">(Нэргүй)</translation>
 <translation id="890616557918890486">Эх сурвалжийг өөрчлөх</translation>
 <translation id="8909138438987180327">Батарей <ph name="PERCENTAGE" /> хувьтай байна.</translation>
+<translation id="8916866375277139011"><ph name="GROUP_NAME" /> дахь зүйлсийг нуух</translation>
 <translation id="8921554779039049422">H+</translation>
 <translation id="8921624153894383499">Google туслах энэ хэлээр ярьдаггүй.</translation>
 <translation id="8926951137623668982">Shelf-г тогтмол нууна</translation>
diff --git a/ash/strings/ash_strings_uz.xtb b/ash/strings/ash_strings_uz.xtb
index e4a0259..abb76b7 100644
--- a/ash/strings/ash_strings_uz.xtb
+++ b/ash/strings/ash_strings_uz.xtb
@@ -968,6 +968,7 @@
 <translation id="4285498937028063278">Olib tashlash</translation>
 <translation id="428715201724021596">Profilga ulanmoqda. Bu bir necha daqiqa vaqt olishi mumkin.</translation>
 <translation id="4287250812980588583">Chrome oynasi</translation>
+<translation id="4291322857434980285">{NUM_APPS,plural, =1{Mikrofon balandligi <ph name="APP_NAME" /> ilovasi boshqaruvida}other{Mikrofon balandligi # ta ilova boshqaruvida}}</translation>
 <translation id="4294319844246081198">Xayrli tong, <ph name="GIVEN_NAME" /></translation>
 <translation id="4296136865091727875">Barcha bildirishnomalarni tozalash (<ph name="COUNT" />)</translation>
 <translation id="4300272766492248925">Ilovani ochish</translation>
diff --git a/ash/webui/media_app_ui/resources/js/receiver.ts b/ash/webui/media_app_ui/resources/js/receiver.ts
index 4b9d259..ddb92b6 100644
--- a/ash/webui/media_app_ui/resources/js/receiver.ts
+++ b/ash/webui/media_app_ui/resources/js/receiver.ts
@@ -369,6 +369,8 @@
     // Close any existing pipes when opening a new file.
     ocrUntrustedService?.$.close();
     mahiUntrustedService?.$.close();
+    // Release Mantis resources if opened previously.
+    mantisUntrustedService?.$.close();
 
     if (type === 'application/pdf') {
       ocrUntrustedService = connectToOcrUntrustedService();
diff --git a/base/values.cc b/base/values.cc
index 292c8260..fde93d6a 100644
--- a/base/values.cc
+++ b/base/values.cc
@@ -1079,6 +1079,38 @@
   return storage_[index];
 }
 
+bool Value::List::contains(bool val) const {
+  return contains(val, &Value::is_bool, &Value::GetBool);
+}
+
+bool Value::List::contains(int val) const {
+  return contains(val, &Value::is_int, &Value::GetInt);
+}
+
+bool Value::List::contains(double val) const {
+  return contains(val, &Value::is_double, &Value::GetDouble);
+}
+
+bool Value::List::contains(std::string_view val) const {
+  return contains(val, &Value::is_string, &Value::GetString);
+}
+
+bool Value::List::contains(const char* val) const {
+  return contains(std::string_view(val), &Value::is_string, &Value::GetString);
+}
+
+bool Value::List::contains(const BlobStorage& val) const {
+  return contains(val, &Value::is_blob, &Value::GetBlob);
+}
+
+bool Value::List::contains(const Dict& val) const {
+  return contains(val, &Value::is_dict, &Value::GetDict);
+}
+
+bool Value::List::contains(const List& val) const {
+  return contains(val, &Value::is_list, &Value::GetList);
+}
+
 void Value::List::clear() {
   storage_.clear();
 }
diff --git a/base/values.h b/base/values.h
index c782e9cc..d366fd7 100644
--- a/base/values.h
+++ b/base/values.h
@@ -8,7 +8,9 @@
 #include <stddef.h>
 #include <stdint.h>
 
+#include <algorithm>
 #include <array>
+#include <concepts>
 #include <initializer_list>
 #include <iosfwd>
 #include <iterator>
@@ -137,9 +139,9 @@
 // Lists support:
 // - `empty()`, `size()`, `begin()`, `end()`, `cbegin()`, `cend()`,
 //       `rbegin()`, `rend()`, `front()`, `back()`, `reserve()`, `operator[]`,
-//       `clear()`, `erase()`: Identical to the STL container equivalents, with
-//       additional safety checks, e.g. `operator[]` will `CHECK()` if the index
-//       is out of range.
+//       `contains()`, `clear()`, `erase()`: Identical to the STL container
+//       equivalents, with additional safety checks, e.g. `operator[]` will
+//       `CHECK()` if the index is out of range.
 // - `Clone()`: Create a deep copy.
 // - `Append()`: Append a value to the end of the list. Accepts `Value` or any
 //       of the subtypes that `Value` can hold.
@@ -700,6 +702,18 @@
     const Value& operator[](size_t index) const;
     Value& operator[](size_t index);
 
+    // Returns true if the specified `val` is present in the list.
+    bool contains(bool val) const;
+    bool contains(int val) const;
+    bool contains(double val) const;
+    // Note: std::u16string_view overload intentionally omitted: Value
+    // internally stores strings as UTF-8.
+    bool contains(std::string_view val) const;
+    bool contains(const char* val) const;
+    bool contains(const BlobStorage& val) const;
+    bool contains(const Dict& val) const;
+    bool contains(const List& val) const;
+
     // Removes all value from this list.
     REINITIALIZES_AFTER_MOVE void clear();
 
@@ -805,6 +819,17 @@
 
     explicit List(const std::vector<Value>& storage);
 
+    // Shared implementation of public `contains()` methods.
+    template <typename T, typename R>
+      requires std::equality_comparable_with<T, R>
+    bool contains(const T& val,
+                  bool (Value::*test)() const,
+                  R (Value::*get)() const) const {
+      return std::ranges::any_of(storage_, [&](const Value& value) {
+        return (value.*test)() && (value.*get)() == val;
+      });
+    }
+
     std::vector<Value> storage_;
   };
 
diff --git a/base/values_unittest.cc b/base/values_unittest.cc
index d3f1d6dd..a61140ba 100644
--- a/base/values_unittest.cc
+++ b/base/values_unittest.cc
@@ -762,6 +762,40 @@
   EXPECT_CHECK_DEATH(const_list.back());
 }
 
+TEST(ValuesTest, ListContains) {
+  Value::List list;
+  list.Append(false);
+  list.Append(1);
+  list.Append(2.3);
+  list.Append("banana");
+  Value::BlobStorage blob = {0xF, 0x0, 0x0, 0xB, 0xA, 0x2};
+  list.Append(Value(blob));
+  Value::Dict dict;
+  dict.Set("foo", "bar");
+  list.Append(dict.Clone());
+  Value::List list2;
+  list2.Append(99);
+  list.Append(list2.Clone());
+
+  EXPECT_TRUE(list.contains(false));
+  EXPECT_TRUE(list.contains(1));
+  EXPECT_TRUE(list.contains(2.3));
+  EXPECT_TRUE(list.contains("banana"));
+  EXPECT_TRUE(list.contains(std::string_view("banana")));
+  EXPECT_TRUE(list.contains(std::string("banana")));
+  EXPECT_TRUE(list.contains(blob));
+  EXPECT_TRUE(list.contains(dict));
+  EXPECT_TRUE(list.contains(list2));
+
+  EXPECT_FALSE(list.contains(true));
+  EXPECT_FALSE(list.contains(0));
+  EXPECT_FALSE(list.contains(4.5));
+  EXPECT_FALSE(list.contains("orange"));
+  EXPECT_FALSE(list.contains(Value::BlobStorage({1, 2, 3})));
+  EXPECT_FALSE(list.contains(Value::Dict()));
+  EXPECT_FALSE(list.contains(list));
+}
+
 TEST(ValuesTest, ListErase) {
   Value::List list;
   list.Append(1);
diff --git a/chrome/VERSION b/chrome/VERSION
index ca83c4c..6519d631 100644
--- a/chrome/VERSION
+++ b/chrome/VERSION
@@ -1,4 +1,4 @@
 MAJOR=134
 MINOR=0
-BUILD=6967
+BUILD=6969
 PATCH=0
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt
index 537e580..92258a56 100644
--- a/chrome/android/profiles/arm.newest.txt
+++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@
-chromeos-chrome-arm-134.0.6962.0_rc-r1-merged.afdo.bz2
+chromeos-chrome-arm-134.0.6967.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/resources/chromium_strings_uz.xtb b/chrome/app/resources/chromium_strings_uz.xtb
index e49a54a..836b7682 100644
--- a/chrome/app/resources/chromium_strings_uz.xtb
+++ b/chrome/app/resources/chromium_strings_uz.xtb
@@ -524,6 +524,7 @@
 <translation id="813913629614996137">Ishga tushirilmoqda...</translation>
 <translation id="8166782796394721554">Chromiumda JavaScript va WebAssembly tizimi uchun qoʻshimcha himoyasini yoqish</translation>
 <translation id="81770708095080097">Bu fayl xavfli edi va u Chromium tomonidan bloklandi.</translation>
+<translation id="8200109504272824693"><ph name="USER_EMAIL" /> hisobingizda Chromium maʼlumotlaridan foydalanish va saqlash uchun kalit iborangizni kiriting</translation>
 <translation id="8221491193165283816">Odatda bildirishnomalarni bloklaysiz. Bu saytga ruxsat berish uchun bu yerga bosing.</translation>
 <translation id="8223363452568144035">Kameradan foydalanish uchun <ph name="BEGIN_LINK" />tizim sozlamalari<ph name="END_LINK" /> orqali Chromiumga ruxsat bering</translation>
 <translation id="8232193495299001329">Chromium bu kengaytma manbasini tekshira olmadi va u xavfli boʻlishi mumkin. Ochilgan saytlarda shaxsiy axborot kabi maʼlumotlarni koʻrishi va oʻzgartirishini tugatish uchun uni Chromiumdan olib tashlang.</translation>
diff --git a/chrome/app/resources/generated_resources_ar.xtb b/chrome/app/resources/generated_resources_ar.xtb
index c7540b7..ff0e86d 100644
--- a/chrome/app/resources/generated_resources_ar.xtb
+++ b/chrome/app/resources/generated_resources_ar.xtb
@@ -2375,6 +2375,7 @@
 <translation id="2638662041295312666">صورة الملف الشخصي</translation>
 <translation id="2640299212685523844">‏استخدام GTK</translation>
 <translation id="264083724974021997">الاتصال بهاتفك - مربع حوار</translation>
+<translation id="2641098199809442625">لم يتم تعديل كلمة المرور، ولكن ما زال بإمكانك الوصول إلى الموقع الإلكتروني باستخدام كلمة المرور القديمة.</translation>
 <translation id="2642111877055905627">كرة القدم</translation>
 <translation id="2642206811783203764">على <ph name="SITE_NAME" /> دائمًا</translation>
 <translation id="2643064289437760082">يمكنك في أي وقت حذف بيانات "قياس أداء الإعلانات" عن طريق حذف بيانات التصفّح.</translation>
diff --git a/chrome/app/resources/generated_resources_fa.xtb b/chrome/app/resources/generated_resources_fa.xtb
index 515ba03..e786affc 100644
--- a/chrome/app/resources/generated_resources_fa.xtb
+++ b/chrome/app/resources/generated_resources_fa.xtb
@@ -2380,6 +2380,7 @@
 <translation id="2638662041295312666">تصویر ورود به سیستم</translation>
 <translation id="2640299212685523844">‏استفاده از GTK</translation>
 <translation id="264083724974021997">اتصال به تلفن - کادر گفتگو</translation>
+<translation id="2641098199809442625">گذرواژه شما به‌روزرسانی نشد اما همچنان می‌توانید با گذرواژه قدیمی خود، به سایت دسترسی داشته باشید.</translation>
 <translation id="2642111877055905627">توپ فوتبال</translation>
 <translation id="2642206811783203764">همیشه در <ph name="SITE_NAME" /></translation>
 <translation id="2643064289437760082">هر زمان بخواهید می‌توانید با حذف کردن داده‌های مرورتان، داده‌های سنجش آگهی را حذف کنید</translation>
diff --git a/chrome/app/resources/generated_resources_mn.xtb b/chrome/app/resources/generated_resources_mn.xtb
index b5f427f..a658af0 100644
--- a/chrome/app/resources/generated_resources_mn.xtb
+++ b/chrome/app/resources/generated_resources_mn.xtb
@@ -2379,6 +2379,7 @@
 <translation id="2638662041295312666">Нэвтрэх зураг</translation>
 <translation id="2640299212685523844">GTK ашиглах</translation>
 <translation id="264083724974021997">Утсандаа холбогдох - харилцах цонх</translation>
+<translation id="2641098199809442625">Таны нууц үгийг шинэчлээгүй ч та хуучин нууц үгээрээ сайтад хандах боломжтой хэвээр байх ёстой.</translation>
 <translation id="2642111877055905627">Хөлбөмбөгийн бөмбөг</translation>
 <translation id="2642206811783203764">Үргэлж <ph name="SITE_NAME" />-д</translation>
 <translation id="2643064289437760082">Та интернэтээр үзсэн өгөгдлөө устгаснаар зарын хэмжилтийн өгөгдлийг мөн хэзээд устгах боломжтой</translation>
diff --git a/chrome/app/resources/generated_resources_pl.xtb b/chrome/app/resources/generated_resources_pl.xtb
index eaa353c..6b6d79f 100644
--- a/chrome/app/resources/generated_resources_pl.xtb
+++ b/chrome/app/resources/generated_resources_pl.xtb
@@ -3097,7 +3097,7 @@
 <translation id="3177909033752230686">Język strony:</translation>
 <translation id="3177914167275935955">Twoje urządzenie ma licencję na Chrome Education, ale Twoja nazwa użytkownika nie jest powiązana z kontem Google for Education. Utwórz takie konto na stronie g.co/workspace/edusignup, korzystając z dodatkowego urządzenia.</translation>
 <translation id="3179982752812949580">Czcionka tekstu</translation>
-<translation id="3180284704187420717">Zapisuj m.in. swoje zakładki i hasła dzięki synchronizacji</translation>
+<translation id="3180284704187420717">Korzystaj z synchronizacji, aby zapisywać m.in. swoje zakładki i hasła</translation>
 <translation id="3180990259147710757">Przesunięcie żuchwy w lewo</translation>
 <translation id="3181825792072797598">Włącz synchronizację</translation>
 <translation id="3181954750937456830">Bezpieczne przeglądanie (chroni Ciebie i Twoje urządzenie przed niebezpiecznymi witrynami)</translation>
diff --git a/chrome/app/resources/generated_resources_uz.xtb b/chrome/app/resources/generated_resources_uz.xtb
index 7303a0f1..e0a118fd 100644
--- a/chrome/app/resources/generated_resources_uz.xtb
+++ b/chrome/app/resources/generated_resources_uz.xtb
@@ -523,6 +523,7 @@
 <translation id="135389172849514421">Internetsiz ishlaydi</translation>
 <translation id="1353980523955420967">PPD topilmadi. Chromebook internetga ulanganligini tekshiring va qaytadan urining.</translation>
 <translation id="1354045473509304750"><ph name="HOST" /> saytiga kamerangizdan foydalanish va siljitishga ruxsat bering</translation>
+<translation id="1354148503392558902">Parol oʻzgartirilmoqda...</translation>
 <translation id="1355088139103479645">Barcha maʼlumotlar tozalansinmi?</translation>
 <translation id="1356376170199999104">Ruxsat berildi: <ph name="PERMISSION_DETAILS" /> Jismoniy kalit yordamida mikrofonni yoqing.</translation>
 <translation id="1356959069439783953">Nofaol varaqlar endi yangi dizaynda</translation>
@@ -1092,6 +1093,7 @@
 <translation id="1751335846119670066">Oʻqishda yordam</translation>
 <translation id="17513872634828108">Ichki oynalarni ochish</translation>
 <translation id="175196451752279553">Yopiq ichki oynani &amp;qayta ochish</translation>
+<translation id="1752557850776261983">Hisobga kirish tekshirilmoqda...</translation>
 <translation id="1753067873202720523">Chromebook yoniq paytida quvvatlanmasligi mumkin.</translation>
 <translation id="1753557900380512635">Interyerlar</translation>
 <translation id="1753905327828125965">Eng ko‘p ochilganlar</translation>
diff --git a/chrome/app/resources/google_chrome_strings_uz.xtb b/chrome/app/resources/google_chrome_strings_uz.xtb
index ab4cc8c..cbe48ba 100644
--- a/chrome/app/resources/google_chrome_strings_uz.xtb
+++ b/chrome/app/resources/google_chrome_strings_uz.xtb
@@ -323,6 +323,7 @@
 <translation id="4990567037958725628">Google Chrome Canary</translation>
 <translation id="4997044641749333913">Sahifalarni kezishni yaxshilash va tezlatish uchun Chrome bu varaqlarni nofaol qilishi mumkin.</translation>
 <translation id="5003967926796347400">“Google Parollar menejeri” ustiga bosing</translation>
+<translation id="5114340746415930644"><ph name="USER_EMAIL" /> hisobingizda Chrome maʼlumotlaridan foydalanish va saqlash uchun kalit iborangizni kiriting</translation>
 <translation id="5120334927898581447">Boshqa Google xizmatlariga kirilganda Chrome hisobiga kirilsin</translation>
 <translation id="5126049312684316860">Chrome siz tashrif buyurishingiz mumkin boʻlgan koʻplab sahifalarni oldindan yuklaydi, shunda ular tashrif buyurganingizda tezroq yuklanadi</translation>
 <translation id="5132929315877954718">Google Chrome uchun zo‘r ilovalar, o‘yinlar, kengaytmalar va mavzular bilan tanishing.</translation>
diff --git a/chrome/browser/accessibility/live_caption/live_caption_unavailability_notifier.cc b/chrome/browser/accessibility/live_caption/live_caption_unavailability_notifier.cc
index 00df0ab5..84bc6813 100644
--- a/chrome/browser/accessibility/live_caption/live_caption_unavailability_notifier.cc
+++ b/chrome/browser/accessibility/live_caption/live_caption_unavailability_notifier.cc
@@ -108,12 +108,10 @@
 }
 
 bool LiveCaptionUnavailabilityNotifier::ErrorSilencedForOrigin() {
-  using SelectConstVersion = const std::string& (base::Value::*)() const;
   return base::Contains(
       profile_prefs_->GetList(
           prefs::kLiveCaptionMediaFoundationRendererErrorSilenced),
-      render_frame_host().GetLastCommittedOrigin().Serialize(),
-      static_cast<SelectConstVersion>(&base::Value::GetString));
+      render_frame_host().GetLastCommittedOrigin().Serialize());
 }
 
 void LiveCaptionUnavailabilityNotifier::DisplayMediaFoundationRendererError() {
diff --git a/chrome/browser/ash/crosapi/BUILD.gn b/chrome/browser/ash/crosapi/BUILD.gn
index 08b84443..1a17a71 100644
--- a/chrome/browser/ash/crosapi/BUILD.gn
+++ b/chrome/browser/ash/crosapi/BUILD.gn
@@ -466,10 +466,6 @@
 
   allow_circular_includes_from = [
     "//chrome/browser/ash/input_method",
-    "//chrome/browser/ash/login",
-    "//chrome/browser/ash/login/app_mode",
-    "//chrome/browser/ash/login/screens",
-    "//chrome/browser/ash/login/session",
     "//chrome/browser/ash/mahi",
     "//chrome/browser/ash/mahi/media_app",
     "//chrome/browser/ash/policy/core",
diff --git a/chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc b/chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc
index 8a32a51d..46d3f35 100644
--- a/chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc
+++ b/chrome/browser/extensions/api/printer_provider/printer_provider_apitest.cc
@@ -244,10 +244,8 @@
       const base::Value::List& printers,
       const std::vector<base::Value::Dict>& expected_printers) {
     ASSERT_EQ(expected_printers.size(), printers.size());
-    const base::Value::Dict& (base::Value::*get_dict)() const =
-        &base::Value::GetDict;
     for (const auto& printer_value : expected_printers) {
-      EXPECT_TRUE(base::Contains(printers, printer_value, get_dict))
+      EXPECT_TRUE(base::Contains(printers, printer_value))
           << "Unable to find " << printer_value << " in " << printers;
     }
   }
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index b6e4ee5..4d3c057 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -1249,6 +1249,8 @@
       "tabs/saved_tab_groups/collaboration_messaging_observer_factory.h",
       "tabs/saved_tab_groups/collaboration_messaging_tab_data.cc",
       "tabs/saved_tab_groups/collaboration_messaging_tab_data.h",
+      "tabs/saved_tab_groups/instant_message_queue_processor.cc",
+      "tabs/saved_tab_groups/instant_message_queue_processor.h",
       "tabs/saved_tab_groups/local_tab_group_listener.cc",
       "tabs/saved_tab_groups/local_tab_group_listener.h",
       "tabs/saved_tab_groups/saved_tab_group_controller.h",
diff --git a/chrome/browser/ui/intent_picker_tab_helper.cc b/chrome/browser/ui/intent_picker_tab_helper.cc
index 75de4aa84..38da861 100644
--- a/chrome/browser/ui/intent_picker_tab_helper.cc
+++ b/chrome/browser/ui/intent_picker_tab_helper.cc
@@ -472,15 +472,10 @@
     const webapps::AppId& app_id) {
   // WebAppTabHelper has an app_id but it is reset during
   // OnWebAppWillBeUninstalled so using FindAppWithUrlInScope.
-  // TODO(crbug.com/340952100): Evaluate call sites of FindBestAppWithUrlInScope
-  // for correctness.
   std::optional<webapps::AppId> local_app_id =
       registrar_->FindBestAppWithUrlInScope(
           web_contents()->GetLastCommittedURL(),
-          {
-              web_app::proto::InstallState::INSTALLED_WITH_OS_INTEGRATION,
-              web_app::proto::InstallState::INSTALLED_WITHOUT_OS_INTEGRATION,
-          });
+          web_app::WebAppFilter::InstalledInChrome());
   if (app_id == local_app_id) {
     ShowOrHideIcon(web_contents(), /*should_show_icon=*/false);
   }
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc b/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc
index 0c9e726a..2bf87e9 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc
+++ b/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.cc
@@ -16,6 +16,8 @@
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "components/saved_tab_groups/public/tab_group_sync_service.h"
 
+using collaboration::messaging::MessagingBackendServiceFactory;
+
 namespace tab_groups {
 namespace {
 
@@ -201,20 +203,21 @@
 }
 
 CollaborationMessagingObserver::CollaborationMessagingObserver(Profile* profile)
-    : profile_(profile) {
-  auto* service =
-      collaboration::messaging::MessagingBackendServiceFactory::GetForProfile(
-          profile_);
-  CHECK(service);
-  messaging_service_observation_.Observe(service);
+    : profile_(profile),
+      instant_message_queue_processor_(profile),
+      service_(MessagingBackendServiceFactory::GetForProfile(profile_)) {
+  CHECK(service_);
+  persistent_message_service_observation_.Observe(service_);
+  service_->SetInstantMessageDelegate(this);
 }
 
-CollaborationMessagingObserver::~CollaborationMessagingObserver() = default;
+CollaborationMessagingObserver::~CollaborationMessagingObserver() {
+  service_->SetInstantMessageDelegate(nullptr);
+}
 
 void CollaborationMessagingObserver::OnMessagingBackendServiceInitialized() {
-  auto* service = messaging_service_observation_.GetSource();
-  CHECK(service);
-  auto messages = service->GetMessages(std::nullopt);
+  CHECK(service_);
+  auto messages = service_->GetMessages(std::nullopt);
   for (auto message : messages) {
     DispatchMessage(message, MessageDisplayStatus::kDisplay);
   }
@@ -238,4 +241,11 @@
                                    : MessageDisplayStatus::kHide);
 }
 
+void CollaborationMessagingObserver::DisplayInstantaneousMessage(
+    InstantMessage message,
+    InstantMessageSuccessCallback success_callback) {
+  instant_message_queue_processor_.Enqueue(message,
+                                           std::move(success_callback));
+}
+
 }  // namespace tab_groups
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.h b/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.h
index 255d663..2afb789 100644
--- a/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.h
+++ b/chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_observer.h
@@ -7,12 +7,15 @@
 
 #include "base/memory/raw_ptr.h"
 #include "base/scoped_observation.h"
-#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor.h"
 #include "components/collaboration/public/messaging/messaging_backend_service.h"
 #include "components/keyed_service/core/keyed_service.h"
 
+class Profile;
+
 namespace tab_groups {
 
+using collaboration::messaging::InstantMessage;
 using collaboration::messaging::MessagingBackendService;
 using collaboration::messaging::PersistentMessage;
 
@@ -34,6 +37,7 @@
 // activity indicators.
 class CollaborationMessagingObserver
     : public MessagingBackendService::PersistentMessageObserver,
+      public MessagingBackendService::InstantMessageDelegate,
       public KeyedService {
  public:
   explicit CollaborationMessagingObserver(Profile* profile);
@@ -43,6 +47,9 @@
       const CollaborationMessagingObserver&) = delete;
   ~CollaborationMessagingObserver() override;
 
+  using InstantMessageSuccessCallback =
+      CollaborationMessagingObserver::InstantMessageDelegate::SuccessCallback;
+
   // Testing-only method. Dispatch method as though it came from the
   // backend service.
   void DispatchMessageForTests(PersistentMessage message, bool display);
@@ -60,6 +67,11 @@
   void DisplayPersistentMessage(PersistentMessage message) override;
   void HidePersistentMessage(PersistentMessage message) override;
 
+  // MessagingBackendService::InstantMessageDelegate
+  void DisplayInstantaneousMessage(
+      InstantMessage message,
+      InstantMessageSuccessCallback success_callback) override;
+
  private:
   // Finds the tab group designated by this message and sets/hides an
   // attention indicator on the tab group header.
@@ -80,10 +92,13 @@
   void DispatchMessage(PersistentMessage message, MessageDisplayStatus display);
 
   raw_ptr<Profile> profile_;
+  InstantMessageQueueProcessor instant_message_queue_processor_;
+  raw_ptr<MessagingBackendService> service_;
 
+  // Observation for persistent messages.
   base::ScopedObservation<MessagingBackendService,
                           MessagingBackendService::PersistentMessageObserver>
-      messaging_service_observation_{this};
+      persistent_message_service_observation_{this};
 };
 
 }  // namespace tab_groups
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor.cc b/chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor.cc
new file mode 100644
index 0000000..40b1e42
--- /dev/null
+++ b/chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor.cc
@@ -0,0 +1,199 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor.h"
+
+#include "base/check_is_test.h"
+#include "base/containers/queue.h"
+#include "base/task/thread_pool.h"
+#include "chrome/browser/collaboration/messaging/messaging_backend_service_factory.h"
+#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
+#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
+#include "chrome/browser/ui/tabs/saved_tab_groups/collaboration_messaging_tab_data.h"
+#include "chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h"
+#include "chrome/browser/ui/tabs/tab_group.h"
+#include "chrome/browser/ui/tabs/tab_group_model.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/ui/toasts/api/toast_id.h"
+#include "chrome/browser/ui/toasts/toast_features.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/tabs/tab_strip.h"
+#include "components/saved_tab_groups/public/tab_group_sync_service.h"
+
+namespace tab_groups {
+namespace {
+
+// Returns the local tab group ID from the InstantMessage.
+std::optional<LocalTabGroupID> UnwrapTabGroupID(InstantMessage message) {
+  auto tab_group_metadata = message.attribution.tab_group_metadata;
+  if (tab_group_metadata.has_value()) {
+    return tab_group_metadata->local_tab_group_id;
+  }
+  return std::nullopt;
+}
+
+}  // namespace
+
+QueuedInstantMessage::QueuedInstantMessage(InstantMessage message_,
+                                           SuccessCallback success_callback_)
+    : message(message_), success_callback(std::move(success_callback_)) {}
+QueuedInstantMessage::QueuedInstantMessage(QueuedInstantMessage&& other) =
+    default;
+QueuedInstantMessage::~QueuedInstantMessage() = default;
+
+InstantMessageQueueProcessor::InstantMessageQueueProcessor(Profile* profile)
+    : profile_(profile) {}
+InstantMessageQueueProcessor::~InstantMessageQueueProcessor() = default;
+
+void InstantMessageQueueProcessor::Enqueue(InstantMessage message,
+                                           SuccessCallback success_callback) {
+  if (!base::FeatureList::IsEnabled(toast_features::kToastFramework)) {
+    return;
+  }
+
+  if (message.level !=
+      collaboration::messaging::InstantNotificationLevel::BROWSER) {
+    // Only handle browser notifications.
+    return;
+  }
+
+  instant_message_queue_.emplace(message, std::move(success_callback));
+  MaybeShowInstantMessage();
+}
+
+const InstantMessage& InstantMessageQueueProcessor::GetCurrentMessage() {
+  CHECK(!instant_message_queue_.empty());
+  const QueuedInstantMessage& it = instant_message_queue_.front();
+  return it.message;
+}
+
+bool InstantMessageQueueProcessor::IsMessageShowing() {
+  return is_showing_instant_message_;
+}
+
+int InstantMessageQueueProcessor::GetQueueSize() {
+  return instant_message_queue_.size();
+}
+
+void InstantMessageQueueProcessor::MaybeShowInstantMessage() {
+  if (IsMessageShowing()) {
+    // Exit early. Since a message is being shown, a callback will cause
+    // this code path to be entered again when the message is no
+    // longer showing.
+    return;
+  }
+
+  if (instant_message_queue_.empty()) {
+    // End the queue-processing loop.
+    return;
+  }
+
+  // Peek at the next item in queue and attempt to find the appropriate
+  // browser to show the message.
+  QueuedInstantMessage& it = instant_message_queue_.front();
+  const bool message_shown = MaybeShowToastInBrowser(
+      GetBrowser(it.message), GetParamsForMessage(it.message));
+  if (!message_shown) {
+    // Inform the backend that the message could not be displayed.
+    std::move(it.success_callback).Run(false);
+    return ProceedToNextQueueMessage();
+  }
+
+  // Inform the backend that the message was displayed.
+  std::move(it.success_callback).Run(true);
+  is_showing_instant_message_ = true;
+
+  // Schedule next step of queue-processing.
+  base::ThreadPool::PostDelayedTask(
+      FROM_HERE, {},
+      base::BindOnce(
+          &InstantMessageQueueProcessor::ProcessQueueAfterMessageShown,
+          base::Unretained(this)),
+      GetMessageInterval());
+}
+
+Browser* InstantMessageQueueProcessor::GetBrowser(
+    const InstantMessage& message) {
+  Browser* browser = nullptr;
+
+  const bool is_tab_removed_message =
+      message.collaboration_event == CollaborationEvent::TAB_REMOVED &&
+      message.type == collaboration::messaging::InstantNotificationType::
+                          CONFLICT_TAB_REMOVED;
+  const bool is_member_added_message =
+      message.collaboration_event ==
+      CollaborationEvent::COLLABORATION_MEMBER_ADDED;
+  const bool is_collaboration_removed_message =
+      message.collaboration_event == CollaborationEvent::COLLABORATION_REMOVED;
+
+  if (is_tab_removed_message || is_member_added_message ||
+      is_collaboration_removed_message) {
+    // In the case of COLLABORATON_REMOVED, the group may or may not be open.
+    // TODO(crbug.com/390380633): Find a fallback browser for this profile.
+    if (std::optional<LocalTabGroupID> local_tab_group_id =
+            UnwrapTabGroupID(message)) {
+      browser = SavedTabGroupUtils::GetBrowserWithTabGroupId(
+          local_tab_group_id.value());
+    }
+  }
+
+  return browser;
+}
+
+bool InstantMessageQueueProcessor::MaybeShowToastInBrowser(
+    Browser* browser,
+    std::optional<ToastParams> params) {
+  if (!browser) {
+    // Browser state does not support showing this message or this is
+    // not a message that has a corresponding toast.
+    return false;
+  }
+
+  if (!params.has_value()) {
+    // Not a valid message to show.
+    return false;
+  }
+
+  ToastController* toast_controller = browser->GetFeatures().toast_controller();
+  if (!toast_controller) {
+    // Encountered an issue with the toast controller for this browser.
+    return false;
+  }
+
+  return toast_controller->MaybeShowToast(std::move(params.value()));
+}
+
+std::optional<ToastParams> InstantMessageQueueProcessor::GetParamsForMessage(
+    const InstantMessage& message) {
+  // TODO(crbug.com/370781127): Add ToastParams construction.
+  return std::nullopt;
+}
+
+base::TimeDelta InstantMessageQueueProcessor::GetMessageInterval() {
+  // Take the maximum time a toast can show and add a second to ensure
+  // that we wait until a message has completely timed out before trying
+  // to show the next message.
+  // TODO(crbug.com/390814333): Determine the correct heuristic for
+  // time-between-messages.
+  return base::Seconds(1) +
+         std::max(toast_features::kToastTimeout.Get(),
+                  toast_features::kToastWithoutActionTimeout.Get());
+}
+
+void InstantMessageQueueProcessor::ProcessQueueAfterMessageShown() {
+  // This function is only entered if a toast was successfully shown and is
+  // solely responsible for resetting the |is_showing_instant_message_| bool.
+  CHECK(IsMessageShowing());
+  is_showing_instant_message_ = false;
+  ProceedToNextQueueMessage();
+}
+
+void InstantMessageQueueProcessor::ProceedToNextQueueMessage() {
+  CHECK(!IsMessageShowing());
+  CHECK(!instant_message_queue_.empty());
+  instant_message_queue_.pop();
+  MaybeShowInstantMessage();
+}
+
+}  // namespace tab_groups
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor.h b/chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor.h
new file mode 100644
index 0000000..5396acd
--- /dev/null
+++ b/chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor.h
@@ -0,0 +1,110 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_INSTANT_MESSAGE_QUEUE_PROCESSOR_H_
+#define CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_INSTANT_MESSAGE_QUEUE_PROCESSOR_H_
+
+#include "base/containers/queue.h"
+#include "base/memory/raw_ptr.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/toasts/toast_controller.h"
+#include "components/collaboration/public/messaging/messaging_backend_service.h"
+
+class Browser;
+
+namespace tab_groups {
+
+using collaboration::messaging::InstantMessage;
+using collaboration::messaging::MessagingBackendService;
+
+using SuccessCallback =
+    MessagingBackendService::InstantMessageDelegate::SuccessCallback;
+
+// Struct used to capture the instant message and its associated callback.
+struct QueuedInstantMessage {
+  QueuedInstantMessage(InstantMessage message_,
+                       SuccessCallback success_callback_);
+  QueuedInstantMessage(QueuedInstantMessage&& other);
+  ~QueuedInstantMessage();
+
+  InstantMessage message;
+  SuccessCallback success_callback;
+};
+
+// This class acts as a buffer for InstantMessages from the
+// MessagingBackendService. These messages are delivered through
+// a delegate to be shown in the ToastController. Toasts currently cannot
+// be queued, so this queue processor maintains the list of messages. As
+// soon as a message is queued, the processor enters the processing loop
+// where a single message is shown at a time, waiting for some interval
+// before attempting to show the next message.
+//
+// A single instance of this class is meant to be owned by the
+// InstantMessageDelegate for the profile.
+//
+// A drawback to this class is that the toast controller does not provide
+// an observer, so the processor cannot know if a message was dismissed
+// early without polling the toast state.
+class InstantMessageQueueProcessor {
+ public:
+  explicit InstantMessageQueueProcessor(Profile* profile);
+  virtual ~InstantMessageQueueProcessor();
+
+  // Queue a message to be shown in a toast.
+  void Enqueue(InstantMessage message, SuccessCallback success_callback);
+
+  // Returns a reference to the head of the message queue. Must check
+  // that the queue is non-empty before calling.
+  const InstantMessage& GetCurrentMessage();
+
+  // Returns whether a message is currently being shown.
+  bool IsMessageShowing();
+
+  // Returns the size of the queue, including the currently showing item.
+  int GetQueueSize();
+
+  // Returns the time to wait between showing messages.
+  base::TimeDelta GetMessageInterval();
+
+ protected:
+  // Triggers showing a toast for the head of the message queue, as long
+  // as the browser is in a state sufficient to show the given message.
+  void MaybeShowInstantMessage();
+
+  // Responsible for resetting the |is_showing_instant_message_| state.
+  // Called following a timeout after a message has been successfully shown.
+  void ProcessQueueAfterMessageShown();
+
+  // Removes the head of the queue and triggers MaybeShowInstantMessage
+  // for the new message queue head.
+  void ProceedToNextQueueMessage();
+
+  // Finds the toast controller needed to show a message for the group
+  // contained in this message.
+  Browser* GetBrowser(const InstantMessage& message);
+
+  // Finds the toast controller needed to show a message for the group
+  // contained in this message. Virtual for testing purposes only.
+  virtual bool MaybeShowToastInBrowser(Browser* browser,
+                                       std::optional<ToastParams> params);
+
+  // Returns the toast params populated for this message. Returns
+  // std::nullopt if this message cannot be converted into a valid
+  // toast. Virtual for tests.
+  // TODO(crbug.com/370781127): Remove virtual after ToastParams are added.
+  virtual std::optional<ToastParams> GetParamsForMessage(
+      const InstantMessage& message);
+
+  raw_ptr<Profile> profile_;
+
+  // Used to track if an instant message is being shown in a toast.
+  bool is_showing_instant_message_ = false;
+
+  // Queue of instant messages remaining to be shown.
+  base::queue<QueuedInstantMessage> instant_message_queue_;
+};
+
+}  // namespace tab_groups
+
+#endif  // CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_INSTANT_MESSAGE_QUEUE_PROCESSOR_H_
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor_unittest.cc b/chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor_unittest.cc
new file mode 100644
index 0000000..7df33d1f
--- /dev/null
+++ b/chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor_unittest.cc
@@ -0,0 +1,214 @@
+// Copyright 2025 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/tabs/saved_tab_groups/instant_message_queue_processor.h"
+
+#include "base/test/mock_callback.h"
+#include "base/test/scoped_feature_list.h"
+#include "base/test/task_environment.h"
+#include "chrome/browser/data_sharing/data_sharing_service_factory.h"
+#include "chrome/browser/favicon/favicon_utils.h"
+#include "chrome/browser/ui/toasts/api/toast_id.h"
+#include "chrome/browser/ui/toasts/toast_controller.h"
+#include "chrome/browser/ui/toasts/toast_features.h"
+#include "chrome/test/base/testing_profile.h"
+#include "components/collaboration/public/messaging/message.h"
+#include "components/data_sharing/public/data_sharing_service.h"
+#include "components/data_sharing/public/group_data.h"
+#include "components/data_sharing/test_support/mock_data_sharing_service.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace tab_groups {
+
+using collaboration::messaging::CollaborationEvent;
+using collaboration::messaging::InstantMessage;
+using collaboration::messaging::InstantNotificationLevel;
+using collaboration::messaging::InstantNotificationType;
+using collaboration::messaging::MessageAttribution;
+using collaboration::messaging::PersistentNotificationType;
+using collaboration::messaging::TabGroupMessageMetadata;
+using data_sharing::GroupMember;
+using testing::_;
+
+using SuccessCallback = collaboration::messaging::MessagingBackendService::
+    InstantMessageDelegate::SuccessCallback;
+
+namespace {
+
+InstantMessage CreateMessage(CollaborationEvent event) {
+  TabGroupMessageMetadata tab_group_metadata;
+  tab_group_metadata.local_tab_group_id = TabGroupId::GenerateNew();
+
+  MessageAttribution attribution;
+  attribution.tab_group_metadata = tab_group_metadata;
+
+  InstantMessage message;
+  message.attribution = attribution;
+  message.collaboration_event = event;
+  message.level = InstantNotificationLevel::BROWSER;
+  message.type = event == CollaborationEvent::TAB_REMOVED
+                     ? InstantNotificationType::CONFLICT_TAB_REMOVED
+                     : InstantNotificationType::UNDEFINED;
+
+  return message;
+}
+
+class TestInstantMessageQueueProcessor : public InstantMessageQueueProcessor {
+ public:
+  TestInstantMessageQueueProcessor() : InstantMessageQueueProcessor(nullptr) {}
+  ~TestInstantMessageQueueProcessor() override = default;
+
+  bool MaybeShowToastInBrowser(Browser* browser,
+                               std::optional<ToastParams> params) override {
+    return toast_will_be_shown_;
+  }
+
+  void SetToastWillBeShown(bool enabled) { toast_will_be_shown_ = enabled; }
+
+  std::optional<ToastParams> GetParamsForMessage(
+      const InstantMessage& message) override {
+    if (should_create_toast_params_) {
+      ToastParams params(ToastId::kMaxValue);
+      return params;
+    }
+    return std::nullopt;
+  }
+
+  // TODO(crbug.com/370781127): Remove this mock function after ToastParams are
+  // added.
+  void SetShouldCreateToastParams(bool enabled) {
+    should_create_toast_params_ = enabled;
+  }
+
+  void FastForwardByToastDuration(
+      base::test::TaskEnvironment* task_environment) {
+    task_environment->FastForwardBy(GetMessageInterval());
+  }
+
+ private:
+  bool toast_will_be_shown_ = false;
+  bool should_create_toast_params_ = false;
+};
+
+}  // namespace
+
+class InstantMessageQueueProcessorTest : public testing::Test {
+ protected:
+  void SetUp() override {
+    feature_list_.InitAndEnableFeature(toast_features::kToastFramework);
+    processor_ = std::make_unique<TestInstantMessageQueueProcessor>();
+  }
+
+  TestInstantMessageQueueProcessor* processor() { return processor_.get(); }
+
+  void FastForwardByToastDuration() {
+    task_environment_.FastForwardBy(processor()->GetMessageInterval());
+  }
+
+ private:
+  base::test::TaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  std::unique_ptr<TestInstantMessageQueueProcessor> processor_;
+  base::test::ScopedFeatureList feature_list_;
+};
+
+TEST_F(InstantMessageQueueProcessorTest, IgnoresUnsupportedEvents) {
+  EXPECT_FALSE(processor()->IsMessageShowing());
+  EXPECT_EQ(0, processor()->GetQueueSize());
+
+  auto message = CreateMessage(CollaborationEvent::TAB_ADDED);
+  base::MockCallback<SuccessCallback> callback;
+
+  // Message will fail because it has the wrong event type.
+  EXPECT_CALL(callback, Run(false));
+  processor()->Enqueue(message, callback.Get());
+
+  EXPECT_FALSE(processor()->IsMessageShowing());
+  EXPECT_EQ(0, processor()->GetQueueSize());
+}
+
+TEST_F(InstantMessageQueueProcessorTest,
+       FailsMessageUnableToCreateToastParams) {
+  // Mock a situation where the toast params cannot be created.
+  processor()->SetShouldCreateToastParams(false);
+
+  EXPECT_FALSE(processor()->IsMessageShowing());
+  EXPECT_EQ(0, processor()->GetQueueSize());
+
+  auto message = CreateMessage(CollaborationEvent::TAB_REMOVED);
+  base::MockCallback<SuccessCallback> callback;
+
+  // Message will fail because toast params could not be created.
+  EXPECT_CALL(callback, Run(false));
+  processor()->Enqueue(message, callback.Get());
+
+  EXPECT_FALSE(processor()->IsMessageShowing());
+  EXPECT_EQ(0, processor()->GetQueueSize());
+}
+
+TEST_F(InstantMessageQueueProcessorTest, ShowsSupportedEvents) {
+  // Mock creating toast params to be created.
+  processor()->SetShouldCreateToastParams(true);
+  // Mock that toast to be shown.
+  processor()->SetToastWillBeShown(true);
+
+  EXPECT_FALSE(processor()->IsMessageShowing());
+  EXPECT_EQ(0, processor()->GetQueueSize());
+
+  auto message = CreateMessage(CollaborationEvent::TAB_REMOVED);
+  base::MockCallback<SuccessCallback> callback;
+
+  // Message will succeed.
+  EXPECT_CALL(callback, Run(true));
+  processor()->Enqueue(message, callback.Get());
+
+  EXPECT_TRUE(processor()->IsMessageShowing());
+  EXPECT_EQ(1, processor()->GetQueueSize());
+
+  // Fast forward until toast has timed out.
+  FastForwardByToastDuration();
+
+  EXPECT_FALSE(processor()->IsMessageShowing());
+  EXPECT_EQ(0, processor()->GetQueueSize());
+}
+
+TEST_F(InstantMessageQueueProcessorTest, QueuesMessages) {
+  // Mock creating toast params to be created.
+  processor()->SetShouldCreateToastParams(true);
+  // Mock that toast to be shown.
+  processor()->SetToastWillBeShown(true);
+
+  EXPECT_FALSE(processor()->IsMessageShowing());
+  EXPECT_EQ(0, processor()->GetQueueSize());
+
+  auto message1 = CreateMessage(CollaborationEvent::TAB_REMOVED);
+  auto message2 = CreateMessage(CollaborationEvent::TAB_REMOVED);
+  base::MockCallback<SuccessCallback> callback1;
+  base::MockCallback<SuccessCallback> callback2;
+
+  // Message will succeed.
+  EXPECT_CALL(callback1, Run(true));
+  processor()->Enqueue(message1, callback1.Get());
+  processor()->Enqueue(message2, callback2.Get());
+
+  EXPECT_TRUE(processor()->IsMessageShowing());
+  EXPECT_EQ(2, processor()->GetQueueSize());
+
+  EXPECT_CALL(callback2, Run(true));
+
+  // Fast forward until toast has timed out.
+  FastForwardByToastDuration();
+
+  EXPECT_TRUE(processor()->IsMessageShowing());
+  EXPECT_EQ(1, processor()->GetQueueSize());
+
+  // Fast forward until toast has timed out.
+  FastForwardByToastDuration();
+
+  EXPECT_FALSE(processor()->IsMessageShowing());
+  EXPECT_EQ(0, processor()->GetQueueSize());
+}
+
+}  // namespace tab_groups
diff --git a/chrome/browser/ui/views/translate/translate_bubble_view.cc b/chrome/browser/ui/views/translate/translate_bubble_view.cc
index 3c824cd..7c3d71877 100644
--- a/chrome/browser/ui/views/translate/translate_bubble_view.cc
+++ b/chrome/browser/ui/views/translate/translate_bubble_view.cc
@@ -38,6 +38,7 @@
 #include "chrome/common/url_constants.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/theme_resources.h"
+#include "components/language_detection/core/constants.h"
 #include "components/prefs/pref_service.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/translate/core/browser/translate_download_manager.h"
@@ -45,7 +46,6 @@
 #include "components/translate/core/browser/translate_metrics_logger.h"
 #include "components/translate/core/browser/translate_prefs.h"
 #include "components/translate/core/browser/translate_ui_delegate.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/vector_icons/vector_icons.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/interaction/element_identifier.h"
@@ -344,14 +344,14 @@
   // Don't show "Always translate <language>" in incognito mode, because it
   // doesn't do anything anyways. Don't show if the source language is unknown.
   if (!is_in_incognito_window_ &&
-      source_language_code != translate::kUnknownLanguageCode) {
+      source_language_code != language_detection::kUnknownLanguageCode) {
     options_menu_model_->AddCheckItem(
         OptionsMenuItem::ALWAYS_TRANSLATE_LANGUAGE,
         l10n_util::GetStringFUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS_TRANSLATE_LANG,
                                    source_language));
   }
 
-  if (source_language_code != translate::kUnknownLanguageCode) {
+  if (source_language_code != language_detection::kUnknownLanguageCode) {
     options_menu_model_->AddCheckItem(
         OptionsMenuItem::NEVER_TRANSLATE_LANGUAGE,
         l10n_util::GetStringFUTF16(IDS_TRANSLATE_BUBBLE_NEVER_TRANSLATE_LANG,
@@ -657,7 +657,7 @@
   // unknown.
   auto source_language_code = model_->GetSourceLanguageCode();
   if (model_->ShouldShowAlwaysTranslateShortcut() &&
-      source_language_code != translate::kUnknownLanguageCode) {
+      source_language_code != language_detection::kUnknownLanguageCode) {
     auto before_always_translate_checkbox = std::make_unique<views::Checkbox>(
         l10n_util::GetStringFUTF16(
             IDS_TRANSLATE_BUBBLE_ALWAYS_TRANSLATE_LANG,
@@ -795,7 +795,7 @@
   std::unique_ptr<views::Checkbox> advanced_always_translate_checkbox;
   auto source_language_code = model_->GetSourceLanguageCode();
   if (!is_in_incognito_window_ &&
-      source_language_code != translate::kUnknownLanguageCode) {
+      source_language_code != language_detection::kUnknownLanguageCode) {
     advanced_always_translate_checkbox = std::make_unique<views::Checkbox>(
         l10n_util::GetStringUTF16(IDS_TRANSLATE_BUBBLE_ALWAYS),
         base::BindRepeating(&TranslateBubbleView::AlwaysTranslatePressed,
diff --git a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
index 1274033e..82972ba 100644
--- a/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/extension_printer_handler_unittest.cc
@@ -616,10 +616,8 @@
           .Set("extensionName", "Provider 2")
           .Set("extensionId", extension_2->id())
           .Set("provisional", true);
-  const base::Value::Dict& (base::Value::*get_dict)() const =
-      &base::Value::GetDict;
-  EXPECT_TRUE(base::Contains(printers, extension_1_entry, get_dict));
-  EXPECT_TRUE(base::Contains(printers, extension_2_entry, get_dict));
+  EXPECT_TRUE(base::Contains(printers, extension_1_entry));
+  EXPECT_TRUE(base::Contains(printers, extension_2_entry));
 
   fake_api->TriggerNextGetPrintersCallback(base::Value::List(), /*done=*/true);
 
diff --git a/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc b/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
index 33aaf6e..dac26d0 100644
--- a/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
+++ b/chrome/browser/ui/webui/settings/settings_secure_dns_handler_browsertest.cc
@@ -119,9 +119,7 @@
   dict.Set("value", value);
   dict.Set("policy", policy);
 
-  const base::Value::Dict& (base::Value::*get_dict)() const =
-      &base::Value::GetDict;
-  return base::Contains(resolvers, dict, get_dict);
+  return base::Contains(resolvers, dict);
 }
 
 }  // namespace
diff --git a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc
index cd3458d..7468ceb30 100644
--- a/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc
+++ b/chrome/browser/ui/webui/side_panel/read_anything/read_anything_untrusted_page_handler.cc
@@ -623,9 +623,7 @@
   ScopedListPrefUpdate update(
       prefs, prefs::kAccessibilityReadAnythingLanguagesEnabled);
   if (enabled) {
-    const std::string& (base::Value::*get_string)() const =
-        &base::Value::GetString;
-    if (!base::Contains(update.Get(), lang, get_string)) {
+    if (!base::Contains(update.Get(), lang)) {
       update->Append(lang);
     }
   } else {
diff --git a/chrome/browser/ui/webui/whats_new/whats_new_storage_service_impl.cc b/chrome/browser/ui/webui/whats_new/whats_new_storage_service_impl.cc
index 2cef115..6f16821 100644
--- a/chrome/browser/ui/webui/whats_new/whats_new_storage_service_impl.cc
+++ b/chrome/browser/ui/webui/whats_new/whats_new_storage_service_impl.cc
@@ -53,9 +53,7 @@
     std::string_view module_name) {
   // Ensure active feature is in local state.
   const base::Value::List& enabled_modules = ReadModuleData();
-  const std::string& (base::Value::*get_string)() const =
-      &base::Value::GetString;
-  if (!base::Contains(enabled_modules, module_name, get_string)) {
+  if (!base::Contains(enabled_modules, module_name)) {
     GetEnabledOrder()->Append(module_name);
   }
 }
diff --git a/chrome/browser/webauthn/chrome_web_authentication_delegate.cc b/chrome/browser/webauthn/chrome_web_authentication_delegate.cc
index ca1b30a..4c56bdb 100644
--- a/chrome/browser/webauthn/chrome_web_authentication_delegate.cc
+++ b/chrome/browser/webauthn/chrome_web_authentication_delegate.cc
@@ -93,9 +93,7 @@
   const PrefService* prefs = profile->GetPrefs();
   const base::Value::List& permit_attestation =
       prefs->GetList(prefs::kSecurityKeyPermitAttestation);
-  const std::string& (base::Value::*get_string)() const =
-      &base::Value::GetString;
-  return base::Contains(permit_attestation, relying_party_id, get_string);
+  return base::Contains(permit_attestation, relying_party_id);
 }
 
 bool IsOriginListedInEnterpriseAttestationSwitch(
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt
index 3a8b6aef..a7e6721 100644
--- a/chrome/build/android-arm32.pgo.txt
+++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@
-chrome-android32-main-1737243944-b2a65eaceafe77449e822697deb1cb24107b6ece-b8d99e8c7f1bb45602c01fe6ee07d433fd5340b8.profdata
+chrome-android32-main-1737352776-43ad6fbaf6345ed82bc9796455a3cd1926d6b10a-766f90393aaa4626d0877ffa478b9a5990c71c6a.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt
index 268f670a..4a983cf 100644
--- a/chrome/build/android-arm64.pgo.txt
+++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@
-chrome-android64-main-1737250376-264ed674ae29ce8737d2c08a0cbb1febf7982a11-610a0250570d85154f57bff3a337086ed4802e15.profdata
+chrome-android64-main-1737351463-1ce331320c7edb2af1ef2ad84af0b10195d9c6b2-826c4594bb26df1b37dea714ed3cc75ddde7daaa.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index e03828a..a107b00 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1737243944-980e526f1990aeec5a36d31ef8b701d83d697ee9-b8d99e8c7f1bb45602c01fe6ee07d433fd5340b8.profdata
+chrome-linux-main-1737352776-fd03fefbb738f225290e83f8672c702f16a2171e-766f90393aaa4626d0877ffa478b9a5990c71c6a.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index dc8f7b2..2597400 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1737250376-e1ac2e00e045e4ca97b919a7c9666f8c591045cf-610a0250570d85154f57bff3a337086ed4802e15.profdata
+chrome-mac-arm-main-1737343869-9a8d9d997360e18826acf14ad385a19a0ff5443b-df0a06ffabd52c8b58e1ac0fa4f16e68d514599e.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 01b6c289..3d07f30 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1737243944-463e0030b9f1a570720dbb987d0b253581501bcb-b8d99e8c7f1bb45602c01fe6ee07d433fd5340b8.profdata
+chrome-mac-main-1737307567-b5176481679c7a07bdaf9146715730f9849dd701-032f7c04e9de12820162e5a49462a0c343739e4a.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt
index 7cee4f3..31790228 100644
--- a/chrome/build/win-arm64.pgo.txt
+++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@
-chrome-win-arm64-main-1737243944-036e3a1b535e727a332d1c4d9ecfb5d417cd6e0c-b8d99e8c7f1bb45602c01fe6ee07d433fd5340b8.profdata
+chrome-win-arm64-main-1737352776-59c107ef5a8ec6f4a6540fddca6562a0071f4e00-766f90393aaa4626d0877ffa478b9a5990c71c6a.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index aecbd2c..4d0111f 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1737232721-b60e130cdedc8f58419ba91f8d96bbb0ac7ee2e0-80a9c764fa2b544a8daabcb62075da1682136408.profdata
+chrome-win32-main-1737341296-ea7ebb1fc810f5e5da4e81bb998e3d29026c8b69-cdc3a5caf4533b7e86ddd4821c8413b3e313215c.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 69899af..087d223 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1737232721-db696e68f8aad85f6909daf987304a331bfa6821-80a9c764fa2b544a8daabcb62075da1682136408.profdata
+chrome-win64-main-1737331168-a63cc2d8f22759edfe5779b7b9d4f5a3cb2cebfe-d84b33fc32daf8b95a737fadebd05decdbca2b02.profdata
diff --git a/chrome/renderer/accessibility/read_anything/read_aloud_app_model_browsertest.cc b/chrome/renderer/accessibility/read_anything/read_aloud_app_model_browsertest.cc
index d774f50..055d64b 100644
--- a/chrome/renderer/accessibility/read_anything/read_aloud_app_model_browsertest.cc
+++ b/chrome/renderer/accessibility/read_anything/read_aloud_app_model_browsertest.cc
@@ -94,12 +94,10 @@
 
   const std::string enabled_lang = "fr";
   SetLanguageEnabled(enabled_lang, true);
-  const std::string& (base::Value::*get_string)() const =
-      &base::Value::GetString;
-  EXPECT_TRUE(base::Contains(EnabledLanguages(), enabled_lang, get_string));
+  EXPECT_TRUE(base::Contains(EnabledLanguages(), enabled_lang));
 
   SetLanguageEnabled(enabled_lang, false);
-  EXPECT_FALSE(base::Contains(EnabledLanguages(), enabled_lang, get_string));
+  EXPECT_FALSE(base::Contains(EnabledLanguages(), enabled_lang));
 }
 
 TEST_F(ReadAnythingReadAloudAppModelTest, Voices) {
diff --git a/chrome/renderer/accessibility/read_anything/read_anything_app_controller_browsertest.cc b/chrome/renderer/accessibility/read_anything/read_anything_app_controller_browsertest.cc
index db23a24..9975def 100644
--- a/chrome/renderer/accessibility/read_anything/read_anything_app_controller_browsertest.cc
+++ b/chrome/renderer/accessibility/read_anything/read_anything_app_controller_browsertest.cc
@@ -746,10 +746,8 @@
   OnLanguagePrefChange(disabled_lang, false);
 
   EXPECT_CALL(page_handler_, OnLanguagePrefChange).Times(3);
-  const std::string& (base::Value::*get_string)() const =
-      &base::Value::GetString;
-  ASSERT_TRUE(base::Contains(EnabledLanguages(), enabled_lang, get_string));
-  ASSERT_FALSE(base::Contains(EnabledLanguages(), disabled_lang, get_string));
+  ASSERT_TRUE(base::Contains(EnabledLanguages(), enabled_lang));
+  ASSERT_FALSE(base::Contains(EnabledLanguages(), disabled_lang));
 }
 
 TEST_F(ReadAnythingAppControllerTest, GetStoredVoice_ReturnsLatestVoice) {
diff --git a/chrome/renderer/translate/translate_agent_browsertest.cc b/chrome/renderer/translate/translate_agent_browsertest.cc
index 731a6ce..0ef8795 100644
--- a/chrome/renderer/translate/translate_agent_browsertest.cc
+++ b/chrome/renderer/translate/translate_agent_browsertest.cc
@@ -19,8 +19,8 @@
 #include "base/types/cxx23_to_underlying.h"
 #include "chrome/common/chrome_isolated_world_ids.h"
 #include "chrome/test/base/chrome_render_view_test.h"
+#include "components/language_detection/core/constants.h"
 #include "components/translate/content/common/translate.mojom.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_util.h"
 #include "content/public/common/url_constants.h"
 #include "content/public/renderer/render_frame.h"
@@ -351,8 +351,8 @@
   // V8 call for performance monitoring should be ignored.
   EXPECT_CALL(*translate_agent_, ExecuteScriptAndGetDoubleResult(_)).Times(3);
 
-  translate_agent_->TranslatePage(translate::kUnknownLanguageCode, "fr",
-                                  std::string());
+  translate_agent_->TranslatePage(language_detection::kUnknownLanguageCode,
+                                  "fr", std::string());
   base::RunLoop().RunUntilIdle();
 
   translate::TranslateErrors error;
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index ed56bd48..c4136cd7 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -1351,6 +1351,7 @@
     "//components/flags_ui:switches",
     "//components/invalidation:test_support",
     "//components/invalidation/impl:test_support",
+    "//components/language_detection/core",
     "//components/metrics",
     "//components/metrics:content",
     "//components/metrics:metrics_pref_names",
@@ -2262,6 +2263,7 @@
       "//components/javascript_dialogs",
       "//components/language/core/browser",
       "//components/language/core/common",
+      "//components/language_detection/core",
       "//components/lens",
       "//components/lens:buildflags",
       "//components/lens:enterprise_policy",
@@ -2427,7 +2429,6 @@
       "//components/tracing:background_tracing_utils",
       "//components/translate/content/browser:test_support",
       "//components/translate/content/renderer",
-      "//components/translate/core/common",
       "//components/translate/core/language_detection",
       "//components/trusted_vault",
       "//components/ukm/content",
@@ -7680,6 +7681,7 @@
       "../browser/ui/tabs/organization/trigger_policies_unittest.cc",
       "../browser/ui/tabs/organization/trigger_unittest.cc",
       "../browser/ui/tabs/saved_tab_groups/collaboration_messaging_tab_data_unittest.cc",
+      "../browser/ui/tabs/saved_tab_groups/instant_message_queue_processor_unittest.cc",
       "../browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service_unittest.cc",
       "../browser/ui/tabs/saved_tab_groups/tab_group_sync_service_proxy_unittest.cc",
       "../browser/ui/thumbnails/thumbnail_capture_driver_unittest.cc",
diff --git a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service.cc b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service.cc
index 50136ac..dd95eb5 100644
--- a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service.cc
+++ b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service.cc
@@ -6,6 +6,7 @@
 
 #include <utility>
 
+#include "base/functional/callback_forward.h"
 #include "chromeos/ash/components/mantis/mojom/mantis_processor.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
@@ -19,8 +20,12 @@
 MantisUntrustedService::~MantisUntrustedService() = default;
 
 mojo::PendingRemote<media_app_ui::mojom::MantisUntrustedService>
-MantisUntrustedService::BindNewPipeAndPassRemote() {
-  return receiver_.BindNewPipeAndPassRemote();
+MantisUntrustedService::BindNewPipeAndPassRemote(
+    base::OnceClosure disconnect_handler) {
+  mojo::PendingRemote<media_app_ui::mojom::MantisUntrustedService> remote =
+      receiver_.BindNewPipeAndPassRemote();
+  receiver_.set_disconnect_handler(std::move(disconnect_handler));
+  return remote;
 }
 
 void MantisUntrustedService::SegmentImage(const std::vector<uint8_t>& image,
diff --git a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service.h b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service.h
index a2c2c3f..f3b73a6 100644
--- a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service.h
+++ b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service.h
@@ -7,6 +7,7 @@
 
 #include "ash/webui/media_app_ui/media_app_ui_untrusted.mojom.h"
 #include "base/component_export.h"
+#include "base/functional/callback_forward.h"
 #include "base/sequence_checker.h"
 #include "chromeos/ash/components/mantis/mojom/mantis_processor.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
@@ -32,7 +33,7 @@
   ~MantisUntrustedService() override;
 
   mojo::PendingRemote<media_app_ui::mojom::MantisUntrustedService>
-  BindNewPipeAndPassRemote();
+  BindNewPipeAndPassRemote(base::OnceClosure disconnect_handler);
 
   // Implements `media_app_ui::mojom::MantisUntrustedService`:
   void SegmentImage(const std::vector<uint8_t>& image,
diff --git a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.cc b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.cc
index be1a82c..84c1fe9 100644
--- a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.cc
+++ b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.cc
@@ -146,6 +146,10 @@
                      std::move(processor)));
 }
 
+void MantisUntrustedServiceManager::ResetService() {
+  mantis_untrusted_service_.reset();
+}
+
 void MantisUntrustedServiceManager::OnInitializeDone(
     CreateCallback callback,
     mojo::PendingRemote<mantis::mojom::MantisProcessor> processor,
@@ -157,7 +161,9 @@
   mantis_untrusted_service_ =
       std::make_unique<MantisUntrustedService>(std::move(processor));
   std::move(callback).Run(CreateResult::NewService(
-      mantis_untrusted_service_->BindNewPipeAndPassRemote()));
+      mantis_untrusted_service_->BindNewPipeAndPassRemote(
+          base::BindOnce(&MantisUntrustedServiceManager::ResetService,
+                         weak_ptr_factory_.GetWeakPtr()))));
 }
 
 }  // namespace ash
diff --git a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.h b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.h
index ec6947a..a8ba7f4 100644
--- a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.h
+++ b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_manager.h
@@ -50,6 +50,7 @@
   mojo::PendingRemote<mantis::mojom::PlatformModelProgressObserver>
   CreateProgressObserver(
       mojo::PendingRemote<media_app_ui::mojom::MantisUntrustedPage> page);
+  void ResetService();
   void OnQueryDone(
       base::OnceCallback<void(bool)> callback,
       chromeos::mojo_service_manager::mojom::ErrorOrServiceStatePtr result);
diff --git a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_unittest.cc b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_unittest.cc
index 534dc87..4b1204fe 100644
--- a/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_unittest.cc
+++ b/chromeos/ash/components/mantis/media_app/mantis_untrusted_service_unittest.cc
@@ -9,12 +9,15 @@
 #include <variant>
 
 #include "base/functional/overloaded.h"
+#include "base/test/bind.h"
 #include "base/test/gmock_callback_support.h"
+#include "base/test/run_until.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
 #include "chromeos/ash/components/mantis/mojom/mantis_processor.mojom.h"
 #include "mojo/public/cpp/bindings/pending_receiver.h"
 #include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/remote.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
@@ -94,9 +97,9 @@
   mojo::Receiver<mantis::mojom::MantisProcessor> receiver_;
 };
 
-class UntrustedProcessorTest : public testing::Test {
+class MantisUntrustedServiceTest : public testing::Test {
  public:
-  UntrustedProcessorTest()
+  MantisUntrustedServiceTest()
       : service_(mojo_mantis_processor_.BindNewPipeAndPassRemote()) {}
 
  protected:
@@ -119,8 +122,22 @@
       test_case);
 }
 
+TEST_F(MantisUntrustedServiceTest, CallDisconnectHandler) {
+  testing::MockFunction<void()> disconnect_handler;
+  EXPECT_CALL(disconnect_handler, Call);
+
+  mojo::PendingRemote<media_app_ui::mojom::MantisUntrustedService>
+      pending_remote = service_.BindNewPipeAndPassRemote(
+          base::BindLambdaForTesting(disconnect_handler.AsStdFunction()));
+  mojo::Remote<media_app_ui::mojom::MantisUntrustedService> remote(
+      std::move(pending_remote));
+
+  remote.reset();
+  ASSERT_TRUE(base::test::RunUntil([&] { return !remote.is_bound(); }));
+}
+
 class ImageInferenceTest
-    : public UntrustedProcessorTest,
+    : public MantisUntrustedServiceTest,
       public testing::WithParamInterface<ImageInferenceTestCase> {};
 
 TEST_P(ImageInferenceTest, SegmentImage) {
@@ -180,7 +197,7 @@
     });
 
 class ClassifyImageSafetyTest
-    : public UntrustedProcessorTest,
+    : public MantisUntrustedServiceTest,
       public testing::WithParamInterface<SafetyClassifierVerdict> {};
 
 TEST_P(ClassifyImageSafetyTest, ClassifyImageSafety) {
diff --git a/clank b/clank
index 2a03afb..82f68d0 160000
--- a/clank
+++ b/clank
@@ -1 +1 @@
-Subproject commit 2a03afbec2cf5258224406339ab653a9899927a0
+Subproject commit 82f68d0ac4e31a5198d219842a3873b82b3ab1cd
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc
index 67ec3e2..dce05f8 100644
--- a/components/autofill/content/renderer/form_autofill_util.cc
+++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -1262,9 +1262,7 @@
   }
   // Skip filling previously autofilled fields unless autofill is instructed to
   // override it.
-  if (element.IsAutofilled() &&
-      !base::FeatureList::IsEnabled(
-          features::kAutofillRemoveAlreadyAutofilledRendererFillSkipReason)) {
+  if (element.IsAutofilled()) {
     base::UmaHistogramEnumeration(kSkipReasonHistogram,
                                   SkipReason::kPreviouslyAutofilled);
     return true;
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 66b850d7..193a41a 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -209,12 +209,6 @@
              "AutofillOptimizeFormExtraction",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Killswitch to remove the condition in `::form_util::ShouldSkipFillField`
-// related to skipping fields that are already autofilled.
-BASE_FEATURE(kAutofillRemoveAlreadyAutofilledRendererFillSkipReason,
-             "AutofillRemoveAlreadyAutofilledRendererFillSkipReason",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 // Killswitch that guards replacing some form and field semantic comparison with
 // just [Form|Field]GlobalId comparisons.
 BASE_FEATURE(kAutofillUseFewerFormAndFieldComparison,
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index 72ecaea..ddc85a8 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -76,8 +76,6 @@
 COMPONENT_EXPORT(AUTOFILL)
 BASE_DECLARE_FEATURE(kAutofillOptimizeFormExtraction);
 COMPONENT_EXPORT(AUTOFILL)
-BASE_DECLARE_FEATURE(kAutofillRemoveAlreadyAutofilledRendererFillSkipReason);
-COMPONENT_EXPORT(AUTOFILL)
 BASE_DECLARE_FEATURE(kAutofillUseFewerFormAndFieldComparison);
 COMPONENT_EXPORT(AUTOFILL)
 BASE_DECLARE_FEATURE(kAutofillAddressFieldSwapping);
diff --git a/components/certificate_transparency/data/log_list.json b/components/certificate_transparency/data/log_list.json
index ce44ff4..ab6850ea 100644
--- a/components/certificate_transparency/data/log_list.json
+++ b/components/certificate_transparency/data/log_list.json
@@ -1,6 +1,6 @@
 {
-  "version": "50.73",
-  "log_list_timestamp": "2025-01-18T12:56:15Z",
+  "version": "50.74",
+  "log_list_timestamp": "2025-01-19T12:54:47Z",
   "operators": [
     {
       "name": "Google",
diff --git a/components/enterprise/watermarking/watermark_test_utils.h b/components/enterprise/watermarking/watermark_test_utils.h
index 384905d9..86e0cbf 100644
--- a/components/enterprise/watermarking/watermark_test_utils.h
+++ b/components/enterprise/watermarking/watermark_test_utils.h
@@ -5,6 +5,8 @@
 #ifndef COMPONENTS_ENTERPRISE_WATERMARKING_WATERMARK_TEST_UTILS_H_
 #define COMPONENTS_ENTERPRISE_WATERMARKING_WATERMARK_TEST_UTILS_H_
 
+#include <string>
+
 #include "components/enterprise/watermarking/mojom/watermark.mojom-forward.h"
 #include "third_party/skia/include/core/SkSize.h"
 
diff --git a/components/language_detection/core/language_detection_model_unittest.cc b/components/language_detection/core/language_detection_model_unittest.cc
index 7898760..4a0faaf 100644
--- a/components/language_detection/core/language_detection_model_unittest.cc
+++ b/components/language_detection/core/language_detection_model_unittest.cc
@@ -16,6 +16,7 @@
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
 #include "build/build_config.h"
+#include "components/language_detection/core/constants.h"
 #include "components/language_detection/core/language_detection_provider.h"
 #include "components/language_detection/testing/language_detection_test_utils.h"
 #include "components/translate/core/common/translate_constants.h"
diff --git a/components/nacl/common/nacl_service.cc b/components/nacl/common/nacl_service.cc
index 5fb500d..9114ec8 100644
--- a/components/nacl/common/nacl_service.cc
+++ b/components/nacl/common/nacl_service.cc
@@ -10,6 +10,7 @@
 #include "base/command_line.h"
 #include "base/task/single_thread_task_runner.h"
 #include "build/build_config.h"
+#include "content/public/common/content_switches.h"
 #include "mojo/core/embedder/scoped_ipc_support.h"
 #include "mojo/public/cpp/platform/platform_channel.h"
 #include "mojo/public/cpp/platform/platform_channel_endpoint.h"
@@ -29,7 +30,12 @@
   endpoint = mojo::PlatformChannelEndpoint(mojo::PlatformHandle(base::ScopedFD(
       base::GlobalDescriptors::GetInstance()->Get(kMojoIPCChannel))));
   DCHECK(endpoint.is_valid());
-  return mojo::IncomingInvitation::Accept(std::move(endpoint));
+  MojoAcceptInvitationFlags flags = MOJO_ACCEPT_INVITATION_FLAG_NONE;
+  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
+          switches::kDisableMojoBroker)) {
+    flags |= MOJO_ACCEPT_INVITATION_FLAG_INHERIT_BROKER;
+  }
+  return mojo::IncomingInvitation::Accept(std::move(endpoint), flags);
 }
 
 }  // namespace
diff --git a/components/strings/components_strings_ar.xtb b/components/strings/components_strings_ar.xtb
index 1fb9d69..21399a8d 100644
--- a/components/strings/components_strings_ar.xtb
+++ b/components/strings/components_strings_ar.xtb
@@ -1969,6 +1969,7 @@
 <translation id="4434045419905280838">النوافذ المنبثقة وإعادة التوجيه</translation>
 <translation id="443673843213245140">تم إيقاف استخدام الخادم الوكيل ولكن تم تحديد إعداد صريح للخادم الوكيل.</translation>
 <translation id="4438821706955556403">السعر العادي</translation>
+<translation id="444116852243722675">فتح الكل (<ph name="ITEMS" />)</translation>
 <translation id="4441832193888514600">تم التجاهل لأنّ هذه السياسة لا يمكن ضبطها كسياسة مستخدم على السحابة الإلكترونية.</translation>
 <translation id="4445133368066241428">مواضيع رائجة</translation>
 <translation id="4445964943162061557">هذه ميزة تجريبية وقد توفِّر نتائج غير دقيقة أحيانًا.</translation>
diff --git a/components/strings/components_strings_fa.xtb b/components/strings/components_strings_fa.xtb
index 7a19ce9..13a8870 100644
--- a/components/strings/components_strings_fa.xtb
+++ b/components/strings/components_strings_fa.xtb
@@ -1967,6 +1967,7 @@
 <translation id="4434045419905280838">پنجره‌های بازشو و هدایت‌ها</translation>
 <translation id="443673843213245140">استفاده از پروکسی غیرفعال است اما یک پیکربندی خاص برای پروکسی تعیین شده است.</translation>
 <translation id="4438821706955556403">قیمت معمول</translation>
+<translation id="444116852243722675">باز کردن همه (<ph name="ITEMS" /> مورد)</translation>
 <translation id="4441832193888514600">نادیده گرفته شد زیرا این خط‌مشی فقط می‌تواند به‌عنوان خط‌مشی کاربر ابری تنظیم شود.</translation>
 <translation id="4445133368066241428">موضوع‌های پرطرفدار</translation>
 <translation id="4445964943162061557">این یک ویژگی آزمایشی است و همیشه درست عمل نمی‌کند.</translation>
diff --git a/components/strings/components_strings_mn.xtb b/components/strings/components_strings_mn.xtb
index 5cfafa1..4b51bbc 100644
--- a/components/strings/components_strings_mn.xtb
+++ b/components/strings/components_strings_mn.xtb
@@ -1968,6 +1968,7 @@
 <translation id="4434045419905280838">Попап болон дахин чиглүүлэлт</translation>
 <translation id="443673843213245140">Орлон ашиглах эрхийг хаасан байгаа боловч тодорхой түвшинд орлон ашиглах тохиргоог тусгасан байна.</translation>
 <translation id="4438821706955556403">Дундаж үнэ</translation>
+<translation id="444116852243722675">Бүгдийг нээх (<ph name="ITEMS" />)</translation>
 <translation id="4441832193888514600">Бодлогыг зөвхөн үүлний хэрэглэгчийн бодлого байдлаар тохируулах боломжтой тул үл хэрэгссэн.</translation>
 <translation id="4445133368066241428">Түгээмэл сэдвүүд</translation>
 <translation id="4445964943162061557">Энэ нь туршилтын онцлог бөгөөд заримдаа алдаа гаргаж болно.</translation>
diff --git a/components/strings/components_strings_uz.xtb b/components/strings/components_strings_uz.xtb
index eec99fc..8749c7c 100644
--- a/components/strings/components_strings_uz.xtb
+++ b/components/strings/components_strings_uz.xtb
@@ -2628,6 +2628,7 @@
 <translation id="5675809467256309336">Raqs va elektron musiqa</translation>
 <translation id="5675959228867414813">Sana asosida saralash</translation>
 <translation id="567604591393105935">Mahsulot haqidagi quyi ekran butun yarim ochildi</translation>
+<translation id="5676641328629468296">Google Pay, Pix</translation>
 <translation id="5678007133659493065">Folga</translation>
 <translation id="5680642791693447368">Triller, kriminal va detektiv filmlar</translation>
 <translation id="568292603005599551">Tasvirning X oʻqidagi joylashuvi</translation>
diff --git a/components/translate/content/android/BUILD.gn b/components/translate/content/android/BUILD.gn
index 4ea2295..09abdbe 100644
--- a/components/translate/content/android/BUILD.gn
+++ b/components/translate/content/android/BUILD.gn
@@ -65,6 +65,7 @@
     ":jni_headers",
     "//base",
     "//components/language/core/common",
+    "//components/language_detection/core",
     "//components/messages/android",
     "//components/metrics",
     "//components/strings:components_strings_grit",
@@ -143,6 +144,7 @@
     "//components/language/core/browser",
     "//components/language/core/browser:test_support",
     "//components/language/core/common",
+    "//components/language_detection/core",
     "//components/messages/android",
     "//components/metrics",
     "//components/pref_registry:pref_registry",
diff --git a/components/translate/content/android/DEPS b/components/translate/content/android/DEPS
index d329248..65423af 100644
--- a/components/translate/content/android/DEPS
+++ b/components/translate/content/android/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+components/browser_ui/widget/android",
+  "+components/language_detection/core",
   "+components/messages/android",
   "+components/metrics",
   "+components/translate/core/browser",
diff --git a/components/translate/content/android/translate_message.cc b/components/translate/content/android/translate_message.cc
index 96c92948..86c17b8a 100644
--- a/components/translate/content/android/translate_message.cc
+++ b/components/translate/content/android/translate_message.cc
@@ -26,6 +26,7 @@
 #include "base/metrics/field_trial_params.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/strings/utf_string_conversions.h"
+#include "components/language_detection/core/constants.h"
 #include "components/messages/android/message_enums.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/translate/core/browser/language_state.h"
@@ -33,7 +34,6 @@
 #include "components/translate/core/browser/translate_metrics_logger.h"
 #include "components/translate/core/browser/translate_ui_delegate.h"
 #include "components/translate/core/browser/translate_ui_languages_manager.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_metrics.h"
 #include "content/public/browser/web_contents.h"
 #include "ui/base/l10n/l10n_util.h"
@@ -474,7 +474,8 @@
       static_cast<int>(OverflowMenuItemId::kInvalid);
 
   if (!ui_delegate_->IsIncognito() &&
-      ui_languages_manager_->GetSourceLanguageCode() != kUnknownLanguageCode) {
+      ui_languages_manager_->GetSourceLanguageCode() !=
+          language_detection::kUnknownLanguageCode) {
     // "Always translate pages in <source language>".
     CHECK_GT(std::extent<decltype(titles)>::value, item_count);
     titles[item_count] = l10n_util::GetStringFUTF16(
@@ -485,7 +486,8 @@
         static_cast<int>(OverflowMenuItemId::kToggleAlwaysTranslateLanguage);
   }
 
-  if (ui_languages_manager_->GetSourceLanguageCode() != kUnknownLanguageCode) {
+  if (ui_languages_manager_->GetSourceLanguageCode() !=
+      language_detection::kUnknownLanguageCode) {
     // "Never translate pages in <source language>".
     CHECK_GT(std::extent<decltype(titles)>::value, item_count);
     titles[item_count] = l10n_util::GetStringFUTF16(
@@ -585,7 +587,8 @@
     case OverflowMenuItemId::kChangeTargetLanguage: {
       ReportCompactInfobarEvent(InfobarEvent::INFOBAR_MORE_LANGUAGES);
       const std::string skip_language_codes[] = {
-          ui_languages_manager_->GetTargetLanguageCode(), kUnknownLanguageCode};
+          ui_languages_manager_->GetTargetLanguageCode(),
+          language_detection::kUnknownLanguageCode};
       std::vector<std::string> content_language_codes;
       ui_delegate_->GetContentLanguagesCodes(&content_language_codes);
       return ConstructLanguagePickerMenu(
diff --git a/components/translate/content/android/translate_message_unittest.cc b/components/translate/content/android/translate_message_unittest.cc
index 861e9bb..c2a5d0f 100644
--- a/components/translate/content/android/translate_message_unittest.cc
+++ b/components/translate/content/android/translate_message_unittest.cc
@@ -15,6 +15,7 @@
 #include "components/language/core/browser/language_prefs.h"
 #include "components/language/core/browser/pref_names.h"
 #include "components/language/core/common/language_experiments.h"
+#include "components/language_detection/core/constants.h"
 #include "components/messages/android/message_enums.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
@@ -897,8 +898,10 @@
        ++i) {
     std::string language_code =
         ui_delegate.translate_ui_languages_manager()->GetLanguageCodeAt(i);
-    if (language_code == "en" || language_code == kUnknownLanguageCode)
+    if (language_code == "en" ||
+        language_code == language_detection::kUnknownLanguageCode) {
       continue;
+    }
     menu_items.emplace_back(SecondaryMenuItem{
         TranslateMessage::OverflowMenuItemId::kChangeTargetLanguage, false,
         std::move(language_code)});
@@ -990,8 +993,10 @@
        ++i) {
     std::string language_code =
         ui_delegate.translate_ui_languages_manager()->GetLanguageCodeAt(i);
-    if (language_code == "en" || language_code == kUnknownLanguageCode)
+    if (language_code == "en" ||
+        language_code == language_detection::kUnknownLanguageCode) {
       continue;
+    }
     menu_items.emplace_back(SecondaryMenuItem{
         TranslateMessage::OverflowMenuItemId::kChangeTargetLanguage, false,
         std::move(language_code)});
@@ -1080,7 +1085,8 @@
   EXPECT_CALL(*bridge_, CreateTranslateMessage(
                             env, _, _, kDefaultDismissalDurationSeconds))
       .WillOnce(Return(true));
-  ShowBeforeTranslationMessage(env, kUnknownLanguageCode, "en");
+  ShowBeforeTranslationMessage(env, language_detection::kUnknownLanguageCode,
+                               "en");
 
   // Doesn't include the kToggleAlwaysTranslateLanguage option or the
   // kToggleNeverTranslateLanguage option.
diff --git a/components/translate/content/renderer/translate_agent.cc b/components/translate/content/renderer/translate_agent.cc
index 45da5dd..19d9f306e 100644
--- a/components/translate/content/renderer/translate_agent.cc
+++ b/components/translate/content/renderer/translate_agent.cc
@@ -25,9 +25,9 @@
 #include "base/task/single_thread_task_runner.h"
 #include "base/trace_event/trace_event.h"
 #include "components/language_detection/content/renderer/language_detection_agent.h"
+#include "components/language_detection/core/constants.h"
 #include "components/language_detection/core/language_detection_provider.h"
 #include "components/translate/content/renderer/isolated_world_util.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_metrics.h"
 #include "components/translate/core/common/translate_util.h"
 #include "components/translate/core/language_detection/language_detection_model.h"
@@ -447,8 +447,9 @@
 
   // If the source language is undetermined, we'll let the translate element
   // detect it.
-  source_lang_ = (source_lang != kUnknownLanguageCode) ? source_lang
-                                                       : kAutoDetectionLanguage;
+  source_lang_ = (source_lang != language_detection::kUnknownLanguageCode)
+                     ? source_lang
+                     : kAutoDetectionLanguage;
   target_lang_ = target_lang;
 
   // Set up v8 isolated world.
diff --git a/components/translate/core/browser/BUILD.gn b/components/translate/core/browser/BUILD.gn
index 1063102..602f76c 100644
--- a/components/translate/core/browser/BUILD.gn
+++ b/components/translate/core/browser/BUILD.gn
@@ -56,6 +56,7 @@
     "//components/keyed_service/core",
     "//components/language/core/browser",
     "//components/language/core/common",
+    "//components/language_detection/core",
     "//components/metrics",
     "//components/pref_registry",
     "//components/prefs",
@@ -116,6 +117,7 @@
     "//components/language/core/browser",
     "//components/language/core/browser:test_support",
     "//components/language/core/common:common",
+    "//components/language_detection/core",
     "//components/pref_registry:pref_registry",
     "//components/prefs",
     "//components/prefs:test_support",
diff --git a/components/translate/core/browser/DEPS b/components/translate/core/browser/DEPS
index d7cb62b..64d70da 100644
--- a/components/translate/core/browser/DEPS
+++ b/components/translate/core/browser/DEPS
@@ -1,5 +1,6 @@
 include_rules = [
   "+components/keyed_service/core",
+  "+components/language_detection/core",
   "+components/metrics",
   "+components/assist_ranker",
   "+components/optimization_guide/core",
diff --git a/components/translate/core/browser/translate_infobar_delegate.cc b/components/translate/core/browser/translate_infobar_delegate.cc
index 62cc8e4..3916117 100644
--- a/components/translate/core/browser/translate_infobar_delegate.cc
+++ b/components/translate/core/browser/translate_infobar_delegate.cc
@@ -17,13 +17,13 @@
 #include "components/infobars/core/infobar_manager.h"
 #include "components/language/core/browser/accept_languages_service.h"
 #include "components/language/core/common/language_experiments.h"
+#include "components/language_detection/core/constants.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/translate/core/browser/language_state.h"
 #include "components/translate/core/browser/translate_client.h"
 #include "components/translate/core/browser/translate_download_manager.h"
 #include "components/translate/core/browser/translate_driver.h"
 #include "components/translate/core/browser/translate_manager.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_util.h"
 #include "ui/base/l10n/l10n_util.h"
 
@@ -72,7 +72,7 @@
       DCHECK(step == translate::TRANSLATE_STEP_TRANSLATING ||
              step == translate::TRANSLATE_STEP_AFTER_TRANSLATE);
 #endif
-      DCHECK_EQ(translate::kUnknownLanguageCode, source_language);
+      DCHECK_EQ(language_detection::kUnknownLanguageCode, source_language);
     }
   }
 
diff --git a/components/translate/core/browser/translate_infobar_delegate.h b/components/translate/core/browser/translate_infobar_delegate.h
index 1f36714..6a00d59 100644
--- a/components/translate/core/browser/translate_infobar_delegate.h
+++ b/components/translate/core/browser/translate_infobar_delegate.h
@@ -24,7 +24,6 @@
 #include "components/translate/core/browser/translate_step.h"
 #include "components/translate/core/browser/translate_ui_delegate.h"
 #include "components/translate/core/browser/translate_ui_languages_manager.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_errors.h"
 
 namespace infobars {
diff --git a/components/translate/core/browser/translate_infobar_delegate_unittest.cc b/components/translate/core/browser/translate_infobar_delegate_unittest.cc
index 4071b76..09e2fec 100644
--- a/components/translate/core/browser/translate_infobar_delegate_unittest.cc
+++ b/components/translate/core/browser/translate_infobar_delegate_unittest.cc
@@ -14,6 +14,7 @@
 #include "components/language/core/browser/language_model.h"
 #include "components/language/core/browser/language_prefs.h"
 #include "components/language/core/browser/pref_names.h"
+#include "components/language_detection/core/constants.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "components/translate/core/browser/mock_translate_client.h"
@@ -23,7 +24,6 @@
 #include "components/translate/core/browser/translate_manager.h"
 #include "components/translate/core/browser/translate_pref_names.h"
 #include "components/translate/core/browser/translate_prefs.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace translate {
@@ -338,19 +338,20 @@
   base::Value::Dict& update_translate_accepted_dict =
       update_translate_accepted_count.Get();
   // Should not trigger auto always translate for unknown source language.
-  update_translate_accepted_dict.Set(kUnknownLanguageCode,
+  update_translate_accepted_dict.Set(language_detection::kUnknownLanguageCode,
                                      kAutoAlwaysThreshold + 1);
 
   const base::Value::Dict* dict =
       &pref_service_->GetDict(TranslatePrefs::kPrefTranslateAutoAlwaysCount);
   std::optional<int> translate_auto_always_count =
-      dict->FindInt(kUnknownLanguageCode);
+      dict->FindInt(language_detection::kUnknownLanguageCode);
   EXPECT_FALSE(translate_auto_always_count.has_value());
 
   TranslateInfoBarDelegate::Create(
       /*replace_existing_infobar=*/true, manager_->GetWeakPtr(),
       infobar_manager_.get(), TranslateStep::TRANSLATE_STEP_TRANSLATING,
-      kUnknownLanguageCode, kTargetLanguage, TranslateErrors::NONE,
+      language_detection::kUnknownLanguageCode, kTargetLanguage,
+      TranslateErrors::NONE,
       /*triggered_from_menu=*/false);
   TranslateInfoBarDelegate* delegate =
       infobar_manager_->infobars()[0]->delegate()->AsTranslateInfoBarDelegate();
@@ -362,7 +363,8 @@
   EXPECT_FALSE(count.has_value());
   // Get the dictionary again in order to update it.
   dict = &pref_service_->GetDict(TranslatePrefs::kPrefTranslateAutoAlwaysCount);
-  translate_auto_always_count = dict->FindInt(kUnknownLanguageCode);
+  translate_auto_always_count =
+      dict->FindInt(language_detection::kUnknownLanguageCode);
   EXPECT_FALSE(translate_auto_always_count.has_value());
 }
 
diff --git a/components/translate/core/browser/translate_manager.cc b/components/translate/core/browser/translate_manager.cc
index d25f441..7fe181d 100644
--- a/components/translate/core/browser/translate_manager.cc
+++ b/components/translate/core/browser/translate_manager.cc
@@ -25,6 +25,7 @@
 #include "components/language/core/common/language_experiments.h"
 #include "components/language/core/common/language_util.h"
 #include "components/language/core/common/locale_util.h"
+#include "components/language_detection/core/constants.h"
 #include "components/prefs/pref_service.h"
 #include "components/translate/core/browser/language_state.h"
 #include "components/translate/core/browser/page_translated_details.h"
@@ -43,7 +44,6 @@
 #include "components/translate/core/browser/translate_trigger_decision.h"
 #include "components/translate/core/browser/translate_url_util.h"
 #include "components/translate/core/common/language_detection_details.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_switches.h"
 #include "components/translate/core/common/translate_util.h"
 #include "components/variations/variations_associated_data.h"
@@ -361,7 +361,7 @@
   // server side auto language detection.
   std::string source_lang(original_source_lang);
   if (!TranslateDownloadManager::IsSupportedLanguage(source_lang))
-    source_lang = std::string(translate::kUnknownLanguageCode);
+    source_lang = std::string(language_detection::kUnknownLanguageCode);
 
   // Capture the translate event if we were triggered from the menu.
   if (triggered_from_menu) {
@@ -377,7 +377,7 @@
     // page with multiple languages we often detect same language, but the
     // Translation service is able to translate the various languages using it's
     // own language detection.
-    source_lang = translate::kUnknownLanguageCode;
+    source_lang = language_detection::kUnknownLanguageCode;
   }
 
   // Trigger the "translating now" UI.
@@ -482,7 +482,7 @@
   language_state_.set_translation_error(error_type != TranslateErrors::NONE);
 
   if ((error_type == TranslateErrors::NONE) &&
-      source_lang != translate::kUnknownLanguageCode &&
+      source_lang != language_detection::kUnknownLanguageCode &&
       !TranslateDownloadManager::IsSupportedLanguage(source_lang)) {
     error_type = TranslateErrors::UNSUPPORTED_LANGUAGE;
   }
@@ -553,7 +553,7 @@
   // preference.
   // We don't enable auto translate feature in incognito profiles so this will
   // always be empty for incognito.
-  if (source_lang_code != translate::kUnknownLanguageCode) {
+  if (source_lang_code != language_detection::kUnknownLanguageCode) {
     std::string auto_translate_language =
         translate::TranslateManager::GetAutoTargetLanguage(source_lang_code,
                                                            prefs);
@@ -1011,7 +1011,8 @@
       // last ditch effort assume that language detection was incorrect and send
       // "und" as the source language to make the translate service attempt to
       // detect the language as it processes the page content.
-      decision->href_translate_source = translate::kUnknownLanguageCode;
+      decision->href_translate_source =
+          language_detection::kUnknownLanguageCode;
     } else {
       decision->PreventAutoHrefTranslate();
       decision->PreventShowingHrefTranslateUI();
@@ -1048,7 +1049,8 @@
     // then as a last ditch effort assume that language detection was incorrect
     // and send "und" as the source language to make the translate service
     // attempt to detect the language as it processes the page content.
-    decision->predefined_translate_source = translate::kUnknownLanguageCode;
+    decision->predefined_translate_source =
+        language_detection::kUnknownLanguageCode;
   }
 }
 
diff --git a/components/translate/core/browser/translate_manager.h b/components/translate/core/browser/translate_manager.h
index 295006d..990f8793 100644
--- a/components/translate/core/browser/translate_manager.h
+++ b/components/translate/core/browser/translate_manager.h
@@ -16,9 +16,9 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "components/language_detection/core/constants.h"
 #include "components/translate/core/browser/language_state.h"
 #include "components/translate/core/browser/translate_metrics_logger.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_errors.h"
 
 namespace language {
@@ -106,7 +106,8 @@
   static std::string GetTargetLanguage(
       TranslatePrefs* prefs,
       language::LanguageModel* language_model,
-      const std::string source_lang_code = translate::kUnknownLanguageCode);
+      const std::string source_lang_code =
+          language_detection::kUnknownLanguageCode);
 
   // Returns the language to automatically translate to. |source_language| is
   // the webpage's source language.
diff --git a/components/translate/core/browser/translate_manager_unittest.cc b/components/translate/core/browser/translate_manager_unittest.cc
index 9b428f1..bc28ce82 100644
--- a/components/translate/core/browser/translate_manager_unittest.cc
+++ b/components/translate/core/browser/translate_manager_unittest.cc
@@ -20,6 +20,7 @@
 #include "components/language/core/browser/language_model.h"
 #include "components/language/core/browser/language_prefs.h"
 #include "components/language/core/common/language_experiments.h"
+#include "components/language_detection/core/constants.h"
 #include "components/pref_registry/pref_registry_syncable.h"
 #include "components/sync_preferences/testing_pref_service_syncable.h"
 #include "components/translate/core/browser/mock_translate_client.h"
@@ -33,7 +34,6 @@
 #include "components/translate/core/browser/translate_pref_names.h"
 #include "components/translate/core/browser/translate_prefs.h"
 #include "components/translate/core/browser/translate_step.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_util.h"
 #include "components/variations/scoped_variations_ids_provider.h"
 #include "components/variations/variations_associated_data.h"
@@ -997,7 +997,7 @@
       .WillByDefault(Return(true));
 
   translate_manager_->GetLanguageState()->LanguageDetermined(
-      kUnknownLanguageCode, true);
+      language_detection::kUnknownLanguageCode, true);
 
   EXPECT_TRUE(translate_manager_->CanManuallyTranslate());
 }
diff --git a/components/translate/core/browser/translate_prefs.cc b/components/translate/core/browser/translate_prefs.cc
index ca7cab8e..43dd4857 100644
--- a/components/translate/core/browser/translate_prefs.cc
+++ b/components/translate/core/browser/translate_prefs.cc
@@ -95,10 +95,8 @@
     // If the old pair's source language matches any of the never-translate
     // languages, it probably means that this source language was set to never
     // be translated after the old pref was deprecated, so avoid this conflict.
-    const std::string& (base::Value::*get_string)() const =
-        &base::Value::GetString;
     if (base::Contains(prefs->GetList(prefs::kBlockedLanguages),
-                       old_language_pair.first, get_string)) {
+                       old_language_pair.first)) {
       continue;
     }
 
diff --git a/components/translate/core/browser/translate_ui_delegate.cc b/components/translate/core/browser/translate_ui_delegate.cc
index 0e71123..8160932 100644
--- a/components/translate/core/browser/translate_ui_delegate.cc
+++ b/components/translate/core/browser/translate_ui_delegate.cc
@@ -8,6 +8,7 @@
 #include "base/metrics/histogram_macros.h"
 #include "components/language/core/browser/pref_names.h"
 #include "components/language/core/common/language_experiments.h"
+#include "components/language_detection/core/constants.h"
 #include "components/translate/core/browser/translate_client.h"
 #include "components/translate/core/browser/translate_download_manager.h"
 #include "components/translate/core/browser/translate_driver.h"
@@ -363,8 +364,9 @@
   const std::string& source_language =
       translate_ui_languages_manager_->GetSourceLanguageCode();
   // Don't trigger for unknown source language.
-  if (source_language == kUnknownLanguageCode)
+  if (source_language == language_detection::kUnknownLanguageCode) {
     return false;
+  }
 
   bool always_translate =
       (prefs_->GetTranslationAcceptedCount(source_language) >=
diff --git a/components/translate/core/browser/translate_ui_languages_manager.cc b/components/translate/core/browser/translate_ui_languages_manager.cc
index f13457b..d0d8822 100644
--- a/components/translate/core/browser/translate_ui_languages_manager.cc
+++ b/components/translate/core/browser/translate_ui_languages_manager.cc
@@ -13,12 +13,12 @@
 #include "base/strings/utf_string_conversions.h"
 #include "build/build_config.h"
 #include "components/language/core/common/language_experiments.h"
+#include "components/language_detection/core/constants.h"
 #include "components/strings/grit/components_strings.h"
 #include "components/translate/core/browser/language_state.h"
 #include "components/translate/core/browser/translate_client.h"
 #include "components/translate/core/browser/translate_download_manager.h"
 #include "components/translate/core/browser/translate_driver.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_util.h"
 #include "components/variations/variations_associated_data.h"
 #include "net/base/url_util.h"
@@ -76,7 +76,7 @@
         return lhs.first < rhs.first;
       });
 
-  languages_.emplace_back(kUnknownLanguageCode,
+  languages_.emplace_back(language_detection::kUnknownLanguageCode,
                           GetUnknownLanguageDisplayName());
   std::rotate(languages_.rbegin(), languages_.rbegin() + 1, languages_.rend());
 
@@ -113,13 +113,13 @@
 
 std::string TranslateUILanguagesManager::GetSourceLanguageCode() const {
   return (GetSourceLanguageIndex() == kNoIndex)
-             ? translate::kUnknownLanguageCode
+             ? language_detection::kUnknownLanguageCode
              : GetLanguageCodeAt(GetSourceLanguageIndex());
 }
 
 std::string TranslateUILanguagesManager::GetTargetLanguageCode() const {
   return (GetTargetLanguageIndex() == kNoIndex)
-             ? translate::kUnknownLanguageCode
+             ? language_detection::kUnknownLanguageCode
              : GetLanguageCodeAt(GetTargetLanguageIndex());
 }
 
diff --git a/components/translate/core/common/translate_constants.h b/components/translate/core/common/translate_constants.h
index 8ac30d4..f06d7f73 100644
--- a/components/translate/core/common/translate_constants.h
+++ b/components/translate/core/common/translate_constants.h
@@ -5,8 +5,6 @@
 #ifndef COMPONENTS_TRANSLATE_CORE_COMMON_TRANSLATE_CONSTANTS_H_
 #define COMPONENTS_TRANSLATE_CORE_COMMON_TRANSLATE_CONSTANTS_H_
 
-#include "components/language_detection/core/constants.h"
-
 namespace translate {
 
 // The maximum number of characters allowed for a text selection in Partial
@@ -18,10 +16,6 @@
 // is shown.
 extern const int kDesktopPartialTranslateBubbleShowDelayMs;
 
-// TODO(https://crbug.com/380786760): Delete this when all users have migrated
-// to the language_detection:: version.
-using language_detection::kUnknownLanguageCode;
-
 }  // namespace translate
 
 #endif  // COMPONENTS_TRANSLATE_CORE_COMMON_TRANSLATE_CONSTANTS_H_
diff --git a/components/translate/core/language_detection/language_detection_model.cc b/components/translate/core/language_detection/language_detection_model.cc
index 2cce45e..8f710d4f 100644
--- a/components/translate/core/language_detection/language_detection_model.cc
+++ b/components/translate/core/language_detection/language_detection_model.cc
@@ -12,8 +12,8 @@
 #include "base/trace_event/trace_event.h"
 #include "build/build_config.h"
 #include "components/language/core/common/language_util.h"
+#include "components/language_detection/core/constants.h"
 #include "components/language_detection/core/language_detection_model.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_util.h"
 #include "components/translate/core/language_detection/language_detection_util.h"
 
@@ -56,15 +56,15 @@
   DCHECK(IsAvailable());
 
   if (!predicted_language || !is_prediction_reliable) {
-    return translate::kUnknownLanguageCode;
+    return language_detection::kUnknownLanguageCode;
   }
 
   *is_prediction_reliable = false;
-  *predicted_language = translate::kUnknownLanguageCode;
+  *predicted_language = language_detection::kUnknownLanguageCode;
   prediction_reliability_score = 0.0;
 
   if (!tflite_model_->IsAvailable()) {
-    return translate::kUnknownLanguageCode;
+    return language_detection::kUnknownLanguageCode;
   }
 
   const language_detection::Prediction prediction = DetectLanguage(contents);
diff --git a/components/translate/core/language_detection/language_detection_model_unittest.cc b/components/translate/core/language_detection/language_detection_model_unittest.cc
index 5715cba5..c7baf1a 100644
--- a/components/translate/core/language_detection/language_detection_model_unittest.cc
+++ b/components/translate/core/language_detection/language_detection_model_unittest.cc
@@ -15,9 +15,9 @@
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
 #include "base/test/task_environment.h"
+#include "components/language_detection/core/constants.h"
 #include "components/language_detection/core/language_detection_model.h"
 #include "components/language_detection/testing/language_detection_test_utils.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace translate {
@@ -66,7 +66,7 @@
       &is_prediction_reliable, model_reliability_score);
   EXPECT_TRUE(is_prediction_reliable);
   EXPECT_EQ("en", predicted_language);
-  EXPECT_EQ(translate::kUnknownLanguageCode, language);
+  EXPECT_EQ(language_detection::kUnknownLanguageCode, language);
   histogram_tester_.ExpectUniqueSample(
       "LanguageDetection.TFLite.DidAttemptDetection", true, 1);
 }
@@ -117,7 +117,7 @@
       std::string("ja"), std::string(), contents, &predicted_language,
       &is_prediction_reliable, model_reliability_score);
   EXPECT_FALSE(is_prediction_reliable);
-  EXPECT_EQ(translate::kUnknownLanguageCode, predicted_language);
+  EXPECT_EQ(language_detection::kUnknownLanguageCode, predicted_language);
   // Rely on the provided language code if the mode is unreliable.
   EXPECT_EQ("ja", language);
   histogram_tester_.ExpectUniqueSample(
@@ -177,7 +177,7 @@
       &is_prediction_reliable, model_reliability_score);
   EXPECT_TRUE(is_prediction_reliable);
   EXPECT_EQ("zh-CN", predicted_language);
-  EXPECT_EQ(translate::kUnknownLanguageCode, language);
+  EXPECT_EQ(language_detection::kUnknownLanguageCode, language);
   histogram_tester_.ExpectUniqueSample(
       "LanguageDetection.TFLite.DidAttemptDetection", true, 1);
 }
diff --git a/components/translate/core/language_detection/language_detection_util.cc b/components/translate/core/language_detection/language_detection_util.cc
index d7badba..80a6861 100644
--- a/components/translate/core/language_detection/language_detection_util.cc
+++ b/components/translate/core/language_detection/language_detection_util.cc
@@ -19,7 +19,7 @@
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
 #include "components/language/core/common/language_util.h"
-#include "components/translate/core/common/translate_constants.h"
+#include "components/language_detection/core/constants.h"
 #include "components/translate/core/common/translate_metrics.h"
 #include "components/translate/core/language_detection/chinese_script_classifier.h"
 #include "third_party/cld_3/src/src/nnet_language_identifier.h"
@@ -110,14 +110,14 @@
   // Ignore unreliable, "unknown", and xx-Latn predictions that are currently
   // not supported.
   if (!is_detection_reliable)
-    return translate::kUnknownLanguageCode;
+    return language_detection::kUnknownLanguageCode;
   // TODO(crbug.com/40169055): Determine if ar-Latn and hi-Latn need to be added
   // for the TFLite-based detection model.
   if (detected_language == "bg-Latn" || detected_language == "el-Latn" ||
       detected_language == "ja-Latn" || detected_language == "ru-Latn" ||
       detected_language == "zh-Latn" ||
       detected_language == chrome_lang_id::NNetLanguageIdentifier::kUnknown) {
-    return translate::kUnknownLanguageCode;
+    return language_detection::kUnknownLanguageCode;
   }
 
   if (detected_language == "zh") {
@@ -132,7 +132,7 @@
       return "zh-TW";
     if (zh_classification == "zh-Hans")
       return "zh-CN";
-    return translate::kUnknownLanguageCode;
+    return language_detection::kUnknownLanguageCode;
   }
   // The detection is reliable and none of the cases that are not handled by the
   // language detection model.
@@ -203,7 +203,7 @@
     LanguageVerificationType language_verification_type) {
   translate::ReportLanguageVerification(language_verification_type);
   std::string language = GetHTMLOrHTTPContentLanguage(code, html_lang);
-  return language.empty() ? kUnknownLanguageCode : language;
+  return language.empty() ? language_detection::kUnknownLanguageCode : language;
 }
 
 // Now consider the web page language details along with the contents language.
@@ -213,7 +213,7 @@
                                   bool is_model_reliable) {
   std::string language = GetHTMLOrHTTPContentLanguage(code, html_lang);
   // If |language| is empty, just use model result even though it might be
-  // translate::kUnknownLanguageCode.
+  // language_detection::kUnknownLanguageCode.
   if (language.empty()) {
     translate::ReportLanguageVerification(
         translate::LanguageVerificationType::kModelOnly);
@@ -222,7 +222,7 @@
 
   // If |model_detected_language| is empty, just use |language|.
   if (model_detected_language.empty() ||
-      model_detected_language == kUnknownLanguageCode) {
+      model_detected_language == language_detection::kUnknownLanguageCode) {
     translate::ReportLanguageVerification(
         translate::LanguageVerificationType::kModelUnknown);
     return language;
@@ -251,7 +251,7 @@
   // rely on any of the language codes, and gives up suggesting a translation.
   translate::ReportLanguageVerification(
       translate::LanguageVerificationType::kModelDisagrees);
-  return kUnknownLanguageCode;
+  return language_detection::kUnknownLanguageCode;
 }
 
 void CorrectLanguageCodeTypo(std::string* code) {
diff --git a/components/translate/core/language_detection/language_detection_util.h b/components/translate/core/language_detection/language_detection_util.h
index a4de198..50eff405 100644
--- a/components/translate/core/language_detection/language_detection_util.h
+++ b/components/translate/core/language_detection/language_detection_util.h
@@ -12,7 +12,7 @@
 
 // Given a detected language and whether that detection is reliable, returns the
 // ISO 639 language code of |utf8_text|. Returns
-// |translate::kUnknownLanguageCode|
+// |language_detection::kUnknownLanguageCode|
 //  for unreliable, "unknown", and xx-Latn predictions that are currently not
 // supported.
 std::string FilterDetectedLanguage(const std::string& utf8_text,
@@ -20,8 +20,8 @@
                                    bool is_detection_reliable);
 
 // Returns the ISO 639 language code of the specified |utf8_text|, or
-// |translate::kUnknownLanguageCode| if it failed. |is_model_reliable| will be
-// set as true if CLD says the detection is reliable and
+// |language_detection::kUnknownLanguageCode| if it failed. |is_model_reliable|
+// will be set as true if CLD says the detection is reliable and
 // |model_reliability_score| will contain the model's confidence in that
 // detection.
 std::string DetermineTextLanguage(const std::string& utf8_text,
diff --git a/components/translate/core/language_detection/language_detection_util_unittest.cc b/components/translate/core/language_detection/language_detection_util_unittest.cc
index a0c09c1..22f3b68 100644
--- a/components/translate/core/language_detection/language_detection_util_unittest.cc
+++ b/components/translate/core/language_detection/language_detection_util_unittest.cc
@@ -8,7 +8,7 @@
 
 #include "base/strings/utf_string_conversions.h"
 #include "base/test/metrics/histogram_tester.h"
-#include "components/translate/core/common/translate_constants.h"
+#include "components/language_detection/core/constants.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace translate {
@@ -109,7 +109,7 @@
   std::string language = translate::DeterminePageLanguage(
       std::string("ja"), std::string(), contents, &model_detected_language,
       &is_model_reliable, model_reliability_score);
-  EXPECT_EQ(translate::kUnknownLanguageCode, language);
+  EXPECT_EQ(language_detection::kUnknownLanguageCode, language);
   EXPECT_EQ("en", model_detected_language);
   EXPECT_TRUE(is_model_reliable);
   EXPECT_GT(model_reliability_score, 0.5);
diff --git a/components/translate/ios/browser/ios_translate_driver.mm b/components/translate/ios/browser/ios_translate_driver.mm
index d54db6c..2290ef4 100644
--- a/components/translate/ios/browser/ios_translate_driver.mm
+++ b/components/translate/ios/browser/ios_translate_driver.mm
@@ -11,11 +11,11 @@
 #include "base/task/thread_pool.h"
 #include "base/time/time.h"
 #include "components/language_detection/core/browser/language_detection_model_service.h"
+#include "components/language_detection/core/constants.h"
 #include "components/language_detection/ios/browser/language_detection_model_loader_service_ios.h"
 #include "components/translate/core/browser/translate_client.h"
 #include "components/translate/core/browser/translate_manager.h"
 #include "components/translate/core/common/language_detection_details.h"
-#include "components/translate/core/common/translate_constants.h"
 #include "components/translate/core/common/translate_metrics.h"
 #include "components/translate/core/common/translate_util.h"
 #include "components/translate/core/language_detection/language_detection_model.h"
@@ -281,9 +281,10 @@
 
   ReportTimeToLoad(load_time);
   ReportTimeToBeReady(ready_time);
-  std::string source = (source_language_ != kUnknownLanguageCode)
-                           ? source_language_
-                           : kAutoDetectionLanguage;
+  std::string source =
+      (source_language_ != language_detection::kUnknownLanguageCode)
+          ? source_language_
+          : kAutoDetectionLanguage;
   TranslateController::FromWebState(web_state_)
       ->StartTranslation(source, target_language_);
 }
diff --git a/docs/vscode.md b/docs/vscode.md
index 97f5214..e0ca28a 100644
--- a/docs/vscode.md
+++ b/docs/vscode.md
@@ -240,8 +240,8 @@
 
 There are two extensions you can use to get Java/Android support in VSCode:
 
-a. [ChromiumIDE](https://marketplace.visualstudio.com/items?itemName=Google.cros-ide)
-b. [Language Support for Java™ by Red Hat](https://marketplace.visualstudio.com/items?itemName=redhat.java)
+*   a. [ChromiumIDE](https://marketplace.visualstudio.com/items?itemName=Google.cros-ide)
+*   b. [Language Support for Java™ by Red Hat](https://marketplace.visualstudio.com/items?itemName=redhat.java)
 
 ChromiumIDE is much faster and more stable than the other extension, mainly
 because it does not rely on background indexing and persistent cache. It works
@@ -259,15 +259,10 @@
 
 Install the latest **pre-release** version of
 [ChromiumIDE](https://marketplace.visualstudio.com/items?itemName=Google.cros-ide)
-from the VSCode marketplace. Make sure the extension version is **0.35.26** or
+from the VSCode marketplace. Make sure the extension version is **0.35.32** or
 later.
 
-After installing the pre-release version, **enable the experimental setting for
-Chromium Java support**. Note that settings should be enabled before opening
-a Chromium workspace; if you have opened one already, please reload the window
-after updating the setting.
-
-Then open a VSCode workspace containing Chromium source tree (opening
+Then just open a VSCode workspace containing Chromium source tree (opening
 subdirectories is fine) and open a Java file. If you haven't, you're prompted to
 select the default build output directory (e.g. `out/Default`).
 
diff --git a/docs/windows_build_instructions.md b/docs/windows_build_instructions.md
index b0dabf0d..2fc2f87 100644
--- a/docs/windows_build_instructions.md
+++ b/docs/windows_build_instructions.md
@@ -85,7 +85,8 @@
 For more information on Git for Windows (which is a separate project from Git),
 see https://gitforwindows.org.
 
-Note: if you are a Google employee, see [go/building-chrome-win#install-git](https://goto.google.com/building-chrome-win#install-git).
+Note: if you are a Google employee, see git installation instructions at
+[go/building-chrome-win](https://goto.google.com/building-chrome-win#install-updates-and-required-software).
 
 ### Update git
 
diff --git a/gpu/command_buffer/client/buffer_tracker.h b/gpu/command_buffer/client/buffer_tracker.h
index fb85b37..4944321 100644
--- a/gpu/command_buffer/client/buffer_tracker.h
+++ b/gpu/command_buffer/client/buffer_tracker.h
@@ -7,6 +7,8 @@
 
 #include <stdint.h>
 
+#include <unordered_map>
+
 #include "base/memory/raw_ptr.h"
 #include "gles2_impl_export.h"
 #include "gpu/command_buffer/common/gles2_cmd_format.h"
diff --git a/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb
index 8cef5ca..0f6937c 100644
--- a/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb
+++ b/ios/chrome/app/strings/resources/ios_chromium_strings_uz.xtb
@@ -184,6 +184,7 @@
 <translation id="5534584691915394889">Bu Chromium va Google Lensdan Apple Calendar ilovasida tadbirlar yaratish uchun ishlatiladi.</translation>
 <translation id="5571094606370987472">Chromiumda oxirgi varaqlarni ochadi.</translation>
 <translation id="5603085937604338780">chromium</translation>
+<translation id="5657280937522795751">Chromium tugmasi</translation>
 <translation id="5664395081284292058">Oxirgi varaq Chromiumda ochilsin</translation>
 <translation id="5671188105328420281">Chromium mashlahatlari</translation>
 <translation id="5688047395118852662">Bu bildirgi Chromiumning barcha imkoniyatlaridan foydalanish yuzasidan takliflar chiqaradi.</translation>
@@ -227,6 +228,7 @@
 <translation id="6752854822223394465">Chromium tashkilotingiz tomonidan sozlanmoqda...</translation>
 <translation id="6794054469102824109">Chromium Dino oʻyinini ochadi.</translation>
 <translation id="6820823224820483452">Chromium barcha parollarni tekshira olmadi. Ertaga qayta urining.</translation>
+<translation id="6830782797004194206">Chromium avtomatik kiritish bilan hisobga tezroq kiring</translation>
 <translation id="6831043979455480757">Tarjima</translation>
 <translation id="6852419005633611413">Chromiumni bosh ekranga mahkamlab, tezroq oching</translation>
 <translation id="6852799557929001644">Bu qurilmadagi boshqa ilovalarda Chromium parollaringiz va boshqalarga kiring.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb
index 0d1cca8..d55c30f 100644
--- a/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb
+++ b/ios/chrome/app/strings/resources/ios_google_chrome_strings_uz.xtb
@@ -170,6 +170,7 @@
 <translation id="5639704535586432836">Kameradan foydalanishga ruxsat berish uchun “Sozlamalar &gt; Maxfiylik &gt; Kamera &gt; Google Chrome” bandini oching.</translation>
 <translation id="5642200033778930880">Google Chrome kamerangizdan Split View rejimida foydalana olmaydi.</translation>
 <translation id="5661521615548540542">Google Parollar menejeri barcha parollarni tekshira olmadi. Keyinroq qayta urining.</translation>
+<translation id="5681291952421236520">Chrome tugmasi</translation>
 <translation id="5690398455483874150">{count,plural, =1{Hozir 1 ta Chrome oynasi chiqarilgan}other{Hozir {count} ta Chrome oynasi chiqarilgan}}</translation>
 <translation id="5690427481109656848">Google LLC</translation>
 <translation id="5709557627224531708">Chromeni standart brauzer etib tayinlang</translation>
@@ -205,6 +206,7 @@
 <translation id="6484712497741564393"><ph name="EMAIL" /> hisobi bilan kirgansiz.
 
 Maʼlumotlaringiz kodli ibora bilan shifrlangan. Chrome maʼlumotlarini Google hisobingizda saqlash va ulardan foydalanish uchun uni kiriting.</translation>
+<translation id="6533470733797826516">Chrome avtomatik kiritish bilan hisobga tezroq kiring</translation>
 <translation id="6545449117344801102">Chrome marshrut va mahalliy axborot berish uchun manzillarni Google Xaritalar yordamida aniqlaydi.</translation>
 <translation id="6634107063912726160">Hisobingizdan chiqsangiz, Chrome yangi maʼlumotlarni Google hisobingizga sinxronlamaydi. Oldin sinxronlangan maʼlumotlar hisobingizda qoladi.</translation>
 <translation id="6636941099779251629">Chrome brauzeridan foydalanishingiz uchun tashkilotingiz roʻyxatdan oʻtishni talab qiladi. <ph name="BEGIN_LINK" />Batafsil<ph name="END_LINK" /></translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_ar.xtb b/ios/chrome/app/strings/resources/ios_strings_ar.xtb
index 8565dd9..cc83d74 100644
--- a/ios/chrome/app/strings/resources/ios_strings_ar.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_ar.xtb
@@ -493,6 +493,7 @@
 <translation id="3130863904455712965">السجلّ وغير ذلك</translation>
 <translation id="313283613037595347">إنشاء علامة تبويب جديدة في وضع التصفُّح المتخفي</translation>
 <translation id="3138611310073113613">تجاهل الاختيار</translation>
+<translation id="3140825265190223781">كلمات المرور ومفاتيح المرور المحفوظة</translation>
 <translation id="3143515551205905069">إلغاء المزامنة</translation>
 <translation id="314837624430314508">يمكنك متابعة آخر الأخبار وتغيّرات الأسعار وغير ذلك.</translation>
 <translation id="3157387275655328056">الإضافة إلى قائمة القراءة</translation>
@@ -1666,6 +1667,7 @@
 <translation id="8299613349954694191">يمكنك فتح علامة تبويب في وضع التصفُّح المتخفي لتصفُّح المواقع الإلكترونية بخصوصية تامّة.</translation>
 <translation id="8307481894409578819">تعذر تحميل هذا الملف</translation>
 <translation id="8319076807703933069">بحث جديد</translation>
+<translation id="833647236762414178">يمكنك إنشاء كلمات المرور ومفاتيح المرور وحفظها وإدارتها لتسجيل الدخول بسهولة إلى المواقع الإلكترونية والتطبيقات. <ph name="BEGIN_LINK" />مزيد من المعلومات<ph name="END_LINK" /></translation>
 <translation id="8343993175958086504">يمكنك الاحتفاظ بنسخة احتياطية من بياناتك واستخدامها على أي جهاز.</translation>
 <translation id="8349305172487531364">شريط الإشارات</translation>
 <translation id="8364563001733875155">لتغيير رقم التعريف الشخصي، عليك أولاً ضبط رمز مرور على جهازك.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_fa.xtb b/ios/chrome/app/strings/resources/ios_strings_fa.xtb
index 60db0c0..e34aced 100644
--- a/ios/chrome/app/strings/resources/ios_strings_fa.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_fa.xtb
@@ -493,6 +493,7 @@
 <translation id="3130863904455712965">سابقه و موارد بیشتر</translation>
 <translation id="313283613037595347">ایجاد «برگه ناشناس» جدید</translation>
 <translation id="3138611310073113613">صرف‌نظر کردن از انتخاب</translation>
+<translation id="3140825265190223781">گذرواژه‌ها و گذرکلیدهای ذخیره‌شده</translation>
 <translation id="3143515551205905069">لغو همگام‌سازی</translation>
 <translation id="314837624430314508">با جدیدترین اخبار، به‌روزرسانی‌های پیگیری قیمت، و موارد دیگر همراه باشید.</translation>
 <translation id="3157387275655328056">افزودن به فهرست خواندن</translation>
@@ -1666,6 +1667,7 @@
 <translation id="8299613349954694191">برای مرور وب به‌صورت خصوصی، «برگه ناشناس» باز کنید.</translation>
 <translation id="8307481894409578819">این فایل بارگذاری نشد</translation>
 <translation id="8319076807703933069">جستجوی جدید</translation>
+<translation id="833647236762414178">گذرواژه‌ها و گذرکلیدهایتان را ایجاد، ذخیره، و مدیریت کنید تا بتوانید به‌راحتی به سیستم سایت‌ها و برنامه‌ها وارد شوید. <ph name="BEGIN_LINK" />بیشتر بدانید<ph name="END_LINK" /></translation>
 <translation id="8343993175958086504">از داده‌هایتان پشتیبان بگیرید و در هر دستگاهی از آن‌ها استفاده کنید.</translation>
 <translation id="8349305172487531364">نوار نشانک‌ها</translation>
 <translation id="8364563001733875155">برای تغییر دادن پین، ابتدا گذرنویسه‌ای دردستگاهتان راه‌اندازی کنید.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_mn.xtb b/ios/chrome/app/strings/resources/ios_strings_mn.xtb
index de3d386..2af68f6 100644
--- a/ios/chrome/app/strings/resources/ios_strings_mn.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_mn.xtb
@@ -493,6 +493,7 @@
 <translation id="3130863904455712965">Түүх болон бусад</translation>
 <translation id="313283613037595347">Шинэ Нууцлалтай таб үүсгэх</translation>
 <translation id="3138611310073113613">Сонголтыг болих</translation>
+<translation id="3140825265190223781">Хадгалсан нууц үг, нэвтрэх түлхүүр</translation>
 <translation id="3143515551205905069">Синкийг цуцлах</translation>
 <translation id="314837624430314508">Хамгийн сүүлийн үеийн мэдээ, үнэ мөшгөх шинэчлэлт болон бусад зүйлийн мэдээллийг авч байгаарай.</translation>
 <translation id="3157387275655328056">Унших жагсаалтад нэмэх</translation>
@@ -1666,6 +1667,7 @@
 <translation id="8299613349954694191">Вебийг нууцлалтайгаар үзэхийн тулд Нууцлалтай табыг нээнэ үү</translation>
 <translation id="8307481894409578819">Энэ файлыг байршуулж чадсангүй</translation>
 <translation id="8319076807703933069">Шинэ хайлт</translation>
+<translation id="833647236762414178">Сайт, аппад хялбархан нэвтрэхийн тулд нууц үг, нэвтрэх түлхүүрээ үүсгэж, хадгалж, удирдана уу. <ph name="BEGIN_LINK" />Нэмэлт мэдээлэл авах<ph name="END_LINK" /></translation>
 <translation id="8343993175958086504">Зүйлсээ хуулбарлаж, дурын төхөөрөмж дээр ашиглана уу.</translation>
 <translation id="8349305172487531364">Хайлтын жагсаалтын цонх</translation>
 <translation id="8364563001733875155">ПИН-ээ өөрчлөхийн тулд эхлээд төхөөрөмж дээрээ нууц код тохируулна уу.</translation>
diff --git a/ios/chrome/app/strings/resources/ios_strings_uz.xtb b/ios/chrome/app/strings/resources/ios_strings_uz.xtb
index b06f163..0242f35 100644
--- a/ios/chrome/app/strings/resources/ios_strings_uz.xtb
+++ b/ios/chrome/app/strings/resources/ios_strings_uz.xtb
@@ -191,6 +191,7 @@
 <translation id="1779354709911146450">Autentifikatsiya xatosi yuz berdi</translation>
 <translation id="1780152987505130652">Guruhni yopish</translation>
 <translation id="178400879184240105">Parollaringiz takrorlanmagan</translation>
+<translation id="17906873777101817">Parollar va kalitlarni saqlash taklif qilinsin</translation>
 <translation id="1807893857950749072">Narx kuzatuvi bildirishnomalariga ruxsat…</translation>
 <translation id="1810976980198522421">Bekor qilish</translation>
 <translation id="1815941218935345331">Maxfiy kod</translation>
@@ -1322,6 +1323,7 @@
 <translation id="6732087373923685049">kamera</translation>
 <translation id="6746338529702829275">Hisobingiz maʼlumotlarini tekshiring</translation>
 <translation id="6755200887046212842">Hisoblarni boshqarish</translation>
+<translation id="6755733078693946548">Parollar va kalitlarni istalgan ilovadan ochish</translation>
 <translation id="6761393919622941301">Audio</translation>
 <translation id="6779455296366983087">Brauzer tarixi tozalanadi</translation>
 <translation id="6790502149545262384">Tez orada yangi varaq ochilganda <ph name="CHANNEL_NAME" /> hikoyalari chiqadi.</translation>
@@ -1589,6 +1591,7 @@
 <translation id="7977451675950311423">Maʼlumotlar sizishi natijasida oshkor boʻlgan paroldan foydalansangiz, sizni ogohlantiradi.</translation>
 <translation id="7977482887663636093"><ph name="NUMBER_OF_TABS_ADDED" /> ta yangi varaq, yopildi:<ph name="NUMBER_OF_TABS_REMOVED" /></translation>
 <translation id="797824194429476746">Varaqlar bu qurilmada ochiq qoladi, ammo guruh butunlay oʻchirib tashlanadi.</translation>
+<translation id="797874245254030665">Parollar va kalitlarni istalgan ilovadan oching</translation>
 <translation id="7982789257301363584">Tarmoq</translation>
 <translation id="7987685713885608670">Xavfsizlikni yanada oshirish uchun parolingizni Google Parollar menejeriga saqlashdan oldin qurilmangizda shifrlang</translation>
 <translation id="798991908416757345">Varaqlar guruhi mavjud emas</translation>
@@ -1670,6 +1673,7 @@
 <translation id="8299613349954694191">Brauzer tarixi saqlanmasligi uchun inkognito tab oching.</translation>
 <translation id="8307481894409578819">Bu faylni yuklash imkonsiz</translation>
 <translation id="8319076807703933069">Yangi qidiruv</translation>
+<translation id="8328607660158575887">Avtomatik kiritish va parollar sozlamalarini ochish</translation>
 <translation id="8343993175958086504">Maʼlumotlaringizni zaxiralang va istalgan qurilmada oching.</translation>
 <translation id="8349305172487531364">Xatcho‘plar paneli</translation>
 <translation id="8364563001733875155">PIN kodni oʻzgartirish uchun qurilmada kirish kodini sozlang</translation>
@@ -1821,6 +1825,7 @@
 <translation id="8909459547399237818">Parollar menejerini tanlang, keyin Vidjet kiritishni bosing</translation>
 <translation id="891282356902782456">Bu parol faqat mazkur qurilmada saqlangan. Boshqa qurilmalarda foydalanish uchun uni Google hisobingizda (<ph name="EMAIL" />) saqlang.</translation>
 <translation id="8915916167043355778">Hammasini yopish</translation>
+<translation id="892185197271200809">“<ph name="GROUP_NAME" />” varaqlar guruhi hammada ishlamay qoladi va barcha qurilmalardan oʻchiriladi</translation>
 <translation id="8921902386312975525">Pochta paketlarini kuzatish parametrlari</translation>
 <translation id="8923178205567790913">Parollar</translation>
 <translation id="892776311701544612">Batafsil…</translation>
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1
index 3a55551..e5bb32c3 100644
--- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-79ca61357236bcb440ad8a7d5b8837915aea811a
\ No newline at end of file
+769fec528d913468e4516ba12631a985cc2c4ed4
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1
index be92cde..25c412a 100644
--- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@
-4d536f661f4477bb6e6be3b28ca510e3defade9a
\ No newline at end of file
+49e26f564dd5bb7467b80e62c0de1d1a899aae7d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
index f7b3169..ab256d4b 100644
--- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-6fe45aaf46e4a4492b6bf3d64de6b28074734518
\ No newline at end of file
+11fdc05c745217e912aae3294105aa92c7525fd1
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1
index 485176c..fdd86270 100644
--- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@
-561f4c57c5f8bf6cd2a187ea4032184acb6875d1
\ No newline at end of file
+8c53029065ac7ab02c653d88ef6333857f574700
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
index a43d4e5..074bf27 100644
--- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@
-e4e157eb2f6aa987a2b2ab3e6fcbc3e93dc17fad
\ No newline at end of file
+b1ba1f24250c708f4003587371ac526d8279e737
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1
index 13efdbb..940a406 100644
--- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1
+++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@
-0769ad8a550a67b48bcae5ed84c2112cb9bdff6c
\ No newline at end of file
+18b53c6baf8efb1d799a82d601a3b99826dd9bf6
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1
index d9cb52b..d1c6dfb 100644
--- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-0846a576b55699196e4f2bdb825e025e64f68993
\ No newline at end of file
+5ba2011bf4c189c3beae0a8554e9441410049c5a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1
index 01a6a83d..ace5413 100644
--- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@
-7bcf5abaeb01da9f40b5c0396c2e8882dbf9f1d0
\ No newline at end of file
+6e9db74024dc725ab924d4787726b21f16903960
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1
index a8094b719..7bacba3e 100644
--- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-e75a931434b2194bf543ca1d14c2480fae18d3ce
\ No newline at end of file
+ae6c9b5ba4c62e75018c9efd0276ff43040440ed
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1
index 2dfeaa9..9c606b2b 100644
--- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@
-51975873954bad3084f00cc4566c4ce4a4b7c5e9
\ No newline at end of file
+e03c67666c056e216fc4865874db4ebc65002972
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
index ee06fd7..58e2b9f 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-9db08e83e621c667476a29c111962b47d7ccecfb
\ No newline at end of file
+60d5fe3af5c3f856da94ce6bca6ef0e29e3e455d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1
index 2fff5ad..04613309c 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@
-46ad7f26b97ab06df25ae7c4e68c63e27d55f997
\ No newline at end of file
+a411a957815fb6982c5e0503d2ac41217f2fe642
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
index b8338b1..0ff88ec 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-e26841ce84643aeffe4769498fca3e58c7519d78
\ No newline at end of file
+b62c5cea3f68741712409b36eb67a7bd3daa9722
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1
index 64cd3b5..616a9f0e 100644
--- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@
-d999734c12d0b8681c6f3cc9513d963b02d7a132
\ No newline at end of file
+1300a3db7a325b8635e7258ef71045c8ad5dbc57
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
index 7679387..293de37 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-f5464d81b09bb2a6f412c67f7a0e86714d50bb87
\ No newline at end of file
+638796e7689d3d1bff2354500669acc6db883531
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1
index 131fc2d2..473ecfc 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@
-21f4a101ab7c08c504fa270738be835a9a8e0a82
\ No newline at end of file
+6e8641b7e2a3ebae91548213a085315e87354e9b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
index 07bbb4a..55911f4 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-87ab0389f35dfe161a626af2805aeb9d794a6cd3
\ No newline at end of file
+1b85838b04c55a81bc8030b9d4ed2785e8efdcae
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1
index dd7b9a0e..02aedf6 100644
--- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@
-593200b8d086ecc13a861c20391eb560da886769
\ No newline at end of file
+33be4b107ceced54570955de1432c7d20644ef7a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
index 2d466a1..3d0fc21 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-2324373444a2693cab7ff778820811a03bb0f6b0
\ No newline at end of file
+346224f7e9c32c72b8ce31d8f709f9def4e5578d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
index 21cb7d2..1efc8f5 100644
--- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-3c6cb739cbfef250c77f4af844695f0b8e4364d6
\ No newline at end of file
+29c967a5e80caf5e6e807ec007bcec33d2c78a7b
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
index b49fd0c..c973ef1 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-c31e3d8bdbfeab3db8ec29411f6ef74b82afbddb
\ No newline at end of file
+d22d65f08ec89e32505870e498055fb2ff9c491d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1
index 98328cd..1347dcc9 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@
-6ca662fbaf40f6c8695055e135d29db4d15b329d
\ No newline at end of file
+113bc54df4fd3dffeccc21c867c18d1455aa3003
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
index 0c646f4..2139c6d 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-208275efc7dd37a67e65958db5e5c86bc6c811bb
\ No newline at end of file
+4787ba9e65a5c58b811327e5afa7e57e66eecc35
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1
index 45d639e..1f459f57 100644
--- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1
+++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@
-126b1c3bf16f611cec10158ba097e48a9c0bf2bd
\ No newline at end of file
+f336663f4d227acdd26fc5f8256bf7f5f7bb442a
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
index 4e2769b..7d214429 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@
-189586649b1bde7e2b7586e3dfd42a5244f365b9
\ No newline at end of file
+19fee450ee9d000b5e8c0d3ef53dad9c7a3dc8fd
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1
index c6368222..3b9bf53 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@
-c1b2596e97dd31b122ca87528da8325b4f52fdae
\ No newline at end of file
+41ce90a499ca9108fc667b74a76da3a7cc238ea5
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
index ca96fbe..39555dc 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@
-76e094653f4247b0b03020307c28ffe1c54348eb
\ No newline at end of file
+746dbefec1b387e62b91f45d72066ddeda5e6b9d
\ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1
index a9a3f2d..6dc443c 100644
--- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1
+++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@
-6bcf5c4dacc824a822fc1586a998e2b4de355e20
\ No newline at end of file
+d636c80a7d9523fb2fd4e70ea2e8761705e0277b
\ No newline at end of file
diff --git a/ios_internal b/ios_internal
index b475270..67d2600 160000
--- a/ios_internal
+++ b/ios_internal
@@ -1 +1 @@
-Subproject commit b4752700af4d89c303eea80d0088c07fb7a5cb21
+Subproject commit 67d2600839370d13a8f8f962d74803d2d129b267
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins
index 5f70225..a2a9e3f 100644
--- a/net/http/transport_security_state_static.pins
+++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@
 #   hash function for preloaded entries again (we have already done so once).
 #
 
-# Last updated: 2025-01-15 12:54 UTC
+# Last updated: 2025-01-19 12:54 UTC
 PinsListTimestamp
-1736945690
+1737291287
 
 TestSPKI
 sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json
index 65c1a85..691b62a 100644
--- a/net/http/transport_security_state_static_pins.json
+++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@
 // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets'
 // refer to, and the timestamp at which the pins list was last updated.
 //
-// Last updated: 2025-01-15 12:54 UTC
+// Last updated: 2025-01-19 12:54 UTC
 //
 {
   "pinsets": [
diff --git a/net/third_party/quiche/src b/net/third_party/quiche/src
index 41e6857..1653567 160000
--- a/net/third_party/quiche/src
+++ b/net/third_party/quiche/src
@@ -1 +1 @@
-Subproject commit 41e68574090ab56109ca785bba9c6a611ab99dce
+Subproject commit 16535679768274d3061f1b991082a6a0c8fd1aac
diff --git a/testing/buildbot/chrome.json b/testing/buildbot/chrome.json
index f3a6d79..6326c4c 100644
--- a/testing/buildbot/chrome.json
+++ b/testing/buildbot/chrome.json
@@ -955,6 +955,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "aura_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "aura_unittests",
@@ -966,6 +967,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "base_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "base_unittests",
@@ -981,6 +983,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "capture_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "capture_unittests",
@@ -992,6 +995,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "cc_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "cc_unittests",
@@ -1003,6 +1007,7 @@
         "autotest_name": "tast.chrome-from-gcs",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "chrome_all_tast_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "shards": 15,
@@ -1019,6 +1024,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "chrome_criticalstaging_tast_tests RELEASE_LKGM",
         "shards": 3,
@@ -1035,6 +1041,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "chrome_disabled_tast_tests RELEASE_LKGM",
         "shards": 2,
@@ -1050,6 +1057,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "chromeos_integration_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "chromeos_integration_tests",
@@ -1061,6 +1069,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "crypto_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "crypto_unittests",
@@ -1072,6 +1081,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "display_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "display_unittests",
@@ -1091,6 +1101,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "fake_libva_driver_unittest RELEASE_LKGM",
         "test": "fake_libva_driver_unittest",
@@ -1102,6 +1113,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "google_apis_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "google_apis_unittests",
@@ -1113,6 +1125,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "ipc_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "ipc_tests",
@@ -1124,6 +1137,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "latency_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "latency_unittests",
@@ -1135,6 +1149,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "libcups_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "libcups_unittests",
@@ -1149,6 +1164,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "media_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "media_unittests",
@@ -1160,6 +1176,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "midi_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "midi_unittests",
@@ -1171,6 +1188,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "mojo_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "mojo_unittests",
@@ -1185,6 +1203,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "ozone_gl_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "ozone_gl_unittests",
@@ -1196,6 +1215,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "ozone_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "ozone_unittests",
@@ -1207,6 +1227,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "pdf_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "pdf_unittests",
@@ -1218,6 +1239,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "printing_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "printing_unittests",
@@ -1233,6 +1255,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "profile_provider_unittest RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "profile_provider_unittest",
@@ -1244,6 +1267,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "rust_gtest_interop_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "rust_gtest_interop_unittests",
@@ -1255,6 +1279,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "sql_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "sql_unittests",
@@ -1266,6 +1291,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "url_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "url_unittests",
@@ -1281,6 +1307,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "vaapi_unittest RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "vaapi_unittest",
@@ -1303,6 +1330,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "video_decode_accelerator_tests_fake_vaapi_av1 RELEASE_LKGM",
         "test": "video_decode_accelerator_tests",
@@ -1325,6 +1353,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "video_decode_accelerator_tests_fake_vaapi_vp8 RELEASE_LKGM",
         "test": "video_decode_accelerator_tests",
@@ -1347,6 +1376,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "video_decode_accelerator_tests_fake_vaapi_vp9 RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "video_decode_accelerator_tests",
@@ -1365,6 +1395,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "aura_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "aura_unittests",
@@ -1376,6 +1407,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "base_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "base_unittests",
@@ -1391,6 +1423,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "capture_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "capture_unittests",
@@ -1402,6 +1435,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "cc_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "cc_unittests",
@@ -1413,6 +1447,7 @@
         "autotest_name": "tast.chrome-from-gcs",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "chrome_all_tast_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "shards": 15,
@@ -1429,6 +1464,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "chrome_criticalstaging_tast_tests RELEASE_LKGM",
         "shards": 3,
@@ -1445,6 +1481,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "chrome_disabled_tast_tests RELEASE_LKGM",
         "shards": 2,
@@ -1460,6 +1497,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "chromeos_integration_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "chromeos_integration_tests",
@@ -1471,6 +1509,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "crypto_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "crypto_unittests",
@@ -1482,6 +1521,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "display_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "display_unittests",
@@ -1501,6 +1541,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "fake_libva_driver_unittest RELEASE_LKGM",
         "test": "fake_libva_driver_unittest",
@@ -1512,6 +1553,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "google_apis_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "google_apis_unittests",
@@ -1523,6 +1565,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "ipc_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "ipc_tests",
@@ -1534,6 +1577,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "latency_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "latency_unittests",
@@ -1545,6 +1589,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "libcups_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "libcups_unittests",
@@ -1559,6 +1604,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "media_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "media_unittests",
@@ -1570,6 +1616,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "midi_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "midi_unittests",
@@ -1581,6 +1628,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "mojo_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "mojo_unittests",
@@ -1595,6 +1643,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "ozone_gl_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "ozone_gl_unittests",
@@ -1606,6 +1655,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "ozone_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "ozone_unittests",
@@ -1617,6 +1667,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "pdf_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "pdf_unittests",
@@ -1628,6 +1679,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "printing_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "printing_unittests",
@@ -1643,6 +1695,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "profile_provider_unittest RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "profile_provider_unittest",
@@ -1654,6 +1707,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "rust_gtest_interop_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "rust_gtest_interop_unittests",
@@ -1665,6 +1719,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "sql_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "sql_unittests",
@@ -1676,6 +1731,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "url_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "url_unittests",
@@ -1691,6 +1747,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "vaapi_unittest RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "vaapi_unittest",
@@ -1713,6 +1770,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "video_decode_accelerator_tests_fake_vaapi_av1 RELEASE_LKGM",
         "test": "video_decode_accelerator_tests",
@@ -1735,6 +1793,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "video_decode_accelerator_tests_fake_vaapi_vp8 RELEASE_LKGM",
         "test": "video_decode_accelerator_tests",
@@ -1757,6 +1816,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "video_decode_accelerator_tests_fake_vaapi_vp9 RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "video_decode_accelerator_tests",
diff --git a/testing/buildbot/chromeos.preuprev.json b/testing/buildbot/chromeos.preuprev.json
index c5b047ce..18bd7ca 100644
--- a/testing/buildbot/chromeos.preuprev.json
+++ b/testing/buildbot/chromeos.preuprev.json
@@ -54,6 +54,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "base_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "base_unittests",
@@ -65,6 +66,7 @@
         "autotest_name": "tast.chrome-from-gcs",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "chrome_all_tast_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "shards": 30,
@@ -80,6 +82,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "chromeos_integration_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "chromeos_integration_tests",
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json
index e8aebc1..fe289888 100644
--- a/testing/buildbot/internal.chromeos.fyi.json
+++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -61,6 +61,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "aura_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "aura_unittests",
@@ -72,6 +73,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "base_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "base_unittests",
@@ -87,6 +89,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "capture_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "capture_unittests",
@@ -98,6 +101,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "cc_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "cc_unittests",
@@ -109,6 +113,7 @@
         "autotest_name": "tast.chrome-from-gcs",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "chrome_all_tast_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "shards": 15,
@@ -125,6 +130,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "chrome_criticalstaging_tast_tests RELEASE_LKGM",
         "shards": 3,
@@ -141,6 +147,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "chrome_disabled_tast_tests RELEASE_LKGM",
         "shards": 2,
@@ -156,6 +163,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "chromeos_integration_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "chromeos_integration_tests",
@@ -167,6 +175,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "crypto_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "crypto_unittests",
@@ -178,6 +187,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "display_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "display_unittests",
@@ -197,6 +207,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "fake_libva_driver_unittest RELEASE_LKGM",
         "test": "fake_libva_driver_unittest",
@@ -208,6 +219,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "google_apis_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "google_apis_unittests",
@@ -219,6 +231,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "ipc_tests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "ipc_tests",
@@ -230,6 +243,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "latency_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "latency_unittests",
@@ -241,6 +255,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "libcups_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "libcups_unittests",
@@ -255,6 +270,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "media_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "media_unittests",
@@ -266,6 +282,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "midi_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "midi_unittests",
@@ -277,6 +294,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "mojo_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "mojo_unittests",
@@ -291,6 +309,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "ozone_gl_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "ozone_gl_unittests",
@@ -302,6 +321,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "ozone_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "ozone_unittests",
@@ -313,6 +333,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "pdf_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "pdf_unittests",
@@ -324,6 +345,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "printing_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "printing_unittests",
@@ -339,6 +361,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "profile_provider_unittest RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "profile_provider_unittest",
@@ -350,6 +373,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "rust_gtest_interop_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "rust_gtest_interop_unittests",
@@ -361,6 +385,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "sql_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "sql_unittests",
@@ -372,6 +397,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "url_unittests RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "url_unittests",
@@ -387,6 +413,7 @@
         "autotest_name": "chromium",
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "vaapi_unittest RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "vaapi_unittest",
@@ -409,6 +436,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "video_decode_accelerator_tests_fake_vaapi_av1 RELEASE_LKGM",
         "test": "video_decode_accelerator_tests",
@@ -431,6 +459,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "experiment_percentage": 100,
         "name": "video_decode_accelerator_tests_fake_vaapi_vp8 RELEASE_LKGM",
         "test": "video_decode_accelerator_tests",
@@ -453,6 +482,7 @@
         "ci_only": true,
         "cros_board": "brya",
         "cros_cbx": true,
+        "cros_model": "kano",
         "name": "video_decode_accelerator_tests_fake_vaapi_vp9 RELEASE_LKGM",
         "shard_level_retries_on_ctp": 1,
         "test": "video_decode_accelerator_tests",
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl
index e451dda1..e73049c 100644
--- a/testing/buildbot/waterfalls.pyl
+++ b/testing/buildbot/waterfalls.pyl
@@ -133,6 +133,7 @@
         },
         'os_type': 'chromeos',
         'cros_board': 'brya',
+        'cros_model': 'kano',
       },
       'chromeos-brya-chrome-tests': {
         'mixins': [
@@ -143,6 +144,7 @@
         },
         'os_type': 'chromeos',
         'cros_board': 'brya',
+        'cros_model': 'kano',
       },
       'chromeos-jacuzzi-chrome': {
         'additional_compile_targets': [
@@ -417,6 +419,7 @@
         },
         'os_type': 'chromeos',
         'cros_board': 'brya',
+        'cros_model': 'kano',
       },
       'chromeos-jacuzzi-chrome-preuprev': {
         'additional_compile_targets': [
@@ -1171,6 +1174,7 @@
         },
         'os_type': 'chromeos',
         'cros_board': 'brya',
+        'cros_model': 'kano',
       },
       'chromeos-eve-chrome': {
         # This builder is build only.
diff --git a/third_party/abseil-cpp/CMake/AbseilDll.cmake b/third_party/abseil-cpp/CMake/AbseilDll.cmake
index ff030e6e..d8a8ecf 100644
--- a/third_party/abseil-cpp/CMake/AbseilDll.cmake
+++ b/third_party/abseil-cpp/CMake/AbseilDll.cmake
@@ -837,6 +837,7 @@
     PRIVATE
       ${_dll_libs}
       ${ABSL_DEFAULT_LINKOPTS}
+      $<$<BOOL:${ANDROID}>:-llog>
   )
   set_target_properties(${_dll} PROPERTIES
     LINKER_LANGUAGE "CXX"
diff --git a/third_party/abseil-cpp/MODULE.bazel b/third_party/abseil-cpp/MODULE.bazel
index 9805065..7ade5e2f 100644
--- a/third_party/abseil-cpp/MODULE.bazel
+++ b/third_party/abseil-cpp/MODULE.bazel
@@ -28,7 +28,7 @@
 # Only direct dependencies need to be listed below.
 # Please keep the versions in sync with the versions in the WORKSPACE file.
 
-bazel_dep(name = "rules_cc", version = "0.1.0")
+bazel_dep(name = "rules_cc", version = "0.0.17")
 bazel_dep(name = "bazel_skylib", version = "1.7.1")
 bazel_dep(name = "platforms", version = "0.0.10")
 
diff --git a/third_party/abseil-cpp/README.chromium b/third_party/abseil-cpp/README.chromium
index c7a9c4e..81a8393 100644
--- a/third_party/abseil-cpp/README.chromium
+++ b/third_party/abseil-cpp/README.chromium
@@ -4,7 +4,7 @@
 License: Apache-2.0
 License File: LICENSE
 Version: N/A
-Revision: a1de53ddde40db01d0ed5ffb01030b219f8d76cf
+Revision: 513583421ac8adc7f397ebc912c2d7d55eea4a75
 Security Critical: yes
 Shipped: yes
 
diff --git a/third_party/abseil-cpp/absl/container/btree_test.cc b/third_party/abseil-cpp/absl/container/btree_test.cc
index d7102fe4..ef1b5bbf 100644
--- a/third_party/abseil-cpp/absl/container/btree_test.cc
+++ b/third_party/abseil-cpp/absl/container/btree_test.cc
@@ -2949,6 +2949,7 @@
 
 TEST(Btree, ConstructImplicitlyWithUnadaptedComparator) {
   absl::btree_set<MultiKey, MultiKeyComp> set = {{}, MultiKeyComp{}};
+  EXPECT_TRUE(set.empty());
 }
 
 TEST(Btree, InvalidComparatorsCaught) {
diff --git a/third_party/abseil-cpp/absl/container/fixed_array.h b/third_party/abseil-cpp/absl/container/fixed_array.h
index 9f1c813..95abb0a 100644
--- a/third_party/abseil-cpp/absl/container/fixed_array.h
+++ b/third_party/abseil-cpp/absl/container/fixed_array.h
@@ -41,6 +41,7 @@
 #include <type_traits>
 
 #include "absl/algorithm/algorithm.h"
+#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/dynamic_annotations.h"
 #include "absl/base/internal/throw_delegate.h"
@@ -74,7 +75,7 @@
 // `std::vector`.
 template <typename T, size_t N = kFixedArrayUseDefault,
           typename A = std::allocator<T>>
-class FixedArray {
+class ABSL_ATTRIBUTE_WARN_UNUSED FixedArray {
   static_assert(!std::is_array<T>::value || std::extent<T>::value > 0,
                 "Arrays with unknown bounds cannot be used with FixedArray.");
 
diff --git a/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc b/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc
index 1dba71a..c59f773 100644
--- a/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc
+++ b/third_party/abseil-cpp/absl/crc/internal/cpu_detect.cc
@@ -296,24 +296,12 @@
   size_t val_size = sizeof(T);
   int ret = sysctlbyname(name, &val, &val_size, nullptr, 0);
   if (ret == -1) {
-    return std::nullopt;
+    return absl::nullopt;
   }
   return val;
 }
 
 bool SupportsArmCRC32PMULL() {
-#if ABSL_HAVE_BUILTIN(__builtin_cpu_supports)
-  // Support for the AES and PMULL instructions are tied together:
-  // "When Cryptographic extensions are implemented and enabled then AESE, AESD,
-  // AESMC, and AESIMC instructions are implemented and also PMULL/PMULL2
-  // instructions operating on 64-bit data quantities."
-  //
-  // __builtin_cpu_supports expects users of PMULL to check for AES.
-  //
-  // https://developer.arm.com/documentation/101800/0201/AArch64-registers/AArch64-Identification-register-summary/ID-AA64ISAR0-EL1--AArch64-Instruction-Set-Attribute-Register-0
-  return __builtin_cpu_supports("crc+aes");
-#endif
-
   // Newer XNU kernels support querying all capabilities in a single
   // sysctlbyname.
 #if defined(CAP_BIT_CRC32) && defined(CAP_BIT_FEAT_PMULL)
diff --git a/third_party/abseil-cpp/absl/flags/BUILD.bazel b/third_party/abseil-cpp/absl/flags/BUILD.bazel
index 7730cfa..d9a30345 100644
--- a/third_party/abseil-cpp/absl/flags/BUILD.bazel
+++ b/third_party/abseil-cpp/absl/flags/BUILD.bazel
@@ -66,6 +66,7 @@
         ":path_util",
         "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/base:no_destructor",
         "//absl/strings",
         "//absl/synchronization",
     ],
@@ -87,6 +88,7 @@
         ":program_name",
         "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/base:no_destructor",
         "//absl/strings",
         "//absl/synchronization",
     ],
@@ -219,6 +221,7 @@
         "//absl/base:config",
         "//absl/base:core_headers",
         "//absl/base:dynamic_annotations",
+        "//absl/base:no_destructor",
         "//absl/memory",
         "//absl/meta:type_traits",
         "//absl/strings",
@@ -270,6 +273,7 @@
         ":reflection",
         "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/base:no_destructor",
         "//absl/strings",
         "//absl/synchronization",
     ],
@@ -318,6 +322,7 @@
         "//absl/algorithm:container",
         "//absl/base:config",
         "//absl/base:core_headers",
+        "//absl/base:no_destructor",
         "//absl/strings",
         "//absl/synchronization",
     ],
diff --git a/third_party/abseil-cpp/absl/flags/BUILD.gn b/third_party/abseil-cpp/absl/flags/BUILD.gn
index 34a104b..38b715e0 100644
--- a/third_party/abseil-cpp/absl/flags/BUILD.gn
+++ b/third_party/abseil-cpp/absl/flags/BUILD.gn
@@ -20,6 +20,7 @@
     ":path_util",
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
+    "//third_party/abseil-cpp/absl/base:no_destructor",
     "//third_party/abseil-cpp/absl/strings:string_view",
     "//third_party/abseil-cpp/absl/synchronization",
   ]
@@ -48,6 +49,7 @@
     ":program_name",
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
+    "//third_party/abseil-cpp/absl/base:no_destructor",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
     "//third_party/abseil-cpp/absl/synchronization",
@@ -140,6 +142,7 @@
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
     "//third_party/abseil-cpp/absl/base:dynamic_annotations",
+    "//third_party/abseil-cpp/absl/base:no_destructor",
     "//third_party/abseil-cpp/absl/memory",
     "//third_party/abseil-cpp/absl/meta:type_traits",
     "//third_party/abseil-cpp/absl/strings",
@@ -183,6 +186,7 @@
     ":reflection",
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
+    "//third_party/abseil-cpp/absl/base:no_destructor",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
     "//third_party/abseil-cpp/absl/synchronization",
@@ -223,6 +227,7 @@
     "//third_party/abseil-cpp/absl/algorithm:container",
     "//third_party/abseil-cpp/absl/base:config",
     "//third_party/abseil-cpp/absl/base:core_headers",
+    "//third_party/abseil-cpp/absl/base:no_destructor",
     "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
     "//third_party/abseil-cpp/absl/synchronization",
diff --git a/third_party/abseil-cpp/absl/flags/CMakeLists.txt b/third_party/abseil-cpp/absl/flags/CMakeLists.txt
index 7376d11..54304299 100644
--- a/third_party/abseil-cpp/absl/flags/CMakeLists.txt
+++ b/third_party/abseil-cpp/absl/flags/CMakeLists.txt
@@ -45,6 +45,7 @@
   DEPS
     absl::config
     absl::core_headers
+    absl::no_destructor
     absl::flags_path_util
     absl::strings
     absl::synchronization
@@ -68,6 +69,7 @@
     absl::flags_path_util
     absl::flags_program_name
     absl::core_headers
+    absl::no_destructor
     absl::strings
     absl::synchronization
 )
@@ -192,6 +194,7 @@
     absl::flags_commandlineflag_internal
     absl::flags_config
     absl::flags_marshalling
+    absl::no_destructor
     absl::synchronization
     absl::meta
     absl::utility
@@ -259,6 +262,7 @@
     absl::config
     absl::core_headers
     absl::flags_usage_internal
+    absl::no_destructor
     absl::raw_logging_internal
     absl::strings
     absl::synchronization
@@ -289,6 +293,7 @@
     absl::flags_program_name
     absl::flags_reflection
     absl::flags_usage
+    absl::no_destructor
     absl::strings
     absl::synchronization
 )
diff --git a/third_party/abseil-cpp/absl/flags/internal/flag.cc b/third_party/abseil-cpp/absl/flags/internal/flag.cc
index 981f19fd..0c50957 100644
--- a/third_party/abseil-cpp/absl/flags/internal/flag.cc
+++ b/third_party/abseil-cpp/absl/flags/internal/flag.cc
@@ -34,7 +34,9 @@
 #include "absl/base/config.h"
 #include "absl/base/const_init.h"
 #include "absl/base/dynamic_annotations.h"
+#include "absl/base/no_destructor.h"
 #include "absl/base/optimization.h"
+#include "absl/base/thread_annotations.h"
 #include "absl/flags/config.h"
 #include "absl/flags/internal/commandlineflag.h"
 #include "absl/flags/usage_config.h"
@@ -85,11 +87,15 @@
 // we move the memory to the freelist where it lives indefinitely, so it can
 // still be safely accessed. This also prevents leak checkers from complaining
 // about the leaked memory that can no longer be accessed through any pointer.
-ABSL_CONST_INIT absl::Mutex s_freelist_guard(absl::kConstInit);
-ABSL_CONST_INIT std::vector<void*>* s_freelist = nullptr;
+absl::Mutex* FreelistMutex() {
+  static absl::NoDestructor<absl::Mutex> mutex;
+  return mutex.get();
+}
+ABSL_CONST_INIT std::vector<void*>* s_freelist ABSL_GUARDED_BY(FreelistMutex())
+    ABSL_PT_GUARDED_BY(FreelistMutex()) = nullptr;
 
 void AddToFreelist(void* p) {
-  absl::MutexLock l(&s_freelist_guard);
+  absl::MutexLock l(FreelistMutex());
   if (!s_freelist) {
     s_freelist = new std::vector<void*>;
   }
@@ -101,7 +107,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 uint64_t NumLeakedFlagValues() {
-  absl::MutexLock l(&s_freelist_guard);
+  absl::MutexLock l(FreelistMutex());
   return s_freelist == nullptr ? 0u : s_freelist->size();
 }
 
diff --git a/third_party/abseil-cpp/absl/flags/internal/program_name.cc b/third_party/abseil-cpp/absl/flags/internal/program_name.cc
index 51d698d..fb06643 100644
--- a/third_party/abseil-cpp/absl/flags/internal/program_name.cc
+++ b/third_party/abseil-cpp/absl/flags/internal/program_name.cc
@@ -19,7 +19,7 @@
 
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
-#include "absl/base/const_init.h"
+#include "absl/base/no_destructor.h"
 #include "absl/base/thread_annotations.h"
 #include "absl/flags/internal/path_util.h"
 #include "absl/strings/string_view.h"
@@ -29,30 +29,31 @@
 ABSL_NAMESPACE_BEGIN
 namespace flags_internal {
 
-ABSL_CONST_INIT static absl::Mutex program_name_guard(absl::kConstInit);
-ABSL_CONST_INIT static std::string* program_name
-    ABSL_GUARDED_BY(program_name_guard) = nullptr;
+static absl::Mutex* ProgramNameMutex() {
+  static absl::NoDestructor<absl::Mutex> mutex;
+  return mutex.get();
+}
+ABSL_CONST_INIT static std::string* program_name ABSL_GUARDED_BY(
+    ProgramNameMutex()) ABSL_PT_GUARDED_BY(ProgramNameMutex()) = nullptr;
 
 std::string ProgramInvocationName() {
-  absl::MutexLock l(&program_name_guard);
-
+  absl::MutexLock l(ProgramNameMutex());
   return program_name ? *program_name : "UNKNOWN";
 }
 
 std::string ShortProgramInvocationName() {
-  absl::MutexLock l(&program_name_guard);
-
+  absl::MutexLock l(ProgramNameMutex());
   return program_name ? std::string(flags_internal::Basename(*program_name))
                       : "UNKNOWN";
 }
 
 void SetProgramInvocationName(absl::string_view prog_name_str) {
-  absl::MutexLock l(&program_name_guard);
-
-  if (!program_name)
+  absl::MutexLock l(ProgramNameMutex());
+  if (!program_name) {
     program_name = new std::string(prog_name_str);
-  else
+  } else {
     program_name->assign(prog_name_str.data(), prog_name_str.size());
+  }
 }
 
 }  // namespace flags_internal
diff --git a/third_party/abseil-cpp/absl/flags/internal/usage.cc b/third_party/abseil-cpp/absl/flags/internal/usage.cc
index 8b169bcd..fc68b03d 100644
--- a/third_party/abseil-cpp/absl/flags/internal/usage.cc
+++ b/third_party/abseil-cpp/absl/flags/internal/usage.cc
@@ -29,7 +29,7 @@
 
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
-#include "absl/base/const_init.h"
+#include "absl/base/no_destructor.h"
 #include "absl/base/thread_annotations.h"
 #include "absl/flags/commandlineflag.h"
 #include "absl/flags/flag.h"
@@ -434,45 +434,48 @@
 
 namespace {
 
-ABSL_CONST_INIT absl::Mutex help_attributes_guard(absl::kConstInit);
-ABSL_CONST_INIT std::string* match_substr
-    ABSL_GUARDED_BY(help_attributes_guard) = nullptr;
-ABSL_CONST_INIT HelpMode help_mode ABSL_GUARDED_BY(help_attributes_guard) =
+absl::Mutex* HelpAttributesMutex() {
+  static absl::NoDestructor<absl::Mutex> mutex;
+  return mutex.get();
+}
+ABSL_CONST_INIT std::string* match_substr ABSL_GUARDED_BY(HelpAttributesMutex())
+    ABSL_PT_GUARDED_BY(HelpAttributesMutex()) = nullptr;
+ABSL_CONST_INIT HelpMode help_mode ABSL_GUARDED_BY(HelpAttributesMutex()) =
     HelpMode::kNone;
-ABSL_CONST_INIT HelpFormat help_format ABSL_GUARDED_BY(help_attributes_guard) =
+ABSL_CONST_INIT HelpFormat help_format ABSL_GUARDED_BY(HelpAttributesMutex()) =
     HelpFormat::kHumanReadable;
 
 }  // namespace
 
 std::string GetFlagsHelpMatchSubstr() {
-  absl::MutexLock l(&help_attributes_guard);
+  absl::MutexLock l(HelpAttributesMutex());
   if (match_substr == nullptr) return "";
   return *match_substr;
 }
 
 void SetFlagsHelpMatchSubstr(absl::string_view substr) {
-  absl::MutexLock l(&help_attributes_guard);
+  absl::MutexLock l(HelpAttributesMutex());
   if (match_substr == nullptr) match_substr = new std::string;
   match_substr->assign(substr.data(), substr.size());
 }
 
 HelpMode GetFlagsHelpMode() {
-  absl::MutexLock l(&help_attributes_guard);
+  absl::MutexLock l(HelpAttributesMutex());
   return help_mode;
 }
 
 void SetFlagsHelpMode(HelpMode mode) {
-  absl::MutexLock l(&help_attributes_guard);
+  absl::MutexLock l(HelpAttributesMutex());
   help_mode = mode;
 }
 
 HelpFormat GetFlagsHelpFormat() {
-  absl::MutexLock l(&help_attributes_guard);
+  absl::MutexLock l(HelpAttributesMutex());
   return help_format;
 }
 
 void SetFlagsHelpFormat(HelpFormat format) {
-  absl::MutexLock l(&help_attributes_guard);
+  absl::MutexLock l(HelpAttributesMutex());
   help_format = format;
 }
 
diff --git a/third_party/abseil-cpp/absl/flags/parse.cc b/third_party/abseil-cpp/absl/flags/parse.cc
index 526b61d1..8be2016 100644
--- a/third_party/abseil-cpp/absl/flags/parse.cc
+++ b/third_party/abseil-cpp/absl/flags/parse.cc
@@ -35,7 +35,7 @@
 #include "absl/algorithm/container.h"
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
-#include "absl/base/const_init.h"
+#include "absl/base/no_destructor.h"
 #include "absl/base/thread_annotations.h"
 #include "absl/flags/commandlineflag.h"
 #include "absl/flags/config.h"
@@ -64,14 +64,17 @@
 namespace flags_internal {
 namespace {
 
-ABSL_CONST_INIT absl::Mutex processing_checks_guard(absl::kConstInit);
+absl::Mutex* ProcessingChecksMutex() {
+  static absl::NoDestructor<absl::Mutex> mutex;
+  return mutex.get();
+}
 
 ABSL_CONST_INIT bool flagfile_needs_processing
-    ABSL_GUARDED_BY(processing_checks_guard) = false;
+    ABSL_GUARDED_BY(ProcessingChecksMutex()) = false;
 ABSL_CONST_INIT bool fromenv_needs_processing
-    ABSL_GUARDED_BY(processing_checks_guard) = false;
+    ABSL_GUARDED_BY(ProcessingChecksMutex()) = false;
 ABSL_CONST_INIT bool tryfromenv_needs_processing
-    ABSL_GUARDED_BY(processing_checks_guard) = false;
+    ABSL_GUARDED_BY(ProcessingChecksMutex()) = false;
 
 ABSL_CONST_INIT absl::Mutex specified_flags_guard(absl::kConstInit);
 ABSL_CONST_INIT std::vector<const CommandLineFlag*>* specified_flags
@@ -106,7 +109,7 @@
     .OnUpdate([]() {
       if (absl::GetFlag(FLAGS_flagfile).empty()) return;
 
-      absl::MutexLock l(&absl::flags_internal::processing_checks_guard);
+      absl::MutexLock l(absl::flags_internal::ProcessingChecksMutex());
 
       // Setting this flag twice before it is handled most likely an internal
       // error and should be reviewed by developers.
@@ -122,7 +125,7 @@
     .OnUpdate([]() {
       if (absl::GetFlag(FLAGS_fromenv).empty()) return;
 
-      absl::MutexLock l(&absl::flags_internal::processing_checks_guard);
+      absl::MutexLock l(absl::flags_internal::ProcessingChecksMutex());
 
       // Setting this flag twice before it is handled most likely an internal
       // error and should be reviewed by developers.
@@ -138,7 +141,7 @@
     .OnUpdate([]() {
       if (absl::GetFlag(FLAGS_tryfromenv).empty()) return;
 
-      absl::MutexLock l(&absl::flags_internal::processing_checks_guard);
+      absl::MutexLock l(absl::flags_internal::ProcessingChecksMutex());
 
       // Setting this flag twice before it is handled most likely an internal
       // error and should be reviewed by developers.
@@ -415,7 +418,7 @@
                           std::vector<std::string>& flagfile_value) {
   bool success = true;
 
-  absl::MutexLock l(&flags_internal::processing_checks_guard);
+  absl::MutexLock l(flags_internal::ProcessingChecksMutex());
 
   // flagfile could have been set either on a command line or
   // programmatically before invoking ParseCommandLine. Note that we do not
@@ -478,7 +481,7 @@
   // going to be {"f1", "f2"}
   if (!flagfile_value.empty()) {
     absl::SetFlag(&FLAGS_flagfile, flagfile_value);
-    absl::MutexLock l(&flags_internal::processing_checks_guard);
+    absl::MutexLock l(flags_internal::ProcessingChecksMutex());
     flags_internal::flagfile_needs_processing = false;
   }
 
@@ -490,7 +493,7 @@
     absl::SetFlag(&FLAGS_tryfromenv, {});
   }
 
-  absl::MutexLock l(&flags_internal::processing_checks_guard);
+  absl::MutexLock l(flags_internal::ProcessingChecksMutex());
   flags_internal::fromenv_needs_processing = false;
   flags_internal::tryfromenv_needs_processing = false;
 }
diff --git a/third_party/abseil-cpp/absl/flags/usage_config.cc b/third_party/abseil-cpp/absl/flags/usage_config.cc
index 5d7426d..5922c5e 100644
--- a/third_party/abseil-cpp/absl/flags/usage_config.cc
+++ b/third_party/abseil-cpp/absl/flags/usage_config.cc
@@ -22,6 +22,7 @@
 #include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/const_init.h"
+#include "absl/base/no_destructor.h"
 #include "absl/base/thread_annotations.h"
 #include "absl/flags/internal/path_util.h"
 #include "absl/flags/internal/program_name.h"
@@ -104,14 +105,18 @@
 
 // --------------------------------------------------------------------
 
-ABSL_CONST_INIT absl::Mutex custom_usage_config_guard(absl::kConstInit);
+absl::Mutex* CustomUsageConfigMutex() {
+  static absl::NoDestructor<absl::Mutex> mutex;
+  return mutex.get();
+}
 ABSL_CONST_INIT FlagsUsageConfig* custom_usage_config
-    ABSL_GUARDED_BY(custom_usage_config_guard) = nullptr;
+    ABSL_GUARDED_BY(CustomUsageConfigMutex())
+        ABSL_PT_GUARDED_BY(CustomUsageConfigMutex()) = nullptr;
 
 }  // namespace
 
 FlagsUsageConfig GetUsageConfig() {
-  absl::MutexLock l(&custom_usage_config_guard);
+  absl::MutexLock l(CustomUsageConfigMutex());
 
   if (custom_usage_config) return *custom_usage_config;
 
@@ -136,7 +141,7 @@
 }  // namespace flags_internal
 
 void SetFlagsUsageConfig(FlagsUsageConfig usage_config) {
-  absl::MutexLock l(&flags_internal::custom_usage_config_guard);
+  absl::MutexLock l(flags_internal::CustomUsageConfigMutex());
 
   if (!usage_config.contains_helpshort_flags)
     usage_config.contains_helpshort_flags =
diff --git a/third_party/abseil-cpp/absl/strings/ascii.cc b/third_party/abseil-cpp/absl/strings/ascii.cc
index a38a612a..d15e424 100644
--- a/third_party/abseil-cpp/absl/strings/ascii.cc
+++ b/third_party/abseil-cpp/absl/strings/ascii.cc
@@ -19,10 +19,8 @@
 #include <cstring>
 #include <string>
 
-#include "absl/base/attributes.h"
 #include "absl/base/config.h"
 #include "absl/base/nullability.h"
-#include "absl/base/optimization.h"
 
 namespace absl {
 ABSL_NAMESPACE_BEGIN
@@ -177,11 +175,17 @@
   return static_cast<signed char>(u) < threshold;
 }
 
-// Force-inline so the compiler won't merge the short and long implementations.
-// `src` may be null iff `size` is zero.
 template <bool ToUpper>
-ABSL_ATTRIBUTE_ALWAYS_INLINE inline constexpr void AsciiStrCaseFoldImpl(
-    absl::Nonnull<char*> dst, absl::Nullable<const char*> src, size_t size) {
+constexpr bool AsciiInAZRangeNaive(unsigned char c) {
+  constexpr unsigned char a = (ToUpper ? 'a' : 'A');
+  constexpr unsigned char z = (ToUpper ? 'z' : 'Z');
+  return a <= c && c <= z;
+}
+
+template <bool ToUpper, bool Naive>
+constexpr void AsciiStrCaseFoldImpl(absl::Nonnull<char*> dst,
+                                    absl::Nullable<const char*> src,
+                                    size_t size) {
   // The upper- and lowercase versions of ASCII characters differ by only 1 bit.
   // When we need to flip the case, we can xor with this bit to achieve the
   // desired result. Note that the choice of 'a' and 'A' here is arbitrary. We
@@ -191,31 +195,26 @@
 
   for (size_t i = 0; i < size; ++i) {
     unsigned char v = static_cast<unsigned char>(src[i]);
-    v ^= AsciiInAZRange<ToUpper>(v) ? kAsciiCaseBitFlip : 0;
+    if ABSL_INTERNAL_CONSTEXPR_SINCE_CXX17 (Naive) {
+      v ^= AsciiInAZRangeNaive<ToUpper>(v) ? kAsciiCaseBitFlip : 0;
+    } else {
+      v ^= AsciiInAZRange<ToUpper>(v) ? kAsciiCaseBitFlip : 0;
+    }
     dst[i] = static_cast<char>(v);
   }
 }
 
-// The string size threshold for starting using the long string version.
-constexpr size_t kCaseFoldThreshold = 16;
-
-// No-inline so the compiler won't merge the short and long implementations.
-// `src` may be null iff `size` is zero.
-template <bool ToUpper>
-ABSL_ATTRIBUTE_NOINLINE constexpr void AsciiStrCaseFoldLong(
-    absl::Nonnull<char*> dst, absl::Nullable<const char*> src, size_t size) {
-  ABSL_ASSUME(size >= kCaseFoldThreshold);
-  AsciiStrCaseFoldImpl<ToUpper>(dst, src, size);
-}
-
 // Splitting to short and long strings to allow vectorization decisions
 // to be made separately in the long and short cases.
+// Using slightly different implementations so the compiler won't optimize them
+// into the same code (the non-naive version is needed for SIMD, so for short
+// strings it's not important).
 // `src` may be null iff `size` is zero.
 template <bool ToUpper>
 constexpr void AsciiStrCaseFold(absl::Nonnull<char*> dst,
                                 absl::Nullable<const char*> src, size_t size) {
-  size < kCaseFoldThreshold ? AsciiStrCaseFoldImpl<ToUpper>(dst, src, size)
-                            : AsciiStrCaseFoldLong<ToUpper>(dst, src, size);
+  size < 16 ? AsciiStrCaseFoldImpl<ToUpper, /*Naive=*/true>(dst, src, size)
+            : AsciiStrCaseFoldImpl<ToUpper, /*Naive=*/false>(dst, src, size);
 }
 
 void AsciiStrToLower(absl::Nonnull<char*> dst, absl::Nullable<const char*> src,
diff --git a/third_party/abseil-cpp/absl/strings/ascii_benchmark.cc b/third_party/abseil-cpp/absl/strings/ascii_benchmark.cc
index 0eff801a..e4d01962 100644
--- a/third_party/abseil-cpp/absl/strings/ascii_benchmark.cc
+++ b/third_party/abseil-cpp/absl/strings/ascii_benchmark.cc
@@ -102,7 +102,7 @@
 BENCHMARK_TEMPLATE(BM_Ascii, absl::ascii_toupper);
 
 static void BM_StrToLower(benchmark::State& state) {
-  const int size = state.range(0);
+  const size_t size = static_cast<size_t>(state.range(0));
   std::string s(size, 'X');
   for (auto _ : state) {
     benchmark::DoNotOptimize(s);
@@ -116,7 +116,7 @@
     ->Range(64, 1 << 26);
 
 static void BM_StrToUpper(benchmark::State& state) {
-  const int size = state.range(0);
+  const size_t size = static_cast<size_t>(state.range(0));
   std::string s(size, 'x');
   for (auto _ : state) {
     benchmark::DoNotOptimize(s);
diff --git a/third_party/abseil-cpp/symbols_arm64_dbg.def b/third_party/abseil-cpp/symbols_arm64_dbg.def
index 8d9a6ed..ec2da83 100644
--- a/third_party/abseil-cpp/symbols_arm64_dbg.def
+++ b/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -426,10 +426,14 @@
     ??$ArgumentToConv@_N@str_format_internal@absl@@YA?AW4FormatConversionCharSet@1@XZ
     ??$AsciiInAZRange@$00@ascii_internal@absl@@YA_NE@Z
     ??$AsciiInAZRange@$0A@@ascii_internal@absl@@YA_NE@Z
+    ??$AsciiInAZRangeNaive@$00@ascii_internal@absl@@YA_NE@Z
+    ??$AsciiInAZRangeNaive@$0A@@ascii_internal@absl@@YA_NE@Z
     ??$AsciiStrCaseFold@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
     ??$AsciiStrCaseFold@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
-    ??$AsciiStrCaseFoldLong@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
-    ??$AsciiStrCaseFoldLong@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
+    ??$AsciiStrCaseFoldImpl@$00$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
+    ??$AsciiStrCaseFoldImpl@$00$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
+    ??$AsciiStrCaseFoldImpl@$0A@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
+    ??$AsciiStrCaseFoldImpl@$0A@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
     ??$AssertHashEqConsistent@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@container_internal@absl@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ??$AssertOnFind@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@container_internal@absl@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ??$AssignElements@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@@inlined_vector_internal@absl@@YAXPEAUPayload@status_internal@1@AEAV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@01@_K@Z
diff --git a/third_party/abseil-cpp/symbols_arm64_rel.def b/third_party/abseil-cpp/symbols_arm64_rel.def
index 863dd0c8..7998a1e 100644
--- a/third_party/abseil-cpp/symbols_arm64_rel.def
+++ b/third_party/abseil-cpp/symbols_arm64_rel.def
@@ -34,8 +34,6 @@
     ??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
     ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z
     ??$AppendImpl@VCord@absl@@@Cord@absl@@AEAAX$$QEAV01@@Z
-    ??$AsciiStrCaseFoldLong@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
-    ??$AsciiStrCaseFoldLong@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
     ??$Base64EscapeInternal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@strings_internal@absl@@YAXPEBE_KPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_NPEBD@Z
     ??$CallOnceImpl@A6AXXZ$$V@base_internal@absl@@YAXPEAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@A6AXXZ@Z
     ??$CallOnceImpl@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@base_internal@absl@@YAXPEAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@$$QEAP8FlagImpl@flags_internal@1@EAAXXZ$$QEAPEAV671@@Z
diff --git a/third_party/abseil-cpp/symbols_x64_dbg.def b/third_party/abseil-cpp/symbols_x64_dbg.def
index 257a59a..3941b63 100644
--- a/third_party/abseil-cpp/symbols_x64_dbg.def
+++ b/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -426,10 +426,14 @@
     ??$ArgumentToConv@_N@str_format_internal@absl@@YA?AW4FormatConversionCharSet@1@XZ
     ??$AsciiInAZRange@$00@ascii_internal@absl@@YA_NE@Z
     ??$AsciiInAZRange@$0A@@ascii_internal@absl@@YA_NE@Z
+    ??$AsciiInAZRangeNaive@$00@ascii_internal@absl@@YA_NE@Z
+    ??$AsciiInAZRangeNaive@$0A@@ascii_internal@absl@@YA_NE@Z
     ??$AsciiStrCaseFold@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
     ??$AsciiStrCaseFold@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
-    ??$AsciiStrCaseFoldLong@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
-    ??$AsciiStrCaseFoldLong@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
+    ??$AsciiStrCaseFoldImpl@$00$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
+    ??$AsciiStrCaseFoldImpl@$00$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
+    ??$AsciiStrCaseFoldImpl@$0A@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
+    ??$AsciiStrCaseFoldImpl@$0A@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
     ??$AssertHashEqConsistent@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@container_internal@absl@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ??$AssertOnFind@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@container_internal@absl@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ??$AssignElements@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@@inlined_vector_internal@absl@@YAXPEAUPayload@status_internal@1@AEAV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@01@_K@Z
diff --git a/third_party/abseil-cpp/symbols_x64_rel.def b/third_party/abseil-cpp/symbols_x64_rel.def
index 1f4124c2..6ac29a6 100644
--- a/third_party/abseil-cpp/symbols_x64_rel.def
+++ b/third_party/abseil-cpp/symbols_x64_rel.def
@@ -34,8 +34,6 @@
     ??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
     ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z
     ??$AppendImpl@VCord@absl@@@Cord@absl@@AEAAX$$QEAV01@@Z
-    ??$AsciiStrCaseFoldLong@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
-    ??$AsciiStrCaseFoldLong@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
     ??$Base64EscapeInternal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@strings_internal@absl@@YAXPEBE_KPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_NPEBD@Z
     ??$CallOnceImpl@A6AXXZ$$V@base_internal@absl@@YAXPEAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@A6AXXZ@Z
     ??$CallOnceImpl@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@base_internal@absl@@YAXPEAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@$$QEAP8FlagImpl@flags_internal@1@EAAXXZ$$QEAPEAV671@@Z
diff --git a/third_party/abseil-cpp/symbols_x64_rel_asan.def b/third_party/abseil-cpp/symbols_x64_rel_asan.def
index 2a3c737..adf9091 100644
--- a/third_party/abseil-cpp/symbols_x64_rel_asan.def
+++ b/third_party/abseil-cpp/symbols_x64_rel_asan.def
@@ -37,8 +37,6 @@
     ??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QEAAX$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
     ??$AppendImpl@AEBVCord@absl@@@Cord@absl@@AEAAXAEBV01@@Z
     ??$AppendImpl@VCord@absl@@@Cord@absl@@AEAAX$$QEAV01@@Z
-    ??$AsciiStrCaseFoldLong@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
-    ??$AsciiStrCaseFoldLong@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
     ??$Base64EscapeInternal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@strings_internal@absl@@YAXPEBE_KPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_NPEBD@Z
     ??$CallOnceImpl@A6AXXZ$$V@base_internal@absl@@YAXPEAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@A6AXXZ@Z
     ??$CallOnceImpl@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@base_internal@absl@@YAXPEAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@$$QEAP8FlagImpl@flags_internal@1@EAAXXZ$$QEAPEAV671@@Z
diff --git a/third_party/abseil-cpp/symbols_x86_dbg.def b/third_party/abseil-cpp/symbols_x86_dbg.def
index cc24207..5a97e359 100644
--- a/third_party/abseil-cpp/symbols_x86_dbg.def
+++ b/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -426,10 +426,14 @@
     ??$ArgumentToConv@_N@str_format_internal@absl@@YA?AW4FormatConversionCharSet@1@XZ
     ??$AsciiInAZRange@$00@ascii_internal@absl@@YA_NE@Z
     ??$AsciiInAZRange@$0A@@ascii_internal@absl@@YA_NE@Z
+    ??$AsciiInAZRangeNaive@$00@ascii_internal@absl@@YA_NE@Z
+    ??$AsciiInAZRangeNaive@$0A@@ascii_internal@absl@@YA_NE@Z
     ??$AsciiStrCaseFold@$00@ascii_internal@absl@@YAXPADPBDI@Z
     ??$AsciiStrCaseFold@$0A@@ascii_internal@absl@@YAXPADPBDI@Z
-    ??$AsciiStrCaseFoldLong@$00@ascii_internal@absl@@YAXPADPBDI@Z
-    ??$AsciiStrCaseFoldLong@$0A@@ascii_internal@absl@@YAXPADPBDI@Z
+    ??$AsciiStrCaseFoldImpl@$00$00@ascii_internal@absl@@YAXPADPBDI@Z
+    ??$AsciiStrCaseFoldImpl@$00$0A@@ascii_internal@absl@@YAXPADPBDI@Z
+    ??$AsciiStrCaseFoldImpl@$0A@$00@ascii_internal@absl@@YAXPADPBDI@Z
+    ??$AsciiStrCaseFoldImpl@$0A@$0A@@ascii_internal@absl@@YAXPADPBDI@Z
     ??$AssertHashEqConsistent@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@container_internal@absl@@IAEXABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ??$AssertOnFind@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@?$raw_hash_set@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@container_internal@absl@@IAEXABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
     ??$AssignElements@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@@inlined_vector_internal@absl@@YAXPAUPayload@status_internal@1@AAV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PAUPayload@status_internal@absl@@@23@@01@I@Z
diff --git a/third_party/abseil-cpp/symbols_x86_rel.def b/third_party/abseil-cpp/symbols_x86_rel.def
index 890f647a..882ad030 100644
--- a/third_party/abseil-cpp/symbols_x86_rel.def
+++ b/third_party/abseil-cpp/symbols_x86_rel.def
@@ -34,8 +34,6 @@
     ??$Append@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@Cord@absl@@QAEX$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
     ??$AppendImpl@ABVCord@absl@@@Cord@absl@@AAEXABV01@@Z
     ??$AppendImpl@VCord@absl@@@Cord@absl@@AAEX$$QAV01@@Z
-    ??$AsciiStrCaseFoldLong@$00@ascii_internal@absl@@YAXPADPBDI@Z
-    ??$AsciiStrCaseFoldLong@$0A@@ascii_internal@absl@@YAXPADPBDI@Z
     ??$Base64EscapeInternal@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@strings_internal@absl@@YAXPBEIPAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@_NPBD@Z
     ??$CallOnceImpl@A6AXXZ$$V@base_internal@absl@@YAXPAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@A6AXXZ@Z
     ??$CallOnceImpl@P8FlagImpl@flags_internal@absl@@AEXXZPAV123@@base_internal@absl@@YAXPAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@$$QAP8FlagImpl@flags_internal@1@AEXXZ$$QAPAV671@@Z
diff --git a/third_party/blink/renderer/core/editing/finder/find_buffer.h b/third_party/blink/renderer/core/editing/finder/find_buffer.h
index aab69fa..382d73c 100644
--- a/third_party/blink/renderer/core/editing/finder/find_buffer.h
+++ b/third_party/blink/renderer/core/editing/finder/find_buffer.h
@@ -8,7 +8,6 @@
 #include <optional>
 
 #include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/display_lock/display_lock_context.h"
 #include "third_party/blink/renderer/core/editing/finder/find_options.h"
 #include "third_party/blink/renderer/core/editing/iterators/text_searcher_icu.h"
 #include "third_party/blink/renderer/core/editing/position.h"
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 df04ce6f..34bec03 100644
--- a/third_party/blink/renderer/modules/ai/ai_language_model.cc
+++ b/third_party/blink/renderer/modules/ai/ai_language_model.cc
@@ -10,6 +10,7 @@
 #include "third_party/blink/public/mojom/ai/ai_language_model.mojom-blink.h"
 #include "third_party/blink/public/mojom/ai/model_streaming_responder.mojom-blink.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/dom/abort_signal.h"
 #include "third_party/blink/renderer/core/dom/events/event.h"
 #include "third_party/blink/renderer/modules/ai/ai_language_model_factory.h"
 #include "third_party/blink/renderer/modules/ai/ai_metrics.h"
@@ -246,10 +247,7 @@
   }
 
   AbortSignal* signal = options->getSignalOr(nullptr);
-  if (signal && signal->aborted()) {
-    // TODO(crbug.com/374879796): figure out how to handling aborted signal for
-    // the streaming API.
-    ThrowAbortedException(exception_state);
+  if (HandleAbortSignal(signal, script_state, exception_state)) {
     return nullptr;
   }
 
diff --git a/third_party/blink/renderer/modules/ai/ai_rewriter.cc b/third_party/blink/renderer/modules/ai/ai_rewriter.cc
index 6882d00..fb89528 100644
--- a/third_party/blink/renderer/modules/ai/ai_rewriter.cc
+++ b/third_party/blink/renderer/modules/ai/ai_rewriter.cc
@@ -103,12 +103,10 @@
                              int(input.CharactersSizeInBytes()));
   CHECK(options);
   AbortSignal* signal = options->getSignalOr(nullptr);
-  if (signal && signal->aborted()) {
-    // TODO(crbug.com/374879796): figure out how to handling aborted signal for
-    // the streaming API.
-    ThrowAbortedException(exception_state);
+  if (HandleAbortSignal(signal, script_state, exception_state)) {
     return nullptr;
   }
+
   const String context_string = options->getContextOr(g_empty_string);
 
   if (!remote_) {
diff --git a/third_party/blink/renderer/modules/ai/ai_summarizer.cc b/third_party/blink/renderer/modules/ai/ai_summarizer.cc
index a55be78..6347cde0 100644
--- a/third_party/blink/renderer/modules/ai/ai_summarizer.cc
+++ b/third_party/blink/renderer/modules/ai/ai_summarizer.cc
@@ -108,12 +108,10 @@
   }
 
   AbortSignal* signal = options->getSignalOr(nullptr);
-  if (signal && signal->aborted()) {
-    // TODO(crbug.com/374879796): figure out how to handling aborted signal for
-    // the streaming API.
-    ThrowAbortedException(exception_state);
+  if (HandleAbortSignal(signal, script_state, exception_state)) {
     return nullptr;
   }
+
   auto [readable_stream, pending_remote] =
       CreateModelExecutionStreamingResponder(
           script_state, signal, task_runner_,
diff --git a/third_party/blink/renderer/modules/ai/ai_writer.cc b/third_party/blink/renderer/modules/ai/ai_writer.cc
index 881eb51..0b86159 100644
--- a/third_party/blink/renderer/modules/ai/ai_writer.cc
+++ b/third_party/blink/renderer/modules/ai/ai_writer.cc
@@ -99,12 +99,10 @@
                              int(input.CharactersSizeInBytes()));
   CHECK(options);
   AbortSignal* signal = options->getSignalOr(nullptr);
-  if (signal && signal->aborted()) {
-    // TODO(crbug.com/374879796): figure out how to handling aborted signal for
-    // the streaming API.
-    ThrowAbortedException(exception_state);
+  if (HandleAbortSignal(signal, script_state, exception_state)) {
     return nullptr;
   }
+
   const String context_string = options->getContextOr(g_empty_string);
 
   if (!remote_) {
diff --git a/third_party/blink/renderer/modules/ai/exception_helpers.cc b/third_party/blink/renderer/modules/ai/exception_helpers.cc
index babc12c..f0ae5d3 100644
--- a/third_party/blink/renderer/modules/ai/exception_helpers.cc
+++ b/third_party/blink/renderer/modules/ai/exception_helpers.cc
@@ -10,6 +10,8 @@
 #include "third_party/blink/public/mojom/ai/ai_manager.mojom-shared.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
 #include "third_party/blink/renderer/platform/bindings/exception_code.h"
+#include "third_party/blink/renderer/platform/bindings/exception_state.h"
+#include "third_party/blink/renderer/platform/bindings/script_state.h"
 
 namespace blink {
 
@@ -78,6 +80,23 @@
       DOMException::GetErrorName(DOMExceptionCode::kOperationError));
 }
 
+bool HandleAbortSignal(AbortSignal* signal,
+                       ScriptState* script_state,
+                       ExceptionState& exception_state) {
+  if (signal && signal->aborted()) {
+    auto reason = signal->reason(script_state);
+    if (reason.IsEmpty()) {
+      ThrowAbortedException(exception_state);
+    } else {
+      V8ThrowException::ThrowException(script_state->GetIsolate(),
+                                       reason.V8Value());
+    }
+    return true;
+  }
+
+  return false;
+}
+
 namespace {
 // Create an UnknownError exception, include `error` in the exception
 // message. This is intended for handling values of
diff --git a/third_party/blink/renderer/modules/ai/exception_helpers.h b/third_party/blink/renderer/modules/ai/exception_helpers.h
index c468591..2bf2013 100644
--- a/third_party/blink/renderer/modules/ai/exception_helpers.h
+++ b/third_party/blink/renderer/modules/ai/exception_helpers.h
@@ -8,6 +8,7 @@
 #include "third_party/blink/public/mojom/ai/ai_manager.mojom-blink-forward.h"
 #include "third_party/blink/public/mojom/ai/model_streaming_responder.mojom-blink-forward.h"
 #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
+#include "third_party/blink/renderer/core/dom/abort_signal.h"
 #include "third_party/blink/renderer/platform/bindings/exception_state.h"
 
 namespace blink {
@@ -37,6 +38,13 @@
 WTF::String ConvertModelAvailabilityCheckResultToDebugString(
     mojom::blink::ModelAvailabilityCheckResult result);
 
+// Throw the reason of the AbortSignal if it's aborted. If the reason is empty,
+// an AbortError will be thrown.
+// Returns if the signal is aborted.
+bool HandleAbortSignal(AbortSignal* signal,
+                       ScriptState* script_state,
+                       ExceptionState& exception_state);
+
 }  // namespace blink
 
 #endif  // THIRD_PARTY_BLINK_RENDERER_MODULES_AI_EXCEPTION_HELPERS_H_
diff --git a/third_party/blink/renderer/modules/ai/model_execution_responder.cc b/third_party/blink/renderer/modules/ai/model_execution_responder.cc
index 12d74f3..04791d7 100644
--- a/third_party/blink/renderer/modules/ai/model_execution_responder.cc
+++ b/third_party/blink/renderer/modules/ai/model_execution_responder.cc
@@ -290,11 +290,14 @@
 
  private:
   void OnAborted() {
-    // TODO(crbug.com/374879795): fix the abort handling for streaming
-    // responder.
-    Controller()->Error(DOMException::Create(
-        kExceptionMessageRequestAborted,
-        DOMException::GetErrorName(DOMExceptionCode::kAbortError)));
+    auto reason = abort_signal_->reason(script_state_);
+    if (reason.IsEmpty()) {
+      Controller()->Error(DOMException::Create(
+          kExceptionMessageRequestAborted,
+          DOMException::GetErrorName(DOMExceptionCode::kAbortError)));
+    } else {
+      Controller()->Error(reason.V8Value());
+    }
     Cleanup();
   }
 
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index b6a6f77..3a9c8f2 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -9062,10 +9062,6 @@
 # Gardener 2025-01-10
 crbug.com/389012014 [ Mac13 ] fast/peerconnection/RTCRtpSender-getParameters.html [ Pass Timeout ]
 
-# TODO(crrev.com/c/6172391): Re-enable after landing CL.
-crbug.com/40659523 http/tests/devtools/profiler/heap-snapshot-orphan-nodes.js [ Failure Skip ]
-crbug.com/40659523 http/tests/devtools/profiler/heap-snapshot-statistics.js [ Failure Skip ]
-
 # Flaky performance API tests
 crbug.com/387096438 virtual/scalefactor200/external/wpt/largest-contentful-paint/animated/observe-video.tentative.html [ Failure Pass ]
 crbug.com/385337582 external/wpt/paint-timing/fcp-only/fcp-document-opacity-image.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/request-abort-ordering.any.js b/third_party/blink/web_tests/external/wpt/IndexedDB/request-abort-ordering.any.js
new file mode 100644
index 0000000..e050d32
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/request-abort-ordering.any.js
@@ -0,0 +1,85 @@
+// META: title=IndexedDB: request abort events are delivered in order
+// META: global=window,worker
+// META: script=resources/support-promises.js
+// META: script=resources/support.js
+
+// Spec: https://w3c.github.io/IndexedDB/#abort-transaction
+
+'use strict';
+
+promise_test(testCase => {
+  let requests;
+
+  return createDatabase(
+             testCase,
+             (database, transaction) => {
+               createBooksStore(testCase, database);
+             })
+      .then(database => {
+        const transaction = database.transaction(['books'], 'readwrite');
+        const store = transaction.objectStore('books');
+        const index = store.index('by_author');
+        const cursorRequest = store.openCursor(IDBKeyRange.lowerBound(0));
+
+        return new Promise((resolve, reject) => {
+          cursorRequest.onerror = testCase.step_func(event => {
+            event.preventDefault();
+            reject(cursorRequest.error);
+          });
+
+          cursorRequest.onsuccess = testCase.step_func(() => {
+            const cursor = cursorRequest.result;
+            requests = [
+              () => store.get(123456),
+              () => index.get('Fred'),
+              () => store.count(),
+              () => index.count(),
+              () =>
+                  store.put({title: 'Bedrock II', author: 'Barney', isbn: 987}),
+              () => store.getAll(),
+              () => index.getAll(),
+              () => store.get(999999),
+              () => index.get('Nobody'),
+              () => store.openCursor(IDBKeyRange.lowerBound(0)),
+              () => index.openCursor(IDBKeyRange.lowerBound('')),
+              () => {
+                cursor.continue();
+                return cursorRequest;
+              },
+            ];
+
+            const results = [];
+            const promises = [];
+            for (let i = 0; i < requests.length; ++i) {
+              promises.push(new Promise((resolve, reject) => {
+                const requestId = i;
+                const request = requests[i](store);
+                request.onsuccess = testCase.step_func(() => {
+                  reject(new Error(
+                      'IDB requests should not succeed after transaction abort'));
+                });
+                request.onerror = testCase.step_func(event => {
+                  event.preventDefault();
+                  results.push([requestId, request.error]);
+                  resolve();
+                });
+              }));
+            };
+            transaction.abort();
+            resolve(Promise.all(promises).then(() => results));
+          });
+        });
+      })
+      .then(results => {
+        assert_equals(
+            results.length, requests.length,
+            'Promise.all should resolve after all sub-promises resolve');
+        for (let i = 0; i < requests.length; ++i) {
+          assert_equals(
+              results[i][0], i, 'error event order should match request order');
+          assert_equals(
+              results[i][1].name, 'AbortError',
+              'transaction aborting should result in AbortError on all requests');
+        }
+      });
+});
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/request-abort-ordering.html b/third_party/blink/web_tests/external/wpt/IndexedDB/request-abort-ordering.html
deleted file mode 100644
index 4374d8d..0000000
--- a/third_party/blink/web_tests/external/wpt/IndexedDB/request-abort-ordering.html
+++ /dev/null
@@ -1,83 +0,0 @@
-<!doctype html>
-<meta charset="utf8">
-<meta name="timeout" content="long">
-<title>IndexedDB: request abort events are delivered in order</title>
-<link rel="help" href="https://w3c.github.io/IndexedDB/#abort-transaction">
-<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="resources/support-promises.js"></script>
-<script>
-'use strict';
-
-promise_test(testCase => {
-  let requests;
-
-  return createDatabase(testCase, (database, transaction) => {
-    createBooksStore(testCase, database);
-  }).then(database => {
-    const transaction = database.transaction(['books'], 'readwrite');
-    const store = transaction.objectStore('books');
-    const index = store.index('by_author');
-    const cursorRequest = store.openCursor(IDBKeyRange.lowerBound(0));
-
-    return new Promise((resolve, reject) => {
-      cursorRequest.onerror = testCase.step_func(event => {
-        event.preventDefault();
-        reject(cursorRequest.error);
-      });
-
-      cursorRequest.onsuccess = testCase.step_func(() => {
-        const cursor = cursorRequest.result;
-        requests = [
-          () => store.get(123456),
-          () => index.get('Fred'),
-          () => store.count(),
-          () => index.count(),
-          () => store.put({title: 'Bedrock II', author: 'Barney', isbn: 987 }),
-          () => store.getAll(),
-          () => index.getAll(),
-          () => store.get(999999),
-          () => index.get('Nobody'),
-          () => store.openCursor(IDBKeyRange.lowerBound(0)),
-          () => index.openCursor(IDBKeyRange.lowerBound('')),
-          () => { cursor.continue(); return cursorRequest; },
-        ];
-
-        const results = [];
-        const promises = [];
-        for (let i = 0; i < requests.length; ++i) {
-          promises.push(new Promise((resolve, reject) => {
-            const requestId = i;
-            const request = requests[i](store);
-            request.onsuccess = testCase.step_func(() => {
-              reject(new Error(
-                  'IDB requests should not succeed after transaction abort'));
-            });
-            request.onerror = testCase.step_func(event => {
-              event.preventDefault();
-              results.push([requestId, request.error]);
-              resolve();
-            });
-          }));
-        };
-        transaction.abort();
-        resolve(Promise.all(promises).then(() => results));
-      });
-    });
-  }).then(results => {
-    assert_equals(
-        results.length, requests.length,
-        'Promise.all should resolve after all sub-promises resolve');
-    for (let i = 0; i < requests.length; ++i) {
-      assert_equals(
-          results[i][0], i,
-          'error event order should match request order');
-      assert_equals(
-          results[i][1].name, 'AbortError',
-          'transaction aborting should result in AbortError on all requests');
-    }
-  });
-});
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/request-event-ordering.html b/third_party/blink/web_tests/external/wpt/IndexedDB/request-event-ordering.any.js
similarity index 74%
rename from third_party/blink/web_tests/external/wpt/IndexedDB/request-event-ordering.html
rename to third_party/blink/web_tests/external/wpt/IndexedDB/request-event-ordering.any.js
index 71eda0d..89c45091 100644
--- a/third_party/blink/web_tests/external/wpt/IndexedDB/request-event-ordering.html
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/request-event-ordering.any.js
@@ -1,13 +1,11 @@
-<!doctype html>
-<meta charset="utf8">
-<meta name="timeout" content="long">
-<title>IndexedDB: request result events are delivered in order</title>
-<link rel="help" href="https://w3c.github.io/IndexedDB/#abort-transaction">
-<link rel="author" href="pwnall@chromium.org" title="Victor Costan">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="resources/support-promises.js"></script>
-<script>
+// META: title=IndexedDB: request result events are delivered in order
+// META: global=window,worker
+// META: script=resources/support-promises.js
+// META: script=resources/support.js
+// META: timeout=long
+
+// Spec: https://w3c.github.io/IndexedDB/#abort-transaction
+
 'use strict';
 
 // Should be large enough to trigger large value handling in the IndexedDB
@@ -15,10 +13,10 @@
 const wrapThreshold = 128 * 1024;
 
 function populateStore(store) {
-  store.put({id: 1, key: 'k1', value: largeValue(wrapThreshold, 1) });
-  store.put({id: 2, key: 'k2', value: ['small-2'] });
-  store.put({id: 3, key: 'k3', value: largeValue(wrapThreshold, 3) });
-  store.put({id: 4, key: 'k4', value: ['small-4'] });
+  store.put({id: 1, key: 'k1', value: largeValue(wrapThreshold, 1)});
+  store.put({id: 2, key: 'k2', value: ['small-2']});
+  store.put({id: 3, key: 'k3', value: largeValue(wrapThreshold, 3)});
+  store.put({id: 4, key: 'k4', value: ['small-4']});
 }
 
 // Assigns cursor indexes for operations that require open cursors.
@@ -41,8 +39,8 @@
     let request;
     switch (opcode) {
       case 'continue':
-        request = index.openCursor(
-            IDBKeyRange.lowerBound(`k${primaryKey - 1}`));
+        request =
+            index.openCursor(IDBKeyRange.lowerBound(`k${primaryKey - 1}`));
         break;
       case 'continue-empty':
         // k4 is the last key in the data set, so calling continue() will get
@@ -77,19 +75,21 @@
     let request;
     switch (opcode) {
       case 'add':  // Tests returning a primary key.
-        request = store.add(
-            { key: `k${primaryKey}`, value: [`small-${primaryKey}`] });
+        request =
+            store.add({key: `k${primaryKey}`, value: [`small-${primaryKey}`]});
         break;
       case 'put':  // Tests returning a primary key.
-        request = store.put(
-            { key: `k${primaryKey}`, value: [`small-${primaryKey}`] });
+        request =
+            store.put({key: `k${primaryKey}`, value: [`small-${primaryKey}`]});
         break;
       case 'put-with-id':  // Tests returning success or a primary key.
-        request = store.put(
-            { key: `k${primaryKey}`, value: [`small-${primaryKey}`],
-              id: primaryKey });
+        request = store.put({
+          key: `k${primaryKey}`,
+          value: [`small-${primaryKey}`],
+          id: primaryKey
+        });
         break;
-      case 'get':  // Tests returning a value.
+      case 'get':        // Tests returning a value.
       case 'get-empty':  // Tests returning undefined.
         request = store.get(primaryKey);
         break;
@@ -97,8 +97,8 @@
         request = store.getAll();
         break;
       case 'error':  // Tests returning an error.
-        request = store.put(
-            { key: `k${primaryKey}`, value: [`small-${primaryKey}`] });
+        request =
+            store.put({key: `k${primaryKey}`, value: [`small-${primaryKey}`]});
         request.onerror = testCase.step_func(event => {
           event.preventDefault();
           results.push([requestId, request.error]);
@@ -173,7 +173,8 @@
   const primaryKey = operation[1];
 
   const expectedValue = (primaryKey == 1 || primaryKey == 3) ?
-      largeValue(wrapThreshold, primaryKey) : [`small-${primaryKey}`];
+      largeValue(wrapThreshold, primaryKey) :
+      [`small-${primaryKey}`];
 
   const requestIndex = result[0];
   assert_equals(
@@ -211,7 +212,8 @@
             `get result ${i + 1} should match put value (key)`);
 
         const expectedValue = (i == 0 || i == 2) ?
-            largeValue(wrapThreshold, i + 1) : [`small-${i + 1}`];
+            largeValue(wrapThreshold, i + 1) :
+            [`small-${i + 1}`];
         assert_equals(
             object.value.join(','), object.value.join(','),
             `get result ${i + 1} should match put value (nested value)`);
@@ -253,56 +255,48 @@
 
 function eventsTest(label, operations) {
   promise_test(testCase => {
-    return createDatabase(testCase, (database, transaction) => {
-      const store = database.createObjectStore(
-          'test-store', { autoIncrement: true, keyPath: 'id' });
-      store.createIndex('test-index', 'key', { unique: true });
-      populateStore(store);
-    }).then(database => {
-      const transaction = database.transaction(['test-store'], 'readwrite');
-      const store = transaction.objectStore('test-store');
-      const index = store.index('test-index');
-      return new Promise((resolve, reject) => {
-        openCursors(testCase, index, operations, reject, () => {
-          const results = [];
-          const promises = [];
-          for (let i = 0; i < operations.length; ++i) {
-            const promise = doOperation(
-                testCase, store, index, operations[i], i, results);
-            promises.push(promise);
-          };
-          resolve(Promise.all(promises).then(() => results));
+    return createDatabase(
+               testCase,
+               (database, transaction) => {
+                 const store = database.createObjectStore(
+                     'test-store', {autoIncrement: true, keyPath: 'id'});
+                 store.createIndex('test-index', 'key', {unique: true});
+                 populateStore(store);
+               })
+        .then(database => {
+          const transaction = database.transaction(['test-store'], 'readwrite');
+          const store = transaction.objectStore('test-store');
+          const index = store.index('test-index');
+          return new Promise((resolve, reject) => {
+            openCursors(testCase, index, operations, reject, () => {
+              const results = [];
+              const promises = [];
+              for (let i = 0; i < operations.length; ++i) {
+                const promise = doOperation(
+                    testCase, store, index, operations[i], i, results);
+                promises.push(promise);
+              };
+              resolve(Promise.all(promises).then(() => results));
+            });
+          });
+        })
+        .then(results => {
+          assert_equals(
+              results.length, operations.length,
+              'Promise.all should resolve after all sub-promises resolve');
+          for (let i = 0; i < operations.length; ++i)
+            checkOperationResult(operations[i], results[i], i);
         });
-      });
-    }).then(results => {
-      assert_equals(
-          results.length, operations.length,
-          'Promise.all should resolve after all sub-promises resolve');
-      for (let i = 0; i < operations.length; ++i)
-        checkOperationResult(operations[i], results[i], i);
-    });
   }, label);
 }
 
 eventsTest('small values', [
-  ['get', 2],
-  ['count', 4],
-  ['continue-empty', null],
-  ['get-empty', 5],
-  ['add', 5],
-  ['open', 2],
-  ['continue', 2],
-  ['get', 4],
-  ['get-empty', 6],
-  ['count', 5],
-  ['put-with-id', 5],
-  ['put', 6],
-  ['error', 3],
-  ['continue', 4],
-  ['count', 6],
-  ['get-empty', 7],
-  ['open', 4],
-  ['open-empty', 7],
+  ['get', 2],       ['count', 4],       ['continue-empty', null],
+  ['get-empty', 5], ['add', 5],         ['open', 2],
+  ['continue', 2],  ['get', 4],         ['get-empty', 6],
+  ['count', 5],     ['put-with-id', 5], ['put', 6],
+  ['error', 3],     ['continue', 4],    ['count', 6],
+  ['get-empty', 7], ['open', 4],        ['open-empty', 7],
   ['add', 7],
 ]);
 
@@ -365,5 +359,3 @@
   ['error', 3],
   ['count', 7],
 ]);
-
-</script>
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/request_bubble-and-capture.any.js b/third_party/blink/web_tests/external/wpt/IndexedDB/request_bubble-and-capture.any.js
new file mode 100644
index 0000000..c80d7f5f
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/IndexedDB/request_bubble-and-capture.any.js
@@ -0,0 +1,70 @@
+// META: title=Bubbling and capturing of request events
+// META: global=window,worker
+// META: script=resources/support-promises.js
+// META: script=resources/support.js
+
+'use strict';
+
+async_test(t => {
+  let events = [];
+
+  let open_rq = createdb(t);
+  open_rq.onupgradeneeded =
+      function(e) {
+    let db = e.target.result;
+    let txn = e.target.transaction;
+    let store = db.createObjectStore('s');
+    let rq1 = store.add('', 1);
+    let rq2 = store.add('', 1);
+    db.onerror = function() {};
+
+    log_request(' db', db);
+    log_request('txn', txn);
+    log_request('rq1', rq1);
+    log_request('rq2', rq2);
+
+    // Don't let it get to abort
+    db.addEventListener('error', function(e) {
+      e.preventDefault()
+    }, false);
+  }
+
+      open_rq.onsuccess =
+          function(e) {
+    log('open_rq.success')(e);
+    assert_array_equals(
+        events,
+        [
+          'capture  db.success', 'capture txn.success', 'capture rq1.success',
+          'bubble  rq1.success',
+
+          'capture  db.error: ConstraintError',
+          'capture txn.error: ConstraintError',
+          'capture rq2.error: ConstraintError',
+          'bubble  rq2.error: ConstraintError',
+          'bubble  txn.error: ConstraintError',
+          'bubble   db.error: ConstraintError',
+
+          'open_rq.success'
+        ],
+        'events');
+    t.done();
+  }
+
+
+  function log_request(type, obj) {
+    obj.addEventListener('success', log('capture ' + type + '.success'), true);
+    obj.addEventListener('success', log('bubble  ' + type + '.success'), false);
+    obj.addEventListener('error', log('capture ' + type + '.error'), true);
+    obj.addEventListener('error', log('bubble  ' + type + '.error'), false);
+  }
+
+  function log(msg) {
+    return function(e) {
+      if (e && e.target && e.target.error)
+        events.push(msg + ': ' + e.target.error.name);
+      else
+        events.push(msg);
+    };
+  }
+}, 'IndexedDB Request Event Propagation: Bubbling and Capturing');
diff --git a/third_party/blink/web_tests/external/wpt/IndexedDB/request_bubble-and-capture.htm b/third_party/blink/web_tests/external/wpt/IndexedDB/request_bubble-and-capture.htm
deleted file mode 100644
index 8238e2c9..0000000
--- a/third_party/blink/web_tests/external/wpt/IndexedDB/request_bubble-and-capture.htm
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<title>Bubbling and capturing of request events</title>
-<link rel="author" href="mailto:odinho@opera.com" title="Odin Hørthe Omdal">
-<script src=/resources/testharness.js></script>
-<script src=/resources/testharnessreport.js></script>
-<script src=resources/support.js></script>
-
-<script>
-    var events = [];
-
-    var open_rq = createdb(async_test());
-    open_rq.onupgradeneeded = function(e) {
-        var db = e.target.result;
-        var txn = e.target.transaction;
-        var store = db.createObjectStore("s");
-        var rq1 = store.add("", 1);
-        var rq2 = store.add("", 1);
-        db.onerror = function(){};
-
-        log_request(' db',  db);
-        log_request('txn', txn);
-        log_request('rq1', rq1);
-        log_request('rq2', rq2);
-
-        // Don't let it get to abort
-        db.addEventListener('error', function(e) { e.preventDefault() }, false);
-    }
-
-    open_rq.onsuccess = function(e) {
-        log("open_rq.success")(e);
-        assert_array_equals(events, [
-                                      "capture  db.success",
-                                      "capture txn.success",
-                                      "capture rq1.success",
-                                      "bubble  rq1.success",
-
-                                      "capture  db.error: ConstraintError",
-                                      "capture txn.error: ConstraintError",
-                                      "capture rq2.error: ConstraintError",
-                                      "bubble  rq2.error: ConstraintError",
-                                      "bubble  txn.error: ConstraintError",
-                                      "bubble   db.error: ConstraintError",
-
-                                      "open_rq.success"
-                                     ],
-                            "events");
-        this.done();
-    }
-
-
-    function log_request(type, obj) {
-        obj.addEventListener('success', log('capture ' + type + '.success'), true);
-        obj.addEventListener('success', log('bubble  ' + type + '.success'), false);
-        obj.addEventListener('error', log('capture ' + type + '.error'), true);
-        obj.addEventListener('error', log('bubble  ' + type + '.error'), false);
-    }
-
-    function log(msg) {
-        return function(e) {
-            if(e && e.target && e.target.error)
-                events.push(msg + ": " + e.target.error.name);
-            else
-                events.push(msg);
-        };
-    }
-</script>
-
-<div id=log></div>
diff --git a/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-orphan-nodes.js b/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-orphan-nodes.js
index e1f7640..377dcd11 100644
--- a/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-orphan-nodes.js
+++ b/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-orphan-nodes.js
@@ -56,7 +56,7 @@
     async function checkStatistics(arg, result) {
       var statistics = await result;
       TestRunner.assertEquals(4610, statistics.total);
-      TestRunner.assertEquals(4610, statistics.v8heap);
+      TestRunner.assertEquals(4610, statistics.v8heap.total);
       TestRunner.addResult('SUCCESS: total size is correct.');
     }
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-statistics-expected.txt b/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-statistics-expected.txt
index 2673e5d48..8850ea7 100644
--- a/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-statistics-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-statistics-expected.txt
@@ -13,7 +13,20 @@
 regexp node size: 7000000
 native node size: 80000000
 bigint node size: 900000000
-{"total":1887654341,"v8heap":1807654341,"native":80000000,"code":50000,"jsArrays":20,"strings":300,"system":900000000}
+{
+  "total": 1887654341,
+  "native": {
+    "total": 80000000,
+    "typedArrays": 0
+  },
+  "v8heap": {
+    "total": 1807654341,
+    "code": 50000,
+    "jsArrays": 20,
+    "strings": 300,
+    "system": 1
+  }
+}
 
 Profiler was disabled.
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-statistics.js b/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-statistics.js
index 0ff39e9b..9990adf 100644
--- a/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-statistics.js
+++ b/third_party/blink/web_tests/http/tests/devtools/profiler/heap-snapshot-statistics.js
@@ -50,7 +50,7 @@
 
     async function step1(arg, result) {
       var statistics = await result;
-      TestRunner.addResult(JSON.stringify(statistics));
+      TestRunner.addResult(JSON.stringify(statistics, null, '  '));
       setTimeout(next, 0);
     }
   }]);
diff --git a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-abort.https.any.js b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-abort.https.any.js
index 7b7a261..09812b6 100644
--- a/third_party/blink/web_tests/wpt_internal/ai/language-model-api-abort.https.any.js
+++ b/third_party/blink/web_tests/wpt_internal/ai/language-model-api-abort.https.any.js
@@ -1,27 +1,34 @@
 // META: script=resources/utils.js
 // META: script=resources/workaround-for-382640509.js
-
-promise_test(async (t) => {
-  testAbort(t, (signal) => {
+promise_test(async t => {
+  await testAbortPromise(t, signal => {
     return ai.languageModel.create({
       signal: signal
     });
   });
 }, "Aborting AILanguageModelFactory.create().");
 
-promise_test(async (t) => {
+promise_test(async t => {
   const session = await ai.languageModel.create();
-  testAbort(t, (signal) => {
+  await testAbortPromise(t, signal => {
     return session.clone({
       signal: signal
     });
   });
 }, "Aborting AILanguageModel.clone().");
 
-promise_test(async (t) => {
+promise_test(async t => {
   const session = await ai.languageModel.create();
-  testAbort(t, (signal) => {
+  await testAbortPromise(t, signal => {
     return session.prompt(kTestPrompt, { signal: signal });
   });
 }, "Aborting AILanguageModel.prompt().");
 
+promise_test(async t => {
+  const session = await ai.languageModel.create();
+  await testAbortReadableStream(t, signal => {
+    return session.promptStreaming(
+      kTestPrompt, { signal: signal }
+    );
+  });
+}, "Aborting AILanguageModel.promptStreaming().");
diff --git a/third_party/blink/web_tests/wpt_internal/ai/resources/utils.js b/third_party/blink/web_tests/wpt_internal/ai/resources/utils.js
index c7ef865..5b25f2a 100644
--- a/third_party/blink/web_tests/wpt_internal/ai/resources/utils.js
+++ b/third_party/blink/web_tests/wpt_internal/ai/resources/utils.js
@@ -2,7 +2,7 @@
 
 const testSession = async (session) => {
   if (typeof session.topK !== 'number') {
-    return {success: false, error: 'session topK property is not properly set'};
+    return { success: false, error: 'session topK property is not properly set' };
   }
 
   if (typeof session.temperature !== 'number') {
@@ -13,8 +13,8 @@
   }
 
   if (typeof session.maxTokens !== 'number' ||
-      typeof session.tokensSoFar !== 'number' ||
-      typeof session.tokensLeft !== 'number') {
+    typeof session.tokensSoFar !== 'number' ||
+    typeof session.tokensLeft !== 'number') {
     return {
       success: false,
       error: 'session token properties is not properly set'
@@ -25,7 +25,7 @@
     return {
       success: false,
       error:
-          'the sum of tokensLeft and tokensSoFar should be equal to maxTokens'
+        'the sum of tokensLeft and tokensSoFar should be equal to maxTokens'
     };
   }
 
@@ -44,7 +44,7 @@
     return {
       success: false,
       error:
-          'the sum of tokensLeft and tokensSoFar should be equal to maxTokens'
+        'the sum of tokensLeft and tokensSoFar should be equal to maxTokens'
     };
   }
 
@@ -128,7 +128,7 @@
 };
 
 // The method should take the AbortSignal as an option and return a promise.
-const testAbort = async (t, method) => {
+const testAbortPromise = async (t, method) => {
   // Test abort signal without custom error.
   {
     const controller = new AbortController();
@@ -153,7 +153,44 @@
     const anotherPromise = method(controller.signal);
     await promise_rejects_exactly(t, err, anotherPromise);
   }
-}
+};
+
+// The method should take the AbortSignal as an option and return a ReadableStream.
+const testAbortReadableStream = async (t, method) => {
+  // Test abort signal without custom error.
+  {
+    const controller = new AbortController();
+    const stream = method(controller.signal);
+    controller.abort();
+    let writableStream = new WritableStream();
+    await promise_rejects_dom(
+      t, "AbortError", stream.pipeTo(writableStream)
+    );
+
+    // Using the same aborted controller will get the `AbortError` as well.
+    await promise_rejects_dom(
+      t, "AbortError", new Promise(() => { method(controller.signal); })
+    );
+  }
+
+  // Test abort signal with custom error.
+  {
+    const error = new DOMException("test", "VersionError");
+    const controller = new AbortController();
+    const stream = method(controller.signal);
+    controller.abort(error);
+    let writableStream = new WritableStream();
+    await promise_rejects_exactly(
+      t, error,
+      stream.pipeTo(writableStream)
+    );
+
+    // Using the same aborted controller will get the same error.
+    await promise_rejects_exactly(
+      t, error, new Promise(() => { method(controller.signal); })
+    );
+  }
+};
 
 const getPromptExceedingAvailableTokens = async session => {
   const maxTokens = session.tokensLeft;
@@ -174,4 +211,4 @@
   }
   // Construct the prompt input.
   return getPrompt(left);
-}
+};
diff --git a/third_party/blink/web_tests/wpt_internal/ai/rewriter-api-abort.https.any.js b/third_party/blink/web_tests/wpt_internal/ai/rewriter-api-abort.https.any.js
index c7b71a59..01fa8e2 100644
--- a/third_party/blink/web_tests/wpt_internal/ai/rewriter-api-abort.https.any.js
+++ b/third_party/blink/web_tests/wpt_internal/ai/rewriter-api-abort.https.any.js
@@ -1,38 +1,25 @@
 // META: script=resources/utils.js
 
-promise_test(async (t) => {
-  testAbort(t, (signal) => {
+promise_test(async t => {
+  await testAbortPromise(t, signal => {
     return ai.rewriter.create({
       signal: signal
     });
   });
-}, 'Aborting AIRewriter.create().');
+}, "Aborting AIRewriter.create().");
 
-promise_test(async (t) => {
-  const rewriter = await ai.rewriter.create();
-  testAbort(t, (signal) => {
-    return rewriter.rewrite(
-      "Rewrite a poem",
-      { signal: signal }
+promise_test(async t => {
+  const session = await ai.rewriter.create();
+  await testAbortPromise(t, signal => {
+    return session.rewrite(kTestPrompt, { signal: signal });
+  });
+}, "Aborting AIRewriter.rewrite().");
+
+promise_test(async t => {
+  const session = await ai.rewriter.create();
+  await testAbortReadableStream(t, signal => {
+    return session.rewriteStreaming(
+      kTestPrompt, { signal: signal }
     );
   });
-}, 'Aborting AIRwriter.rewrite().');
-
-promise_test(async (t) => {
-  const rewriter = await ai.rewriter.create();
-  const controller = new AbortController();
-  const streamingResponse =
-    rewriter.rewriteStreaming('hello', { signal: controller.signal });
-  controller.abort();
-  const reader = streamingResponse.getReader();
-  await promise_rejects_dom(t, 'AbortError', reader.read());
-}, 'Aborting AIRewriter.rewriteStreaming()');
-
-promise_test(async (t) => {
-  const rewriter = await ai.rewriter.create();
-  const controller = new AbortController();
-  controller.abort();
-  assert_throws_dom(
-    'AbortError',
-    () => rewriter.rewriteStreaming('hello', { signal: controller.signal }));
-}, 'AIRewriter.rewriteStreaming() call with an aborted signal.');
+}, "Aborting AIRewriter.rewriteStreaming().");
diff --git a/third_party/blink/web_tests/wpt_internal/ai/summarize-api-abort.https.any.js b/third_party/blink/web_tests/wpt_internal/ai/summarize-api-abort.https.any.js
index 61b6d8e3..a42b2de 100644
--- a/third_party/blink/web_tests/wpt_internal/ai/summarize-api-abort.https.any.js
+++ b/third_party/blink/web_tests/wpt_internal/ai/summarize-api-abort.https.any.js
@@ -1,19 +1,25 @@
 // META: script=resources/utils.js
 
-promise_test(async (t) => {
-  testAbort(t, (signal) => {
-    return createSummarizerMaybeDownload({
+promise_test(async t => {
+  await testAbortPromise(t, signal => {
+    return ai.summarizer.create({
       signal: signal
     });
   });
-}, 'Aborting AISummarizerFactory.create().');
+}, "Aborting AISummarizer.create().");
 
-promise_test(async (t) => {
-  const summarizer = await createSummarizerMaybeDownload({});
-  testAbort(t, (signal) => {
-    return summarizer.summarize(
-      "Minccino is a furry, gray chinchilla-like Pokémon with scruffs of fur on its head and neck.",
-      { signal: signal }
+promise_test(async t => {
+  const session = await ai.summarizer.create();
+  await testAbortPromise(t, signal => {
+    return session.summarize(kTestPrompt, { signal: signal });
+  });
+}, "Aborting AISummarizer.summarize().");
+
+promise_test(async t => {
+  const session = await ai.summarizer.create();
+  await testAbortReadableStream(t, signal => {
+    return session.summarizeStreaming(
+      kTestPrompt, { signal: signal }
     );
   });
-}, 'Aborting AISummarizer.summarize().');
+}, "Aborting AISummarizer.summarizeStreaming().");
diff --git a/third_party/blink/web_tests/wpt_internal/ai/writer-api-abort.https.any.js b/third_party/blink/web_tests/wpt_internal/ai/writer-api-abort.https.any.js
index 445c813..3207e0c 100644
--- a/third_party/blink/web_tests/wpt_internal/ai/writer-api-abort.https.any.js
+++ b/third_party/blink/web_tests/wpt_internal/ai/writer-api-abort.https.any.js
@@ -1,38 +1,25 @@
 // META: script=resources/utils.js
 
-promise_test(async (t) => {
-  testAbort(t, (signal) => {
+promise_test(async t => {
+  await testAbortPromise(t, signal => {
     return ai.writer.create({
       signal: signal
     });
   });
-}, 'Aborting AIWriter.create().');
+}, "Aborting AIWriter.create().");
 
-promise_test(async (t) => {
-  const writer = await ai.writer.create();
-  testAbort(t, (signal) => {
-    return writer.write(
-      "Write a poem",
-      { signal: signal }
+promise_test(async t => {
+  const session = await ai.writer.create();
+  await testAbortPromise(t, signal => {
+    return session.write(kTestPrompt, { signal: signal });
+  });
+}, "Aborting AIWriter.write().");
+
+promise_test(async t => {
+  const session = await ai.writer.create();
+  await testAbortReadableStream(t, signal => {
+    return session.writeStreaming(
+      kTestPrompt, { signal: signal }
     );
   });
-}, 'Aborting AIWriter.writer().');
-
-promise_test(async (t) => {
-  const writer = await ai.writer.create();
-  const controller = new AbortController();
-  const streamingResponse =
-    writer.writeStreaming('hello', { signal: controller.signal });
-  controller.abort();
-  const reader = streamingResponse.getReader();
-  await promise_rejects_dom(t, 'AbortError', reader.read());
-}, 'Aborting AIWriter.writeStreaming()');
-
-promise_test(async (t) => {
-  const writer = await ai.writer.create();
-  const controller = new AbortController();
-  controller.abort();
-  assert_throws_dom(
-    'AbortError',
-    () => writer.writeStreaming('hello', { signal: controller.signal }));
-}, 'AIWriter.writeStreaming() call with an aborted signal.');
+}, "Aborting AIWriter.writeStreaming().");
diff --git a/third_party/chromium-variations b/third_party/chromium-variations
index 60f815f..d66e3e7 160000
--- a/third_party/chromium-variations
+++ b/third_party/chromium-variations
@@ -1 +1 @@
-Subproject commit 60f815f521c36d4b0a6d54e7fb30a103cfc32738
+Subproject commit d66e3e79647b84e230bec45ffea13c456f4c01e3
diff --git a/third_party/dawn b/third_party/dawn
index 571eea1..4585c94 160000
--- a/third_party/dawn
+++ b/third_party/dawn
@@ -1 +1 @@
-Subproject commit 571eea1e9b33486148be3257d49588f190956454
+Subproject commit 4585c9495dd4c1958890921fa2abacd8546d088d
diff --git a/third_party/skia b/third_party/skia
index ffd7fec..dac8081 160000
--- a/third_party/skia
+++ b/third_party/skia
@@ -1 +1 @@
-Subproject commit ffd7fec8b6c5df912dbd7e382f7a0d7c1f51937d
+Subproject commit dac808134f758c75b52cd53a4c93f84dea22803a
diff --git a/third_party/webrtc b/third_party/webrtc
index 1305eb9..9aeeb61 160000
--- a/third_party/webrtc
+++ b/third_party/webrtc
@@ -1 +1 @@
-Subproject commit 1305eb90832d17fc5edf2e8fb2e71dab5b689820
+Subproject commit 9aeeb6123d2a4fc868626a9ee8f45b268d223c03