diff --git a/DEPS b/DEPS
index 7721977..42212f6 100644
--- a/DEPS
+++ b/DEPS
@@ -196,7 +196,7 @@
   #   - workstation.qemu-x64
   #   Hardware:
   #   - workstation_eng.chromebook-x64
-  #   - workstation_eng.chromebook-x64-dfv2 
+  #   - workstation_eng.chromebook-x64-dfv2
   #
   # Since the images are hundreds of MB, default to only downloading the image
   # most commonly useful for developers. Bots and developers that need to use
@@ -306,7 +306,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': 'cdf8348e6fba8f93459d9b86e7396dcd0cfa5664',
+  'skia_revision': '36efebf14ad81e7af323695c58dc09b091e81b1d',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
@@ -314,7 +314,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
-  'angle_revision': '2fa255da8c829c4c7537401d51bc92e00f7e7a67',
+  'angle_revision': '4b084310d7bbb33631d58a461eb5814c12220926',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling SwiftShader
   # and whatever else without interference from each other.
@@ -357,7 +357,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
-  'freetype_revision': '47e61d02e6efb00d9e3c2b38d7fc3211a7514c7f',
+  'freetype_revision': '0f43a0e7ebfbda303f0b2e8b6d5db63c362233a3',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling freetype
   # and whatever else without interference from each other.
@@ -421,7 +421,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
-  'dawn_revision': 'acce83d10975dd9c6ef0137ba11198a22754034a',
+  'dawn_revision': '4b260af6722f5f6b81d72afa42cf34d85420b6f4',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -816,7 +816,7 @@
 
   'src/clank': {
     'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' +
-    '795bc6f85115ff26d9eb7466f81394f40823bcfa',
+    '9ec2dac221888e0793edd548be8f6223c8c25554',
     'condition': 'checkout_android and checkout_src_internal and not checkout_clank_via_src_internal',
   },
 
@@ -1000,7 +1000,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'S-O8vat1G6foJoqAgxU92SlGn71HS1Kw31OCiSEf1aUC',
+          'version': '06CY8QJEKQvLc6nEso6R3iTnrmW1NDVyz5Mmsu5y5_MC',
       },
     ],
     'condition': 'checkout_android',
@@ -1249,7 +1249,7 @@
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '69a59b11fca4255301ea9f1af114ceeb8594bc84',
+      'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + '6747e8aa347517fda0836da5159f9237e78dc50c',
     'condition': 'checkout_src_internal',
   },
 
@@ -1647,7 +1647,7 @@
     Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + 'db956674bbdfbaab5acdd3fdb4117c2fef5527e9',
 
   'src/third_party/openscreen/src':
-    Var('chromium_git') + '/openscreen' + '@' + '9be5eefa2605408a671cc11c695849400caecbbb',
+    Var('chromium_git') + '/openscreen' + '@' + '14705b3117e89c3bb2d284648bf778f27b78a39d',
 
   'src/third_party/openxr/src': {
     'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + 'bf21ccb1007bb531b45d9978919a56ea5059c245',
@@ -1849,7 +1849,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '8c74caae35d253e20d294ed1c3d035726282587b',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '12046bf8c4159584ff78d8e15023cf4bac28b256',
+    Var('webrtc_git') + '/src.git' + '@' + '82c8e4af7ce40771b9b15664a2068d7913b7a98f',
 
   # 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.
@@ -1919,7 +1919,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@a9a55a97339f30faa4bfcfa4dd4471dfca838f73',
+    'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@268390b999ce0a5fe5cb20da08000e9528f0ba60',
     'condition': 'checkout_src_internal',
   },
 
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 426ba0cf..a854f41 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -1164,6 +1164,41 @@
       ),
     ),
     BanRule(
+      'CREATE VIEW',
+      (
+        'SQL views are disabled in Chromium feature code',
+        'https://chromium.googlesource.com/chromium/src/+/HEAD/sql#no-views',
+      ),
+      True,
+      (
+        _THIRD_PARTY_EXCEPT_BLINK,
+        # sql/ itself uses views when using memory-mapped IO.
+        r'^sql/.*',
+        # Various performance tools that do not build as part of Chrome.
+        r'^infra/.*',
+        r'^tools/perf.*',
+        r'.*perfetto.*',
+      ),
+    ),
+    BanRule(
+      'CREATE VIRTUAL TABLE',
+      (
+        'SQL virtual tables are disabled in Chromium feature code',
+        'https://chromium.googlesource.com/chromium/src/+/HEAD/sql#no-virtual-tables',
+      ),
+      True,
+      (
+        _THIRD_PARTY_EXCEPT_BLINK,
+        # sql/ itself uses virtual tables in the recovery module and tests.
+        r'^sql/.*',
+        # TODO(https://crbug.com/695592): Remove once WebSQL is deprecated.
+        r'third_party/blink/web_tests/storage/websql/.*'
+        # Various performance tools that do not build as part of Chrome.
+        r'^tools/perf.*',
+        r'.*perfetto.*',
+      ),
+    ),
+    BanRule(
       'std::random_shuffle',
       (
         'std::random_shuffle is deprecated in C++14, and removed in C++17. Use',
diff --git a/ash/BUILD.gn b/ash/BUILD.gn
index f1bf8cc..ed7ae62 100644
--- a/ash/BUILD.gn
+++ b/ash/BUILD.gn
@@ -1851,8 +1851,6 @@
     "system/unified/quick_settings_header.h",
     "system/unified/quick_settings_metrics_util.cc",
     "system/unified/quick_settings_metrics_util.h",
-    "system/unified/quick_settings_slider.cc",
-    "system/unified/quick_settings_slider.h",
     "system/unified/quick_settings_view.cc",
     "system/unified/quick_settings_view.h",
     "system/unified/quiet_mode_feature_pod_controller.cc",
diff --git a/ash/accelerators/accelerator_controller_unittest.cc b/ash/accelerators/accelerator_controller_unittest.cc
index d440fa2..bcbc99c 100644
--- a/ash/accelerators/accelerator_controller_unittest.cc
+++ b/ash/accelerators/accelerator_controller_unittest.cc
@@ -203,9 +203,7 @@
 class DummyKeyboardBrightnessControlDelegate
     : public KeyboardBrightnessControlDelegate {
  public:
-  DummyKeyboardBrightnessControlDelegate()
-      : handle_keyboard_brightness_down_count_(0),
-        handle_keyboard_brightness_up_count_(0) {}
+  DummyKeyboardBrightnessControlDelegate() = default;
 
   DummyKeyboardBrightnessControlDelegate(
       const DummyKeyboardBrightnessControlDelegate&) = delete;
@@ -226,7 +224,11 @@
         ui::Accelerator(ui::VKEY_BRIGHTNESS_UP, ui::EF_ALT_DOWN);
   }
 
-  void HandleToggleKeyboardBacklight() override {}
+  void HandleToggleKeyboardBacklight() override {
+    ++handle_toggle_keyboard_backlight_count_;
+    last_accelerator_ =
+        ui::Accelerator(ui::VKEY_KBD_BACKLIGHT_TOGGLE, ui::EF_NONE);
+  }
 
   int handle_keyboard_brightness_down_count() const {
     return handle_keyboard_brightness_down_count_;
@@ -236,11 +238,16 @@
     return handle_keyboard_brightness_up_count_;
   }
 
+  int handle_toggle_keyboard_backlight_count() const {
+    return handle_toggle_keyboard_backlight_count_;
+  }
+
   const ui::Accelerator& last_accelerator() const { return last_accelerator_; }
 
  private:
-  int handle_keyboard_brightness_down_count_;
-  int handle_keyboard_brightness_up_count_;
+  int handle_keyboard_brightness_down_count_ = 0;
+  int handle_keyboard_brightness_up_count_ = 0;
+  int handle_toggle_keyboard_backlight_count_ = 0;
   ui::Accelerator last_accelerator_;
 };
 
@@ -1253,21 +1260,32 @@
                                             ui::EF_ALT_DOWN);
   const ui::Accelerator alt_brightness_up(ui::VKEY_BRIGHTNESS_UP,
                                           ui::EF_ALT_DOWN);
+  const ui::Accelerator toggle_keyboard_backlight(ui::VKEY_KBD_BACKLIGHT_TOGGLE,
+                                                  ui::EF_NONE);
   {
     EXPECT_TRUE(ProcessInController(alt_brightness_down));
     EXPECT_TRUE(ProcessInController(alt_brightness_up));
+    EXPECT_TRUE(ProcessInController(toggle_keyboard_backlight));
+
     DummyKeyboardBrightnessControlDelegate* delegate =
         new DummyKeyboardBrightnessControlDelegate;
     SetKeyboardBrightnessControlDelegate(
         std::unique_ptr<KeyboardBrightnessControlDelegate>(delegate));
+
     EXPECT_EQ(0, delegate->handle_keyboard_brightness_down_count());
     EXPECT_TRUE(ProcessInController(alt_brightness_down));
     EXPECT_EQ(1, delegate->handle_keyboard_brightness_down_count());
     EXPECT_EQ(alt_brightness_down, delegate->last_accelerator());
+
     EXPECT_EQ(0, delegate->handle_keyboard_brightness_up_count());
     EXPECT_TRUE(ProcessInController(alt_brightness_up));
     EXPECT_EQ(1, delegate->handle_keyboard_brightness_up_count());
     EXPECT_EQ(alt_brightness_up, delegate->last_accelerator());
+
+    EXPECT_EQ(0, delegate->handle_toggle_keyboard_backlight_count());
+    EXPECT_TRUE(ProcessInController(toggle_keyboard_backlight));
+    EXPECT_EQ(1, delegate->handle_toggle_keyboard_backlight_count());
+    EXPECT_EQ(toggle_keyboard_backlight, delegate->last_accelerator());
   }
 
   // Exit
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc
index f6d3ef5..1b6b495 100644
--- a/ash/constants/ash_features.cc
+++ b/ash/constants/ash_features.cc
@@ -441,16 +441,6 @@
              "ContextualNudges",
              base::FEATURE_ENABLED_BY_DEFAULT);
 
-// Enables upgrading the crostini container to debian bullseye.
-BASE_FEATURE(kCrostiniBullseyeUpgrade,
-             "CrostiniBullseyeUpgrade",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
-// Enables or disables Crostini Disk Resizing.
-BASE_FEATURE(kCrostiniDiskResizing,
-             "CrostiniDiskResizing",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 // Enables or disables Crostini GPU support.
 // Note that this feature can be overridden by login_manager based on
 // whether a per-board build sets the USE virtio_gpu flag.
@@ -464,11 +454,6 @@
              "CrostiniResetLxdDb",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Do we use the default LXD version or try LXD 4?
-BASE_FEATURE(kCrostiniUseLxd4,
-             "CrostiniUseLxd4",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 // Enables experimental UI creating and managing multiple Crostini containers.
 BASE_FEATURE(kCrostiniMultiContainer,
              "CrostiniMultiContainer",
@@ -1009,9 +994,6 @@
 // Enable glanceables on login.
 BASE_FEATURE(kGlanceables, "Glanceables", base::FEATURE_DISABLED_BY_DEFAULT);
 
-// Enable GuestOS integration with the files app.
-BASE_FEATURE(kGuestOsFiles, "GuestOsFiles", base::FEATURE_ENABLED_BY_DEFAULT);
-
 // Enables the Gaia reauth endpoint.
 BASE_FEATURE(kGaiaReauthEndpoint,
              "GaiaReauthEndpoint",
@@ -2597,10 +2579,6 @@
   return base::FeatureList::IsEnabled(kGlanceables);
 }
 
-bool IsGuestOsFilesEnabled() {
-  return base::FeatureList::IsEnabled(kGuestOsFiles);
-}
-
 bool IsHatsUseNewHistogramsEnabled() {
   return base::FeatureList::IsEnabled(kHatsUseNewHistograms);
 }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h
index 8848798..1a10270c 100644
--- a/ash/constants/ash_features.h
+++ b/ash/constants/ash_features.h
@@ -133,13 +133,10 @@
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrosPrivacyHub);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrosPrivacyHubV0);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrosPrivacyHubV2);
-COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrostiniBullseyeUpgrade);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kDesksCloseAll);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kDesksTemplates);
-COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrostiniDiskResizing);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrostiniGpuSupport);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrostiniResetLxdDb);
-COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrostiniUseLxd4);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrostiniMultiContainer);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kCrostiniImeSupport);
 COMPONENT_EXPORT(ASH_CONSTANTS)
@@ -297,7 +294,6 @@
 COMPONENT_EXPORT(ASH_CONSTANTS)
 extern const base::FeatureParam<std::string> kGalleryAppPdfEditNotificationText;
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kGlanceables);
-COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kGuestOsFiles);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kGaiaReauthEndpoint);
 COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kGamepadVibration);
 COMPONENT_EXPORT(ASH_CONSTANTS)
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc
index 0b228b3..3721276 100644
--- a/ash/constants/ash_pref_names.cc
+++ b/ash/constants/ash_pref_names.cc
@@ -1149,6 +1149,10 @@
 // value of the pref is `true`. Controlled by RecoveryFactorBehavior policy.
 const char kRecoveryFactorBehavior[] = "ash.recovery.recovery_factor_behavior";
 
+// Pref which stores ICCIDs of cellular networks that have been migrated to the
+// APN Revamp feature.
+const char kApnMigratedIccids[] = "ash.cellular.apn_migrated_iccids";
+
 // NOTE: New prefs should start with the "ash." prefix. Existing prefs moved
 // into this file should not be renamed, since they may be synced.
 
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h
index 72b3c8b5..4fcb7e3 100644
--- a/ash/constants/ash_pref_names.h
+++ b/ash/constants/ash_pref_names.h
@@ -525,6 +525,8 @@
 
 COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kRecoveryFactorBehavior[];
 
+COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kApnMigratedIccids[];
+
 }  // namespace prefs
 }  // namespace ash
 
diff --git a/ash/system/keyboard_brightness/keyboard_brightness_controller.cc b/ash/system/keyboard_brightness/keyboard_brightness_controller.cc
index ef129e7..342635f 100644
--- a/ash/system/keyboard_brightness/keyboard_brightness_controller.cc
+++ b/ash/system/keyboard_brightness/keyboard_brightness_controller.cc
@@ -4,19 +4,11 @@
 
 #include "ash/system/keyboard_brightness/keyboard_brightness_controller.h"
 
-#include "base/logging.h"
+#include "chromeos/dbus/power/power_manager_client.h"
 #include "chromeos/dbus/power_manager/backlight.pb.h"
 
 namespace ash {
 
-KeyboardBrightnessController::KeyboardBrightnessController() {
-  chromeos::PowerManagerClient::Get()->AddObserver(this);
-}
-
-KeyboardBrightnessController::~KeyboardBrightnessController() {
-  chromeos::PowerManagerClient::Get()->RemoveObserver(this);
-}
-
 void KeyboardBrightnessController::HandleKeyboardBrightnessDown() {
   chromeos::PowerManagerClient::Get()->DecreaseKeyboardBrightness();
 }
@@ -25,44 +17,8 @@
   chromeos::PowerManagerClient::Get()->IncreaseKeyboardBrightness();
 }
 
-void KeyboardBrightnessController::KeyboardBrightnessChanged(
-    const power_manager::BacklightBrightnessChange& change) {
-  // Officially set our stored toggle state.  We're toggled off if
-  // power_manager says we are, otherwise we're toggled on.
-  keyboard_backlight_toggled_off_ =
-      change.cause() ==
-      power_manager::BacklightBrightnessChange_Cause_USER_TOGGLED_OFF;
-}
-
-void KeyboardBrightnessController::PowerManagerBecameAvailable(bool available) {
-  if (available) {
-    chromeos::PowerManagerClient::Get()->GetKeyboardBacklightToggledOff(
-        base::BindOnce(
-            &KeyboardBrightnessController::KeyboardBacklightToggledOffReceived,
-            weak_ptr_factory_.GetWeakPtr()));
-  }
-}
-
-void KeyboardBrightnessController::KeyboardBacklightToggledOffReceived(
-    absl::optional<bool> toggled_off) {
-  // Initialize our toggle state.
-  if (!toggled_off.has_value()) {
-    LOG(ERROR) << __FUNCTION__ << " No value present for toggled_off";
-    return;
-  }
-  keyboard_backlight_toggled_off_ = toggled_off.value();
-}
-
 void KeyboardBrightnessController::HandleToggleKeyboardBacklight() {
-  // User has explicitly toggled the KBL.  A toggle state with no value means
-  // we have yet to receive the initial value from power_manager.
-  if (keyboard_backlight_toggled_off_.has_value()) {
-    // Tell power_manager to set the toggle state to the opposite of our
-    // stored value.  We'll update the stored value when we receive the next
-    // brightness change.
-    chromeos::PowerManagerClient::Get()->SetKeyboardBacklightToggledOff(
-        !keyboard_backlight_toggled_off_.value());
-  }
+  chromeos::PowerManagerClient::Get()->ToggleKeyboardBacklight();
 }
 
 }  // namespace ash
diff --git a/ash/system/keyboard_brightness/keyboard_brightness_controller.h b/ash/system/keyboard_brightness/keyboard_brightness_controller.h
index 538c6e5a..a60fc6cf 100644
--- a/ash/system/keyboard_brightness/keyboard_brightness_controller.h
+++ b/ash/system/keyboard_brightness/keyboard_brightness_controller.h
@@ -7,46 +7,28 @@
 
 #include "ash/ash_export.h"
 #include "ash/system/keyboard_brightness_control_delegate.h"
-#include "chromeos/dbus/power/power_manager_client.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash {
 
 // A class which controls keyboard brightness when Alt+F6, Alt+F7 or a
 // multimedia key for keyboard brightness is pressed.
 class ASH_EXPORT KeyboardBrightnessController
-    : public KeyboardBrightnessControlDelegate,
-      public chromeos::PowerManagerClient::Observer {
+    : public KeyboardBrightnessControlDelegate {
  public:
-  KeyboardBrightnessController();
+  KeyboardBrightnessController() = default;
 
+  // Disallow copy and move.
   KeyboardBrightnessController(const KeyboardBrightnessController&) = delete;
   KeyboardBrightnessController& operator=(const KeyboardBrightnessController&) =
       delete;
 
-  ~KeyboardBrightnessController() override;
-
-  // chromeos::PowerManagerClient
-  void KeyboardBrightnessChanged(
-      const power_manager::BacklightBrightnessChange& change) override;
-  void PowerManagerBecameAvailable(bool available) final;
+  ~KeyboardBrightnessController() override = default;
 
  private:
   // Overridden from KeyboardBrightnessControlDelegate:
   void HandleKeyboardBrightnessDown() override;
   void HandleKeyboardBrightnessUp() override;
   void HandleToggleKeyboardBacklight() override;
-
-  // Callbacks:
-  void KeyboardBacklightToggledOffReceived(absl::optional<bool> toggled_off);
-
-  // The current toggle state of the keyboard backlight.  This value is true
-  // if the KBL is toggled off, false otherwise.  No value present means
-  // power_manager has not yet informed us one way or the other.
-  absl::optional<bool> keyboard_backlight_toggled_off_;
-
-  // This has to be last, so it gets destroyed last.
-  base::WeakPtrFactory<KeyboardBrightnessController> weak_ptr_factory_{this};
 };
 
 }  // namespace ash
diff --git a/ash/system/unified/quick_settings_slider.cc b/ash/system/unified/quick_settings_slider.cc
deleted file mode 100644
index 6abe1a0..0000000
--- a/ash/system/unified/quick_settings_slider.cc
+++ /dev/null
@@ -1,214 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ash/system/unified/quick_settings_slider.h"
-
-#include "ash/constants/ash_features.h"
-#include "ash/style/ash_color_provider.h"
-#include "ash/style/color_util.h"
-#include "base/notreached.h"
-#include "cc/paint/paint_flags.h"
-#include "ui/base/metadata/metadata_impl_macros.h"
-#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
-#include "ui/color/color_id.h"
-#include "ui/color/color_provider.h"
-#include "ui/events/event.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/geometry/rect.h"
-#include "ui/views/controls/slider.h"
-
-namespace ash {
-
-namespace {
-
-// The thickness of the empty slider.
-constexpr int kEmptySliderThickness = 4;
-
-// The thickness of the full slider.
-constexpr int kFullSliderThickness = 32;
-
-// The radius used to draw the rounded empty slider ends.
-constexpr float kEmptySliderRoundedRadius = 2.f;
-constexpr float kEmptySliderWidth = 2 * kEmptySliderRoundedRadius;
-
-// The radius used to draw the rounded full slider ends.
-constexpr float kFullSliderRoundedRadius = 16.f;
-constexpr float kFullSliderWidth = 2 * kFullSliderRoundedRadius;
-
-// The radius used to draw the rounded corner for active/inactive slider on the
-// audio subpage.
-constexpr float kActiveRadioSliderRoundedRadius = 16.f;
-// TODO(b/256705775): Replace the actual radius value once the spec is updated.
-constexpr float kInactiveRadioSliderRoundedRadius = 8.f;
-
-// TODO(b/256705775): Replace the value once the spec is updated.
-// The thickness of the focus ring border.
-constexpr int kLineThickness = 2;
-// The gap between the focus ring and the slider.
-constexpr int kFocusOffset = 2;
-
-float GetSliderRoundedCornerRadius(QuickSettingsSlider::Style slider_style) {
-  switch (slider_style) {
-    case QuickSettingsSlider::Style::kDefault:
-      return kFullSliderRoundedRadius;
-    case QuickSettingsSlider::Style::kRadioActive:
-      return kActiveRadioSliderRoundedRadius;
-    case QuickSettingsSlider::Style::kRadioInactive:
-      return kInactiveRadioSliderRoundedRadius;
-    default:
-      NOTREACHED();
-  }
-}
-
-}  // namespace
-
-QuickSettingsSlider::QuickSettingsSlider(views::SliderListener* listener,
-                                         Style slider_style)
-    : views::Slider(listener), slider_style_(slider_style) {
-  if (!features::IsQsRevampEnabled())
-    return;
-  SetValueIndicatorRadius(kFullSliderRoundedRadius);
-  SetFocusBehavior(FocusBehavior::ALWAYS);
-}
-
-QuickSettingsSlider::~QuickSettingsSlider() = default;
-
-void QuickSettingsSlider::SetSliderStyle(Style style) {
-  if (slider_style_ == style)
-    return;
-
-  slider_style_ = style;
-
-  if (slider_style_ == Style::kRadioInactive)
-    SetFocusBehavior(FocusBehavior::NEVER);
-
-  SchedulePaint();
-}
-
-SkColor QuickSettingsSlider::GetThumbColor() const {
-  // TODO(b/256705775): Updates the color when QsRevamp is disabled but Jelly is
-  // enabled.
-  if (!features::IsQsRevampEnabled()) {
-    using Type = AshColorProvider::ContentLayerType;
-    return AshColorProvider::Get()->GetContentLayerColor(
-        (style() == RenderingStyle::kMinimalStyle) ? Type::kSliderColorInactive
-                                                   : Type::kSliderColorActive);
-  }
-
-  switch (slider_style_) {
-    case Style::kDefault:
-    case Style::kRadioActive:
-      return GetColorProvider()->GetColor(static_cast<ui::ColorId>(
-          cros_tokens::kCrosSysSystemPrimaryContainer));
-    case Style::kRadioInactive:
-      return GetColorProvider()->GetColor(
-          static_cast<ui::ColorId>(cros_tokens::kCrosSysDisabled));
-    default:
-      NOTREACHED();
-  }
-}
-
-SkColor QuickSettingsSlider::GetTroughColor() const {
-  // TODO(b/256705775): Updates the color when QsRevamp is disabled but Jelly is
-  // enabled.
-  if (!features::IsQsRevampEnabled())
-    return ColorUtil::GetSecondToneColor(GetThumbColor());
-
-  switch (slider_style_) {
-    case Style::kDefault:
-      return GetColorProvider()->GetColor(
-          static_cast<ui::ColorId>(cros_tokens::kCrosSysSystemOnBase));
-    case Style::kRadioActive:
-      return GetColorProvider()->GetColor(
-          static_cast<ui::ColorId>(cros_tokens::kCrosSysHighlightShape));
-    case Style::kRadioInactive:
-      return GetColorProvider()->GetColor(
-          static_cast<ui::ColorId>(cros_tokens::kCrosSysDisabled));
-    default:
-      NOTREACHED();
-  }
-}
-
-void QuickSettingsSlider::OnPaint(gfx::Canvas* canvas) {
-  // Paints the `QuickSettingsSlider`. If the feature is not enabled, use
-  // `Slider::OnPaint()`.
-  if (!ash::features::IsQsRevampEnabled()) {
-    views::Slider::OnPaint(canvas);
-    return;
-  }
-
-  const gfx::Rect content = GetContentsBounds();
-  const int width = content.width() - kFullSliderWidth;
-  const int full_width = GetAnimatingValue() * width + kFullSliderWidth;
-  const int x = content.x();
-  const int y = content.height() / 2 - kFullSliderThickness / 2;
-
-  gfx::Rect empty_slider_rect;
-  float empty_slider_radius;
-  switch (slider_style_) {
-    case Style::kDefault: {
-      const int empty_width =
-          width + kFullSliderRoundedRadius - full_width + kEmptySliderWidth;
-      const int x_empty = x + full_width - kEmptySliderRoundedRadius;
-      const int y_empty = content.height() / 2 - kEmptySliderThickness / 2;
-
-      empty_slider_rect =
-          gfx::Rect(x_empty, y_empty, empty_width, kEmptySliderThickness);
-      empty_slider_radius = kEmptySliderRoundedRadius;
-      break;
-    }
-    case Style::kRadioActive:
-    case Style::kRadioInactive: {
-      empty_slider_rect =
-          gfx::Rect(x, y, content.width(), kFullSliderThickness);
-      empty_slider_radius = GetSliderRoundedCornerRadius(slider_style_);
-      break;
-    }
-    default:
-      NOTREACHED();
-  }
-
-  cc::PaintFlags slider_flags;
-  slider_flags.setAntiAlias(true);
-
-  slider_flags.setColor(GetTroughColor());
-  canvas->DrawRoundRect(empty_slider_rect, empty_slider_radius, slider_flags);
-
-  slider_flags.setColor(GetThumbColor());
-  canvas->DrawRoundRect(gfx::Rect(x, y, full_width, kFullSliderThickness),
-                        GetSliderRoundedCornerRadius(slider_style_),
-                        slider_flags);
-
-  // Paints the focusing ring for the slider. It should be painted last to be
-  // on the top.
-  if (HasFocus()) {
-    cc::PaintFlags highlight_border;
-    highlight_border.setColor(GetColorProvider()->GetColor(
-        static_cast<ui::ColorId>(cros_tokens::kCrosSysPrimary)));
-    highlight_border.setAntiAlias(true);
-    highlight_border.setStyle(cc::PaintFlags::kStroke_Style);
-    highlight_border.setStrokeWidth(kLineThickness);
-    canvas->DrawRoundRect(gfx::Rect(x - kFocusOffset, y - kFocusOffset,
-                                    full_width + 2 * kFocusOffset,
-                                    kFullSliderThickness + 2 * kFocusOffset),
-                          kFullSliderRoundedRadius, highlight_border);
-  }
-}
-
-ReadOnlySlider::ReadOnlySlider(Style slider_style)
-    : QuickSettingsSlider(/*listener=*/nullptr, slider_style) {}
-
-ReadOnlySlider::~ReadOnlySlider() = default;
-
-bool ReadOnlySlider::CanAcceptEvent(const ui::Event& event) {
-  return false;
-}
-
-BEGIN_METADATA(QuickSettingsSlider, views::View)
-END_METADATA
-
-BEGIN_METADATA(ReadOnlySlider, views::View)
-END_METADATA
-
-}  // namespace ash
diff --git a/ash/system/unified/quick_settings_slider.h b/ash/system/unified/quick_settings_slider.h
deleted file mode 100644
index ce455f81..0000000
--- a/ash/system/unified/quick_settings_slider.h
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef ASH_SYSTEM_UNIFIED_QUICK_SETTINGS_SLIDER_H_
-#define ASH_SYSTEM_UNIFIED_QUICK_SETTINGS_SLIDER_H_
-
-#include "ash/ash_export.h"
-#include "ui/views/controls/slider.h"
-
-namespace gfx {
-class Canvas;
-}  // namespace gfx
-
-namespace views {
-class View;
-}  // namespace views
-
-namespace ui {
-class Event;
-}  // namespace ui
-
-namespace ash {
-
-// This slider view is used in quick settings in the status area. It will be
-// used in the `QuickSettingsView` and `TrayBubbleView`. This slider view
-// supports different styles. `kDefault` slider is used in `QuickSettingsView`
-// and in `TrayBubbleView`. `kRadioActive` slider will be used for the active
-// input/output device in `AudioDetailedView`. `kRadioInactive` slider will be
-// used for the inactive device in `AudioDetailedView`.
-class ASH_EXPORT QuickSettingsSlider : public views::Slider {
- public:
-  METADATA_HEADER(QuickSettingsSlider);
-
-  // Represents the style of the slider.
-  enum class Style {
-    // Represents the slider where the full part is a rounded corner rectangle
-    // with a height of `kFullSliderThickness`, and the empty part is a rounded
-    // corner rectangle with a height of `kEmptySliderThickness`. These two
-    // parts are center-aligned horizontally. The ends of both parts have fully
-    // rounded corners.
-    kDefault,
-    // Represents the style where both the full part and the empty part of the
-    // slider have a height of `kFullSliderThickness`. The ends are fully
-    // rounded.
-    kRadioActive,
-    // Represents the style where the full part and the empty part also have the
-    // same height of `kFullSliderThickness`, except that the ends are not fully
-    // rounded but have a radius of `kInactiveRadioSliderRoundedRadius`.
-    kRadioInactive
-  };
-
-  QuickSettingsSlider(views::SliderListener* listener, Style slider_style);
-  QuickSettingsSlider(const QuickSettingsSlider&) = delete;
-  QuickSettingsSlider& operator=(const QuickSettingsSlider&) = delete;
-  ~QuickSettingsSlider() override;
-
-  // Setter and Getter of the slider style. Schedules paint after setting the
-  // style since styles and colors may change for the radio sliders because of
-  // the active status change. If the slider is the `kRadioInactive`, also
-  // disables the focus behavior for it.
-  void SetSliderStyle(Style style);
-  Style slider_style() const { return slider_style_; }
-
- private:
-  // views::Slider:
-  SkColor GetThumbColor() const override;
-  SkColor GetTroughColor() const override;
-
-  // views::View:
-  void OnPaint(gfx::Canvas* canvas) override;
-
-  Style slider_style_;
-};
-
-// A slider that ignores inputs. This will be used in the
-// `UnifiedKeyboardBrightnessView` and `UnifiedKeyboardBacklightToggleView`.
-class ASH_EXPORT ReadOnlySlider : public QuickSettingsSlider {
- public:
-  METADATA_HEADER(ReadOnlySlider);
-
-  explicit ReadOnlySlider(Style slider_style);
-  ReadOnlySlider(const ReadOnlySlider&) = delete;
-  ReadOnlySlider& operator=(const ReadOnlySlider&) = delete;
-  ~ReadOnlySlider() override;
-
- private:
-  // views::View:
-  bool CanAcceptEvent(const ui::Event& event) override;
-};
-
-}  // namespace ash
-
-#endif  // ASH_SYSTEM_UNIFIED_QUICK_SETTINGS_SLIDER_H_
diff --git a/ash/system/unified/unified_slider_view.cc b/ash/system/unified/unified_slider_view.cc
index ba43321..11e27698 100644
--- a/ash/system/unified/unified_slider_view.cc
+++ b/ash/system/unified/unified_slider_view.cc
@@ -6,6 +6,7 @@
 
 #include "ash/constants/quick_settings_catalogs.h"
 #include "ash/style/ash_color_provider.h"
+#include "ash/style/color_util.h"
 #include "ash/system/tray/tray_popup_utils.h"
 #include "ash/system/unified/quick_settings_metrics_util.h"
 #include "base/check_op.h"
@@ -14,14 +15,74 @@
 #include "ui/views/accessibility/view_accessibility.h"
 #include "ui/views/border.h"
 #include "ui/views/controls/label.h"
-#include "ui/views/controls/slider.h"
 #include "ui/views/layout/box_layout.h"
+#include "ui/views/view_class_properties.h"
 #include "ui/views/widget/widget.h"
 
 namespace ash {
 
 using ContentLayerType = AshColorProvider::ContentLayerType;
 
+namespace {
+
+// Custom the slider to use different colors.
+class SystemSlider : public views::Slider {
+ public:
+  explicit SystemSlider(views::SliderListener* listener = nullptr)
+      : views::Slider(listener) {}
+  SystemSlider(const SystemSlider&) = delete;
+  SystemSlider& operator=(const SystemSlider&) = delete;
+  ~SystemSlider() override {}
+
+ private:
+  // views::Slider:
+  SkColor GetThumbColor() const override {
+    using Type = AshColorProvider::ContentLayerType;
+    return AshColorProvider::Get()->GetContentLayerColor(
+        (style() == RenderingStyle::kMinimalStyle) ? Type::kSliderColorInactive
+                                                   : Type::kSliderColorActive);
+  }
+
+  // views::Slider:
+  SkColor GetTroughColor() const override {
+    return ColorUtil::GetSecondToneColor(GetThumbColor());
+  }
+
+  // views::View:
+  void OnThemeChanged() override {
+    views::Slider::OnThemeChanged();
+    SchedulePaint();
+  }
+};
+
+// A slider that ignores inputs.
+class ReadOnlySlider : public SystemSlider {
+ public:
+  ReadOnlySlider() : SystemSlider() {}
+  ReadOnlySlider(const ReadOnlySlider&) = delete;
+  ReadOnlySlider& operator=(const ReadOnlySlider&) = delete;
+  ~ReadOnlySlider() override {}
+
+ private:
+  // views::View:
+  bool OnMousePressed(const ui::MouseEvent& event) override { return false; }
+  bool OnMouseDragged(const ui::MouseEvent& event) override { return false; }
+  void OnMouseReleased(const ui::MouseEvent& event) override {}
+  bool OnKeyPressed(const ui::KeyEvent& event) override { return false; }
+  const char* GetClassName() const override { return "ReadOnlySlider"; }
+
+  // ui::EventHandler:
+  void OnGestureEvent(ui::GestureEvent* event) override {}
+};
+
+std::unique_ptr<views::Slider> CreateSlider(UnifiedSliderListener* listener,
+                                            bool readonly) {
+  return readonly ? std::make_unique<ReadOnlySlider>()
+                  : std::make_unique<SystemSlider>(listener);
+}
+
+}  // namespace
+
 void UnifiedSliderListener::TrackToggleUMA(bool target_toggle_state) {
   DCHECK_NE(GetCatalogName(), QsSliderCatalogName::kUnknown);
   quick_settings_metrics_util::RecordQsSliderToggle(
@@ -38,7 +99,7 @@
                                      UnifiedSliderListener* listener,
                                      const gfx::VectorIcon& icon,
                                      int accessible_name_id,
-                                     bool read_only)
+                                     bool readonly)
     : button_(
           AddChildView(std::make_unique<IconButton>(std::move(callback),
                                                     IconButton::Type::kSmall,
@@ -46,10 +107,7 @@
                                                     accessible_name_id,
                                                     /*is_togglable=*/true,
                                                     /*has_border=*/true))),
-      slider_(
-          AddChildView(CreateSlider(listener,
-                                    read_only,
-                                    QuickSettingsSlider::Style::kDefault))) {
+      slider_(AddChildView(CreateSlider(listener, readonly))) {
   auto* layout = SetLayoutManager(std::make_unique<views::BoxLayout>(
       views::BoxLayout::Orientation::kHorizontal, kUnifiedSliderRowPadding,
       kUnifiedSliderViewSpacing));
@@ -71,15 +129,6 @@
   layer()->SetFillsBoundsOpaquely(false);
 }
 
-std::unique_ptr<views::Slider> UnifiedSliderView::CreateSlider(
-    UnifiedSliderListener* listener,
-    bool read_only,
-    QuickSettingsSlider::Style slider_style) {
-  return read_only
-             ? std::make_unique<ReadOnlySlider>(slider_style)
-             : std::make_unique<QuickSettingsSlider>(listener, slider_style);
-}
-
 void UnifiedSliderView::SetSliderValue(float value, bool by_user) {
   // SetValue() calls |listener|, so we should ignore the call when the widget
   // is closed, because controllers are already deleted.
diff --git a/ash/system/unified/unified_slider_view.h b/ash/system/unified/unified_slider_view.h
index ca0c322a..07f957a 100644
--- a/ash/system/unified/unified_slider_view.h
+++ b/ash/system/unified/unified_slider_view.h
@@ -7,7 +7,8 @@
 
 #include "ash/constants/quick_settings_catalogs.h"
 #include "ash/style/icon_button.h"
-#include "quick_settings_slider.h"
+#include "ui/views/controls/slider.h"
+#include "ui/views/view.h"
 
 namespace gfx {
 struct VectorIcon;
@@ -15,8 +16,6 @@
 
 namespace views {
 class Label;
-class Slider;
-class View;
 }  // namespace views
 
 namespace ash {
@@ -48,23 +47,18 @@
 // left side and a slider on the right side.
 class UnifiedSliderView : public views::View {
  public:
-  // If |read_only| is set, the slider will not accept any user events.
+  // If |readonly| is set, the slider will not accept any user events.
   UnifiedSliderView(views::Button::PressedCallback callback,
                     UnifiedSliderListener* listener,
                     const gfx::VectorIcon& icon,
                     int accessible_name_id,
-                    bool read_only = false);
+                    bool readonly = false);
 
   UnifiedSliderView(const UnifiedSliderView&) = delete;
   UnifiedSliderView& operator=(const UnifiedSliderView&) = delete;
 
   ~UnifiedSliderView() override;
 
-  std::unique_ptr<views::Slider> CreateSlider(
-      UnifiedSliderListener* listener,
-      bool read_only,
-      QuickSettingsSlider::Style slider_style);
-
   IconButton* button() { return button_; }
   views::Slider* slider() { return slider_; }
   views::Label* toast_label() { return toast_label_; }
diff --git a/ash/webui/diagnostics_ui/resources/keyboard_tester.html b/ash/webui/diagnostics_ui/resources/keyboard_tester.html
index 732872d..16744d1 100644
--- a/ash/webui/diagnostics_ui/resources/keyboard_tester.html
+++ b/ash/webui/diagnostics_ui/resources/keyboard_tester.html
@@ -28,7 +28,7 @@
     margin-inline-end: 12px;
   }
 </style>
-<cr-dialog id="dialog" show-close-button on-close="handleClose">
+<cr-dialog id="dialog" on-close="handleClose">
   <div slot="title">[[i18n('keyboardTesterTitle')]]</div>
   <div slot="body">
     <p>[[i18n('keyboardTesterInstruction')]]</p>
diff --git a/ash/webui/files_internals/resources/index.html b/ash/webui/files_internals/resources/index.html
index 1b70d9e..09d2b401 100644
--- a/ash/webui/files_internals/resources/index.html
+++ b/ash/webui/files_internals/resources/index.html
@@ -16,12 +16,20 @@
 </ul>
 
 <h2>SMB</h2>
-<div>
+<div style="display: flex; flex-direction: row">
 <label>
-Verbose logging (restart after toggling)
+  <b>Enable verbose logging</b>
 <input type="checkbox" id="smb-verbose-logging-toggle">
 </label>
-</div>
+<span style="flex: 3 0px"><b>WARNING:</b> Enabling this option can cause the
+  names of files and directories on SMB shares to be recorded in ChromeOS system
+  logs, which may be uploaded to Google in ChromeOS feedback reports. This
+  option should only be enabled for detailed debugging purposes and should be
+  disabled as soon as debugging is complete.
 
+  <p><i>You must logout / login, or remove / re-add the share after toggling
+    this option.</i></p>
+</span>
+</div>
 </body>
 </html>
diff --git a/base/files/file_descriptor_watcher_posix.cc b/base/files/file_descriptor_watcher_posix.cc
index ab1a036..717a438 100644
--- a/base/files/file_descriptor_watcher_posix.cc
+++ b/base/files/file_descriptor_watcher_posix.cc
@@ -72,7 +72,7 @@
 
   // WaitableEvent to signal to ensure that the Watcher is always destroyed
   // before the Controller.
-  const raw_ref<base::WaitableEvent> on_destroyed_;
+  const raw_ref<base::WaitableEvent, DanglingUntriaged> on_destroyed_;
 
   // Whether this Watcher is notified when |fd_| becomes readable or writable
   // without blocking.
diff --git a/base/fuchsia/test_component_context_for_process_unittest.cc b/base/fuchsia/test_component_context_for_process_unittest.cc
index 929f7bac..4a1168f 100644
--- a/base/fuchsia/test_component_context_for_process_unittest.cc
+++ b/base/fuchsia/test_component_context_for_process_unittest.cc
@@ -109,7 +109,7 @@
 
   // Use the Loader to verify that it was the system service that was connected.
   // Load the component containing this test since we know it exists.
-  // TODO(https://fxbug.dev/51490): Use a programmatic mechanism to obtain this.
+  // The URL cannot be obtained programmatically - see fxbug.dev/51490.
   const char kComponentUrl[] =
       "fuchsia-pkg://fuchsia.com/base_unittests#meta/base_unittests.cm";
   loader->LoadUrl(kComponentUrl, [quit_loop = wait_loop.QuitClosure(),
diff --git a/base/value_iterators.h b/base/value_iterators.h
index adcaebc..f10f1868 100644
--- a/base/value_iterators.h
+++ b/base/value_iterators.h
@@ -168,7 +168,7 @@
   const_reverse_iterator crend() const;
 
  private:
-  raw_ptr<DictStorage> storage_;
+  raw_ptr<DictStorage, DanglingUntriaged> storage_;
 };
 
 // This class wraps the various const |begin| and |end| methods of the
@@ -205,7 +205,7 @@
   const_reverse_iterator crend() const;
 
  private:
-  raw_ptr<const DictStorage> storage_;
+  raw_ptr<const DictStorage, DanglingUntriaged> storage_;
 };
 }  // namespace detail
 
diff --git a/cc/tiles/gpu_image_decode_cache.cc b/cc/tiles/gpu_image_decode_cache.cc
index b1cd837..479d5055 100644
--- a/cc/tiles/gpu_image_decode_cache.cc
+++ b/cc/tiles/gpu_image_decode_cache.cc
@@ -641,7 +641,7 @@
   ~ImageUploadTaskImpl() override = default;
 
  private:
-  raw_ptr<GpuImageDecodeCache> cache_;
+  raw_ptr<GpuImageDecodeCache, DanglingUntriaged> cache_;
   DrawImage image_;
   const ImageDecodeCache::TracingInfo tracing_info_;
 };
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index e8f85d7..f9af63c9 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -312,7 +312,8 @@
   }
 
  private:
-  raw_ptr<ImageDecodeCache> image_decode_cache_ptr_ = nullptr;
+  raw_ptr<ImageDecodeCache, DanglingUntriaged> image_decode_cache_ptr_ =
+      nullptr;
   std::unique_ptr<ImageDecodeCache> image_decode_cache_;
 };
 
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
index abde2bd..a3ec763 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
@@ -1260,7 +1260,16 @@
         checkPreferencesForCategory(SiteSettingsCategory.Type.COOKIES, cookie);
     }
 
-    // TODO(b/254415173): Add tests for site data and third-party cookies page.
+    @Test
+    @SmallTest
+    @Feature({"Preferences"})
+    @EnableFeatures(ChromeFeatureList.PRIVACY_SANDBOX_SETTINGS_4)
+    public void testOnlyExpectedPreferencesSiteData() {
+        testExpectedPreferences(SiteSettingsCategory.Type.SITE_DATA, BINARY_TOGGLE_WITH_EXCEPTION,
+                BINARY_TOGGLE_WITH_EXCEPTION);
+    }
+
+    // TODO(b/254415173): Add tests for third-party cookies page.
 
     @Test
     @SmallTest
@@ -2252,11 +2261,12 @@
                     singleCategorySettings.findPreference(SingleCategorySettings.BINARY_TOGGLE_KEY);
             assert toggle != null;
 
+            var delegate = new ChromeSiteSettingsDelegate(
+                    toggle.getContext(), Profile.getLastUsedRegularProfile());
+
             Assert.assertEquals("Preference title is not set correctly.",
                     singleCategorySettings.getResources().getString(
-                            ContentSettingsResources.getTitle(mContentSettingsType,
-                                    new ChromeSiteSettingsDelegate(toggle.getContext(),
-                                            Profile.getLastUsedRegularProfile()))),
+                            ContentSettingsResources.getTitle(mContentSettingsType, delegate)),
                     toggle.getTitle());
             assertNotNull("Enabled summary text should not be null.", toggle.getSummaryOn());
             assertNotNull("Disabled summary text should not be null.", toggle.getSummaryOff());
@@ -2264,8 +2274,10 @@
             String summary = mIsCategoryEnabled ? toggle.getSummaryOn().toString()
                                                 : toggle.getSummaryOff().toString();
             String expected = singleCategorySettings.getResources().getString(mIsCategoryEnabled
-                            ? ContentSettingsResources.getEnabledSummary(mContentSettingsType)
-                            : ContentSettingsResources.getDisabledSummary(mContentSettingsType));
+                            ? ContentSettingsResources.getEnabledSummary(
+                                    mContentSettingsType, delegate)
+                            : ContentSettingsResources.getDisabledSummary(
+                                    mContentSettingsType, delegate));
             Assert.assertEquals(
                     "Summary text in state <" + mIsCategoryEnabled + "> does not match.", expected,
                     summary);
diff --git a/chrome/app/chrome.cml b/chrome/app/chrome.cml
index e5fea9d..3288b1b 100644
--- a/chrome/app/chrome.cml
+++ b/chrome/app/chrome.cml
@@ -57,6 +57,8 @@
                 "fuchsia.camera3.DeviceWatcher",
                 "fuchsia.device.NameProvider",
                 "fuchsia.element.GraphicalPresenter",
+                "fuchsia.feedback.ComponentDataRegister",
+                "fuchsia.feedback.CrashReportingProductRegister",
                 "fuchsia.fonts.Provider",
                 "fuchsia.hwinfo.Product",
                 "fuchsia.input.virtualkeyboard.ControllerCreator",
diff --git a/chrome/app/chrome_v1.cmx b/chrome/app/chrome_v1.cmx
index cd376be..2727000 100644
--- a/chrome/app/chrome_v1.cmx
+++ b/chrome/app/chrome_v1.cmx
@@ -17,6 +17,8 @@
       "fuchsia.buildinfo.Provider",
       "fuchsia.device.NameProvider",
       "fuchsia.element.GraphicalPresenter",
+      "fuchsia.feedback.ComponentDataRegister",
+      "fuchsia.feedback.CrashReportingProductRegister",
       "fuchsia.fonts.Provider",
       "fuchsia.hwinfo.Product",
       "fuchsia.input.virtualkeyboard.ControllerCreator",
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp
index 79a2631..8a24a85c 100644
--- a/chrome/app/chromeos_strings.grdp
+++ b/chrome/app/chromeos_strings.grdp
@@ -4590,9 +4590,6 @@
   <message name="IDS_CROSTINI_INSTALLER_USERNAME_LABEL" desc="Label for the field where the user enters their username">
     Username
   </message>
-  <message name="IDS_CROSTINI_INSTALLER_USERNAME_MESSAGE" desc="Text shown in the Crostini installer dialog prompting the user to pick their username">
-    Select a username
-  </message>
   <message name="IDS_CROSTINI_INSTALLER_USERNAME_INVALID_FIRST_CHARACTER_ERROR" desc="Text shown in the Crostini installer dialog when the user picks a username starting with an invalid character">
     Must start with a lowercase character or underscore
   </message>
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 909a40e..2f24277 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -6623,6 +6623,9 @@
       <message name="IDS_NTP_CUSTOMIZE_HIDE_SHORTCUTS_DESC" desc="The description for the option to hide shortcuts in the customization menu on the New Tab Page">
         Don't show shortcuts on this page
       </message>
+      <message name="IDS_NTP_CUSTOMIZE_SHOW_SHORTCUTS_LABEL" desc="The label for the option to show shortcuts in the customization menu on the New Tab Page">
+        Show shortcuts
+      </message>
       <message name="IDS_NTP_CUSTOMIZE_MY_SHORTCUTS_LABEL" desc="The label for the option to show user selected shortcuts in the customization menu on the New Tab Page">
         My shortcuts
       </message>
diff --git a/chrome/app/generated_resources_grd/IDS_NTP_CUSTOMIZE_SHOW_SHORTCUTS_LABEL.png.sha1 b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOMIZE_SHOW_SHORTCUTS_LABEL.png.sha1
new file mode 100644
index 0000000..85b5ab1
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_NTP_CUSTOMIZE_SHOW_SHORTCUTS_LABEL.png.sha1
@@ -0,0 +1 @@
+725c4099221db5eaf0cb2522f44934dda02cd1d3
\ No newline at end of file
diff --git a/chrome/app/theme/chrome_unscaled_resources.grd b/chrome/app/theme/chrome_unscaled_resources.grd
index f7cb4c7f..47b9d2dc 100644
--- a/chrome/app/theme/chrome_unscaled_resources.grd
+++ b/chrome/app/theme/chrome_unscaled_resources.grd
@@ -31,6 +31,7 @@
             </else>
           </if>
           <include name="IDR_ASSISTANT_LOGO_MONOCHROME" file="google_chrome/google_assistant.svg" type="BINDATA" />
+          <include name="IDR_CHROME_PASSWORD_MANAGER_LOGO" file="google_chrome/google_password_manager_logo.svg" type="BINDATA" />
           <include name="IDR_PRODUCT_LOGO_24PX_1X" file="google_chrome/chrome_24px_1x.svg" type="BINDATA" />
           <include name="IDR_PRODUCT_LOGO_128PX_SVG" file="google_chrome/chrome_128px.svg" type="BINDATA" />
           <if expr="chromeos_ash">
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn
index 0459eac7..2d50e2c 100644
--- a/chrome/browser/BUILD.gn
+++ b/chrome/browser/BUILD.gn
@@ -6564,6 +6564,7 @@
     ]
 
     deps += [
+      "//components/fuchsia_component_support",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.app",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.composition",
       "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.ui.scenic",
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS
index 1b2935ab..abe2719 100644
--- a/chrome/browser/DEPS
+++ b/chrome/browser/DEPS
@@ -46,6 +46,7 @@
   "+components/access_code_cast",
   "+components/accuracy_tips",
   "+components/account_manager_core",
+  "+components/app_restore",
   "+components/assist_ranker",
   "+components/autofill_assistant/android",
   "+components/autofill_assistant/browser",
@@ -156,7 +157,7 @@
   "+components/file_access",
   "+components/find_in_page",
   "+components/flags_ui",
-  "+components/app_restore",
+  "+components/fuchsia_component_support",
   "+components/gcm_driver",
   "+components/global_media_controls",
   "+components/google/core/browser",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc
index acfe9c64..4a43a82 100644
--- a/chrome/browser/about_flags.cc
+++ b/chrome/browser/about_flags.cc
@@ -4495,10 +4495,6 @@
      flag_descriptions::kEnableServiceWorkersForChromeUntrustedDescription,
      kOsCrOS,
      FEATURE_VALUE_TYPE(features::kEnableServiceWorkersForChromeUntrusted)},
-    {"crostini-bullseye-upgrade",
-     flag_descriptions::kCrostiniBullseyeUpgradeName,
-     flag_descriptions::kCrostiniBullseyeUpgradeDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(chromeos::features::kCrostiniBullseyeUpgrade)},
     {"crostini-reset-lxd-db", flag_descriptions::kCrostiniResetLxdDbName,
      flag_descriptions::kCrostiniResetLxdDbDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::features::kCrostiniResetLxdDb)},
@@ -4519,9 +4515,6 @@
      flag_descriptions::kTerminalTmuxIntegrationName,
      flag_descriptions::kTerminalTmuxIntegrationDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::features::kTerminalTmuxIntegration)},
-    {"crostini-use-lxd-4", flag_descriptions::kCrostiniUseLxd4Name,
-     flag_descriptions::kCrostiniUseLxd4Description, kOsCrOS,
-     FEATURE_VALUE_TYPE(chromeos::features::kCrostiniUseLxd4)},
     {"crostini-multi-container", flag_descriptions::kCrostiniMultiContainerName,
      flag_descriptions::kCrostiniMultiContainerDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(chromeos::features::kCrostiniMultiContainer)},
@@ -5416,9 +5409,6 @@
     {kWelcomeScreenInternalName, flag_descriptions::kWelcomeScreenName,
      flag_descriptions::kWelcomeScreenDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(ash::features::kGlanceables)},
-    {"guest-os-files", flag_descriptions::kGuestOsFilesName,
-     flag_descriptions::kGuestOsFilesDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(chromeos::features::kGuestOsFiles)},
     {"spectre-v2-mitigation", flag_descriptions::kSpectreVariant2MitigationName,
      flag_descriptions::kSpectreVariant2MitigationDescription, kOsCrOS,
      FEATURE_VALUE_TYPE(sandbox::policy::features::kSpectreVariant2Mitigation)},
@@ -7503,9 +7493,6 @@
      flag_descriptions::kCrostiniContainerInstallName,
      flag_descriptions::kCrostiniContainerInstallDescription, kOsCrOS,
      MULTI_VALUE_TYPE(kCrostiniContainerChoices)},
-    {"crostini-disk-resizing", flag_descriptions::kCrostiniDiskResizingName,
-     flag_descriptions::kCrostiniDiskResizingDescription, kOsCrOS,
-     FEATURE_VALUE_TYPE(chromeos::features::kCrostiniDiskResizing)},
 #endif  // BUILDFLAG(IS_CHROMEOS_ASH)
 
 #if BUILDFLAG(IS_CHROMEOS_ASH)
@@ -8208,8 +8195,10 @@
 #if BUILDFLAG(ENABLE_PDF)
 
 #if !BUILDFLAG(IS_ANDROID)
+    // TODO(https://crbug.com/1278249): Add Windows once library supports it.
     {"pdf-ocr", flag_descriptions::kPdfOcrName,
-     flag_descriptions::kPdfOcrDescription, kOsDesktop,
+     flag_descriptions::kPdfOcrDescription,
+     kOsMac | kOsLinux | kOsCrOS | kOsLacros,
      FEATURE_VALUE_TYPE(features::kPdfOcr)},
 #endif  // !BUILDFLAG(IS_ANDROID)
 
@@ -8354,12 +8343,6 @@
      kOsWin | kOsLinux | kOsLacros | kOsMac | kOsCrOS | kOsAndroid | kOsFuchsia,
      FEATURE_VALUE_TYPE(net::features::kSplitCacheByNetworkIsolationKey)},
 
-    {"autofill-address-save-prompt",
-     flag_descriptions::kEnableAutofillAddressSavePromptName,
-     flag_descriptions::kEnableAutofillAddressSavePromptDescription,
-     kOsWin | kOsMac | kOsLinux | kOsLacros | kOsCrOS | kOsAndroid | kOsFuchsia,
-     FEATURE_VALUE_TYPE(autofill::features::kAutofillAddressProfileSavePrompt)},
-
 #if BUILDFLAG(IS_ANDROID)
     {"content-languages-in-language-picker",
      flag_descriptions::kContentLanguagesInLanguagePickerName,
@@ -9081,9 +9064,11 @@
 #endif
 
 #if !BUILDFLAG(IS_ANDROID)
-    {"screen-ai", flag_descriptions::kScreenAIName,
-     flag_descriptions::kScreenAIDescription, kOsDesktop,
-     FEATURE_VALUE_TYPE(features::kScreenAI)},
+    // TODO(https://crbug.com/1278249): Add Windows once library supports it.
+    {"layout-extraction", flag_descriptions::kLayoutExtractionName,
+     flag_descriptions::kLayoutExtractionDescription,
+     kOsMac | kOsLinux | kOsCrOS | kOsLacros,
+     FEATURE_VALUE_TYPE(features::kLayoutExtraction)},
 #endif
 
     {"autofill-enable-virtual-card-management-in-desktop-settings-page",
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_decoder.h b/chrome/browser/apps/app_service/app_icon/app_icon_decoder.h
index b4893d4..960d2549 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_decoder.h
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_decoder.h
@@ -6,8 +6,8 @@
 #define CHROME_BROWSER_APPS_APP_SERVICE_APP_ICON_APP_ICON_DECODER_H_
 
 #include <map>
+#include <memory>
 #include <set>
-#include <utility>
 #include <vector>
 
 #include "base/files/file_path.h"
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc b/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
index 850ce0b38..6d96ec5 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_reader.cc
@@ -5,6 +5,8 @@
 #include "chrome/browser/apps/app_service/app_icon/app_icon_reader.h"
 
 #include "base/task/thread_pool.h"
+#include "chrome/browser/apps/app_service/app_icon/app_icon_decoder.h"
+#include "chrome/browser/apps/app_service/app_icon/app_icon_factory.h"
 #include "chrome/browser/apps/app_service/app_icon/dip_px_util.h"
 #include "chrome/browser/profiles/profile.h"
 
@@ -15,7 +17,7 @@
 AppIconReader::~AppIconReader() = default;
 
 void AppIconReader::ReadIcons(const std::string& app_id,
-                              int32_t size_hint_in_dip,
+                              int32_t size_in_dip,
                               IconEffects icon_effects,
                               IconType icon_type,
                               LoadIconCallback callback) {
@@ -32,10 +34,10 @@
             FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
             base::BindOnce(&ReadOnBackgroundThread, base_path, app_id,
                            apps_util::ConvertDipToPx(
-                               size_hint_in_dip,
+                               size_in_dip,
                                /*quantize_to_supported_scale_factor=*/true)),
-            base::BindOnce(&AppIconReader::OnIconRead,
-                           weak_ptr_factory_.GetWeakPtr(), icon_type,
+            base::BindOnce(&AppIconReader::OnCompleteWithCompressedData,
+                           weak_ptr_factory_.GetWeakPtr(),
                            std::move(callback)));
         return;
       }
@@ -43,19 +45,83 @@
     case IconType::kUncompressed:
       [[fallthrough]];
     case IconType::kStandard: {
-      // TODO(crbug.com/1380608): Implement the icon reading function.
+      decodes_.emplace_back(std::make_unique<AppIconDecoder>(
+          base_path, app_id, size_in_dip,
+          base::BindOnce(&AppIconReader::OnUncompressedIconRead,
+                         weak_ptr_factory_.GetWeakPtr(), size_in_dip,
+                         icon_effects, icon_type, std::move(callback))));
+      decodes_.back()->Start();
     }
   }
 }
 
-void AppIconReader::OnIconRead(IconType icon_type,
-                               LoadIconCallback callback,
-                               std::vector<uint8_t> icon_data) {
-  // TODO(crbug.com/1380608): Implement OnIconRead for uncompressed and standard
-  // icons.
+void AppIconReader::OnUncompressedIconRead(int32_t size_in_dip,
+                                           IconEffects icon_effects,
+                                           IconType icon_type,
+                                           LoadIconCallback callback,
+                                           AppIconDecoder* decoder,
+                                           gfx::ImageSkia image) {
+  DCHECK_NE(IconType::kUnknown, icon_type);
 
   auto iv = std::make_unique<apps::IconValue>();
   iv->icon_type = icon_type;
+  iv->uncompressed = image;
+
+  auto it = base::ranges::find(decodes_, decoder,
+                               &std::unique_ptr<AppIconDecoder>::get);
+  DCHECK(it != decodes_.end());
+  decodes_.erase(it);
+
+  if (image.isNull()) {
+    std::move(callback).Run(std::move(iv));
+    return;
+  }
+
+  // Apply the icon effects on the uncompressed data. If the caller requests
+  // an uncompressed icon, return the uncompressed result; otherwise, encode
+  // the icon to a compressed icon, return the compressed result.
+  if (icon_effects) {
+    apps::ApplyIconEffects(
+        icon_effects, size_in_dip, std::move(iv),
+        base::BindOnce(&AppIconReader::OnCompleteWithIconValue,
+                       weak_ptr_factory_.GetWeakPtr(), size_in_dip, icon_type,
+                       std::move(callback)));
+    return;
+  }
+
+  // If icon effects are none, ReadIcons can return the compressed icon
+  // directly.
+  DCHECK_NE(IconType::kCompressed, icon_type);
+
+  std::move(callback).Run(std::move(iv));
+}
+
+void AppIconReader::OnCompleteWithIconValue(int32_t size_in_dip,
+                                            IconType icon_type,
+                                            LoadIconCallback callback,
+                                            IconValuePtr iv) {
+  if (icon_type != IconType::kCompressed) {
+    std::move(callback).Run(std::move(iv));
+    return;
+  }
+
+  float icon_scale = static_cast<float>(apps_util::ConvertDipToPx(
+                         size_in_dip,
+                         /*quantize_to_supported_scale_factor=*/true)) /
+                     size_in_dip;
+  base::ThreadPool::PostTaskAndReplyWithResult(
+      FROM_HERE, {base::MayBlock(), base::TaskPriority::USER_VISIBLE},
+      base::BindOnce(&apps::EncodeImageToPngBytes, iv->uncompressed,
+                     icon_scale),
+      base::BindOnce(&AppIconReader::OnCompleteWithCompressedData,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+}
+
+void AppIconReader::OnCompleteWithCompressedData(
+    LoadIconCallback callback,
+    std::vector<uint8_t> icon_data) {
+  auto iv = std::make_unique<IconValue>();
+  iv->icon_type = IconType::kCompressed;
   iv->compressed = std::move(icon_data);
 
   std::move(callback).Run(std::move(iv));
diff --git a/chrome/browser/apps/app_service/app_icon/app_icon_reader.h b/chrome/browser/apps/app_service/app_icon/app_icon_reader.h
index 929cbf1..5642a652 100644
--- a/chrome/browser/apps/app_service/app_icon/app_icon_reader.h
+++ b/chrome/browser/apps/app_service/app_icon/app_icon_reader.h
@@ -5,6 +5,7 @@
 #ifndef CHROME_BROWSER_APPS_APP_SERVICE_APP_ICON_APP_ICON_READER_H_
 #define CHROME_BROWSER_APPS_APP_SERVICE_APP_ICON_APP_ICON_READER_H_
 
+#include <memory>
 #include <string>
 #include <vector>
 
@@ -16,6 +17,8 @@
 
 namespace apps {
 
+class AppIconDecoder;
+
 // AppIconReader reads app icons from the icon image files in the local
 // disk and provides an ImageSkia for UI code to use.
 //
@@ -30,18 +33,32 @@
   // Reads specified app icons from the local disk for an app identified by
   // `app_id`.
   void ReadIcons(const std::string& app_id,
-                 int32_t size_hint_in_dip,
+                 int32_t size_in_dip,
                  IconEffects icon_effects,
                  IconType icon_type,
                  LoadIconCallback callback);
 
  private:
-  void OnIconRead(IconType icon_type,
-                  LoadIconCallback callback,
-                  std::vector<uint8_t> icon_data);
+  void OnUncompressedIconRead(int32_t size_in_dip,
+                              IconEffects icon_effects,
+                              IconType icon_type,
+                              LoadIconCallback callback,
+                              AppIconDecoder* decoder,
+                              gfx::ImageSkia image);
+
+  void OnCompleteWithIconValue(int32_t size_in_dip,
+                               IconType icon_type,
+                               LoadIconCallback callback,
+                               IconValuePtr iv);
+
+  void OnCompleteWithCompressedData(LoadIconCallback callback,
+                                    std::vector<uint8_t> icon_data);
 
   const raw_ptr<Profile> profile_;
 
+  // Contains pending image app icon decoders.
+  std::vector<std::unique_ptr<AppIconDecoder>> decodes_;
+
   base::WeakPtrFactory<AppIconReader> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/browser/apps/app_shim/mach_bootstrap_acceptor.h b/chrome/browser/apps/app_shim/mach_bootstrap_acceptor.h
index 5647270..c7b61ca 100644
--- a/chrome/browser/apps/app_shim/mach_bootstrap_acceptor.h
+++ b/chrome/browser/apps/app_shim/mach_bootstrap_acceptor.h
@@ -62,7 +62,7 @@
   mach_port_t port();
 
   mojo::NamedPlatformChannel::ServerName server_name_;
-  raw_ptr<Delegate> delegate_;
+  raw_ptr<Delegate, DanglingUntriaged> delegate_;
   mojo::PlatformChannelServerEndpoint endpoint_;
   std::unique_ptr<base::DispatchSourceMach> dispatch_source_;
 };
diff --git a/chrome/browser/apps/platform_apps/app_shim_quit_interactive_uitest_mac.mm b/chrome/browser/apps/platform_apps/app_shim_quit_interactive_uitest_mac.mm
index 469576f..651820f4 100644
--- a/chrome/browser/apps/platform_apps/app_shim_quit_interactive_uitest_mac.mm
+++ b/chrome/browser/apps/platform_apps/app_shim_quit_interactive_uitest_mac.mm
@@ -103,7 +103,7 @@
   }
 
   base::FilePath app_path_;
-  raw_ptr<AppShimManager> manager_ = nullptr;
+  raw_ptr<AppShimManager, DanglingUntriaged> manager_ = nullptr;
   std::string extension_id_;
 };
 
diff --git a/chrome/browser/ash/app_mode/kiosk_app_data.cc b/chrome/browser/ash/app_mode/kiosk_app_data.cc
index 758deec..aec2dc88 100644
--- a/chrome/browser/ash/app_mode/kiosk_app_data.cc
+++ b/chrome/browser/ash/app_mode/kiosk_app_data.cc
@@ -217,7 +217,7 @@
       std::unique_ptr<base::DictionaryValue> parsed_manifest) override {
     extensions::Manifest manifest(
         extensions::mojom::ManifestLocation::kInvalidLocation,
-        std::move(parsed_manifest), id);
+        std::move(*parsed_manifest).TakeDict(), id);
 
     if (!IsValidKioskAppManifest(manifest)) {
       ReportFailure();
diff --git a/chrome/browser/ash/crostini/crostini_manager.cc b/chrome/browser/ash/crostini/crostini_manager.cc
index 52bbe7a..fa8186e 100644
--- a/chrome/browser/ash/crostini/crostini_manager.cc
+++ b/chrome/browser/ash/crostini/crostini_manager.cc
@@ -1058,12 +1058,8 @@
 }
 
 bool IsUpgradableContainerVersion(ContainerOsVersion version) {
-  if (base::FeatureList::IsEnabled(
-          chromeos::features::kCrostiniBullseyeUpgrade)) {
-    return version == ContainerOsVersion::kDebianStretch ||
-           version == ContainerOsVersion::kDebianBuster;
-  }
-  return version == ContainerOsVersion::kDebianStretch;
+  return version == ContainerOsVersion::kDebianStretch ||
+         version == ContainerOsVersion::kDebianBuster;
 }
 
 }  // namespace
@@ -1562,9 +1558,7 @@
       profile_->GetPrefs()->GetBoolean(::prefs::kAudioCaptureAllowed)) {
     request.set_enable_audio_capture(true);
   }
-  if (base::FeatureList::IsEnabled(chromeos::features::kCrostiniUseLxd4)) {
-    request.add_features(vm_tools::concierge::StartVmRequest::LXD_4_LTS);
-  }
+  request.add_features(vm_tools::concierge::StartVmRequest::LXD_4_LTS);
   const int32_t cpus = base::SysInfo::NumberOfProcessors() - num_cores_disabled;
   DCHECK_LT(0, cpus);
   request.set_cpus(cpus);
diff --git a/chrome/browser/ash/crostini/crostini_upgrader.cc b/chrome/browser/ash/crostini/crostini_upgrader.cc
index 494867b..07d452ac 100644
--- a/chrome/browser/ash/crostini/crostini_upgrader.cc
+++ b/chrome/browser/ash/crostini/crostini_upgrader.cc
@@ -4,8 +4,6 @@
 
 #include "chrome/browser/ash/crostini/crostini_upgrader.h"
 
-#include "ash/constants/ash_features.h"
-#include "base/feature_list.h"
 #include "base/files/file_util.h"
 #include "base/location.h"
 #include "base/no_destructor.h"
@@ -327,13 +325,7 @@
               return;
             }
 
-            ContainerVersion target_version;
-            if (base::FeatureList::IsEnabled(
-                    chromeos::features::kCrostiniBullseyeUpgrade)) {
-              target_version = ContainerVersion::BULLSEYE;
-            } else {
-              target_version = ContainerVersion::BUSTER;
-            }
+            auto target_version = ContainerVersion::BULLSEYE;
 
             CrostiniManager::GetForProfile(weak_this->profile_)
                 ->UpgradeContainer(
diff --git a/chrome/browser/ash/extensions/desk_api/desk_api_extension_manager.h b/chrome/browser/ash/extensions/desk_api/desk_api_extension_manager.h
index fbc07170..0edcd51 100644
--- a/chrome/browser/ash/extensions/desk_api/desk_api_extension_manager.h
+++ b/chrome/browser/ash/extensions/desk_api/desk_api_extension_manager.h
@@ -87,8 +87,9 @@
   // Removes the component extension if it is already installed.
   void RemoveExtensionIfInstalled();
 
-  const raw_ptr<::extensions::ComponentLoader> component_loader_;
-  const raw_ptr<Profile> profile_;
+  const raw_ptr<::extensions::ComponentLoader, DanglingUntriaged>
+      component_loader_;
+  const raw_ptr<Profile, DanglingUntriaged> profile_;
 
   const std::unique_ptr<Delegate> delegate_;
   PrefChangeRegistrar registrar_;
diff --git a/chrome/browser/ash/extensions/file_manager/event_router.cc b/chrome/browser/ash/extensions/file_manager/event_router.cc
index 6ad12ba17..070cda3d 100644
--- a/chrome/browser/ash/extensions/file_manager/event_router.cc
+++ b/chrome/browser/ash/extensions/file_manager/event_router.cc
@@ -13,7 +13,6 @@
 #include <vector>
 
 #include "ash/components/arc/arc_prefs.h"
-#include "ash/constants/ash_features.h"
 #include "ash/constants/ash_pref_names.h"
 #include "ash/public/cpp/tablet_mode.h"
 #include "ash/webui/file_manager/file_manager_ui.h"
@@ -574,11 +573,9 @@
       chromeos::PowerManagerClient::Get();
   power_manager_client->RemoveObserver(device_event_router_.get());
 
-  if (base::FeatureList::IsEnabled(chromeos::features::kGuestOsFiles)) {
-    auto* registry = guest_os::GuestOsService::GetForProfile(profile_)
-                         ->MountProviderRegistry();
-    registry->RemoveObserver(this);
-  }
+  auto* registry = guest_os::GuestOsService::GetForProfile(profile_)
+                       ->MountProviderRegistry();
+  registry->RemoveObserver(this);
 
   if (apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(profile_)) {
     apps::AppServiceProxy* proxy =
@@ -681,11 +678,9 @@
   if (tablet_mode)
     tablet_mode->AddObserver(this);
 
-  if (base::FeatureList::IsEnabled(chromeos::features::kGuestOsFiles)) {
-    auto* registry = guest_os::GuestOsService::GetForProfile(profile_)
-                         ->MountProviderRegistry();
-    registry->AddObserver(this);
-  }
+  auto* registry = guest_os::GuestOsService::GetForProfile(profile_)
+                       ->MountProviderRegistry();
+  registry->AddObserver(this);
 
   if (apps::AppServiceProxyFactory::IsAppServiceAvailableForProfile(profile_)) {
     apps::AppServiceProxy* proxy =
diff --git a/chrome/browser/ash/extensions/file_manager/private_api_file_system.cc b/chrome/browser/ash/extensions/file_manager/private_api_file_system.cc
index 1726c98..8d019f9 100644
--- a/chrome/browser/ash/extensions/file_manager/private_api_file_system.cc
+++ b/chrome/browser/ash/extensions/file_manager/private_api_file_system.cc
@@ -1644,12 +1644,13 @@
   validator_ = std::make_unique<file_manager::trash::TrashInfoValidator>(
       profile, /*base_path=*/base::FilePath());
 
-  auto barrier_callback = base::BarrierCallback<
-      base::FileErrorOr<file_manager::trash::ParsedTrashInfoData>>(
-      trash_info_paths.size(),
-      base::BindOnce(&FileManagerPrivateInternalParseTrashInfoFilesFunction::
-                         OnTrashInfoFilesParsed,
-                     this));
+  auto barrier_callback =
+      base::BarrierCallback<file_manager::trash::ParsedTrashInfoDataOrError>(
+          trash_info_paths.size(),
+          base::BindOnce(
+              &FileManagerPrivateInternalParseTrashInfoFilesFunction::
+                  OnTrashInfoFilesParsed,
+              this));
 
   for (const base::FilePath& path : trash_info_paths) {
     validator_->ValidateAndParseTrashInfo(std::move(path), barrier_callback);
@@ -1660,8 +1661,8 @@
 
 void FileManagerPrivateInternalParseTrashInfoFilesFunction::
     OnTrashInfoFilesParsed(
-        std::vector<base::FileErrorOr<file_manager::trash::ParsedTrashInfoData>>
-            parsed_data) {
+        std::vector<file_manager::trash::ParsedTrashInfoDataOrError>
+            parsed_data_or_error) {
   // The underlying trash service could potentially live longer than the Files
   // window that invoked this function, ensure the frame host and browser
   // context are alive before continuing.
@@ -1676,24 +1677,24 @@
   std::vector<file_manager::trash::ParsedTrashInfoData> valid_data;
   url::Origin origin = render_frame_host()->GetLastCommittedOrigin();
 
-  for (auto& trash_info_data : parsed_data) {
-    if (!trash_info_data.has_value()) {
+  for (auto& trash_info_data_or_error : parsed_data_or_error) {
+    if (!trash_info_data_or_error.has_value()) {
       LOG(ERROR) << "Failed parsing trashinfo file: "
-                 << trash_info_data.error();
+                 << trash_info_data_or_error.error();
       continue;
     }
 
     file_manager::util::FileDefinition file_definition;
     if (!file_manager::util::ConvertAbsoluteFilePathToRelativeFileSystemPath(
             Profile::FromBrowserContext(browser_context()), origin.GetURL(),
-            trash_info_data.value().absolute_restore_path,
+            trash_info_data_or_error.value().absolute_restore_path,
             &file_definition.virtual_path)) {
       LOG(ERROR) << "Failed to convert absolute path to relative path";
       continue;
     }
 
     file_definition_list.push_back(std::move(file_definition));
-    valid_data.push_back(std::move(trash_info_data.value()));
+    valid_data.push_back(std::move(trash_info_data_or_error.value()));
   }
 
   file_manager::util::ConvertFileDefinitionListToEntryDefinitionList(
diff --git a/chrome/browser/ash/extensions/file_manager/private_api_file_system.h b/chrome/browser/ash/extensions/file_manager/private_api_file_system.h
index 0a49a83..c9e2acaf 100644
--- a/chrome/browser/ash/extensions/file_manager/private_api_file_system.h
+++ b/chrome/browser/ash/extensions/file_manager/private_api_file_system.h
@@ -17,6 +17,7 @@
 
 #include "base/callback_forward.h"
 #include "base/memory/weak_ptr.h"
+#include "base/types/expected.h"
 #include "chrome/browser/ash/extensions/file_manager/logged_extension_function.h"
 #include "chrome/browser/ash/file_manager/trash_info_validator.h"
 #include "chrome/browser/ash/policy/dlp/dlp_files_controller.h"
@@ -542,8 +543,7 @@
   // retrieved from the .trashinfo files. If any are error'd out they are logged
   // and ultimately discarded.
   void OnTrashInfoFilesParsed(
-      std::vector<base::FileErrorOr<file_manager::trash::ParsedTrashInfoData>>
-          parsed_data);
+      std::vector<file_manager::trash::ParsedTrashInfoDataOrError> parsed_data);
 
   // After converting the restorePath (converted to Entry to ensure we can
   // perform a getMetadata on it to verify existence) zip the 2 `std::vector`'s
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest.cc b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
index 8788675d..83ce3028 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest.cc
@@ -162,11 +162,6 @@
     return *this;
   }
 
-  TestCase& EnableGuestOsFiles() {
-    options.enable_guest_os_files = true;
-    return *this;
-  }
-
   TestCase& EnableVirtioBlkForData() {
     options.enable_virtio_blk_for_data = true;
     return *this;
@@ -816,8 +811,7 @@
         TestCase("fileDisplayCheckReadOnlyIconOnFakeDirectory"),
         TestCase("fileDisplayCheckNoReadOnlyIconOnDownloads"),
         TestCase("fileDisplayCheckNoReadOnlyIconOnLinuxFiles"),
-        TestCase("fileDisplayCheckNoReadOnlyIconOnGuestOs")
-            .EnableGuestOsFiles()));
+        TestCase("fileDisplayCheckNoReadOnlyIconOnGuestOs")));
 
 WRAPPED_INSTANTIATE_TEST_SUITE_P(
     OpenVideoMediaApp, /* open_video_media_app.js */
@@ -1038,13 +1032,11 @@
         TestCase("openQuickViewDrive"),
         TestCase("openQuickViewSmbfs"),
         TestCase("openQuickViewAndroid"),
-        TestCase("openQuickViewAndroidGuestOs")
-            .EnableGuestOsFiles()
-            .EnableVirtioBlkForData(),
+        TestCase("openQuickViewAndroidGuestOs").EnableVirtioBlkForData(),
         TestCase("openQuickViewDocumentsProvider")
             .EnableGenericDocumentsProvider(),
         TestCase("openQuickViewCrostini"),
-        TestCase("openQuickViewGuestOs").EnableGuestOsFiles(),
+        TestCase("openQuickViewGuestOs"),
         TestCase("openQuickViewLastModifiedMetaData")
             .EnableGenericDocumentsProvider(),
         TestCase("openQuickViewUsb"),
@@ -1454,16 +1446,10 @@
         TestCase("openFileDialogFileListShowContextMenu").WithBrowser(),
         TestCase("openFileDialogSelectAllDisabled").WithBrowser(),
         TestCase("openMultiFileDialogSelectAllEnabled").WithBrowser(),
-        TestCase("saveFileDialogGuestOs").WithBrowser().EnableGuestOsFiles(),
-        TestCase("saveFileDialogGuestOs")
-            .WithBrowser()
-            .EnableGuestOsFiles()
-            .InIncognito(),
-        TestCase("openFileDialogGuestOs").WithBrowser().EnableGuestOsFiles(),
-        TestCase("openFileDialogGuestOs")
-            .WithBrowser()
-            .EnableGuestOsFiles()
-            .InIncognito()));
+        TestCase("saveFileDialogGuestOs").WithBrowser(),
+        TestCase("saveFileDialogGuestOs").WithBrowser().InIncognito(),
+        TestCase("openFileDialogGuestOs").WithBrowser(),
+        TestCase("openFileDialogGuestOs").WithBrowser().InIncognito()));
 
 WRAPPED_INSTANTIATE_TEST_SUITE_P(
     CopyBetweenWindows, /* copy_between_windows.js */
@@ -1784,12 +1770,9 @@
     GuestOs, /* guest_os.js */
     FilesAppBrowserTest,
     ::testing::Values(
-        TestCase("fakesListed").EnableGuestOsFiles(),
-        TestCase("listUpdatedWhenGuestsChanged").EnableGuestOsFiles(),
-        TestCase("mountGuestSuccess").EnableGuestOsFiles(),
-        TestCase("notListedWithoutFlag"),
-        TestCase("mountAndroidVolumeSuccess")
-            .EnableGuestOsFiles()
-            .EnableVirtioBlkForData()));
+        TestCase("fakesListed"),
+        TestCase("listUpdatedWhenGuestsChanged"),
+        TestCase("mountGuestSuccess"),
+        TestCase("mountAndroidVolumeSuccess").EnableVirtioBlkForData()));
 
 }  // namespace file_manager
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
index 6dbe168..9b62af9 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -858,7 +858,6 @@
   PRINT_IF_NOT_DEFAULT(photos_documents_provider)
   PRINT_IF_NOT_DEFAULT(single_partition_format)
   PRINT_IF_NOT_DEFAULT(tablet_mode)
-  PRINT_IF_NOT_DEFAULT(enable_guest_os_files)
   PRINT_IF_NOT_DEFAULT(enable_virtio_blk_for_data)
 
 #undef PRINT_IF_NOT_DEFAULT
@@ -1977,12 +1976,6 @@
         command_line->GetSwitchValuePath(switches::kDevtoolsCodeCoverage);
   }
 
-  if (options.enable_guest_os_files) {
-    enabled_features.push_back(chromeos::features::kGuestOsFiles);
-  } else {
-    disabled_features.push_back(chromeos::features::kGuestOsFiles);
-  }
-
   if (options.enable_virtio_blk_for_data) {
     enabled_features.push_back(arc::kEnableVirtioBlkForData);
   } else {
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.h b/chrome/browser/ash/file_manager/file_manager_browsertest_base.h
index 7f631f3..539fca6 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.h
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.h
@@ -121,9 +121,6 @@
     // Whether test should run with the Upload Office to Cloud feature.
     bool enable_upload_office_to_cloud = false;
 
-    // Whether test should run with the GuestOs <-> Files app integration.
-    bool enable_guest_os_files = false;
-
     // Whether test should run Android with the virtio-blk for /data.
     bool enable_virtio_blk_for_data = false;
 
diff --git a/chrome/browser/ash/file_manager/file_manager_jstest.cc b/chrome/browser/ash/file_manager/file_manager_jstest.cc
index f64183a..7bd56a7 100644
--- a/chrome/browser/ash/file_manager/file_manager_jstest.cc
+++ b/chrome/browser/ash/file_manager/file_manager_jstest.cc
@@ -274,10 +274,6 @@
   RunTestURL("foreground/js/metadata/thumbnail_model_unittest.js");
 }
 
-IN_PROC_BROWSER_TEST_F(FileManagerJsTest, Trash) {
-  RunTestURL("background/js/trash_unittest.js");
-}
-
 IN_PROC_BROWSER_TEST_F(FileManagerJsTest, UtilTest) {
   RunTestURL("common/js/util_unittest.js");
 }
diff --git a/chrome/browser/ash/file_manager/file_manager_string_util.cc b/chrome/browser/ash/file_manager/file_manager_string_util.cc
index 206ad99c..123fe06 100644
--- a/chrome/browser/ash/file_manager/file_manager_string_util.cc
+++ b/chrome/browser/ash/file_manager/file_manager_string_util.cc
@@ -1071,8 +1071,7 @@
   dict->Set("INLINE_SYNC_STATUS",
             chromeos::features::IsInlineSyncStatusEnabled());
 
-  dict->Set("GUEST_OS",
-            base::FeatureList::IsEnabled(chromeos::features::kGuestOsFiles));
+  dict->Set("GUEST_OS", true);
 
   if (base::FeatureList::IsEnabled(features::kDataLeakPreventionPolicy) &&
       base::FeatureList::IsEnabled(
diff --git a/chrome/browser/ash/file_manager/restore_io_task.cc b/chrome/browser/ash/file_manager/restore_io_task.cc
index af40997..923bd3eb 100644
--- a/chrome/browser/ash/file_manager/restore_io_task.cc
+++ b/chrome/browser/ash/file_manager/restore_io_task.cc
@@ -128,21 +128,23 @@
 
 void RestoreIOTask::EnsureParentRestorePathExists(
     size_t idx,
-    base::FileErrorOr<trash::ParsedTrashInfoData> parsed_data) {
-  if (!parsed_data.has_value()) {
-    progress_.sources[idx].error = parsed_data.error();
+    trash::ParsedTrashInfoDataOrError parsed_data_or_error) {
+  if (!parsed_data_or_error.has_value()) {
+    progress_.sources[idx].error =
+        trash::ValidationErrorToFileError(parsed_data_or_error.error());
     Complete(State::kError);
     return;
   }
 
   base::ThreadPool::PostTaskAndReplyWithResult(
       FROM_HERE, {base::MayBlock()},
-      base::BindOnce(&CreateNestedPath,
-                     parsed_data.value().absolute_restore_path.DirName()),
+      base::BindOnce(
+          &CreateNestedPath,
+          parsed_data_or_error.value().absolute_restore_path.DirName()),
       base::BindOnce(&RestoreIOTask::OnParentRestorePathExists,
                      weak_ptr_factory_.GetWeakPtr(), idx,
-                     parsed_data.value().trashed_file_path,
-                     parsed_data.value().absolute_restore_path));
+                     parsed_data_or_error.value().trashed_file_path,
+                     parsed_data_or_error.value().absolute_restore_path));
 }
 
 void RestoreIOTask::OnParentRestorePathExists(
diff --git a/chrome/browser/ash/file_manager/restore_io_task.h b/chrome/browser/ash/file_manager/restore_io_task.h
index 808ad91..050f6456 100644
--- a/chrome/browser/ash/file_manager/restore_io_task.h
+++ b/chrome/browser/ash/file_manager/restore_io_task.h
@@ -54,7 +54,7 @@
   // actually exists. In the event the file path has been removed, recreate it.
   void EnsureParentRestorePathExists(
       size_t idx,
-      base::FileErrorOr<trash::ParsedTrashInfoData> parsed_data);
+      trash::ParsedTrashInfoDataOrError parsed_data_or_error);
 
   void OnParentRestorePathExists(size_t idx,
                                  const base::FilePath& trashed_file_location,
diff --git a/chrome/browser/ash/file_manager/restore_to_destination_io_task.cc b/chrome/browser/ash/file_manager/restore_to_destination_io_task.cc
index d70a1129..9faf8255 100644
--- a/chrome/browser/ash/file_manager/restore_to_destination_io_task.cc
+++ b/chrome/browser/ash/file_manager/restore_to_destination_io_task.cc
@@ -11,6 +11,7 @@
 #include "base/task/sequenced_task_runner.h"
 #include "chrome/browser/ash/file_manager/io_task_util.h"
 #include "chrome/browser/ash/file_manager/path_util.h"
+#include "chrome/browser/ash/file_manager/trash_info_validator.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace file_manager::io_task {
@@ -109,19 +110,21 @@
 
 void RestoreToDestinationIOTask::OnTrashInfoParsed(
     size_t idx,
-    base::FileErrorOr<trash::ParsedTrashInfoData> parsed_data) {
-  if (!parsed_data.has_value()) {
-    progress_.sources[idx].error = parsed_data.error();
+    trash::ParsedTrashInfoDataOrError parsed_data_or_error) {
+  if (!parsed_data_or_error.has_value()) {
+    progress_.sources[idx].error =
+        trash::ValidationErrorToFileError(parsed_data_or_error.error());
     Complete(State::kError);
     return;
   }
 
   destination_file_names_.emplace_back(
-      parsed_data.value().absolute_restore_path.BaseName());
+      parsed_data_or_error.value().absolute_restore_path.BaseName());
   source_urls_.push_back(file_system_context_->CreateCrackedFileSystemURL(
       progress_.sources[idx].url.storage_key(),
       progress_.sources[idx].url.type(),
-      MakeRelativeFromBasePath(parsed_data.value().trashed_file_path)));
+      MakeRelativeFromBasePath(
+          parsed_data_or_error.value().trashed_file_path)));
 
   if (progress_.sources.size() == (idx + 1)) {
     // Make sure to reset the TrashInfoValidator as it is not required anymore.
diff --git a/chrome/browser/ash/file_manager/restore_to_destination_io_task.h b/chrome/browser/ash/file_manager/restore_to_destination_io_task.h
index 9e8ac56..460c8387 100644
--- a/chrome/browser/ash/file_manager/restore_to_destination_io_task.h
+++ b/chrome/browser/ash/file_manager/restore_to_destination_io_task.h
@@ -8,11 +8,11 @@
 #include <memory>
 #include <vector>
 
-#include "base/files/file_error_or.h"
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
+#include "base/types/expected.h"
 #include "chrome/browser/ash/file_manager/copy_or_move_io_task.h"
 #include "chrome/browser/ash/file_manager/io_task.h"
 #include "chrome/browser/ash/file_manager/trash_info_validator.h"
@@ -65,7 +65,7 @@
   // `move_io_task`
   void OnTrashInfoParsed(
       size_t idx,
-      base::FileErrorOr<trash::ParsedTrashInfoData> parsed_data);
+      trash::ParsedTrashInfoDataOrError parsed_data_or_error);
 
   // Used to intercept the `move_io_task_` ProgressCallback and ensure the
   // progress is coming from the current task with the relevant task_id.
diff --git a/chrome/browser/ash/file_manager/trash_info_validator.cc b/chrome/browser/ash/file_manager/trash_info_validator.cc
index e5e592db..06055b58 100644
--- a/chrome/browser/ash/file_manager/trash_info_validator.cc
+++ b/chrome/browser/ash/file_manager/trash_info_validator.cc
@@ -6,6 +6,7 @@
 
 #include "base/files/file.h"
 #include "base/files/file_util.h"
+#include "base/notreached.h"
 #include "base/strings/string_piece.h"
 #include "base/task/bind_post_task.h"
 #include "base/task/sequenced_task_runner.h"
@@ -18,9 +19,9 @@
 
 namespace {
 
-void RunCallbackWithError(base::File::Error error,
+void RunCallbackWithError(ValidationError error,
                           ValidateAndParseTrashInfoCallback callback) {
-  std::move(callback).Run(base::unexpected(error));
+  std::move(callback).Run(base::unexpected<ValidationError>(std::move(error)));
 }
 
 }  // namespace
@@ -32,6 +33,43 @@
 ParsedTrashInfoData& ParsedTrashInfoData::operator=(
     ParsedTrashInfoData&& other) = default;
 
+std::ostream& operator<<(std::ostream& out, const ValidationError& value) {
+  switch (value) {
+    case ValidationError::kFileNotExist:
+      out << "kFileNotExist";
+      break;
+    case ValidationError::kInfoNotExist:
+      out << "kInfoNotExist";
+      break;
+    case ValidationError::kInfoFileInvalidLocation:
+      out << "kInfoFileInvalidLocation";
+      break;
+    case ValidationError::kInfoFileInvalid:
+      out << "kInfoFileInvalid";
+      break;
+    default:
+      NOTREACHED();
+      break;
+  }
+  return out;
+}
+
+base::File::Error ValidationErrorToFileError(ValidationError error) {
+  switch (error) {
+    case ValidationError::kFileNotExist:
+      return base::File::FILE_ERROR_NOT_FOUND;
+    case ValidationError::kInfoNotExist:
+      return base::File::FILE_ERROR_NOT_FOUND;
+    case ValidationError::kInfoFileInvalidLocation:
+      return base::File::FILE_ERROR_INVALID_URL;
+    case ValidationError::kInfoFileInvalid:
+      return base::File::FILE_ERROR_INVALID_OPERATION;
+    default:
+      NOTREACHED();
+      break;
+  }
+}
+
 TrashInfoValidator::TrashInfoValidator(Profile* profile,
                                        const base::FilePath& base_path) {
   enabled_trash_locations_ =
@@ -55,7 +93,7 @@
     ValidateAndParseTrashInfoCallback callback) {
   // Validates the supplied file ends in a .trashinfo extension.
   if (trash_info_path.FinalExtension() != kTrashInfoExtension) {
-    RunCallbackWithError(base::File::FILE_ERROR_INVALID_URL,
+    RunCallbackWithError(ValidationError::kInfoFileInvalid,
                          std::move(callback));
     return;
   }
@@ -73,7 +111,7 @@
   }
 
   if (mount_point_path.empty() || trash_folder_location.empty()) {
-    RunCallbackWithError(base::File::FILE_ERROR_INVALID_OPERATION,
+    RunCallbackWithError(ValidationError::kInfoFileInvalidLocation,
                          std::move(callback));
     return;
   }
@@ -100,7 +138,7 @@
     ValidateAndParseTrashInfoCallback callback,
     bool exists) {
   if (!exists) {
-    RunCallbackWithError(base::File::FILE_ERROR_NOT_FOUND, std::move(callback));
+    RunCallbackWithError(ValidationError::kFileNotExist, std::move(callback));
     return;
   }
 
@@ -123,14 +161,17 @@
     const base::FilePath& restore_path,
     base::Time deletion_date) {
   if (status != base::File::FILE_OK) {
-    RunCallbackWithError(status, std::move(callback));
+    RunCallbackWithError((status == base::File::FILE_ERROR_NOT_FOUND)
+                             ? ValidationError::kInfoNotExist
+                             : ValidationError::kInfoFileInvalid,
+                         std::move(callback));
     return;
   }
 
   // The restore path that was parsed could be empty or not have a leading "/".
   if (restore_path.empty() ||
       restore_path.value()[0] != base::FilePath::kSeparators[0]) {
-    RunCallbackWithError(base::File::FILE_ERROR_INVALID_URL,
+    RunCallbackWithError(ValidationError::kInfoFileInvalid,
                          std::move(callback));
     return;
   }
@@ -147,7 +188,8 @@
   parsed_data.absolute_restore_path = std::move(absolute_restore_path);
   parsed_data.deletion_date = std::move(deletion_date);
 
-  std::move(callback).Run(std::move(parsed_data));
+  std::move(callback).Run(
+      base::ok<ParsedTrashInfoData>(std::move(parsed_data)));
 }
 
 }  // namespace file_manager::trash
diff --git a/chrome/browser/ash/file_manager/trash_info_validator.h b/chrome/browser/ash/file_manager/trash_info_validator.h
index d9328946..b931a1c 100644
--- a/chrome/browser/ash/file_manager/trash_info_validator.h
+++ b/chrome/browser/ash/file_manager/trash_info_validator.h
@@ -7,10 +7,9 @@
 
 #include <utility>
 
-#include "base/callback.h"
-#include "base/files/file_error_or.h"
 #include "base/files/file_path.h"
 #include "base/time/time.h"
+#include "base/types/expected.h"
 #include "chrome/browser/ash/file_manager/trash_common_util.h"
 #include "chromeos/ash/components/trash_service/public/cpp/trash_info_parser.h"
 
@@ -41,9 +40,25 @@
   base::Time deletion_date;
 };
 
+// Possible validation errors that may arise.
+enum class ValidationError {
+  kFileNotExist = 0,
+  kInfoNotExist = 1,
+  kInfoFileInvalid = 2,
+  kInfoFileInvalidLocation = 3,
+};
+
+// Helper operator to enable pretty printing of the validation errors to logs.
+std::ostream& operator<<(std::ostream& out, const ValidationError& value);
+
+// Helper to convert the underlying `ValidationError` to a base::File::Error.
+base::File::Error ValidationErrorToFileError(ValidationError error);
+
 // Helper alias to define the callback type that is returned from the validator.
+using ParsedTrashInfoDataOrError =
+    base::expected<ParsedTrashInfoData, ValidationError>;
 using ValidateAndParseTrashInfoCallback =
-    base::OnceCallback<void(base::FileErrorOr<ParsedTrashInfoData>)>;
+    base::OnceCallback<void(ParsedTrashInfoDataOrError)>;
 
 // Validates and parses individual .trashinfo files to ensure they conform to
 // the XDG specification. This is exposed here as we need to get a file handler
diff --git a/chrome/browser/ash/telemetry_extension/BUILD.gn b/chrome/browser/ash/telemetry_extension/BUILD.gn
index 2ca5790..9557f04 100644
--- a/chrome/browser/ash/telemetry_extension/BUILD.gn
+++ b/chrome/browser/ash/telemetry_extension/BUILD.gn
@@ -32,6 +32,7 @@
 source_set("unit_tests") {
   testonly = true
   sources = [
+    "diagnostics_service_ash_unittest.cc",
     "diagnostics_service_converters_unittest.cc",
     "probe_service_ash_unittest.cc",
     "probe_service_converters_unittest.cc",
diff --git a/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.cc b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.cc
index 7affd5f..c5d8c31 100644
--- a/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.cc
+++ b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.cc
@@ -336,6 +336,18 @@
           std::move(callback)));
 }
 
+void DiagnosticsServiceAsh::RunSensitiveSensorRoutine(
+    RunSensitiveSensorRoutineCallback callback) {
+  GetService()->RunSensitiveSensorRoutine(base::BindOnce(
+      [](crosapi::mojom::DiagnosticsService::RunSensitiveSensorRoutineCallback
+             callback,
+         cros_healthd::mojom::RunRoutineResponsePtr ptr) {
+        std::move(callback).Run(
+            converters::ConvertDiagnosticsPtr(std::move(ptr)));
+      },
+      std::move(callback)));
+}
+
 void DiagnosticsServiceAsh::RunSignalStrengthRoutine(
     RunSignalStrengthRoutineCallback callback) {
   GetService()->RunSignalStrengthRoutine(base::BindOnce(
diff --git a/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h
index 95dd487..f1ddc144 100644
--- a/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h
+++ b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h
@@ -99,6 +99,8 @@
       RunNvmeWearLevelRoutineCallback callback) override;
   void RunPrimeSearchRoutine(uint32_t length_seconds,
                              RunPrimeSearchRoutineCallback callback) override;
+  void RunSensitiveSensorRoutine(
+      RunSensitiveSensorRoutineCallback callback) override;
   void RunSignalStrengthRoutine(
       RunSignalStrengthRoutineCallback callback) override;
   void RunSmartctlCheckRoutine(
diff --git a/chrome/browser/ash/telemetry_extension/diagnostics_service_ash_unittest.cc b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash_unittest.cc
new file mode 100644
index 0000000..69ff58b
--- /dev/null
+++ b/chrome/browser/ash/telemetry_extension/diagnostics_service_ash_unittest.cc
@@ -0,0 +1,450 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/telemetry_extension/diagnostics_service_ash.h"
+
+#include <cstdint>
+#include <memory>
+#include <utility>
+#include <vector>
+
+#include "base/test/task_environment.h"
+#include "base/test/test_future.h"
+#include "chromeos/ash/services/cros_healthd/public/cpp/fake_cros_healthd.h"
+#include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom.h"
+#include "chromeos/crosapi/mojom/diagnostics_service.mojom.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace ash {
+
+class DiagnosticsServiceAshTest : public testing::Test {
+ public:
+  // testing::Test:
+  void SetUp() override { cros_healthd::FakeCrosHealthd::Initialize(); }
+  void TearDown() override { cros_healthd::FakeCrosHealthd::Shutdown(); }
+
+  crosapi::mojom::DiagnosticsServiceProxy* diagnostics_service() {
+    return remote_diagnostics_service_.get();
+  }
+
+ protected:
+  void SetSuccessfulRoutineResponse() {
+    auto response = cros_healthd::mojom::RunRoutineResponse::New();
+    response->status = cros_healthd::mojom::DiagnosticRoutineStatusEnum::kReady;
+    response->id = 42;
+    cros_healthd::FakeCrosHealthd::Get()->SetRunRoutineResponseForTesting(
+        response);
+  }
+
+  void ValidateResponse(
+      const crosapi::mojom::DiagnosticsRunRoutineResponsePtr& result,
+      cros_healthd::mojom::DiagnosticRoutineEnum expected_routine) {
+    EXPECT_EQ(result->id, 42);
+    EXPECT_EQ(result->status,
+              crosapi::mojom::DiagnosticsRoutineStatusEnum::kReady);
+    EXPECT_EQ(cros_healthd::FakeCrosHealthd::Get()->GetLastRunRoutine(),
+              expected_routine);
+  }
+
+ private:
+  base::test::TaskEnvironment task_environment_;
+
+  mojo::Remote<crosapi::mojom::DiagnosticsService> remote_diagnostics_service_;
+  std::unique_ptr<crosapi::mojom::DiagnosticsService> diagnostics_service_{
+      DiagnosticsServiceAsh::Factory::Create(
+          remote_diagnostics_service_.BindNewPipeAndPassReceiver())};
+};
+
+TEST_F(DiagnosticsServiceAshTest, GetAvailableRoutinesSuccess) {
+  // Configure FakeCrosHealthd.
+  {
+    cros_healthd::FakeCrosHealthd::Get()->SetAvailableRoutinesForTesting({
+        cros_healthd::mojom::DiagnosticRoutineEnum::kAcPower,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryCapacity,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryCharge,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryDischarge,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryHealth,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kCpuCache,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kFloatingPointAccuracy,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kPrimeSearch,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kCpuStress,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kDiskRead,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kDnsResolution,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kDnsResolverPresent,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kLanConnectivity,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kMemory,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kNvmeWearLevel,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kSignalStrength,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kGatewayCanBePinged,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kSmartctlCheck,
+        cros_healthd::mojom::DiagnosticRoutineEnum::kSensitiveSensor,
+    });
+  }
+
+  base::test::TestFuture<
+      const std::vector<crosapi::mojom::DiagnosticsRoutineEnum>&>
+      future;
+  diagnostics_service()->GetAvailableRoutines(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+
+  EXPECT_THAT(
+      future.Get(),
+      testing::ElementsAre(
+          crosapi::mojom::DiagnosticsRoutineEnum::kAcPower,
+          crosapi::mojom::DiagnosticsRoutineEnum::kBatteryCapacity,
+          crosapi::mojom::DiagnosticsRoutineEnum::kBatteryCharge,
+          crosapi::mojom::DiagnosticsRoutineEnum::kBatteryDischarge,
+          crosapi::mojom::DiagnosticsRoutineEnum::kBatteryHealth,
+          crosapi::mojom::DiagnosticsRoutineEnum::kCpuCache,
+          crosapi::mojom::DiagnosticsRoutineEnum::kFloatingPointAccuracy,
+          crosapi::mojom::DiagnosticsRoutineEnum::kPrimeSearch,
+          crosapi::mojom::DiagnosticsRoutineEnum::kCpuStress,
+          crosapi::mojom::DiagnosticsRoutineEnum::kDiskRead,
+          crosapi::mojom::DiagnosticsRoutineEnum::kDnsResolution,
+          crosapi::mojom::DiagnosticsRoutineEnum::kDnsResolverPresent,
+          crosapi::mojom::DiagnosticsRoutineEnum::kLanConnectivity,
+          crosapi::mojom::DiagnosticsRoutineEnum::kMemory,
+          crosapi::mojom::DiagnosticsRoutineEnum::kNvmeWearLevel,
+          crosapi::mojom::DiagnosticsRoutineEnum::kSignalStrength,
+          crosapi::mojom::DiagnosticsRoutineEnum::kGatewayCanBePinged,
+          crosapi::mojom::DiagnosticsRoutineEnum::kSmartctlCheck,
+          crosapi::mojom::DiagnosticsRoutineEnum::kSensitiveSensor));
+}
+
+TEST_F(DiagnosticsServiceAshTest, GetRoutineUpdateSuccess) {
+  constexpr char kStatusMessage[] = "Routine ran by Google.";
+  constexpr uint32_t kProgress = 87;
+
+  // Configure FakeCrosHealthd.
+  {
+    auto non_interactive_routine_update =
+        cros_healthd::mojom::NonInteractiveRoutineUpdate::New();
+    non_interactive_routine_update->status =
+        cros_healthd::mojom::DiagnosticRoutineStatusEnum::kReady;
+    non_interactive_routine_update->status_message = kStatusMessage;
+
+    auto routine_update_union =
+        cros_healthd::mojom::RoutineUpdateUnion::NewNoninteractiveUpdate(
+            std::move(non_interactive_routine_update));
+
+    auto response = cros_healthd::mojom::RoutineUpdate::New();
+    response->progress_percent = kProgress;
+    response->routine_update_union = std::move(routine_update_union);
+
+    cros_healthd::FakeCrosHealthd::Get()->SetGetRoutineUpdateResponseForTesting(
+        response);
+  }
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRoutineUpdatePtr> future;
+  diagnostics_service()->GetRoutineUpdate(
+      123456, crosapi::mojom::DiagnosticsRoutineCommandEnum::kGetStatus, true,
+      future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+
+  const auto& result = future.Get();
+  EXPECT_EQ(result->progress_percent, kProgress);
+  ASSERT_TRUE(result->routine_update_union);
+  ASSERT_TRUE(result->routine_update_union->is_noninteractive_update());
+
+  const auto& update_result =
+      result->routine_update_union->get_noninteractive_update();
+  EXPECT_EQ(update_result->status_message, kStatusMessage);
+  EXPECT_EQ(update_result->status,
+            crosapi::mojom::DiagnosticsRoutineStatusEnum::kReady);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunAcPowerRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunAcPowerRoutine(
+      crosapi::mojom::DiagnosticsAcPowerStatusEnum::kConnected, absl::nullopt,
+      future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kAcPower);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunBatteryCapacityRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunBatteryCapacityRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(
+      result, cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryCapacity);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunBatteryChargeRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunBatteryChargeRoutine(423, 123,
+                                                 future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryCharge);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunBatteryDischargeRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunBatteryDischargeRoutine(423, 123,
+                                                    future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(
+      result, cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryDischarge);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunBatteryHealthRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunBatteryHealthRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryHealth);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunCpuCacheRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunCpuCacheRoutine(100, future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kCpuCache);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunCpuStressRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunCpuStressRoutine(100, future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kCpuStress);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunDiskReadRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunDiskReadRoutine(
+      crosapi::mojom::DiagnosticsDiskReadRoutineTypeEnum::kLinearRead, 100, 32,
+      future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kDiskRead);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunDnsResolutionRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunDnsResolutionRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kDnsResolution);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunDnsResolverPresentRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunDnsResolverPresentRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(
+      result, cros_healthd::mojom::DiagnosticRoutineEnum::kDnsResolverPresent);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunFloatingPointAccuracyRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunFloatingPointAccuracyRoutine(100,
+                                                         future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(
+      result,
+      cros_healthd::mojom::DiagnosticRoutineEnum::kFloatingPointAccuracy);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunGatewayCanBePingedRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunGatewayCanBePingedRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(
+      result, cros_healthd::mojom::DiagnosticRoutineEnum::kGatewayCanBePinged);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunLanConnectivityRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunLanConnectivityRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(
+      result, cros_healthd::mojom::DiagnosticRoutineEnum::kLanConnectivity);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunMemoryRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunMemoryRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result, cros_healthd::mojom::DiagnosticRoutineEnum::kMemory);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunNvmeSelfTestRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunNvmeSelfTestRoutine(
+      crosapi::mojom::DiagnosticsNvmeSelfTestTypeEnum::kLongSelfTest,
+      future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kNvmeSelfTest);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunNvmeWearLevelRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunNvmeWearLevelRoutine(80, future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kNvmeWearLevel);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunPrimeSearchRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunPrimeSearchRoutine(100, future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kPrimeSearch);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunSensitiveSensorRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunSensitiveSensorRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(
+      result, cros_healthd::mojom::DiagnosticRoutineEnum::kSensitiveSensor);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunSignalStrengthRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunSignalStrengthRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kSignalStrength);
+}
+
+TEST_F(DiagnosticsServiceAshTest, RunSmartctlCheckRoutineSuccess) {
+  // Configure FakeCrosHealthd.
+  SetSuccessfulRoutineResponse();
+
+  base::test::TestFuture<crosapi::mojom::DiagnosticsRunRoutineResponsePtr>
+      future;
+  diagnostics_service()->RunSmartctlCheckRoutine(future.GetCallback());
+
+  ASSERT_TRUE(future.Wait());
+  const auto& result = future.Get();
+  ValidateResponse(result,
+                   cros_healthd::mojom::DiagnosticRoutineEnum::kSmartctlCheck);
+}
+
+}  // namespace ash
diff --git a/chrome/browser/ash/telemetry_extension/diagnostics_service_converters.cc b/chrome/browser/ash/telemetry_extension/diagnostics_service_converters.cc
index aa9e4ee3..199828f 100644
--- a/chrome/browser/ash/telemetry_extension/diagnostics_service_converters.cc
+++ b/chrome/browser/ash/telemetry_extension/diagnostics_service_converters.cc
@@ -72,6 +72,8 @@
 absl::optional<crosapi::mojom::DiagnosticsRoutineEnum> Convert(
     cros_healthd::mojom::DiagnosticRoutineEnum input) {
   switch (input) {
+    case cros_healthd::mojom::DiagnosticRoutineEnum::kUnknown:
+      return crosapi::mojom::DiagnosticsRoutineEnum::kUnknown;
     case cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryCapacity:
       return crosapi::mojom::DiagnosticsRoutineEnum::kBatteryCapacity;
     case cros_healthd::mojom::DiagnosticRoutineEnum::kBatteryHealth:
@@ -110,6 +112,8 @@
       return crosapi::mojom::DiagnosticsRoutineEnum::kSignalStrength;
     case cros_healthd::mojom::DiagnosticRoutineEnum::kGatewayCanBePinged:
       return crosapi::mojom::DiagnosticsRoutineEnum::kGatewayCanBePinged;
+    case cros_healthd::mojom::DiagnosticRoutineEnum::kSensitiveSensor:
+      return crosapi::mojom::DiagnosticsRoutineEnum::kSensitiveSensor;
     default:
       return absl::nullopt;
   }
diff --git a/chrome/browser/ash/telemetry_extension/diagnostics_service_converters_unittest.cc b/chrome/browser/ash/telemetry_extension/diagnostics_service_converters_unittest.cc
index 2fb4d686..089d5870 100644
--- a/chrome/browser/ash/telemetry_extension/diagnostics_service_converters_unittest.cc
+++ b/chrome/browser/ash/telemetry_extension/diagnostics_service_converters_unittest.cc
@@ -4,9 +4,14 @@
 
 #include "chrome/browser/ash/telemetry_extension/diagnostics_service_converters.h"
 
+#include <cstdint>
+#include <vector>
+
 #include "chromeos/ash/services/cros_healthd/public/mojom/cros_healthd_diagnostics.mojom.h"
 #include "chromeos/crosapi/mojom/diagnostics_service.mojom.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace ash {
 namespace converters {
@@ -20,6 +25,87 @@
           .is_null());
 }
 
+TEST(DiagnosticsServiceConvertersTest, ConvertDiagnosticRoutineEnum) {
+  namespace cros_healthd = cros_healthd::mojom;
+  namespace crosapi = ::crosapi::mojom;
+
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kAcPower),
+            crosapi::DiagnosticsRoutineEnum::kAcPower);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kBatteryCapacity),
+            crosapi::DiagnosticsRoutineEnum::kBatteryCapacity);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kBatteryHealth),
+            crosapi::DiagnosticsRoutineEnum::kBatteryHealth);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kBatteryDischarge),
+            crosapi::DiagnosticsRoutineEnum::kBatteryDischarge);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kBatteryCharge),
+            crosapi::DiagnosticsRoutineEnum::kBatteryCharge);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kCpuCache),
+            crosapi::DiagnosticsRoutineEnum::kCpuCache);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kCpuStress),
+            crosapi::DiagnosticsRoutineEnum::kCpuStress);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kDiskRead),
+            crosapi::DiagnosticsRoutineEnum::kDiskRead);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kDnsResolution),
+            crosapi::DiagnosticsRoutineEnum::kDnsResolution);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kDnsResolverPresent),
+            crosapi::DiagnosticsRoutineEnum::kDnsResolverPresent);
+  EXPECT_EQ(
+      Convert(cros_healthd::DiagnosticRoutineEnum::kFloatingPointAccuracy),
+      crosapi::DiagnosticsRoutineEnum::kFloatingPointAccuracy);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kGatewayCanBePinged),
+            crosapi::DiagnosticsRoutineEnum::kGatewayCanBePinged);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kLanConnectivity),
+            crosapi::DiagnosticsRoutineEnum::kLanConnectivity);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kMemory),
+            crosapi::DiagnosticsRoutineEnum::kMemory);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kNvmeSelfTest),
+            crosapi::DiagnosticsRoutineEnum::kNvmeSelfTest);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kNvmeWearLevel),
+            crosapi::DiagnosticsRoutineEnum::kNvmeWearLevel);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kNvmeWearLevel),
+            crosapi::DiagnosticsRoutineEnum::kNvmeWearLevel);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kPrimeSearch),
+            crosapi::DiagnosticsRoutineEnum::kPrimeSearch);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kSignalStrength),
+            crosapi::DiagnosticsRoutineEnum::kSignalStrength);
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kSensitiveSensor),
+            crosapi::DiagnosticsRoutineEnum::kSensitiveSensor);
+
+  EXPECT_EQ(Convert(cros_healthd::DiagnosticRoutineEnum::kArcHttp),
+            absl::nullopt);
+}
+
+// This test checks, that successful conversion of all
+// `cros_health::DiagnosticRoutineEnum` variants match to all
+// `crosapi::DiagnosticsRoutineEnum` variants. If this test fails, the
+// corresponding crosapi variant was added, but no conversion from a
+// cros_healthd variant.
+TEST(DiagnosticsServiceConvertersTest, CheckAllVariantsCovered) {
+  namespace cros_healthd = cros_healthd::mojom;
+  namespace crosapi = ::crosapi::mojom;
+
+  // Create a vector of all conversions by converting all possible
+  // cros_healthd variants.
+  std::vector<crosapi::DiagnosticsRoutineEnum> found_conversions;
+  for (auto iter = cros_healthd::DiagnosticRoutineEnum::kMinValue;
+       iter <= cros_healthd::DiagnosticRoutineEnum::kMaxValue;
+       iter = static_cast<cros_healthd::DiagnosticRoutineEnum>(
+           static_cast<int>(iter) + 1)) {
+    auto converted = Convert(iter);
+    if (converted) {
+      found_conversions.push_back(converted.value());
+    }
+  }
+
+  // Assure that each crosapi variant is part of the conversions.
+  for (auto iter = crosapi::DiagnosticsRoutineEnum::kMinValue;
+       iter <= crosapi::DiagnosticsRoutineEnum::kMaxValue;
+       iter = static_cast<crosapi::DiagnosticsRoutineEnum>(
+           static_cast<int>(iter) + 1)) {
+    EXPECT_THAT(found_conversions, testing::Contains(iter));
+  }
+}
+
 TEST(DiagnosticsServiceConvertersTest, ConvertDiagnosticRoutineStatusEnum) {
   namespace cros_healthd = cros_healthd::mojom;
   namespace crosapi = ::crosapi::mojom;
diff --git a/chrome/browser/autofill/android/save_update_address_profile_message_controller.cc b/chrome/browser/autofill/android/save_update_address_profile_message_controller.cc
index 19f4e31aa..863848e 100644
--- a/chrome/browser/autofill/android/save_update_address_profile_message_controller.cc
+++ b/chrome/browser/autofill/android/save_update_address_profile_message_controller.cc
@@ -39,9 +39,6 @@
   DCHECK(save_address_profile_callback);
   DCHECK(primary_action_callback);
 
-  DCHECK(base::FeatureList::IsEnabled(
-      autofill::features::kAutofillAddressProfileSavePrompt));
-
   // Dismiss previous message if it is displayed.
   DismissMessage();
   DCHECK(!message_);
diff --git a/chrome/browser/autofill/android/save_update_address_profile_message_controller_unittest.cc b/chrome/browser/autofill/android/save_update_address_profile_message_controller_unittest.cc
index 0c15612..81e1a026 100644
--- a/chrome/browser/autofill/android/save_update_address_profile_message_controller_unittest.cc
+++ b/chrome/browser/autofill/android/save_update_address_profile_message_controller_unittest.cc
@@ -80,8 +80,6 @@
 };
 
 void SaveUpdateAddressProfileMessageControllerTest::SetUp() {
-  feature_list_.InitAndEnableFeature(
-      features::kAutofillAddressProfileSavePrompt);
   ChromeRenderViewHostTestHarness::SetUp();
   messages::MessageDispatcherBridge::SetInstanceForTesting(
       &message_dispatcher_bridge_);
diff --git a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc
index a125350..67ee790 100644
--- a/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc
+++ b/chrome/browser/autofill/android/save_update_address_profile_prompt_controller.cc
@@ -37,8 +37,6 @@
   DCHECK(prompt_view_);
   DCHECK(decision_callback_);
   DCHECK(dismissal_callback_);
-  DCHECK(base::FeatureList::IsEnabled(
-      autofill::features::kAutofillAddressProfileSavePrompt));
 }
 
 SaveUpdateAddressProfilePromptController::
diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
index a9f1fa7a..30009c6e 100644
--- a/chrome/browser/chrome_browser_main.cc
+++ b/chrome/browser/chrome_browser_main.cc
@@ -48,7 +48,6 @@
 #include "base/time/time.h"
 #include "base/trace_event/trace_event.h"
 #include "base/values.h"
-#include "build/branding_buildflags.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
 #include "cc/base/switches.h"
diff --git a/chrome/browser/chromeos/app_mode/app_session.h b/chrome/browser/chromeos/app_mode/app_session.h
index 54c436c8b..2144ecf 100644
--- a/chrome/browser/chromeos/app_mode/app_session.h
+++ b/chrome/browser/chromeos/app_mode/app_session.h
@@ -105,7 +105,7 @@
   std::unique_ptr<KioskSessionPluginHandler> plugin_handler_;
 #endif
 
-  raw_ptr<Profile> profile_ = nullptr;
+  raw_ptr<Profile, DanglingUntriaged> profile_ = nullptr;
 
   base::OnceClosure attempt_user_exit_;
   const std::unique_ptr<AppSessionMetricsService> metrics_service_;
diff --git a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h
index ee050c50..878a85b 100644
--- a/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h
+++ b/chrome/browser/chromeos/app_mode/app_session_browser_window_handler.h
@@ -72,7 +72,7 @@
   // open.
   bool IsOnlySettingsBrowserRemainOpen() const;
 
-  const raw_ptr<Profile> profile_;
+  const raw_ptr<Profile, DanglingUntriaged> profile_;
   // |web_app_name_| is set only when we have the initial browser in the web
   // kiosk session.
   absl::optional<std::string> web_app_name_;
diff --git a/chrome/browser/chromeos/app_mode/app_session_policies.h b/chrome/browser/chromeos/app_mode/app_session_policies.h
index 9ae723e..8d7cc86 100644
--- a/chrome/browser/chromeos/app_mode/app_session_policies.h
+++ b/chrome/browser/chromeos/app_mode/app_session_policies.h
@@ -20,7 +20,7 @@
   bool IsWindowCreationAllowed() const;
 
  private:
-  raw_ptr<PrefService> pref_service_;
+  raw_ptr<PrefService, DanglingUntriaged> pref_service_;
 };
 
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/contact_center_insights/contact_center_insights_extension_manager.h b/chrome/browser/chromeos/extensions/contact_center_insights/contact_center_insights_extension_manager.h
index 836c0816..b1d8a32d 100644
--- a/chrome/browser/chromeos/extensions/contact_center_insights/contact_center_insights_extension_manager.h
+++ b/chrome/browser/chromeos/extensions/contact_center_insights/contact_center_insights_extension_manager.h
@@ -79,8 +79,9 @@
   // Removes the component extension if it is already installed.
   void RemoveExtensionIfInstalled();
 
-  const raw_ptr<::extensions::ComponentLoader> component_loader_;
-  const raw_ptr<Profile> profile_;
+  const raw_ptr<::extensions::ComponentLoader, DanglingUntriaged>
+      component_loader_;
+  const raw_ptr<Profile, DanglingUntriaged> profile_;
 
   const std::unique_ptr<Delegate> delegate_;
   PrefChangeRegistrar registrar_;
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
index 35d1dd4..45c228a 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/base_telemetry_extension_api_guard_function_browsertest.cc
@@ -323,6 +323,19 @@
         );
         chrome.test.succeed();
       },
+      async function runNvmeSelfTestRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runNvmeSelfTestRoutine(
+              {
+                test_type: 'short_test'
+              }
+            ),
+            'Error: Unauthorized access to ' +
+            'chrome.os.diagnostics.runNvmeSelfTestRoutine. ' +
+            '%s'
+        );
+        chrome.test.succeed();
+      },
       async function runNvmeWearLevelRoutine() {
         await chrome.test.assertPromiseRejects(
             chrome.os.diagnostics.runNvmeWearLevelRoutine(
@@ -336,6 +349,15 @@
         );
         chrome.test.succeed();
       },
+      async function runSensitiveSensorRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runSensitiveSensorRoutine(),
+            'Error: Unauthorized access to ' +
+            'chrome.os.diagnostics.runSensitiveSensorRoutine. ' +
+            '%s'
+        );
+        chrome.test.succeed();
+      },
       async function runSignalStrengthRoutine() {
         await chrome.test.assertPromiseRejects(
             chrome.os.diagnostics.runSignalStrengthRoutine(),
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.cc b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.cc
index 4817657..ced94da 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.cc
@@ -443,6 +443,30 @@
   GetRemoteService()->RunMemoryRoutine(std::move(cb));
 }
 
+// OsDiagnosticsRunNvmeSelfTestRoutineFunction ---------------------------------
+
+OsDiagnosticsRunNvmeSelfTestRoutineFunction::
+    OsDiagnosticsRunNvmeSelfTestRoutineFunction() = default;
+OsDiagnosticsRunNvmeSelfTestRoutineFunction::
+    ~OsDiagnosticsRunNvmeSelfTestRoutineFunction() = default;
+
+void OsDiagnosticsRunNvmeSelfTestRoutineFunction::RunIfAllowed() {
+  std::unique_ptr<api::os_diagnostics::RunNvmeSelfTestRoutine::Params> params(
+      api::os_diagnostics::RunNvmeSelfTestRoutine::Params::Create(args()));
+  if (!params) {
+    SetBadMessage();
+    Respond(BadMessage());
+    return;
+  }
+
+  auto cb =
+      base::BindOnce(&DiagnosticsApiRunRoutineFunctionBase::OnResult, this);
+
+  GetRemoteService()->RunNvmeSelfTestRoutine(
+      converters::ConvertNvmeSelfTestRoutineType(std::move(params->request)),
+      std::move(cb));
+}
+
 // OsDiagnosticsRunNvmeWearLevelRoutineFunction --------------------------------
 
 OsDiagnosticsRunNvmeWearLevelRoutineFunction::
@@ -466,6 +490,20 @@
       params->request.wear_level_threshold, std::move(cb));
 }
 
+// OsDiagnosticsRunSensitiveSensorRoutineFunction -----------------------------
+
+OsDiagnosticsRunSensitiveSensorRoutineFunction::
+    OsDiagnosticsRunSensitiveSensorRoutineFunction() = default;
+OsDiagnosticsRunSensitiveSensorRoutineFunction::
+    ~OsDiagnosticsRunSensitiveSensorRoutineFunction() = default;
+
+void OsDiagnosticsRunSensitiveSensorRoutineFunction::RunIfAllowed() {
+  auto cb =
+      base::BindOnce(&DiagnosticsApiRunRoutineFunctionBase::OnResult, this);
+
+  GetRemoteService()->RunSensitiveSensorRoutine(std::move(cb));
+}
+
 // OsDiagnosticsRunSignalStrengthRoutineFunction -------------------------------
 
 OsDiagnosticsRunSignalStrengthRoutineFunction::
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.h b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.h
index 5603d7d..f1d81f2c 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.h
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api.h
@@ -384,6 +384,25 @@
   void RunIfAllowed() override;
 };
 
+class OsDiagnosticsRunNvmeSelfTestRoutineFunction
+    : public DiagnosticsApiRunRoutineFunctionBase {
+ public:
+  DECLARE_EXTENSION_FUNCTION("os.diagnostics.runNvmeSelfTestRoutine",
+                             OS_DIAGNOSTICS_RUNNVMESELFTESTROUTINE)
+
+  OsDiagnosticsRunNvmeSelfTestRoutineFunction();
+  OsDiagnosticsRunNvmeSelfTestRoutineFunction(
+      const OsDiagnosticsRunNvmeSelfTestRoutineFunction&) = delete;
+  OsDiagnosticsRunNvmeSelfTestRoutineFunction& operator=(
+      const OsDiagnosticsRunNvmeSelfTestRoutineFunction&) = delete;
+
+ private:
+  ~OsDiagnosticsRunNvmeSelfTestRoutineFunction() override;
+
+  // BaseTelemetryExtensionApiGuardFunction:
+  void RunIfAllowed() override;
+};
+
 class OsDiagnosticsRunNvmeWearLevelRoutineFunction
     : public DiagnosticsApiRunRoutineFunctionBase {
  public:
@@ -403,6 +422,25 @@
   void RunIfAllowed() override;
 };
 
+class OsDiagnosticsRunSensitiveSensorRoutineFunction
+    : public DiagnosticsApiRunRoutineFunctionBase {
+ public:
+  DECLARE_EXTENSION_FUNCTION("os.diagnostics.runSensitiveSensorRoutine",
+                             OS_DIAGNOSTICS_RUNSENSITIVESENSORROUTINE)
+
+  OsDiagnosticsRunSensitiveSensorRoutineFunction();
+  OsDiagnosticsRunSensitiveSensorRoutineFunction(
+      const OsDiagnosticsRunSensitiveSensorRoutineFunction&) = delete;
+  OsDiagnosticsRunSensitiveSensorRoutineFunction& operator=(
+      const OsDiagnosticsRunSensitiveSensorRoutineFunction&) = delete;
+
+ private:
+  ~OsDiagnosticsRunSensitiveSensorRoutineFunction() override;
+
+  // BaseTelemetryExtensionApiGuardFunction:
+  void RunIfAllowed() override;
+};
+
 class OsDiagnosticsRunSignalStrengthRoutineFunction
     : public DiagnosticsApiRunRoutineFunctionBase {
  public:
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc
index e73249a..5e2078d 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_browsertest.cc
@@ -272,6 +272,18 @@
         );
         chrome.test.succeed();
       },
+      async function runNvmeSelfTestRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runNvmeSelfTestRoutine(
+              {
+                test_type: 'short_test'
+              }
+            ),
+            'Error: API chrome.os.diagnostics.runNvmeSelfTestRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
       async function runNvmeWearLevelRoutine() {
         await chrome.test.assertPromiseRejects(
             chrome.os.diagnostics.runNvmeWearLevelRoutine(
@@ -284,6 +296,14 @@
         );
         chrome.test.succeed();
       },
+      async function runSensitiveSensorRoutine() {
+        await chrome.test.assertPromiseRejects(
+            chrome.os.diagnostics.runSensitiveSensorRoutine(),
+            'Error: API chrome.os.diagnostics.runSensitiveSensorRoutine ' +
+            'failed. Not supported by ash browser'
+        );
+        chrome.test.succeed();
+      },
       async function runSignalStrengthRoutine() {
         await chrome.test.assertPromiseRejects(
             chrome.os.diagnostics.runSignalStrengthRoutine(),
@@ -356,6 +376,8 @@
         crosapi::mojom::DiagnosticsRoutineEnum::kSignalStrength,
         crosapi::mojom::DiagnosticsRoutineEnum::kGatewayCanBePinged,
         crosapi::mojom::DiagnosticsRoutineEnum::kSmartctlCheck,
+        crosapi::mojom::DiagnosticsRoutineEnum::kSensitiveSensor,
+        crosapi::mojom::DiagnosticsRoutineEnum::kNvmeSelfTest,
     });
 
     SetServiceForTesting(std::move(fake_service_impl));
@@ -386,7 +408,9 @@
               "nvme_wear_level",
               "signal_strength",
               "gateway_can_be_pinged",
-              "smartctl_check"
+              "smartctl_check",
+              "sensitive_sensor",
+              "nvme_self_test"
             ]
           }, response);
         chrome.test.succeed();
@@ -1232,6 +1256,59 @@
 }
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
+                       RunNvmeSelfTestRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
+  // Configure FakeDiagnosticsService.
+  {
+    auto expected_response =
+        crosapi::mojom::DiagnosticsRunRoutineResponse::New();
+    expected_response->id = 0;
+    expected_response->status =
+        crosapi::mojom::DiagnosticsRoutineStatusEnum::kReady;
+
+    // Set the return value for a call to RunNvmeSelfTestRoutine.
+    auto fake_service_impl = std::make_unique<FakeDiagnosticsService>();
+    fake_service_impl->SetRunRoutineResponse(std::move(expected_response));
+
+    base::Value::Dict expected_result;
+    expected_result.Set(
+        "test_type",
+        static_cast<int32_t>(
+            crosapi::mojom::DiagnosticsNvmeSelfTestTypeEnum::kShortSelfTest));
+
+    // Set the expected runtime actions.
+    fake_service_impl->SetExpectedLastPassedParameters(
+        std::move(expected_result));
+    fake_service_impl->SetExpectedLastCalledRoutine(
+        crosapi::mojom::DiagnosticsRoutineEnum::kNvmeSelfTest);
+
+    SetServiceForTesting(std::move(fake_service_impl));
+  }
+
+  CreateExtensionAndRunServiceWorker(R"(
+    chrome.test.runTests([
+      async function runNvmeSelfTestRoutine() {
+        const response =
+          await chrome.os.diagnostics.runNvmeSelfTestRoutine(
+            {
+              test_type: 'short_test'
+            }
+          );
+        chrome.test.assertEq({id: 0, status: "ready"}, response);
+        chrome.test.succeed();
+      }
+    ]);
+  )");
+}
+
+IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunNvmeWearLevelRoutineSuccess) {
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   // If Diagnostics interface is not available on this version of ash-chrome,
@@ -1282,6 +1359,47 @@
 }
 
 IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
+                       RunSensitiveSensorRoutineSuccess) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+  // If Diagnostics interface is not available on this version of ash-chrome,
+  // this test suite will no-op.
+  if (!IsServiceAvailable()) {
+    return;
+  }
+#endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
+
+  // Configure FakeDiagnosticsService.
+  {
+    auto expected_response =
+        crosapi::mojom::DiagnosticsRunRoutineResponse::New();
+    expected_response->id = 0;
+    expected_response->status =
+        crosapi::mojom::DiagnosticsRoutineStatusEnum::kReady;
+
+    // Set the return value for a call to RunSmartctlCheckRoutine.
+    auto fake_service_impl = std::make_unique<FakeDiagnosticsService>();
+    fake_service_impl->SetRunRoutineResponse(std::move(expected_response));
+
+    // Set the expected called routine.
+    fake_service_impl->SetExpectedLastCalledRoutine(
+        crosapi::mojom::DiagnosticsRoutineEnum::kSensitiveSensor);
+
+    SetServiceForTesting(std::move(fake_service_impl));
+  }
+
+  CreateExtensionAndRunServiceWorker(R"(
+    chrome.test.runTests([
+      async function runSensitiveSensorRoutine() {
+        const response =
+          await chrome.os.diagnostics.runSensitiveSensorRoutine();
+        chrome.test.assertEq({id: 0, status: "ready"}, response);
+        chrome.test.succeed();
+      }
+    ]);
+  )");
+}
+
+IN_PROC_BROWSER_TEST_F(TelemetryExtensionDiagnosticsApiBrowserTest,
                        RunSignalStrengthRoutineSuccess) {
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
   // If Diagnostics interface is not available on this version of ash-chrome,
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters.cc b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters.cc
index 9eb97cf..1ef3b84 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters.cc
@@ -21,6 +21,7 @@
     crosapi::mojom::DiagnosticsRoutineUserMessageEnum;
 using MojoDiskReadRoutineType =
     crosapi::mojom::DiagnosticsDiskReadRoutineTypeEnum;
+using MojoNvmeSelfTestType = crosapi::mojom::DiagnosticsNvmeSelfTestTypeEnum;
 
 using RoutineCommandType = ::chromeos::api::os_diagnostics::RoutineCommandType;
 using RoutineStatus = ::chromeos::api::os_diagnostics::RoutineStatus;
@@ -30,6 +31,8 @@
 using RoutineUserMessageType = ::chromeos::api::os_diagnostics::UserMessageType;
 using RoutineDiskReadRoutineType =
     ::chromeos::api::os_diagnostics::DiskReadRoutineType;
+using RoutineNvmeSelfTestRoutineType =
+    ::chromeos::api::os_diagnostics::RunNvmeSelfTestRequest;
 
 }  // namespace
 
@@ -90,6 +93,12 @@
     case MojoRoutineType::kSmartctlCheck:
       *out = RoutineType::ROUTINE_TYPE_SMARTCTL_CHECK;
       return true;
+    case MojoRoutineType::kSensitiveSensor:
+      *out = RoutineType::ROUTINE_TYPE_SENSITIVE_SENSOR;
+      return true;
+    case MojoRoutineType::kNvmeSelfTest:
+      *out = RoutineType::ROUTINE_TYPE_NVME_SELF_TEST;
+      return true;
     default:
       return false;
   }
@@ -189,5 +198,17 @@
       static_cast<int>(MojoDiskReadRoutineType::kMaxValue) + 1);
 }
 
+MojoNvmeSelfTestType ConvertNvmeSelfTestRoutineType(
+    RoutineNvmeSelfTestRoutineType routine_type) {
+  switch (routine_type.test_type) {
+    case api::os_diagnostics::NVME_SELF_TEST_TYPE_NONE:
+      return MojoNvmeSelfTestType::kUnknown;
+    case api::os_diagnostics::NVME_SELF_TEST_TYPE_SHORT_TEST:
+      return MojoNvmeSelfTestType::kShortSelfTest;
+    case api::os_diagnostics::NVME_SELF_TEST_TYPE_LONG_TEST:
+      return MojoNvmeSelfTestType::kLongSelfTest;
+  }
+}
+
 }  // namespace converters
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters.h b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters.h
index 9afe75d..de01e70 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters.h
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters.h
@@ -29,6 +29,9 @@
 crosapi::mojom::DiagnosticsDiskReadRoutineTypeEnum ConvertDiskReadRoutineType(
     chromeos::api::os_diagnostics::DiskReadRoutineType routineType);
 
+crosapi::mojom::DiagnosticsNvmeSelfTestTypeEnum ConvertNvmeSelfTestRoutineType(
+    chromeos::api::os_diagnostics::RunNvmeSelfTestRequest routineType);
+
 }  // namespace converters
 }  // namespace chromeos
 
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters_unittest.cc b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters_unittest.cc
index 6a232c1..ed6245a 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters_unittest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/diagnostics_api_converters_unittest.cc
@@ -20,6 +20,7 @@
 using MojoDiskReadRoutineType =
     crosapi::mojom::DiagnosticsDiskReadRoutineTypeEnum;
 using MojoAcPowerStatusType = crosapi::mojom::DiagnosticsAcPowerStatusEnum;
+using MojoNvmeSelfTestType = crosapi::mojom::DiagnosticsNvmeSelfTestTypeEnum;
 
 using RoutineCommandType = ::chromeos::api::os_diagnostics::RoutineCommandType;
 using RoutineStatus = ::chromeos::api::os_diagnostics::RoutineStatus;
@@ -29,6 +30,10 @@
     ::chromeos::api::os_diagnostics::DiskReadRoutineType;
 using RoutineAcPowerStatusRoutineType =
     ::chromeos::api::os_diagnostics::AcPowerStatus;
+using RoutineNvmeSelfTestRoutineType =
+    ::chromeos::api::os_diagnostics::RunNvmeSelfTestRequest;
+using RoutineNvmeSelfTestEnum =
+    ::chromeos::api::os_diagnostics::NvmeSelfTestType;
 
 }  // namespace
 
@@ -106,6 +111,11 @@
   }
   {
     RoutineType out = RoutineType::ROUTINE_TYPE_NONE;
+    EXPECT_TRUE(ConvertMojoRoutine(MojoRoutineType::kNvmeSelfTest, &out));
+    EXPECT_EQ(out, RoutineType::ROUTINE_TYPE_NVME_SELF_TEST);
+  }
+  {
+    RoutineType out = RoutineType::ROUTINE_TYPE_NONE;
     EXPECT_TRUE(ConvertMojoRoutine(MojoRoutineType::kNvmeWearLevel, &out));
     EXPECT_EQ(out, RoutineType::ROUTINE_TYPE_NVME_WEAR_LEVEL);
   }
@@ -121,17 +131,13 @@
   }
   {
     RoutineType out = RoutineType::ROUTINE_TYPE_NONE;
-    EXPECT_TRUE(ConvertMojoRoutine(MojoRoutineType::kSmartctlCheck, &out));
-    EXPECT_EQ(out, RoutineType::ROUTINE_TYPE_SMARTCTL_CHECK);
+    EXPECT_TRUE(ConvertMojoRoutine(MojoRoutineType::kSensitiveSensor, &out));
+    EXPECT_EQ(out, RoutineType::ROUTINE_TYPE_SENSITIVE_SENSOR);
   }
-
-  // Tests for unsupported routines.
-  // Note: If an unsupported routine becomes supported, the respective test
-  // should be changed.
   {
     RoutineType out = RoutineType::ROUTINE_TYPE_NONE;
-    EXPECT_FALSE(ConvertMojoRoutine(MojoRoutineType::kNvmeSelfTest, &out));
-    EXPECT_EQ(out, RoutineType::ROUTINE_TYPE_NONE);
+    EXPECT_TRUE(ConvertMojoRoutine(MojoRoutineType::kSmartctlCheck, &out));
+    EXPECT_EQ(out, RoutineType::ROUTINE_TYPE_SMARTCTL_CHECK);
   }
 }
 
@@ -208,5 +214,24 @@
             MojoAcPowerStatusType::kDisconnected);
 }
 
+TEST(TelemetryExtensionDiagnosticsApiConvertersUnitTest,
+     ConvertNvmeSelfTestRoutineType) {
+  RoutineNvmeSelfTestRoutineType input_short;
+  input_short.test_type =
+      RoutineNvmeSelfTestEnum::NVME_SELF_TEST_TYPE_SHORT_TEST;
+  EXPECT_EQ(ConvertNvmeSelfTestRoutineType(std::move(input_short)),
+            MojoNvmeSelfTestType::kShortSelfTest);
+
+  RoutineNvmeSelfTestRoutineType input_long;
+  input_long.test_type = RoutineNvmeSelfTestEnum::NVME_SELF_TEST_TYPE_LONG_TEST;
+  EXPECT_EQ(ConvertNvmeSelfTestRoutineType(std::move(input_long)),
+            MojoNvmeSelfTestType::kLongSelfTest);
+
+  RoutineNvmeSelfTestRoutineType input_unknown;
+  input_unknown.test_type = RoutineNvmeSelfTestEnum::NVME_SELF_TEST_TYPE_NONE;
+  EXPECT_EQ(ConvertNvmeSelfTestRoutineType(std::move(input_unknown)),
+            MojoNvmeSelfTestType::kUnknown);
+}
+
 }  // namespace converters
 }  // namespace chromeos
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service.cc b/chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service.cc
index fdd79af..3149d3b 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service.cc
@@ -249,7 +249,7 @@
     crosapi::mojom::DiagnosticsNvmeSelfTestTypeEnum nvme_self_test_type,
     RunNvmeSelfTestRoutineCallback callback) {
   actual_passed_parameters_.clear();
-  actual_passed_parameters_.Set("nvme_self_test_type",
+  actual_passed_parameters_.Set("test_type",
                                 static_cast<int32_t>(nvme_self_test_type));
 
   actual_called_routine_ =
@@ -289,6 +289,16 @@
       base::BindOnce(std::move(callback), run_routine_response_->Clone()));
 }
 
+void FakeDiagnosticsService::RunSensitiveSensorRoutine(
+    RunSensitiveSensorRoutineCallback callback) {
+  actual_passed_parameters_.clear();
+  actual_called_routine_ =
+      crosapi::mojom::DiagnosticsRoutineEnum::kSensitiveSensor;
+  base::SequencedTaskRunner::GetCurrentDefault()->PostTask(
+      FROM_HERE,
+      base::BindOnce(std::move(callback), run_routine_response_->Clone()));
+}
+
 void FakeDiagnosticsService::RunSignalStrengthRoutine(
     RunSignalStrengthRoutineCallback callback) {
   actual_passed_parameters_.clear();
diff --git a/chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service.h b/chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service.h
index 174e145e..0d5bc4f 100644
--- a/chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service.h
+++ b/chrome/browser/chromeos/extensions/telemetry/api/fake_diagnostics_service.h
@@ -77,6 +77,8 @@
       RunNvmeWearLevelRoutineCallback callback) override;
   void RunPrimeSearchRoutine(uint32_t length_seconds,
                              RunPrimeSearchRoutineCallback callback) override;
+  void RunSensitiveSensorRoutine(
+      RunSensitiveSensorRoutineCallback callback) override;
   void RunSignalStrengthRoutine(
       RunSignalStrengthRoutineCallback callback) override;
   void RunSmartctlCheckRoutine(
diff --git a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
index 38a267b..8d3a94a 100644
--- a/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/data_transfer_dlp_controller_browsertest.cc
@@ -260,14 +260,14 @@
         widget_->GetNativeWindow()->GetRootWindow());
   }
 
-  raw_ptr<MockDlpRulesManager> rules_manager_;
+  raw_ptr<MockDlpRulesManager, DanglingUntriaged> rules_manager_;
   std::unique_ptr<DlpReportingManager> reporting_manager_;
   std::vector<DlpPolicyEvent> events_;
   FakeClipboardNotifier helper_;
   std::unique_ptr<FakeDlpController> dlp_controller_;
   std::unique_ptr<ui::test::EventGenerator> event_generator_;
   std::unique_ptr<views::Widget> widget_;
-  raw_ptr<views::Textfield> textfield_ = nullptr;
+  raw_ptr<views::Textfield, DanglingUntriaged> textfield_ = nullptr;
 };
 
 // Flaky on MSan bots: http://crbug.com/1178328
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h
index 332cb29..a12abb8 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager.h
@@ -406,7 +406,7 @@
   // List of the currently running screen shares.
   std::vector<std::unique_ptr<ScreenShareInfo>> running_screen_shares_;
 
-  raw_ptr<DlpReportingManager> reporting_manager_{nullptr};
+  raw_ptr<DlpReportingManager, DanglingUntriaged> reporting_manager_{nullptr};
 
   std::unique_ptr<DlpWarnNotifier> warn_notifier_;
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc b/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc
index 8b7b561..c7bba75 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager_browsertest.cc
@@ -133,7 +133,7 @@
  protected:
   std::unique_ptr<DlpContentManagerTestHelper> helper_;
   base::HistogramTester histogram_tester_;
-  raw_ptr<MockDlpRulesManager> mock_rules_manager_;
+  raw_ptr<MockDlpRulesManager, DanglingUntriaged> mock_rules_manager_;
   std::vector<DlpPolicyEvent> events_;
 };
 
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_content_manager_test_helper.h b/chrome/browser/chromeos/policy/dlp/dlp_content_manager_test_helper.h
index bb1d018..10392d9 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_content_manager_test_helper.h
+++ b/chrome/browser/chromeos/policy/dlp/dlp_content_manager_test_helper.h
@@ -69,9 +69,10 @@
   DlpReportingManager* GetReportingManager() const;
 
  private:
-  raw_ptr<DlpContentManager> manager_;
-  raw_ptr<DlpReportingManager> reporting_manager_;
-  raw_ptr<ScopedDlpContentObserverForTesting> scoped_dlp_content_observer_;
+  raw_ptr<DlpContentManager, DanglingUntriaged> manager_;
+  raw_ptr<DlpReportingManager, DanglingUntriaged> reporting_manager_;
+  raw_ptr<ScopedDlpContentObserverForTesting, DanglingUntriaged>
+      scoped_dlp_content_observer_;
 };
 
 }  // namespace policy
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_browsertest.cc b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_browsertest.cc
index 644fe02a..5685ef4 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_browsertest.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_rules_manager_impl_browsertest.cc
@@ -52,7 +52,7 @@
     return new_rules_manager;
   }
 
-  raw_ptr<DlpRulesManager> rules_manager_;
+  raw_ptr<DlpRulesManager, DanglingUntriaged> rules_manager_;
 };
 
 IN_PROC_BROWSER_TEST_F(DlpRulesPolicyTest, ParsePolicyPref) {
diff --git a/chrome/browser/download/notification/download_notification_browsertest.cc b/chrome/browser/download/notification/download_notification_browsertest.cc
index 5775974..ae5ab6aa 100644
--- a/chrome/browser/download/notification/download_notification_browsertest.cc
+++ b/chrome/browser/download/notification/download_notification_browsertest.cc
@@ -541,8 +541,8 @@
   }
 
  private:
-  raw_ptr<download::DownloadItem> download_item_ = nullptr;
-  raw_ptr<Browser> incognito_browser_ = nullptr;
+  raw_ptr<download::DownloadItem, DanglingUntriaged> download_item_ = nullptr;
+  raw_ptr<Browser, DanglingUntriaged> incognito_browser_ = nullptr;
   std::string notification_id_;
 };
 
diff --git a/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc b/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc
index a638e722..b9e30742 100644
--- a/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc
+++ b/chrome/browser/extensions/api/certificate_provider/certificate_provider_apitest.cc
@@ -298,8 +298,8 @@
 
  protected:
   testing::NiceMock<policy::MockConfigurationPolicyProvider> provider_;
-  raw_ptr<chromeos::CertificateProviderService> cert_provider_service_ =
-      nullptr;
+  raw_ptr<chromeos::CertificateProviderService, DanglingUntriaged>
+      cert_provider_service_ = nullptr;
   policy::PolicyMap policy_map_;
 
  private:
@@ -507,8 +507,9 @@
     return certificate_data;
   }
 
-  raw_ptr<content::WebContents> extension_contents_ = nullptr;
-  raw_ptr<const extensions::Extension> extension_ = nullptr;
+  raw_ptr<content::WebContents, DanglingUntriaged> extension_contents_ =
+      nullptr;
+  raw_ptr<const extensions::Extension, DanglingUntriaged> extension_ = nullptr;
   base::FilePath extension_path_;
 };
 
@@ -614,7 +615,7 @@
     extension_ = LoadExtension(extension_path);
   }
 
-  raw_ptr<const extensions::Extension> extension_ = nullptr;
+  raw_ptr<const extensions::Extension, DanglingUntriaged> extension_ = nullptr;
   std::unique_ptr<ExtensionTestMessageListener> command_request_listener_;
 };
 
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_apitest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_apitest.cc
index ed4e10c..1c05c1fa 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_apitest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_apitest.cc
@@ -134,7 +134,8 @@
   base::test::ScopedFeatureList feature_list_;
 };
 
-IN_PROC_BROWSER_TEST_F(DeclarativeNetRequestApiFencedFrameTest, Load) {
+// TODO(crbug.com/1383550): Re-enable this test
+IN_PROC_BROWSER_TEST_F(DeclarativeNetRequestApiFencedFrameTest, DISABLED_Load) {
   ASSERT_TRUE(RunExtensionTest("fenced_frames")) << message_;
 }
 
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
index 639af17..3665015 100644
--- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
+++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -305,7 +305,7 @@
   base::ScopedObservation<download::DownloadItem,
                           download::DownloadItem::Observer>
       open_observation_{this};
-  raw_ptr<download::DownloadItem> item_;
+  raw_ptr<download::DownloadItem, DanglingUntriaged> item_;
   base::OnceClosure completion_closure_;
 };
 
diff --git a/chrome/browser/extensions/api/preference/preference_api_lacros_browsertest.cc b/chrome/browser/extensions/api/preference/preference_api_lacros_browsertest.cc
index 106e93c..19c16a4 100644
--- a/chrome/browser/extensions/api/preference/preference_api_lacros_browsertest.cc
+++ b/chrome/browser/extensions/api/preference/preference_api_lacros_browsertest.cc
@@ -111,7 +111,7 @@
                kExtensionControlledPrefObserversCapability);
   }
 
-  raw_ptr<Profile> profile_ = nullptr;
+  raw_ptr<Profile, DanglingUntriaged> profile_ = nullptr;
   std::unique_ptr<ScopedKeepAlive> keep_alive_;
 };
 
diff --git a/chrome/browser/extensions/api/system_display/system_display_extension_apitest.cc b/chrome/browser/extensions/api/system_display/system_display_extension_apitest.cc
index 6beff58..50e69a2 100644
--- a/chrome/browser/extensions/api/system_display/system_display_extension_apitest.cc
+++ b/chrome/browser/extensions/api/system_display/system_display_extension_apitest.cc
@@ -16,6 +16,7 @@
 #include "extensions/browser/api_test_utils.h"
 #include "extensions/browser/mock_display_info_provider.h"
 #include "extensions/common/api/system_display.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/display/display.h"
 
 namespace extensions {
@@ -80,8 +81,7 @@
             api_test_utils::RunFunctionAndReturnError(
                 set_info_function.get(), "[\"display_id\", {}]", profile()));
 
-  std::unique_ptr<base::DictionaryValue> set_info =
-      provider_->GetSetInfoValue();
+  absl::optional<base::Value::Dict> set_info = provider_->GetSetInfoValue();
   EXPECT_FALSE(set_info);
 }
 
diff --git a/chrome/browser/extensions/api/terminal/terminal_private_api.cc b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
index 731e849..799ad053 100644
--- a/chrome/browser/extensions/api/terminal/terminal_private_api.cc
+++ b/chrome/browser/extensions/api/terminal/terminal_private_api.cc
@@ -60,9 +60,7 @@
 #include "extensions/browser/app_window/app_window.h"
 #include "extensions/browser/app_window/app_window_registry.h"
 #include "extensions/browser/event_router.h"
-#include "extensions/browser/extension_system.h"
 #include "extensions/browser/extensions_browser_client.h"
-#include "extensions/common/constants.h"
 #include "ui/display/types/display_constants.h"
 
 namespace terminal_private = extensions::api::terminal_private;
@@ -742,10 +740,6 @@
       base::FeatureList::IsEnabled(chromeos::features::kTerminalMultiProfile));
   info.SetBoolKey(
       "sftp", base::FeatureList::IsEnabled(chromeos::features::kTerminalSftp));
-  info.SetBoolKey("tast", extensions::ExtensionSystem::Get(browser_context())
-                              ->extension_service()
-                              ->IsExtensionEnabled(
-                                  extension_misc::kGuestModeTestExtensionId));
   info.SetBoolKey("tmux_integration",
                   base::FeatureList::IsEnabled(
                       chromeos::features::kTerminalTmuxIntegration));
diff --git a/chrome/browser/extensions/api/vpn_provider/vpn_provider_apitest.cc b/chrome/browser/extensions/api/vpn_provider/vpn_provider_apitest.cc
index 4a5e864..2eb63a5 100644
--- a/chrome/browser/extensions/api/vpn_provider/vpn_provider_apitest.cc
+++ b/chrome/browser/extensions/api/vpn_provider/vpn_provider_apitest.cc
@@ -171,7 +171,7 @@
     extension_id_ = extension_->id();
   }
 
-  raw_ptr<const extensions::Extension> extension_ = nullptr;
+  raw_ptr<const extensions::Extension, DanglingUntriaged> extension_ = nullptr;
   absl::optional<std::string> extension_id_;
 };
 
diff --git a/chrome/browser/extensions/extension_csp_bypass_browsertest.cc b/chrome/browser/extensions/extension_csp_bypass_browsertest.cc
index 5ddca9a8..602b5a9 100644
--- a/chrome/browser/extensions/extension_csp_bypass_browsertest.cc
+++ b/chrome/browser/extensions/extension_csp_bypass_browsertest.cc
@@ -133,11 +133,8 @@
   EXPECT_TRUE(CanLoadScript(ext_without_permission));
 
   // chrome-extension:-URLs can never bypass CSP in WebUI.
-  // TODO(crbug.com/1098690): Find a way to make this test work for pages that
-  // do use TrustedTypes. In the meantime, just use a WebUI that has not
-  // enabled TrustedTypes yet.
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(),
-                                           GURL(chrome::kChromeUIWelcomeURL)));
+                                           GURL(chrome::kChromeUISettingsURL)));
 
   EXPECT_FALSE(CanLoadScript(component_ext_with_permission));
   EXPECT_FALSE(CanLoadScript(component_ext_without_permission));
diff --git a/chrome/browser/extensions/webstore_installer.cc b/chrome/browser/extensions/webstore_installer.cc
index 0885461..3cf8e4d 100644
--- a/chrome/browser/extensions/webstore_installer.cc
+++ b/chrome/browser/extensions/webstore_installer.cc
@@ -248,9 +248,9 @@
   std::unique_ptr<Approval> result(new Approval());
   result->extension_id = extension_id;
   result->profile = profile;
-  result->manifest =
-      std::make_unique<Manifest>(mojom::ManifestLocation::kInvalidLocation,
-                                 std::move(parsed_manifest), extension_id);
+  result->manifest = std::make_unique<Manifest>(
+      mojom::ManifestLocation::kInvalidLocation,
+      std::move(*parsed_manifest).TakeDict(), extension_id);
   result->skip_install_dialog = true;
   result->manifest_check_level = strict_manifest_check ?
     MANIFEST_CHECK_LEVEL_STRICT : MANIFEST_CHECK_LEVEL_LOOSE;
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index c39bf74..438560a 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -416,11 +416,6 @@
     "expiry_milestone": 111
   },
   {
-    "name": "autofill-address-save-prompt",
-    "owners": [ "mamir", "koerber" ],
-    "expiry_milestone": 106
-  },
-  {
       "name": "autofill-address-verification-in-save-prompt",
       "owners": [ "mamir", "koerber" ],
       "expiry_milestone": 106
@@ -773,12 +768,12 @@
   {
     "name": "bruschetta",
     "owners": [ "davidmunro@google.com", "nverne", "sidereal" ],
-    "expiry_milestone": 110
+    "expiry_milestone": 120
   },
   {
     "name": "bruschetta-alpha-migrate",
     "owners": [ "davidmunro@google.com", "nverne", "sidereal" ],
-    "expiry_milestone": 114
+    "expiry_milestone": 120
   },
   {
     "name": "bubble-rich-iph",
@@ -1158,21 +1153,11 @@
     "expiry_milestone": 120
   },
   {
-    "name": "crostini-bullseye-upgrade",
-    "owners": [ "sidereal@google.com", "clumptini@google.com" ],
-    "expiry_milestone": 110
-  },
-  {
     "name": "crostini-container-install",
     "owners": [ "davidmunro@google.com", "clumptini@google.com" ],
     "expiry_milestone": 130
   },
   {
-    "name": "crostini-disk-resizing",
-    "owners": [ "davidmunro@google.com", "nverne" ],
-    "expiry_milestone": 110
-  },
-  {
     "name": "crostini-gpu-support",
     "owners": [ "nverne", "benwells" ],
     "expiry_milestone": 110
@@ -1190,12 +1175,7 @@
   {
     "name": "crostini-reset-lxd-db",
     "owners": [ "davidmunro@google.com", "nverne", "sidereal" ],
-    "expiry_milestone": 110
-  },
-  {
-    "name": "crostini-use-lxd-4",
-    "owners": [ "sidereal", "davidmunro@google.com", "nverne" ],
-    "expiry_milestone": 110
+    "expiry_milestone": 120
   },
   {
     "name": "crostini-virtual-keyboard-support",
@@ -3906,7 +3886,7 @@
   {
     "name": "global-media-controls-cast-start-stop",
     "owners": [  "takumif", "muyaoxu@google.com", "openscreen-eng@google.com" ],
-    "expiry_milestone": 110
+    "expiry_milestone": 130
   },
   {
     "name": "global-media-controls-for-cast",
@@ -3942,11 +3922,6 @@
     "expiry_milestone": 114
   },
   {
-    "name": "guest-os-files",
-    "owners": [ "davidmunro@google.com", "clumptini@google.com" ],
-    "expiry_milestone": 110
-  },
-  {
     "name": "handwriting-gesture-editing",
     "owners": [ "curtismcmullan", "essential-inputs-team@google.com" ],
     "expiry_milestone": 111
@@ -4445,6 +4420,14 @@
     "expiry_milestone": 115
   },
   {
+    "name": "layout-extraction",
+    "owners": [
+      "rhalavati",
+      "//ui/accessibility/OWNERS"
+    ],
+    "expiry_milestone": 120
+  },
+  {
     "name": "legacy-tls-interstitial",
     "owners": [ "cthomp" ],
     "expiry_milestone": 92
@@ -6498,7 +6481,7 @@
     "expiry_milestone": -1
   },
   {
-    "name": "tab-grid-recency-sort",
+    "name": "tab-grid-sort",
     "owners": [ "gambard", "bling-flags@google.com" ],
     "expiry_milestone": 114
   },
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc
index 9e783e1..159082c 100644
--- a/chrome/browser/flag_descriptions.cc
+++ b/chrome/browser/flag_descriptions.cc
@@ -4358,6 +4358,11 @@
 const char kHappinessTrackingSurveysForDesktopDemoDescription[] =
     "Enable showing Happiness Tracking Surveys Demo to users on Desktop";
 
+const char kLayoutExtractionName[] = "Layout Extraction";
+const char kLayoutExtractionDescription[] =
+    "Enables Layout Extraction local machine intelligence library to use "
+    "screen snapshots to add metadata for accessibility tools.";
+
 const char kOmniboxDriveSuggestionsName[] =
     "Omnibox Google Drive Document suggestions";
 const char kOmniboxDriveSuggestionsDescription[] =
@@ -4374,11 +4379,6 @@
 const char kPasswordManagerRedesignDescription[] =
     "Enables new Password Manager UI on Desktop";
 
-const char kScreenAIName[] = "Screen AI";
-const char kScreenAIDescription[] =
-    "Enables Screen AI local machine intelligence library to use the screen "
-    "snapshots to add metadata for accessibility tools.";
-
 const char kSCTAuditingName[] = "SCT auditing";
 const char kSCTAuditingDescription[] =
     "Enables SCT auditing for users who have opted in to Safe Browsing "
@@ -4955,15 +4955,6 @@
 const char kEnableServiceWorkersForChromeUntrustedDescription[] =
     "When enabled, allows chrome-untrusted:// WebUIs to use service workers.";
 
-const char kCrostiniBullseyeUpgradeName[] = "Upgrade Crostini to Bullseye";
-const char kCrostiniBullseyeUpgradeDescription[] =
-    "Offer to upgrade Crostini containers on older versions to bullseye.";
-
-const char kCrostiniDiskResizingName[] = "Allow resizing Crostini disks";
-const char kCrostiniDiskResizingDescription[] =
-    "Use preallocated user-resizeable disks for Crostini instead of sparse "
-    "automatically sized disks.";
-
 const char kCrostiniContainerInstallName[] =
     "Debian version for new Crostini containers";
 const char kCrostiniContainerInstallDescription[] =
@@ -4976,12 +4967,6 @@
 const char kCrostiniResetLxdDbDescription[] =
     "Recreates the LXD database every time we launch it";
 
-const char kCrostiniUseLxd4Name[] =
-    "Use LXD 4 instead of the default - Dangerous & Irreversible";
-const char kCrostiniUseLxd4Description[] =
-    "Uses LXD version 4 instead of the default version. WARNING: Once this is "
-    "set you can't unset it without deleting your entire container";
-
 const char kCrostiniMultiContainerName[] = "Allow multiple Crostini containers";
 const char kCrostiniMultiContainerDescription[] =
     "Experimental UI for creating and managing multiple Crostini containers";
@@ -5494,12 +5479,6 @@
 const char kFuseBoxDebugDescription[] =
     "Show additional debugging UI for ChromeOS FuseBox service.";
 
-const char kGuestOsFilesName[] =
-    "Enabled Guest OS Service + file manager integration";
-const char kGuestOsFilesDescription[] =
-    "The files app sources information about guests from the Guest OS service, "
-    "instead of querying each type individually";
-
 const char kHelpAppBackgroundPageName[] = "Help App Background Page";
 const char kHelpAppBackgroundPageDescription[] =
     "Enables the Background page in the help app. The background page is used "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h
index 573b417..dc9f33be 100644
--- a/chrome/browser/flag_descriptions.h
+++ b/chrome/browser/flag_descriptions.h
@@ -2505,6 +2505,9 @@
 extern const char kHappinessTrackingSurveysForDesktopDemoName[];
 extern const char kHappinessTrackingSurveysForDesktopDemoDescription[];
 
+extern const char kLayoutExtractionName[];
+extern const char kLayoutExtractionDescription[];
+
 extern const char kOmniboxDriveSuggestionsName[];
 extern const char kOmniboxDriveSuggestionsDescription[];
 
@@ -2514,9 +2517,6 @@
 extern const char kPasswordManagerRedesignName[];
 extern const char kPasswordManagerRedesignDescription[];
 
-extern const char kScreenAIName[];
-extern const char kScreenAIDescription[];
-
 extern const char kSCTAuditingName[];
 extern const char kSCTAuditingDescription[];
 
@@ -2849,12 +2849,6 @@
 extern const char kEnableServiceWorkersForChromeUntrustedName[];
 extern const char kEnableServiceWorkersForChromeUntrustedDescription[];
 
-extern const char kCrostiniBullseyeUpgradeName[];
-extern const char kCrostiniBullseyeUpgradeDescription[];
-
-extern const char kCrostiniDiskResizingName[];
-extern const char kCrostiniDiskResizingDescription[];
-
 extern const char kCrostiniContainerInstallName[];
 extern const char kCrostiniContainerInstallDescription[];
 
@@ -2864,9 +2858,6 @@
 extern const char kCrostiniResetLxdDbName[];
 extern const char kCrostiniResetLxdDbDescription[];
 
-extern const char kCrostiniUseLxd4Name[];
-extern const char kCrostiniUseLxd4Description[];
-
 extern const char kCrostiniMultiContainerName[];
 extern const char kCrostiniMultiContainerDescription[];
 
@@ -3157,9 +3148,6 @@
 extern const char kFuseBoxDebugName[];
 extern const char kFuseBoxDebugDescription[];
 
-extern const char kGuestOsFilesName[];
-extern const char kGuestOsFilesDescription[];
-
 extern const char kHelpAppBackgroundPageName[];
 extern const char kHelpAppBackgroundPageDescription[];
 
diff --git a/chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.cc b/chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.cc
index 13bdb679..6d1f41a 100644
--- a/chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.cc
+++ b/chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.cc
@@ -29,11 +29,13 @@
 #include "base/memory/raw_ptr.h"
 #include "base/notreached.h"
 #include "base/numerics/clamped_math.h"
+#include "build/branding_buildflags.h"
 #include "chrome/browser/fuchsia/element_manager_impl.h"
 #include "chrome/browser/fuchsia/switches.h"
 #include "chrome/browser/lifetime/application_lifetime.h"
 #include "chrome/browser/ui/browser_list.h"
 #include "chrome/common/chrome_switches.h"
+#include "components/fuchsia_component_support/feedback_registration.h"
 #include "components/keep_alive_registry/keep_alive_types.h"
 #include "components/keep_alive_registry/scoped_keep_alive.h"
 #include "content/public/common/content_switches.h"
@@ -43,6 +45,34 @@
 
 namespace {
 
+// Registers product data for the Chrome browser Component. This should only
+// be called once per browser instance, and the calling thread must have an
+// async_dispatcher.
+void RegisterChromeProductData() {
+  // The URL cannot be obtained programmatically - see fxbug.dev/51490.
+  constexpr char kComponentUrl[] =
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+      "fuchsia-pkg://chrome.com/chrome#meta/chrome.cm";
+#else
+      "fuchsia-pkg://chromium.org/chrome#meta/chrome.cm";
+#endif
+
+  constexpr char kCrashProductName[] = "Chrome_Fuchsia";
+
+  constexpr char kFeedbackAnnotationsNamespace[] =
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+      "google-chrome";
+#else
+      "chromium";
+#endif
+
+  fuchsia_component_support::RegisterProductDataForCrashReporting(
+      kComponentUrl, kCrashProductName);
+
+  fuchsia_component_support::RegisterProductDataForFeedback(
+      kFeedbackAnnotationsNamespace);
+}
+
 // Checks the supported ozone platform with Scenic if no arg is specified.
 // TODO(fxbug.dev/94001): Delete this after Flatland migration is completed.
 void HandleOzonePlatformArgs() {
@@ -646,6 +676,12 @@
   return ChromeBrowserMainParts::PreEarlyInitialization();
 }
 
+void ChromeBrowserMainPartsFuchsia::PostCreateMainMessageLoop() {
+  RegisterChromeProductData();
+
+  ChromeBrowserMainParts::PostCreateMainMessageLoop();
+}
+
 int ChromeBrowserMainPartsFuchsia::PreMainMessageLoopRun() {
   const bool enable_cfv2 =
       base::CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableCFv2);
diff --git a/chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.h b/chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.h
index fee0d89..0a548df 100644
--- a/chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.h
+++ b/chrome/browser/fuchsia/chrome_browser_main_parts_fuchsia.h
@@ -33,6 +33,7 @@
 
   // content::BrowserMainParts overrides.
   int PreEarlyInitialization() override;
+  void PostCreateMainMessageLoop() override;
   int PreMainMessageLoopRun() override;
   void PostMainMessageLoopRun() override;
 
diff --git a/chrome/browser/lacros/download_controller_client_lacros_browsertest.cc b/chrome/browser/lacros/download_controller_client_lacros_browsertest.cc
index 7b97a79f..afbc28a 100644
--- a/chrome/browser/lacros/download_controller_client_lacros_browsertest.cc
+++ b/chrome/browser/lacros/download_controller_client_lacros_browsertest.cc
@@ -80,8 +80,8 @@
 
   std::unique_ptr<crosapi::mojom::DownloadControllerClient>
       download_controller_client_;
-  raw_ptr<testing::NiceMock<content::MockDownloadManager>> download_manager_ =
-      nullptr;
+  raw_ptr<testing::NiceMock<content::MockDownloadManager>, DanglingUntriaged>
+      download_manager_ = nullptr;
 };
 
 // Tests -----------------------------------------------------------------------
diff --git a/chrome/browser/lacros/holding_space_service_lacros_browsertest.cc b/chrome/browser/lacros/holding_space_service_lacros_browsertest.cc
index f0bb56b..00e78be 100644
--- a/chrome/browser/lacros/holding_space_service_lacros_browsertest.cc
+++ b/chrome/browser/lacros/holding_space_service_lacros_browsertest.cc
@@ -125,7 +125,7 @@
   }
 
   std::unique_ptr<printing::PdfPrinterHandler> pdf_printer_handler_;
-  raw_ptr<Browser> incognito_browser_ = nullptr;
+  raw_ptr<Browser, DanglingUntriaged> incognito_browser_ = nullptr;
 };
 
 INSTANTIATE_TEST_SUITE_P(All,
diff --git a/chrome/browser/lacros/lacros_extension_apps_controller.h b/chrome/browser/lacros/lacros_extension_apps_controller.h
index 92d5750..dc919eca 100644
--- a/chrome/browser/lacros/lacros_extension_apps_controller.h
+++ b/chrome/browser/lacros/lacros_extension_apps_controller.h
@@ -116,7 +116,8 @@
   // The key is the raw pointer to the ExtensionAppsEnableFlow.
   std::map<void*, std::unique_ptr<apps::ExtensionAppsEnableFlow>> enable_flows_;
 
-  raw_ptr<LacrosExtensionAppsPublisher> publisher_ = nullptr;  // Not owned.
+  raw_ptr<LacrosExtensionAppsPublisher, DanglingUntriaged> publisher_ =
+      nullptr;  // Not owned.
 
   // Mojo endpoint that's responsible for receiving messages from Ash.
   mojo::Receiver<crosapi::mojom::AppController> controller_;
diff --git a/chrome/browser/lacros/metrics_reporting_observer.cc b/chrome/browser/lacros/metrics_reporting_observer.cc
index fb3c77c0..3a6c9bd 100644
--- a/chrome/browser/lacros/metrics_reporting_observer.cc
+++ b/chrome/browser/lacros/metrics_reporting_observer.cc
@@ -40,7 +40,7 @@
   }
 
  private:
-  raw_ptr<metrics::MetricsService> metrics_service_;
+  raw_ptr<metrics::MetricsService, DanglingUntriaged> metrics_service_;
 };
 
 std::unique_ptr<MetricsReportingObserver>
diff --git a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h
index b655da8..22077a1 100644
--- a/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h
+++ b/chrome/browser/media/router/discovery/access_code/access_code_cast_sink_service.h
@@ -342,7 +342,8 @@
 
   raw_ptr<PrefService, DanglingUntriaged> prefs_;
 
-  raw_ptr<signin::IdentityManager> identity_manager_ = nullptr;
+  raw_ptr<signin::IdentityManager, DanglingUntriaged> identity_manager_ =
+      nullptr;
 
   // This registrar monitors for user prefs changes.
   std::unique_ptr<PrefChangeRegistrar> user_prefs_registrar_;
diff --git a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
index b16eabe..98de4754 100644
--- a/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
+++ b/chrome/browser/media/webrtc/webrtc_getdisplaymedia_browsertest.cc
@@ -1039,7 +1039,7 @@
 
   base::test::ScopedFeatureList feature_list_;
   const TestConfigForHiDpi test_config_;
-  raw_ptr<content::WebContents> tab_ = nullptr;
+  raw_ptr<content::WebContents, DanglingUntriaged> tab_ = nullptr;
 };
 
 IN_PROC_BROWSER_TEST_P(GetDisplayMediaHiDpiBrowserTest, Capture) {
diff --git a/chrome/browser/metrics/chrome_metrics_service_client.cc b/chrome/browser/metrics/chrome_metrics_service_client.cc
index d9b06f42..d64e2a82 100644
--- a/chrome/browser/metrics/chrome_metrics_service_client.cc
+++ b/chrome/browser/metrics/chrome_metrics_service_client.cc
@@ -385,7 +385,7 @@
   if (kill(pid, 0) == 0 || errno != ESRCH)
     return true;
 #elif BUILDFLAG(IS_FUCHSIA)
-  // TODO(crbug.com/1235293)
+  // TODO(crbug.com/967028): Implement along with metrics support.
   NOTIMPLEMENTED_LOG_ONCE();
 #else
 #error Unsupported OS. Might be okay to just return false.
diff --git a/chrome/browser/net/profile_network_context_service.cc b/chrome/browser/net/profile_network_context_service.cc
index eb8daa2c..bc66df1 100644
--- a/chrome/browser/net/profile_network_context_service.cc
+++ b/chrome/browser/net/profile_network_context_service.cc
@@ -697,7 +697,7 @@
   // selection dialog.
   return nullptr;
 #elif BUILDFLAG(IS_FUCHSIA)
-  // TODO(crbug.com/1235293)
+  // TODO(crbug.com/1380609): Implement ClientCertStore support.
   NOTIMPLEMENTED_LOG_ONCE();
   return nullptr;
 #else
diff --git a/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc b/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc
index 340b756..e519f3740 100644
--- a/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc
+++ b/chrome/browser/new_tab_page/new_tab_page_interactive_uitest.cc
@@ -200,8 +200,8 @@
 
  protected:
   base::test::ScopedFeatureList features_;
-  raw_ptr<content::WebContents> contents_;
-  raw_ptr<BrowserView> browser_view_;
+  raw_ptr<content::WebContents, DanglingUntriaged> contents_;
+  raw_ptr<BrowserView, DanglingUntriaged> browser_view_;
   scoped_refptr<content::DevToolsAgentHost> agent_host_;
   std::map<std::string, GURL> loading_resources_;
   std::set<GURL> loaded_resources_;
diff --git a/chrome/browser/notifications/scheduler/internal/impression_history_tracker.h b/chrome/browser/notifications/scheduler/internal/impression_history_tracker.h
index 265a752..23e0a62 100644
--- a/chrome/browser/notifications/scheduler/internal/impression_history_tracker.h
+++ b/chrome/browser/notifications/scheduler/internal/impression_history_tracker.h
@@ -200,7 +200,7 @@
   std::unique_ptr<CollectionStore<ClientState>> store_;
 
   // System configuration.
-  const raw_ref<const SchedulerConfig> config_;
+  const raw_ref<const SchedulerConfig, DanglingUntriaged> config_;
 
   const std::vector<SchedulerClientType> registered_clients_;
 
diff --git a/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.cc b/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.cc
index 691fd407..ffbdd24 100644
--- a/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.cc
+++ b/chrome/browser/notifications/scheduler/internal/scheduled_notification_manager.cc
@@ -444,7 +444,7 @@
   std::map<SchedulerClientType,
            std::map<std::string, std::unique_ptr<NotificationEntry>>>
       notifications_;
-  const raw_ref<const SchedulerConfig> config_;
+  const raw_ref<const SchedulerConfig, DanglingUntriaged> config_;
   base::WeakPtrFactory<ScheduledNotificationManagerImpl> weak_ptr_factory_{
       this};
 };
diff --git a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
index fba72ca..3338cb4 100644
--- a/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
+++ b/chrome/browser/optimization_guide/page_content_annotations_service_browsertest.cc
@@ -56,13 +56,14 @@
 // results in a pretty big difference in the scores. This matcher offers up to
 // 0.1 of absolute difference in score, but the topic itself must match.
 // See crbug.com/1307251.
+const double kMaxScoreErrorBetweenPlatforms = 0.1;
 testing::Matcher<WeightedIdentifier> CrossPlatformMatcher(
     const WeightedIdentifier& wi) {
   return testing::AllOf(
       testing::Property(&WeightedIdentifier::value, wi.value()),
       testing::Property(
           &WeightedIdentifier::weight,
-          testing::DoubleNear(wi.weight(), /*max_abs_error=*/0.1)));
+          testing::DoubleNear(wi.weight(), kMaxScoreErrorBetweenPlatforms)));
 }
 #endif
 
@@ -367,25 +368,6 @@
   }
 
   void LoadAndWaitForModel() {
-    proto::Any any_metadata;
-    any_metadata.set_type_url(
-        "type.googleapis.com/com.foo.PageTopicsModelMetadata");
-    proto::PageTopicsModelMetadata page_topics_model_metadata;
-    page_topics_model_metadata.set_version(123);
-    page_topics_model_metadata.add_supported_output(
-        proto::PAGE_TOPICS_SUPPORTED_OUTPUT_CATEGORIES);
-    auto* output_params =
-        page_topics_model_metadata.mutable_output_postprocessing_params();
-    auto* category_params = output_params->mutable_category_params();
-    category_params->set_max_categories(5);
-    category_params->set_min_none_weight(0.8);
-    category_params->set_min_category_weight(0.0);
-    category_params->set_min_normalized_weight_within_top_n(0.1);
-    // TODO(crbug.com/1200677): migrate the category name on the test model
-    // itself provided by model owners.
-    output_params->mutable_visibility_params()->set_category_name(
-        "FLOC_PROTECTED");
-    page_topics_model_metadata.SerializeToString(any_metadata.mutable_value());
     base::FilePath source_root_dir;
     base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root_dir);
     base::FilePath model_file_path =
@@ -393,7 +375,7 @@
             .AppendASCII("test")
             .AppendASCII("data")
             .AppendASCII("optimization_guide")
-            .AppendASCII("bert_page_topics_model.tflite");
+            .AppendASCII("visibility_test_model.tflite");
 
     base::HistogramTester histogram_tester;
 
@@ -402,7 +384,6 @@
             proto::OPTIMIZATION_TARGET_PAGE_VISIBILITY,
             optimization_guide::TestModelInfoBuilder()
                 .SetModelFilePath(model_file_path)
-                .SetModelMetadata(any_metadata)
                 .Build());
 
 #if BUILDFLAG(BUILD_WITH_TFLITE_LIB)
@@ -533,6 +514,40 @@
 
 #if BUILDFLAG(BUILD_WITH_TFLITE_LIB)
 IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceBrowserTest,
+                       PageVisibilityModel_GoldenData) {
+  LoadAndWaitForModel();
+
+  PageContentAnnotationsService* service =
+      PageContentAnnotationsServiceFactory::GetForProfile(browser()->profile());
+
+  // Important: Consumers of the visibility score should query the HistoryDB
+  // instead of hitting the PCAService directly. We only do this in tests
+  // because it is less flaky.
+  // TODO(b/258468574): Maybe move this to a navigation-based test once those
+  // are less flaky?
+  base::RunLoop run_loop;
+  service->BatchAnnotate(
+      base::BindOnce(
+          [](base::RunLoop* run_loop,
+             const std::vector<BatchAnnotationResult>& results) {
+            ASSERT_EQ(results.size(), 1U);
+            EXPECT_EQ(results[0].input(), "this is a test");
+            EXPECT_EQ(results[0].type(), AnnotationType::kContentVisibility);
+
+            ASSERT_TRUE(results[0].visibility_score());
+            EXPECT_NEAR(*results[0].visibility_score(), 0.14453125,
+                        kMaxScoreErrorBetweenPlatforms);
+
+            run_loop->Quit();
+          },
+          &run_loop),
+      std::vector<std::string>{"this is a test"},
+      AnnotationType::kContentVisibility);
+
+  run_loop.Run();
+}
+
+IN_PROC_BROWSER_TEST_F(PageContentAnnotationsServiceBrowserTest,
                        PageTopicsDomainPreProcessing) {
   PageContentAnnotationsService* service =
       PageContentAnnotationsServiceFactory::GetForProfile(browser()->profile());
diff --git a/chrome/browser/page_load_metrics/integration_tests/DEPS b/chrome/browser/page_load_metrics/integration_tests/DEPS
new file mode 100644
index 0000000..9ffdb86
--- /dev/null
+++ b/chrome/browser/page_load_metrics/integration_tests/DEPS
@@ -0,0 +1,5 @@
+specific_include_rules = {
+  "cross_document_resource_reuse_test\.cc": [
+    "+third_party/blink/renderer/platform/loader/fetch/resource.h",
+  ]
+}
diff --git a/chrome/browser/page_load_metrics/integration_tests/cross_document_resource_reuse_test.cc b/chrome/browser/page_load_metrics/integration_tests/cross_document_resource_reuse_test.cc
new file mode 100644
index 0000000..509338b
--- /dev/null
+++ b/chrome/browser/page_load_metrics/integration_tests/cross_document_resource_reuse_test.cc
@@ -0,0 +1,35 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h"
+
+#include "chrome/browser/ui/browser.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "components/metrics/content/subprocess_metrics_provider.h"
+#include "content/public/test/browser_test.h"
+#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
+
+using CrossDocumentResourceReuseTest = MetricIntegrationTest;
+
+// The test verifies the metrics for reusing resources among different
+// documents. The first and the second page share an image in common. We
+// verify the resource reuse is correctly recorded in the UMA.
+IN_PROC_BROWSER_TEST_F(CrossDocumentResourceReuseTest,
+                       CrossDocumentResourceReuse) {
+  Start();
+  Load("/cross_document_resource.html");
+  // The new document contains an imaged reused from the previous HTML
+  Load("/cross_document_resource_reuse.html");
+
+  // Finish session.
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), GURL("about:blank")));
+
+  // Actually fetch the metrics.
+  content::FetchHistogramsFromChildProcesses();
+  metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
+
+  ExpectUniqueUMABucketCount(
+      "Blink.MemoryCache.CrossDocumentCachedResource",
+      static_cast<base::Histogram::Sample>(blink::ResourceType::kImage), 1);
+}
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/blue.png b/chrome/browser/page_load_metrics/integration_tests/data/blue.png
new file mode 100644
index 0000000..4498dd2
--- /dev/null
+++ b/chrome/browser/page_load_metrics/integration_tests/data/blue.png
Binary files differ
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/blue.png.mock-http-headers b/chrome/browser/page_load_metrics/integration_tests/data/blue.png.mock-http-headers
new file mode 100644
index 0000000..6e2fdec
--- /dev/null
+++ b/chrome/browser/page_load_metrics/integration_tests/data/blue.png.mock-http-headers
@@ -0,0 +1,3 @@
+HTTP/1.1 200 OK
+Content-Type: image/png
+Cache-Control: max-age=300
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/cross_document_resource.html b/chrome/browser/page_load_metrics/integration_tests/data/cross_document_resource.html
new file mode 100644
index 0000000..9aafadf
--- /dev/null
+++ b/chrome/browser/page_load_metrics/integration_tests/data/cross_document_resource.html
@@ -0,0 +1 @@
+<img src="/blue.png">
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/cross_document_resource_reuse.html b/chrome/browser/page_load_metrics/integration_tests/data/cross_document_resource_reuse.html
new file mode 100644
index 0000000..d0229b2
--- /dev/null
+++ b/chrome/browser/page_load_metrics/integration_tests/data/cross_document_resource_reuse.html
@@ -0,0 +1,5 @@
+<!-- blue.png shall be reused from cross_document_reuse.html -->
+<!-- The image is repeated to ensure that the same resource is not counted multiple times -->
+<img src="/blue.png">
+<img src="/blue.png">
+<img src="/green.png">
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/green.png b/chrome/browser/page_load_metrics/integration_tests/data/green.png
new file mode 100644
index 0000000..28a1faa
--- /dev/null
+++ b/chrome/browser/page_load_metrics/integration_tests/data/green.png
Binary files differ
diff --git a/chrome/browser/page_load_metrics/integration_tests/data/green.png.mock-http-headers b/chrome/browser/page_load_metrics/integration_tests/data/green.png.mock-http-headers
new file mode 100644
index 0000000..6e2fdec
--- /dev/null
+++ b/chrome/browser/page_load_metrics/integration_tests/data/green.png.mock-http-headers
@@ -0,0 +1,3 @@
+HTTP/1.1 200 OK
+Content-Type: image/png
+Cache-Control: max-age=300
diff --git a/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.cc b/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.cc
index 54d451ab..6a6f69c 100644
--- a/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.cc
+++ b/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.cc
@@ -216,6 +216,13 @@
       << expected_value;
 }
 
+void MetricIntegrationTest::ExpectUniqueUMABucketCount(
+    StringPiece metric_name,
+    base::HistogramBase::Sample sample,
+    base::HistogramBase::Count count) {
+  histogram_tester_->ExpectBucketCount(metric_name, sample, count);
+}
+
 void MetricIntegrationTest::ExpectUniqueUMAPageLoadMetricNear(
     StringPiece metric_name,
     double expected_value) {
diff --git a/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h b/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h
index 01608a06..57d5709c 100644
--- a/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h
+++ b/chrome/browser/page_load_metrics/integration_tests/metric_integration_test.h
@@ -125,6 +125,11 @@
                                   double below,
                                   double above);
 
+  // Checks that the UMA bucket count precisely matches the provided value.
+  void ExpectUniqueUMABucketCount(base::StringPiece metric_name,
+                                  base::Histogram::Sample sample,
+                                  base::Histogram::Count count);
+
   // Checks that we have a single UMA entry.
   void ExpectUniqueUMA(base::StringPiece metric_name);
 
diff --git a/chrome/browser/page_load_metrics/integration_tests/sources.gni b/chrome/browser/page_load_metrics/integration_tests/sources.gni
index d277911..6be8d24b 100644
--- a/chrome/browser/page_load_metrics/integration_tests/sources.gni
+++ b/chrome/browser/page_load_metrics/integration_tests/sources.gni
@@ -3,6 +3,7 @@
 # found in the LICENSE file.
 
 metric_integration_sources = [
+  "//chrome/browser/page_load_metrics/integration_tests/cross_document_resource_reuse_test.cc",
   "//chrome/browser/page_load_metrics/integration_tests/event_counts_browsertest.cc",
   "//chrome/browser/page_load_metrics/integration_tests/first_input_delay_browsertest.cc",
   "//chrome/browser/page_load_metrics/integration_tests/first_scroll_delay_browsertest.cc",
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h
index 6467b9ff..7123362 100644
--- a/chrome/browser/password_manager/chrome_password_manager_client.h
+++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -421,7 +421,8 @@
       generated_password_saved_message_delegate_;
 #endif  // BUILDFLAG(IS_ANDROID)
 
-  raw_ptr<password_manager::ContentPasswordManagerDriverFactory>
+  raw_ptr<password_manager::ContentPasswordManagerDriverFactory,
+          DanglingUntriaged>
       driver_factory_;
 
   // As a mojo service, will be registered into service registry
diff --git a/chrome/browser/password_manager/password_manager_test_base.h b/chrome/browser/password_manager/password_manager_test_base.h
index 203d769..faf1dd8 100644
--- a/chrome/browser/password_manager/password_manager_test_base.h
+++ b/chrome/browser/password_manager/password_manager_test_base.h
@@ -100,7 +100,8 @@
   void WaitForSaveUnsyncedCredentialsPrompt() const;
 
  private:
-  const raw_ptr<ManagePasswordsUIController> passwords_ui_controller_;
+  const raw_ptr<ManagePasswordsUIController, DanglingUntriaged>
+      passwords_ui_controller_;
 };
 
 // A helper class that synchronously waits until the password store handles a
diff --git a/chrome/browser/performance_monitor/system_monitor.cc b/chrome/browser/performance_monitor/system_monitor.cc
index 32d03ad..72970c42 100644
--- a/chrome/browser/performance_monitor/system_monitor.cc
+++ b/chrome/browser/performance_monitor/system_monitor.cc
@@ -246,7 +246,7 @@
 #elif BUILDFLAG(IS_POSIX)
   return std::make_unique<MetricEvaluatorsHelperPosix>();
 #elif BUILDFLAG(IS_FUCHSIA)
-  // TODO(crbug.com/1235293)
+  // TODO(crbug.com/1166873): Implement this in support of tracing.
   NOTIMPLEMENTED_LOG_ONCE();
   return nullptr;
 #else
diff --git a/chrome/browser/platform_util_fuchsia.cc b/chrome/browser/platform_util_fuchsia.cc
index c97c6cd..b118356 100644
--- a/chrome/browser/platform_util_fuchsia.cc
+++ b/chrome/browser/platform_util_fuchsia.cc
@@ -8,21 +8,21 @@
 namespace platform_util {
 
 void ShowItemInFolder(Profile* profile, const base::FilePath& full_path) {
-  // TODO(crbug.com/1235293)
+  // TODO(crbug.com/1231928): Implement once Fuchsia supports opening folders.
   NOTIMPLEMENTED_LOG_ONCE();
 }
 
 namespace internal {
 
 void PlatformOpenVerifiedItem(const base::FilePath& path, OpenItemType type) {
-  // TODO(crbug.com/1235293)
+  // TODO(crbug.com/1231928): Implement once Fuchsia supports opening folders.
   NOTIMPLEMENTED_LOG_ONCE();
 }
 
 }  // namespace internal
 
 void OpenExternal(const GURL& url) {
-  // TODO(crbug.com/1235293)
+  // TODO(crbug.com/1231928): Implement once Fuchsia supports opening folders.
   NOTIMPLEMENTED_LOG_ONCE();
 }
 
diff --git a/chrome/browser/policy/extension_force_install_mixin.h b/chrome/browser/policy/extension_force_install_mixin.h
index 0574211..cd0f33c 100644
--- a/chrome/browser/policy/extension_force_install_mixin.h
+++ b/chrome/browser/policy/extension_force_install_mixin.h
@@ -239,7 +239,7 @@
   base::ScopedTempDir temp_dir_;
   net::EmbeddedTestServer embedded_test_server_;
   bool initialized_ = false;
-  raw_ptr<Profile> profile_ = nullptr;
+  raw_ptr<Profile, DanglingUntriaged> profile_ = nullptr;
   raw_ptr<policy::MockConfigurationPolicyProvider> mock_policy_provider_ =
       nullptr;
 #if BUILDFLAG(IS_CHROMEOS_ASH)
diff --git a/chrome/browser/policy/test/policy_certs_browsertest.cc b/chrome/browser/policy/test/policy_certs_browsertest.cc
index 4c73f52..81e7af8 100644
--- a/chrome/browser/policy/test/policy_certs_browsertest.cc
+++ b/chrome/browser/policy/test/policy_certs_browsertest.cc
@@ -356,7 +356,7 @@
   }
 
  private:
-  raw_ptr<Profile> profile_1_ = nullptr;
+  raw_ptr<Profile, DanglingUntriaged> profile_1_ = nullptr;
   Profile* profile_2_ = nullptr;
 
   testing::NiceMock<MockConfigurationPolicyProvider> policy_for_profile_1_;
diff --git a/chrome/browser/process_singleton_fuchsia.cc b/chrome/browser/process_singleton_fuchsia.cc
index ad3b9bc..e87ed04b 100644
--- a/chrome/browser/process_singleton_fuchsia.cc
+++ b/chrome/browser/process_singleton_fuchsia.cc
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "chrome/browser/process_singleton.h"
+
 // On Fuchsia, we assume that the Component Framework ensures that only a single
 // Chrome component instance will run against a particular data-directory.
 // This file contains a stubbed-out ProcessSingleton implementation. :)
@@ -9,8 +11,8 @@
 // In future we will need to support a mechanism for URL launch attempts to
 // be handled by a running Chrome instance, e.g. by registering the instance as
 // the Runner for HTTP[S] component URLs.
-
-#include "chrome/browser/process_singleton.h"
+//
+// TODO(crbug.com/1370080): Implement these methods as appropriate.
 
 ProcessSingleton::ProcessSingleton(
     const base::FilePath& user_data_dir,
@@ -21,29 +23,24 @@
 }
 
 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() {
-  // TODO(crbug.com/1235293)
   NOTIMPLEMENTED_LOG_ONCE();
   return PROCESS_NONE;
 }
 
 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() {
-  // TODO(crbug.com/1235293)
   NOTIMPLEMENTED_LOG_ONCE();
   return PROCESS_NONE;
 }
 
 bool ProcessSingleton::Create() {
-  // TODO(crbug.com/1235293)
   NOTIMPLEMENTED_LOG_ONCE();
   return true;
 }
 
 void ProcessSingleton::StartWatching() {
-  // TODO(crbug.com/1235293)
   NOTIMPLEMENTED_LOG_ONCE();
 }
 
 void ProcessSingleton::Cleanup() {
-  // TODO(crbug.com/1235293)
   NOTIMPLEMENTED_LOG_ONCE();
 }
diff --git a/chrome/browser/profiles/avatar_menu.h b/chrome/browser/profiles/avatar_menu.h
index 4eeb0b1..ff61d8399 100644
--- a/chrome/browser/profiles/avatar_menu.h
+++ b/chrome/browser/profiles/avatar_menu.h
@@ -191,10 +191,10 @@
   base::WeakPtr<ProfileAttributesStorage> profile_storage_;
 
   // The observer of this model, which is notified of changes. Weak.
-  raw_ptr<AvatarMenuObserver> observer_;
+  raw_ptr<AvatarMenuObserver, DanglingUntriaged> observer_;
 
   // Browser in which this avatar menu resides. Weak.
-  raw_ptr<Browser> browser_;
+  raw_ptr<Browser, DanglingUntriaged> browser_;
 };
 
 #endif  // CHROME_BROWSER_PROFILES_AVATAR_MENU_H_
diff --git a/chrome/browser/resources/chromeos/crostini_installer/app.html b/chrome/browser/resources/chromeos/crostini_installer/app.html
index 17cb7bb..3ccb62d7 100644
--- a/chrome/browser/resources/chromeos/crostini_installer/app.html
+++ b/chrome/browser/resources/chromeos/crostini_installer/app.html
@@ -110,13 +110,13 @@
       <a href="$i18n{learnMoreUrl}" target="_blank">$i18n{learnMore}</a>
     </div>
     <div id="configure-message" hidden="[[!eq_(state_, State.CONFIGURE)]]">
-      <div id="configure-message-title">[[getConfigureMessageTitle_()]]</div>
+      <div id="configure-message-title">$i18n{configureMessage}</div>
       <cr-input label="$i18n{usernameLabel}" id="username" type="text"
           value="{{username_}}" maxlength="[[MAX_USERNAME_LENGTH]]"
           invalid="[[!eq_(usernameError_, '')]]"
           error-message="[[usernameError_]]">
       </cr-input>
-      <div id='disk-size-section' hidden="[[!showDiskResizing_()]]">
+      <div id='disk-size-section'>
         <div id="disk-size-message">
           <div style="color:var(--cr-primary-text-color)">
             $i18n{diskSizeSubtitle}
diff --git a/chrome/browser/resources/chromeos/crostini_installer/app.js b/chrome/browser/resources/chromeos/crostini_installer/app.js
index 8bda198..2c33e3da 100644
--- a/chrome/browser/resources/chromeos/crostini_installer/app.js
+++ b/chrome/browser/resources/chromeos/crostini_installer/app.js
@@ -255,12 +255,10 @@
   onInstallButtonClick_() {
     assert(this.showInstallButton_(this.state_, this.error_));
     var diskSize = 0;
-    if (loadTimeData.getBoolean('diskResizingEnabled')) {
-      if (this.showDiskSlider_) {
-        diskSize = this.diskSizeTicks_[this.$$('#diskSlider').value].value;
-      } else {
-        diskSize = this.diskSizeTicks_[this.defaultDiskSizeTick_].value;
-      }
+    if (this.showDiskSlider_) {
+      diskSize = this.diskSizeTicks_[this.$$('#diskSlider').value].value;
+    } else {
+      diskSize = this.diskSizeTicks_[this.defaultDiskSizeTick_].value;
     }
     this.installerState_ = InstallerState.kStart;
     this.installerProgress_ = 0;
@@ -510,25 +508,6 @@
     return messageId ? loadTimeData.getString(messageId) : '';
   },
 
-  /**
-   * @private
-   */
-  showDiskResizing_() {
-    return loadTimeData.getBoolean('diskResizingEnabled');
-  },
-
-  /**
-   * @private
-   */
-  getConfigureMessageTitle_() {
-    // If the flags only allow username config, then we show a username specific
-    // subtitle instead of a generic configure subtitle.
-    if (!this.showDiskResizing_()) {
-      return loadTimeData.getString('usernameMessage');
-    }
-    return loadTimeData.getString('configureMessage');
-  },
-
   /** @private */
   onUsernameChanged_(username, oldUsername) {
     if (!username) {
diff --git a/chrome/browser/resources/password_manager/BUILD.gn b/chrome/browser/resources/password_manager/BUILD.gn
index 4cb10ee..c0de7e0bd 100644
--- a/chrome/browser/resources/password_manager/BUILD.gn
+++ b/chrome/browser/resources/password_manager/BUILD.gn
@@ -7,16 +7,17 @@
 build_webui("build") {
   grd_prefix = "password_manager"
   static_files = [
-    "password_manager.html",
-    "manifest.webmanifest",
-    "images/checkup_result_banner_error_dark.svg",
-    "images/checkup_result_banner_compromised_dark.svg",
-    "images/checkup_result_banner_running_dark.svg",
-    "images/checkup_result_banner_error.svg",
     "images/checkup_result_banner_compromised.svg",
-    "images/checkup_result_banner_running.svg",
-    "images/checkup_result_banner_ok_dark.svg",
+    "images/checkup_result_banner_compromised_dark.svg",
+    "images/checkup_result_banner_error.svg",
+    "images/checkup_result_banner_error_dark.svg",
     "images/checkup_result_banner_ok.svg",
+    "images/checkup_result_banner_ok_dark.svg",
+    "images/checkup_result_banner_running.svg",
+    "images/checkup_result_banner_running_dark.svg",
+    "images/password_manager_logo.svg",
+    "manifest.webmanifest",
+    "password_manager.html",
   ]
   web_component_files = [
     "checkup_section.ts",
diff --git a/chrome/browser/resources/password_manager/images/password_manager_logo.svg b/chrome/browser/resources/password_manager/images/password_manager_logo.svg
new file mode 100644
index 0000000..d1593d78
--- /dev/null
+++ b/chrome/browser/resources/password_manager/images/password_manager_logo.svg
@@ -0,0 +1 @@
+<svg width="151" height="151" viewBox="0 0 151 83" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M79.961 27.667C74.333 11.55 59.096 0 41.181 0 18.464 0 0 18.606 0 41.5S18.463 83 41.182 83c17.914 0 33.151-11.55 38.78-27.667h29.856V83h27.455V55.333H151V27.667H79.961Zm-38.78 27.666c-7.55 0-13.726-6.225-13.726-13.833 0-7.608 6.177-13.833 13.727-13.833 7.55 0 13.727 6.225 13.727 13.833 0 7.608-6.177 13.833-13.727 13.833Z" fill="#1A73E8"/></svg>
\ No newline at end of file
diff --git a/chrome/browser/resources/password_manager/manifest.webmanifest b/chrome/browser/resources/password_manager/manifest.webmanifest
index 7b11c7b2..20cca606 100644
--- a/chrome/browser/resources/password_manager/manifest.webmanifest
+++ b/chrome/browser/resources/password_manager/manifest.webmanifest
@@ -3,9 +3,9 @@
   "name": "Password Manager",
   "icons": [
     {
-      "src": "chrome://theme/current-channel-logo",
-      "type": "image/png",
-      "sizes": "32x32"
+      "src": "chrome://password-manager/images/password_manager_logo.svg",
+      "type": "image/svg+xml",
+      "sizes": "any"
     }
   ],
   "start_url": "/?source=pwa",
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_subpage.html b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_subpage.html
index b98a5af7..44c0ac68 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_subpage.html
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_subpage.html
@@ -70,35 +70,31 @@
       role-description="$i18n{subpageArrowRoleDescription}">
   </cr-link-row>
 </template>
-<template is="dom-if" if="[[showCrostiniDiskResize_]]">
-  <div class="settings-box hr" id="crostini-disk-resize">
-    <div class="start">
-      <div>
-        $i18n{crostiniDiskResizeLabel}
-      </div>
-      <div class="secondary" id="diskSizeDescription">
-        [[diskSizeLabel_]]
-      </div>
+<div class="settings-box hr" id="crostini-disk-resize">
+  <div class="start">
+    <div>
+      $i18n{crostiniDiskResizeLabel}
     </div>
-    <cr-button on-click="onDiskResizeClick_" hidden="[[!canDiskResize_]]"
-        aria-label="[[diskResizeButtonAriaLabel_]]"
-        aria-describedby="diskSizeDescription"
-        id="showDiskResizeButton"
-        deep-link-focus-id$="[[Setting.kCrostiniDiskResize]]">
-      [[diskResizeButtonLabel_]]
-    </cr-button>
+    <div class="secondary" id="diskSizeDescription">
+      [[diskSizeLabel_]]
+    </div>
   </div>
-  <template is="dom-if" if="[[showDiskResizeDialog_]]" restamp>
-    <settings-crostini-disk-resize-dialog
-        on-close="onDiskResizeDialogClose_">
-    </settings-crostini-disk-resize-dialog>
-  </template>
-  <template is="dom-if" if="[[showDiskResizeConfirmationDialog_]]" restamp>
-    <settings-crostini-disk-resize-confirmation-dialog
-        on-close="onDiskResizeConfirmationDialogClose_"
-        on-cancel="onDiskResizeConfirmationDialogCancel_">
-    </settings-crostini-disk-resize-confirmation-dialog>
-  </template>
+  <cr-button on-click="onDiskResizeClick_" hidden="[[!canDiskResize_]]"
+      aria-label="[[diskResizeButtonAriaLabel_]]"
+      aria-describedby="diskSizeDescription" id="showDiskResizeButton"
+      deep-link-focus-id$="[[Setting.kCrostiniDiskResize]]">
+    [[diskResizeButtonLabel_]]
+  </cr-button>
+</div>
+<template is="dom-if" if="[[showDiskResizeDialog_]]" restamp>
+  <settings-crostini-disk-resize-dialog on-close="onDiskResizeDialogClose_">
+  </settings-crostini-disk-resize-dialog>
+</template>
+<template is="dom-if" if="[[showDiskResizeConfirmationDialog_]]" restamp>
+  <settings-crostini-disk-resize-confirmation-dialog
+      on-close="onDiskResizeConfirmationDialogClose_"
+      on-cancel="onDiskResizeConfirmationDialogCancel_">
+  </settings-crostini-disk-resize-confirmation-dialog>
 </template>
 <settings-toggle-button
     class="hr"
diff --git a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_subpage.ts b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_subpage.ts
index 8f14126..4a421f4 100644
--- a/chrome/browser/resources/settings/chromeos/crostini_page/crostini_subpage.ts
+++ b/chrome/browser/resources/settings/chromeos/crostini_page/crostini_subpage.ts
@@ -133,16 +133,6 @@
         },
       },
 
-      /**
-       * Whether the button to show the disk resizing view should be shown.
-       */
-      showCrostiniDiskResize_: {
-        type: Boolean,
-        value() {
-          return loadTimeData.getBoolean('showCrostiniDiskResize');
-        },
-      },
-
       showDiskResizeConfirmationDialog_: {
         type: Boolean,
         value: false,
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.html b/chrome/browser/resources/settings/controls/settings_checkbox.html
index 649d4c8..74f8601 100644
--- a/chrome/browser/resources/settings/controls/settings_checkbox.html
+++ b/chrome/browser/resources/settings/controls/settings_checkbox.html
@@ -28,7 +28,7 @@
       aria-label="[[label]]">
     <div id="label" class="label">[[label]] <slot></slot></div>
     <div id="subLabel" class="secondary label">
-      <div inner-h-t-m-l="[[sanitizeInnerHtml_(subLabelHtml)]]"></div>
+      <div inner-h-t-m-l="[[subLabelHtml]]"></div>
       [[subLabel]]
     </div>
   </cr-checkbox>
diff --git a/chrome/browser/resources/settings/controls/settings_checkbox.ts b/chrome/browser/resources/settings/controls/settings_checkbox.ts
index 7e605284..6b86c7b 100644
--- a/chrome/browser/resources/settings/controls/settings_checkbox.ts
+++ b/chrome/browser/resources/settings/controls/settings_checkbox.ts
@@ -11,7 +11,6 @@
 import '../settings_shared.css.js';
 
 import {CrCheckboxElement} from 'chrome://resources/cr_elements/cr_checkbox/cr_checkbox.js';
-import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {SettingsBooleanControlMixin} from './settings_boolean_control_mixin.js';
@@ -76,10 +75,6 @@
   private hasSubLabel_(subLabel: string, subLabelHtml: string): boolean {
     return !!subLabel || !!subLabelHtml;
   }
-
-  private sanitizeInnerHtml_(rawString: string): TrustedHTML {
-    return sanitizeInnerHtml(rawString);
-  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/settings/ensure_lazy_loaded.ts b/chrome/browser/resources/settings/ensure_lazy_loaded.ts
index a4b3fdc2..b44d2aa6 100644
--- a/chrome/browser/resources/settings/ensure_lazy_loaded.ts
+++ b/chrome/browser/resources/settings/ensure_lazy_loaded.ts
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {getTrustedScriptURL} from 'chrome://resources/js/static_types.js';
-
 let lazyLoadPromise: Promise<void>|null = null;
 
 /** @return Resolves when the lazy load module is imported. */
@@ -11,7 +9,7 @@
   if (lazyLoadPromise === null) {
     const script = document.createElement('script');
     script.type = 'module';
-    script.src = getTrustedScriptURL`./lazy_load.js`;
+    script.src = './lazy_load.js';
     document.body.appendChild(script);
 
     lazyLoadPromise =
diff --git a/chrome/browser/resources/settings/people_page/signout_dialog.ts b/chrome/browser/resources/settings/people_page/signout_dialog.ts
index 7bc56c17..cee7ad1 100644
--- a/chrome/browser/resources/settings/people_page/signout_dialog.ts
+++ b/chrome/browser/resources/settings/people_page/signout_dialog.ts
@@ -18,7 +18,6 @@
 
 import {CrDialogElement} from '//resources/cr_elements/cr_dialog/cr_dialog.js';
 import {WebUiListenerMixin} from '//resources/cr_elements/web_ui_listener_mixin.js';
-import {sanitizeInnerHtml} from '//resources/js/parse_html_subset.js';
 import {microTask, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {loadTimeData} from '../i18n_setup.js';
@@ -127,20 +126,19 @@
   }
 
   // <if expr="not chromeos_ash">
-  private getDisconnectExplanationHtml_(domain: string): TrustedHTML {
+  private getDisconnectExplanationHtml_(domain: string): string {
     if (domain) {
-      return sanitizeInnerHtml(loadTimeData.getStringF(
-          'syncDisconnectManagedProfileExplanation', `<span>${domain}</span>`));
+      return loadTimeData.getStringF(
+          'syncDisconnectManagedProfileExplanation',
+          '<span id="managed-by-domain-name">' + domain + '</span>');
     }
-    return sanitizeInnerHtml(
-        loadTimeData.getString('syncDisconnectExplanation'));
+    return loadTimeData.getString('syncDisconnectExplanation');
   }
   // </if>
 
   // <if expr="chromeos_ash">
-  private getDisconnectExplanationHtml_(_domain: string): TrustedHTML {
-    return sanitizeInnerHtml(
-        loadTimeData.getString('syncDisconnectExplanation'));
+  private getDisconnectExplanationHtml_(_domain: string): string {
+    return loadTimeData.getString('syncDisconnectExplanation');
   }
   // </if>
 
diff --git a/chrome/browser/resources/settings/people_page/sync_page.ts b/chrome/browser/resources/settings/people_page/sync_page.ts
index 39b10aa..4e6a8aa 100644
--- a/chrome/browser/resources/settings/people_page/sync_page.ts
+++ b/chrome/browser/resources/settings/people_page/sync_page.ts
@@ -236,7 +236,7 @@
   // </if>
 
   private enterPassphraseLabel_: TrustedHTML;
-  private existingPassphraseLabel_: TrustedHTML;
+  private existingPassphraseLabel_: string;
 
   private browserProxy_: SyncBrowserProxy = SyncBrowserProxyImpl.getInstance();
   private collapsibleSectionsInitialized_: boolean;
@@ -566,18 +566,18 @@
     });
   }
 
-  private computeExistingPassphraseLabel_(): TrustedHTML {
+  private computeExistingPassphraseLabel_(): string {
     if (!this.syncPrefs || !this.syncPrefs.encryptAllData) {
-      return window.trustedTypes!.emptyHTML;
+      return '';
     }
 
     if (!this.syncPrefs.explicitPassphraseTime) {
-      return this.i18nAdvanced('existingPassphraseLabel');
+      return this.i18n('existingPassphraseLabel');
     }
 
-    return this.i18nAdvanced('existingPassphraseLabelWithDate', {
-      substitutions: [this.syncPrefs.explicitPassphraseTime],
-    });
+    return this.i18n(
+        'existingPassphraseLabelWithDate',
+        this.syncPrefs.explicitPassphraseTime);
   }
 
   /**
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.html b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.html
index 099fd43..ce0fbea 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.html
+++ b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.html
@@ -25,7 +25,7 @@
 <div id="descriptionItemWrapper">
   <iron-icon icon="[[icon]]" aria-hidden="true"></iron-icon>
   <div class="secondary">
-    <div inner-h-t-m-l="[[sanitizeInnerHtml_(labelHtml)]]"></div>
+    <div inner-h-t-m-l="[[labelHtml]]"></div>
     [[label]]
   </div>
 </div>
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.ts b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.ts
index d61b535..c4153bb 100644
--- a/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.ts
+++ b/chrome/browser/resources/settings/privacy_page/privacy_guide/privacy_guide_description_item.ts
@@ -11,7 +11,6 @@
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import '../../settings_shared.css.js';
 
-import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {getTemplate} from './privacy_guide_description_item.html.js';
@@ -43,10 +42,6 @@
       },
     };
   }
-
-  private sanitizeInnerHtml_(rawString: string): TrustedHTML {
-    return sanitizeInnerHtml(rawString);
-  }
 }
 
 customElements.define(
diff --git a/chrome/browser/resources/settings/privacy_page/secure_dns.ts b/chrome/browser/resources/settings/privacy_page/secure_dns.ts
index 4b3de5aa..e6c5dab5 100644
--- a/chrome/browser/resources/settings/privacy_page/secure_dns.ts
+++ b/chrome/browser/resources/settings/privacy_page/secure_dns.ts
@@ -23,9 +23,8 @@
 import './secure_dns_input.js';
 
 import {CrRadioGroupElement} from 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.js';
-import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js';
 import {assertNotReached} from 'chrome://resources/js/assert_ts.js';
-import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
+import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {SettingsToggleButtonElement} from '../controls/settings_toggle_button.js';
@@ -140,7 +139,7 @@
   private secureDnsRadio_: SecureDnsMode;
   private resolverOptions_: ResolverOption[];
   private lastResolverOption_: string;
-  private privacyPolicyString_: TrustedHTML;
+  private privacyPolicyString_: string;
   private secureDnsInputValue_: string;
   private browserProxy_: PrivacyPageBrowserProxy =
       PrivacyPageBrowserProxyImpl.getInstance();
@@ -394,9 +393,9 @@
       return;
     }
 
-    this.privacyPolicyString_ = sanitizeInnerHtml(loadTimeData.substituteString(
+    this.privacyPolicyString_ = loadTimeData.substituteString(
         loadTimeData.getString('secureDnsSecureDropdownModePrivacyPolicy'),
-        resolver.policy));
+        resolver.policy);
   }
 
   /**
diff --git a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
index 703e648e..fdc696d 100644
--- a/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
+++ b/chrome/browser/resources/settings/reset_page/reset_profile_dialog.html
@@ -14,8 +14,8 @@
         [[getPageTitle_(isTriggered_, triggeredResetToolName_)]]
       </div>
       <div id="dialog-body" slot="body">
-        <span inner-h-t-m-l="[[getExplanationText_(
-              isTriggered_, triggeredResetToolName_)]]">
+        <span inner-h-t-m-l="
+          [[getExplanationText_(isTriggered_, triggeredResetToolName_)]]">
         </span>
         <span>
           <a href="$i18nRaw{resetPageLearnMoreUrl}" target="_blank">
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_child.html b/chrome/browser/resources/settings/safety_check_page/safety_check_child.html
index 3b40ac8..dd01a48 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_child.html
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_child.html
@@ -43,9 +43,8 @@
     aria-label="[[getStatusIconAriaLabel_(iconStatus)]]">
 </iron-icon>
 <div class="flex cr-padded-text">
-  <div id="label" inner-h-t-m-l="[[sanitizeInnerHtml_(label)]]"></div>
-  <div id="subLabel" class="secondary" no-search
-      inner-h-t-m-l="[[sanitizeInnerHtml_(subLabel)]]">
+  <div id="label" inner-h-t-m-l="[[label]]"></div>
+  <div id="subLabel" class="secondary" no-search inner-h-t-m-l="[[subLabel]]">
   </div>
 </div>
 <template is="dom-if" if="[[showButton_(buttonLabel)]]" restamp>
diff --git a/chrome/browser/resources/settings/safety_check_page/safety_check_child.ts b/chrome/browser/resources/settings/safety_check_page/safety_check_child.ts
index ab2fe857..670529570 100644
--- a/chrome/browser/resources/settings/safety_check_page/safety_check_child.ts
+++ b/chrome/browser/resources/settings/safety_check_page/safety_check_child.ts
@@ -16,9 +16,8 @@
 import 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js';
 import '../settings_shared.css.js';
 
-import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
 import {assertNotReached} from 'chrome://resources/js/assert_ts.js';
-import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
+import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {getTemplate} from './safety_check_child.html.js';
@@ -198,10 +197,6 @@
     // For cr-actionable-row-style.
     this.toggleAttribute('effectively-disabled_', !this.rowClickable);
   }
-
-  private sanitizeInnerHtml_(rawString: string): TrustedHTML {
-    return sanitizeInnerHtml(rawString);
-  }
 }
 
 declare global {
diff --git a/chrome/browser/resources/settings/settings.ts b/chrome/browser/resources/settings/settings.ts
index db35018..acd9c8e 100644
--- a/chrome/browser/resources/settings/settings.ts
+++ b/chrome/browser/resources/settings/settings.ts
@@ -14,7 +14,6 @@
 export {CrToolbarElement} from 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar.js';
 export {CrToolbarSearchFieldElement} from 'chrome://resources/cr_elements/cr_toolbar/cr_toolbar_search_field.js';
 export {PluralStringProxyImpl as SettingsPluralStringProxyImpl} from 'chrome://resources/js/plural_string_proxy.js';
-export {getTrustedHTML} from 'chrome://resources/js/static_types.js';
 export {SettingsAboutPageElement} from './about_page/about_page.js';
 export {AboutPageBrowserProxy, AboutPageBrowserProxyImpl, UpdateStatus} from './about_page/about_page_browser_proxy.js';
 // <if expr="_google_chrome and is_macosx">
diff --git a/chrome/browser/resources/settings/site_settings/site_details_permission.ts b/chrome/browser/resources/settings/site_settings/site_details_permission.ts
index a77ae8a..8f57381a 100644
--- a/chrome/browser/resources/settings/site_settings/site_details_permission.ts
+++ b/chrome/browser/resources/settings/site_settings/site_details_permission.ts
@@ -13,10 +13,9 @@
 import '../settings_vars.css.js';
 import '../i18n_setup.js';
 
+import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
 import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js';
 import {WebUiListenerMixin} from 'chrome://resources/cr_elements/web_ui_listener_mixin.js';
-import {assert, assertNotReached} from 'chrome://resources/js/assert_ts.js';
-import {sanitizeInnerHtml} from 'chrome://resources/js/parse_html_subset.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {ContentSetting, ContentSettingsTypes, SiteSettingSource} from './constants.js';
@@ -233,7 +232,7 @@
       setting: ContentSetting): boolean {
     // This method assumes that an empty string will be returned for categories
     // that have no permission info string.
-    return String(this.permissionInfoString_(
+    return this.permissionInfoString_(
                source, category, setting,
                // Set all permission info string arguments as null. This is OK
                // because there is no need to know what the information string
@@ -242,7 +241,7 @@
                // <if expr="is_win and _google_chrome">
                null,
                // </if>
-               null, null, null, null, null, null)) !== '';
+               null, null, null, null, null, null) !== '';
   }
 
   /**
@@ -344,16 +343,16 @@
    * @param setting The permission setting.
    * @param  allowlistString The string to show if the permission is
    *     allowlisted.
-   * @param adsBlocklistString The string to show if the site is
-   *     blocklisted for showing bad ads.
+   * @param adsBlacklistString The string to show if the site is
+   *     blacklisted for showing bad ads.
    * @param adsBlockString The string to show if ads are blocked, but
-   *     the site is not blocklisted.
+   *     the site is not blacklisted.
    * @return The permission information string to display in the HTML.
    */
   private permissionInfoString_(
       source: SiteSettingSource, category: ContentSettingsTypes,
       setting: ContentSetting, allowlistString: string|null,
-      adsBlocklistString: string|null, adsBlockString: string|null,
+      adsBlacklistString: string|null, adsBlockString: string|null,
       embargoString: string|null, insecureOriginString: string|null,
       killSwitchString: string|null,
       // <if expr="is_win and _google_chrome">
@@ -362,10 +361,10 @@
       extensionAllowString: string|null, extensionBlockString: string|null,
       extensionAskString: string|null, policyAllowString: string|null,
       policyBlockString: string|null,
-      policyAskString: string|null): (TrustedHTML|null) {
+      policyAskString: string|null): (string|null) {
     if (source === undefined || category === undefined ||
         setting === undefined) {
-      return window.trustedTypes!.emptyHTML;
+      return null;
     }
 
     const extensionStrings: {[key: string]: string|null} = {};
@@ -378,50 +377,46 @@
     policyStrings[ContentSetting.BLOCK] = policyBlockString;
     policyStrings[ContentSetting.ASK] = policyAskString;
 
-    function htmlOrNull(str: string|null): TrustedHTML|null {
-      return str === null ? null : sanitizeInnerHtml(str);
-    }
-
     if (source === SiteSettingSource.ALLOWLIST) {
-      return htmlOrNull(allowlistString);
+      return allowlistString;
     } else if (source === SiteSettingSource.ADS_FILTER_BLACKLIST) {
       assert(
           ContentSettingsTypes.ADS === category,
-          'The ads filter blocklist only applies to Ads.');
-      return htmlOrNull(adsBlocklistString);
+          'The ads filter blacklist only applies to Ads.');
+      return adsBlacklistString;
     } else if (
         category === ContentSettingsTypes.ADS &&
         setting === ContentSetting.BLOCK) {
-      return htmlOrNull(adsBlockString);
+      return adsBlockString;
     } else if (source === SiteSettingSource.EMBARGO) {
       assert(
           ContentSetting.BLOCK === setting,
           'Embargo is only used to block permissions.');
-      return htmlOrNull(embargoString);
+      return embargoString;
     } else if (source === SiteSettingSource.EXTENSION) {
-      return htmlOrNull(extensionStrings[setting]);
+      return extensionStrings[setting];
     } else if (source === SiteSettingSource.INSECURE_ORIGIN) {
       assert(
           ContentSetting.BLOCK === setting,
           'Permissions can only be blocked due to insecure origins.');
-      return htmlOrNull(insecureOriginString);
+      return insecureOriginString;
     } else if (source === SiteSettingSource.KILL_SWITCH) {
       assert(
           ContentSetting.BLOCK === setting,
           'The permissions kill switch can only be used to block permissions.');
-      return htmlOrNull(killSwitchString);
+      return killSwitchString;
     } else if (source === SiteSettingSource.POLICY) {
-      return htmlOrNull(policyStrings[setting]);
+      return policyStrings[setting];
       // <if expr="is_win and _google_chrome">
     } else if (
         category === ContentSettingsTypes.PROTECTED_CONTENT &&
         setting === ContentSetting.ALLOW) {
-      return htmlOrNull(protectedContentIdentifierAllowedString);
+      return protectedContentIdentifierAllowedString;
       // </if>
     } else if (
         source === SiteSettingSource.DEFAULT ||
         source === SiteSettingSource.PREFERENCE) {
-      return window.trustedTypes!.emptyHTML;
+      return '';
     }
     assertNotReached(`No string for ${category} setting source '${source}'`);
   }
diff --git a/chrome/browser/resources/side_panel/customize_chrome/shortcuts.html b/chrome/browser/resources/side_panel/customize_chrome/shortcuts.html
index e467df5..f787da6e 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/shortcuts.html
+++ b/chrome/browser/resources/side_panel/customize_chrome/shortcuts.html
@@ -1 +1,49 @@
-<p>Customize Shortcuts Page</p>
+<style>
+  #shortcutsTitle {
+    font-weight: 500;
+    margin-bottom: 34px;
+    margin-inline-start: 16px;
+  }
+
+  #showToggleContainer {
+    align-items: center;
+    display: flex;
+    margin-bottom: 16px;
+    margin-inline-start: 16px;
+  }
+
+  #options {
+    align-items: center;
+    display: flex;
+    margin-bottom: 24px;
+    margin-inline-start: 40px;
+  }
+</style>
+<div id="shortcutsTitle">$i18n{shortcutsMenuItem}</div>
+<div id="showToggleContainer">
+  <div id="showToggleTitle">$i18n{showToggleTitle}</div>
+  <cr-toggle id="showToggle" title="$i18n{showToggleTitle}"
+      checked="[[show_]]" on-change="onShowChange_"></cr-toggle>
+</div>
+<div id="options">
+  <cr-radio-group id="shortcutsRadioSelection" disabled="[[!show_]]"
+      selected="[[shortcutsRadioSelection_(customLinksEnabled_)]]"
+      on-selected-changed="onShortcutsRadioSelectionChanged_">
+    <cr-radio-button id="customLinksButton" name="customLinksOption">
+      <div id="customLinksTitleContainer">
+      <div id="customLinksTitle">$i18n{myShortcuts}</div>
+      <div id="customLinksDescription">
+        $i18n{shortcutsCurated}
+      </div>
+    </div>
+    </cr-radio-button>
+    <cr-radio-button id="mostVisitedButton" name="mostVisitedOption">
+      <div id="mostVisitedTitleContainer">
+        <div id="mostVisitedTitle">$i18n{mostVisited}</div>
+        <div id="mostVisitedDescription">
+          $i18n{shortcutsSuggested}
+        </div>
+      </div>
+    </cr-radio-button>
+  </cr-radio-group>
+</div>
diff --git a/chrome/browser/resources/side_panel/customize_chrome/shortcuts.ts b/chrome/browser/resources/side_panel/customize_chrome/shortcuts.ts
index 55edb1f..5cce2719 100644
--- a/chrome/browser/resources/side_panel/customize_chrome/shortcuts.ts
+++ b/chrome/browser/resources/side_panel/customize_chrome/shortcuts.ts
@@ -2,12 +2,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+import 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js';
+import 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.js';
+import 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.js';
+
+import {CrRadioButtonElement} from 'chrome://resources/cr_elements/cr_radio_button/cr_radio_button.js';
+import {CrRadioGroupElement} from 'chrome://resources/cr_elements/cr_radio_group/cr_radio_group.js';
+import {CrToggleElement} from 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js';
 import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
 
 import {CustomizeChromePageHandlerInterface} from './customize_chrome.mojom-webui.js';
 import {CustomizeChromeApiProxy} from './customize_chrome_api_proxy.js';
 import {getTemplate} from './shortcuts.html.js';
 
+export interface ShortcutsElement {
+  $: {
+    showToggle: CrToggleElement,
+    shortcutsRadioSelection: CrRadioGroupElement,
+    customLinksButton: CrRadioButtonElement,
+    mostVisitedButton: CrRadioButtonElement,
+  };
+}
 
 export interface ShortcutsElement {}
 
@@ -23,26 +38,24 @@
   static get properties() {
     return {
       customLinksEnabled_: Boolean,
-      shortcutsVisible_: Boolean,
+      show_: Boolean,
     };
   }
 
   private customLinksEnabled_: boolean;
-  private shortcutsVisible_: boolean;
+  private show_: boolean;
   private pageHandler_: CustomizeChromePageHandlerInterface;
 
-  override ready() {
-    super.ready();
-  }
-
   constructor() {
     super();
     const {handler} = CustomizeChromeApiProxy.getInstance();
     this.pageHandler_ = handler;
+    // TODO(crbug.com/1384278) Auto update most visited settings if they change
+    // while the side panel is open.
     this.pageHandler_.getMostVisitedSettings().then(
         ({customLinksEnabled, shortcutsVisible}) => {
           this.customLinksEnabled_ = customLinksEnabled;
-          this.shortcutsVisible_ = shortcutsVisible;
+          this.show_ = shortcutsVisible;
         });
   }
 
@@ -50,10 +63,23 @@
     super.connectedCallback();
   }
 
-  apply() {
+  private setMostVisitedSettings_() {
     this.pageHandler_.setMostVisitedSettings(
-        this.customLinksEnabled_,
-        /* shortcutsVisible= */ this.shortcutsVisible_);
+        this.customLinksEnabled_, /* shortcutsVisible= */ this.show_);
+  }
+
+  private onShortcutsRadioSelectionChanged_(e: CustomEvent<{value: string}>) {
+    this.customLinksEnabled_ = e.detail.value === 'customLinksOption';
+    this.setMostVisitedSettings_();
+  }
+
+  private shortcutsRadioSelection_(): string {
+    return this.customLinksEnabled_ ? 'customLinksOption' : 'mostVisitedOption';
+  }
+
+  private onShowChange_(e: CustomEvent<boolean>) {
+    this.show_ = e.detail;
+    this.setMostVisitedSettings_();
   }
 }
 
diff --git a/chrome/browser/search/background/ntp_custom_background_service.h b/chrome/browser/search/background/ntp_custom_background_service.h
index bab3c45c..f75a87f 100644
--- a/chrome/browser/search/background/ntp_custom_background_service.h
+++ b/chrome/browser/search/background/ntp_custom_background_service.h
@@ -118,10 +118,10 @@
                                                       const GURL& fetch_url);
 
   const raw_ptr<Profile> profile_;
-  raw_ptr<PrefService> pref_service_;
-  raw_ptr<ThemeService> theme_service_;
+  raw_ptr<PrefService, DanglingUntriaged> pref_service_;
+  raw_ptr<ThemeService, DanglingUntriaged> theme_service_;
   PrefChangeRegistrar pref_change_registrar_;
-  raw_ptr<NtpBackgroundService> background_service_;
+  raw_ptr<NtpBackgroundService, DanglingUntriaged> background_service_;
   base::ScopedObservation<NtpBackgroundService, NtpBackgroundServiceObserver>
       background_service_observation_{this};
   raw_ptr<base::Clock> clock_;
diff --git a/chrome/browser/sessions/session_restore.cc b/chrome/browser/sessions/session_restore.cc
index 30ca0a3..073afa14 100644
--- a/chrome/browser/sessions/session_restore.cc
+++ b/chrome/browser/sessions/session_restore.cc
@@ -1015,7 +1015,7 @@
   raw_ptr<Profile> profile_;
 
   // The first browser to restore to, may be null.
-  raw_ptr<Browser> browser_;
+  raw_ptr<Browser, DanglingUntriaged> browser_;
 
   // Whether or not restore is synchronous.
   const bool synchronous_;
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc
index 3cfd684..67f0f99 100644
--- a/chrome/browser/ssl/ssl_browsertest.cc
+++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -3620,10 +3620,8 @@
 // This test checks the behavior of mixed content blocking for the requests
 // from a dedicated worker by changing the settings in WebPreferences
 // with allow_running_insecure_content = false.
-// Disabled due to being flaky. crbug.com/1116670
-IN_PROC_BROWSER_TEST_P(
-    SSLUIWorkerFetchTest,
-    DISABLED_MixedContentSettings_DisallowRunningInsecureContent) {
+IN_PROC_BROWSER_TEST_P(SSLUIWorkerFetchTest,
+                       MixedContentSettings_DisallowRunningInsecureContent) {
   ChromeContentBrowserClientForMixedContentTest browser_client;
   content::ScopedContentBrowserClientSetting setting(&browser_client);
 
diff --git a/chrome/browser/task_manager/providers/web_contents/back_forward_cache_task.h b/chrome/browser/task_manager/providers/web_contents/back_forward_cache_task.h
index 3bd4643..c0dac72 100644
--- a/chrome/browser/task_manager/providers/web_contents/back_forward_cache_task.h
+++ b/chrome/browser/task_manager/providers/web_contents/back_forward_cache_task.h
@@ -43,9 +43,9 @@
   // is created per site. Therefore a 1:1 mapping of main frame task to subframe
   // task is not guaranteed.
   // For cached main frame tasks |parent_task_| is nullptr.
-  raw_ptr<RendererTask> parent_task_;
+  raw_ptr<RendererTask, DanglingUntriaged> parent_task_;
   // The provider has the same lifespan as the task manager.
-  const raw_ptr<WebContentsTaskProvider> task_provider_;
+  const raw_ptr<WebContentsTaskProvider, DanglingUntriaged> task_provider_;
 };
 
 }  // namespace task_manager
diff --git a/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc b/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc
index 3a5fa82e..f5cba88a 100644
--- a/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc
+++ b/chrome/browser/task_manager/providers/web_contents/web_contents_task_provider.cc
@@ -365,8 +365,7 @@
   }
 
   bool site_instance_exists = site_instance_infos_.count(site_instance) != 0;
-  auto* primary_main_rfh = web_contents()->GetPrimaryMainFrame();
-  bool is_primary_main_frame = (render_frame_host == primary_main_rfh);
+  bool is_primary_main_frame = render_frame_host->IsInPrimaryMainFrame();
   bool site_instance_is_main =
       (site_instance == primary_main_frame_site_instance_);
 
@@ -377,7 +376,8 @@
   // represented by a SubframeTask.
   if (!site_instance_exists ||
       (is_primary_main_frame && !site_instance_is_main)) {
-    auto* primary_main_frame_task = GetTaskForFrame(primary_main_rfh);
+    auto* primary_main_frame_task =
+        GetTaskForFrame(web_contents()->GetPrimaryMainFrame());
     if (rfh_state == RenderFrameHost::LifecycleState::kInBackForwardCache) {
       // Use RFH::GetMainFrame instead web_contents()->GetPrimaryMainFrame()
       // because the BFCached frames are not the currently active main frame.
diff --git a/chrome/browser/ui/android/autofill/save_update_address_profile_flow_manager.cc b/chrome/browser/ui/android/autofill/save_update_address_profile_flow_manager.cc
index b921a9d..58550d9 100644
--- a/chrome/browser/ui/android/autofill/save_update_address_profile_flow_manager.cc
+++ b/chrome/browser/ui/android/autofill/save_update_address_profile_flow_manager.cc
@@ -25,8 +25,6 @@
     AutofillClient::AddressProfileSavePromptCallback callback) {
   DCHECK(web_contents);
   DCHECK(callback);
-  DCHECK(base::FeatureList::IsEnabled(
-      autofill::features::kAutofillAddressProfileSavePrompt));
 
   // If the message or prompt is already shown, suppress the incoming offer.
   if (save_update_address_profile_message_controller_.IsMessageDisplayed() ||
diff --git a/chrome/browser/ui/android/autofill/save_update_address_profile_flow_manager_browsertest.cc b/chrome/browser/ui/android/autofill/save_update_address_profile_flow_manager_browsertest.cc
index 544b552..3060a17 100644
--- a/chrome/browser/ui/android/autofill/save_update_address_profile_flow_manager_browsertest.cc
+++ b/chrome/browser/ui/android/autofill/save_update_address_profile_flow_manager_browsertest.cc
@@ -23,8 +23,6 @@
   ~SaveUpdateAddressProfileFlowManagerBrowserTest() override = default;
 
   void SetUp() override {
-    feature_list_.InitAndEnableFeature(
-        features::kAutofillAddressProfileSavePrompt);
     AndroidBrowserTest::SetUp();
     profile_ = test::GetFullProfile();
     original_profile_ = test::GetFullProfile2();
@@ -55,7 +53,6 @@
   AutofillProfile profile_;
   AutofillProfile original_profile_;
   std::unique_ptr<SaveUpdateAddressProfileFlowManager> flow_manager_;
-  base::test::ScopedFeatureList feature_list_;
 };
 
 IN_PROC_BROWSER_TEST_F(SaveUpdateAddressProfileFlowManagerBrowserTest,
diff --git a/chrome/browser/ui/autofill/edit_address_profile_dialog_controller_impl.cc b/chrome/browser/ui/autofill/edit_address_profile_dialog_controller_impl.cc
index 3fb8fc5c..d33e4e2 100644
--- a/chrome/browser/ui/autofill/edit_address_profile_dialog_controller_impl.cc
+++ b/chrome/browser/ui/autofill/edit_address_profile_dialog_controller_impl.cc
@@ -22,10 +22,7 @@
     content::WebContents* web_contents)
     : content::WebContentsObserver(web_contents),
       content::WebContentsUserData<EditAddressProfileDialogControllerImpl>(
-          *web_contents) {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kAutofillAddressProfileSavePrompt));
-}
+          *web_contents) {}
 
 EditAddressProfileDialogControllerImpl::
     ~EditAddressProfileDialogControllerImpl() {
diff --git a/chrome/browser/ui/autofill/edit_address_profile_dialog_controller_impl_browsertest.cc b/chrome/browser/ui/autofill/edit_address_profile_dialog_controller_impl_browsertest.cc
index 87240a45..5cbf6e0 100644
--- a/chrome/browser/ui/autofill/edit_address_profile_dialog_controller_impl_browsertest.cc
+++ b/chrome/browser/ui/autofill/edit_address_profile_dialog_controller_impl_browsertest.cc
@@ -17,10 +17,7 @@
 
 class EditAddressProfileDialogControllerImplTest : public DialogBrowserTest {
  public:
-  EditAddressProfileDialogControllerImplTest() {
-    feature_list_.InitAndEnableFeature(
-        features::kAutofillAddressProfileSavePrompt);
-  }
+  EditAddressProfileDialogControllerImplTest() = default;
 
   // DialogBrowserTest:
   void ShowUi(const std::string& name) override {
@@ -35,9 +32,6 @@
         test::GetFullProfile(), /*original_profile=*/nullptr,
         /*address_profile_save_prompt_callback=*/base::DoNothing());
   }
-
- private:
-  base::test::ScopedFeatureList feature_list_;
 };
 
 IN_PROC_BROWSER_TEST_F(EditAddressProfileDialogControllerImplTest,
diff --git a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl.cc b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl.cc
index 9de8ece..1df8e05 100644
--- a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl.cc
+++ b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl.cc
@@ -22,10 +22,7 @@
         content::WebContents* web_contents)
     : AutofillBubbleControllerBase(web_contents),
       content::WebContentsUserData<
-          SaveUpdateAddressProfileBubbleControllerImpl>(*web_contents) {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kAutofillAddressProfileSavePrompt));
-}
+          SaveUpdateAddressProfileBubbleControllerImpl>(*web_contents) {}
 
 SaveUpdateAddressProfileBubbleControllerImpl::
     ~SaveUpdateAddressProfileBubbleControllerImpl() {
diff --git a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_browsertest.cc b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_browsertest.cc
index c021411..5fc19692 100644
--- a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_browsertest.cc
+++ b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_browsertest.cc
@@ -20,10 +20,7 @@
 class SaveUpdateAddressProfileBubbleControllerImplTest
     : public DialogBrowserTest {
  public:
-  SaveUpdateAddressProfileBubbleControllerImplTest() {
-    feature_list_.InitAndEnableFeature(
-        features::kAutofillAddressProfileSavePrompt);
-  }
+  SaveUpdateAddressProfileBubbleControllerImplTest() = default;
 
   void SetUpCommandLine(base::CommandLine* command_line) override {
     DialogBrowserTest::SetUpCommandLine(command_line);
@@ -53,7 +50,6 @@
  private:
   raw_ptr<SaveUpdateAddressProfileBubbleControllerImpl, DanglingUntriaged>
       controller_ = nullptr;
-  base::test::ScopedFeatureList feature_list_;
 };
 
 IN_PROC_BROWSER_TEST_F(SaveUpdateAddressProfileBubbleControllerImplTest,
diff --git a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_unittest.cc
index cfab3278..52ef39f 100644
--- a/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_unittest.cc
+++ b/chrome/browser/ui/autofill/save_update_address_profile_bubble_controller_impl_unittest.cc
@@ -21,10 +21,6 @@
  public:
   SaveUpdateAddressProfileBubbleControllerImplTest() = default;
   void SetUp() override {
-    base::test::ScopedFeatureList feature_list;
-    feature_list.InitAndEnableFeature(
-        features::kAutofillAddressProfileSavePrompt);
-
     BrowserWithTestWindowTest::SetUp();
     AddTab(browser(), GURL("about:blank"));
     content::WebContents* web_contents =
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 273dea90..f424612 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -1492,9 +1492,8 @@
       IDC_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY, main_not_fullscreen);
 
 #if BUILDFLAG(ENABLE_SCREEN_AI_SERVICE)
-  command_updater_.UpdateCommandEnabled(
-      IDC_RUN_SCREEN_AI_VISUAL_ANNOTATIONS,
-      features::IsScreenAIVisualAnnotationsEnabled());
+  command_updater_.UpdateCommandEnabled(IDC_RUN_SCREEN_AI_VISUAL_ANNOTATIONS,
+                                        features::IsLayoutExtractionEnabled());
 #endif
 
   // Show various bits of UI
diff --git a/chrome/browser/ui/cocoa/history_menu_cocoa_controller.h b/chrome/browser/ui/cocoa/history_menu_cocoa_controller.h
index 72f796b..c6deb20 100644
--- a/chrome/browser/ui/cocoa/history_menu_cocoa_controller.h
+++ b/chrome/browser/ui/cocoa/history_menu_cocoa_controller.h
@@ -15,7 +15,7 @@
 // creation and maintenance of the menu happens in the Bridge.
 @interface HistoryMenuCocoaController : NSObject<NSMenuDelegate> {
  @private
-  raw_ptr<HistoryMenuBridge> _bridge;  // weak; owns us
+  raw_ptr<HistoryMenuBridge, DanglingUntriaged> _bridge;  // weak; owns us
 }
 
 - (instancetype)initWithBridge:(HistoryMenuBridge*)bridge;
diff --git a/chrome/browser/ui/views/apps/native_app_window_frame_view_mac.h b/chrome/browser/ui/views/apps/native_app_window_frame_view_mac.h
index 297d485..9e86be39 100644
--- a/chrome/browser/ui/views/apps/native_app_window_frame_view_mac.h
+++ b/chrome/browser/ui/views/apps/native_app_window_frame_view_mac.h
@@ -33,7 +33,7 @@
  private:
   // Weak. Owned by extensions::AppWindow (which manages our Widget via its
   // WebContents).
-  raw_ptr<extensions::NativeAppWindow> native_app_window_;
+  raw_ptr<extensions::NativeAppWindow, DanglingUntriaged> native_app_window_;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_APPS_NATIVE_APP_WINDOW_FRAME_VIEW_MAC_H_
diff --git a/chrome/browser/ui/views/autofill/edit_address_profile_view.cc b/chrome/browser/ui/views/autofill/edit_address_profile_view.cc
index ec44949..4f8be234 100644
--- a/chrome/browser/ui/views/autofill/edit_address_profile_view.cc
+++ b/chrome/browser/ui/views/autofill/edit_address_profile_view.cc
@@ -19,8 +19,6 @@
     EditAddressProfileDialogController* controller)
     : controller_(controller) {
   DCHECK(controller);
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kAutofillAddressProfileSavePrompt));
 
   SetButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
   SetModalType(ui::MODAL_TYPE_CHILD);
diff --git a/chrome/browser/ui/views/autofill/edit_address_profile_view_unittest.cc b/chrome/browser/ui/views/autofill/edit_address_profile_view_unittest.cc
index 0cd4826..08a4c8d 100644
--- a/chrome/browser/ui/views/autofill/edit_address_profile_view_unittest.cc
+++ b/chrome/browser/ui/views/autofill/edit_address_profile_view_unittest.cc
@@ -49,8 +49,6 @@
   void CreateViewAndShow();
 
   void SetUp() override {
-    feature_list_.InitAndEnableFeature(
-        features::kAutofillAddressProfileSavePrompt);
     ChromeViewsTestBase::SetUp();
 
     address_profile_to_edit_ = test::GetFullProfile();
diff --git a/chrome/browser/ui/views/autofill/save_address_profile_view.cc b/chrome/browser/ui/views/autofill/save_address_profile_view.cc
index 51e3b2a..23037cc 100644
--- a/chrome/browser/ui/views/autofill/save_address_profile_view.cc
+++ b/chrome/browser/ui/views/autofill/save_address_profile_view.cc
@@ -211,8 +211,6 @@
     SaveUpdateAddressProfileBubbleController* controller)
     : LocationBarBubbleDelegateView(anchor_view, web_contents),
       controller_(controller) {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kAutofillAddressProfileSavePrompt));
   // Since this is a save prompt, original profile must not be set. Otherwise,
   // it would have been an update prompt.
   DCHECK(!controller_->GetOriginalProfile());
diff --git a/chrome/browser/ui/views/autofill/save_address_profile_view_unittest.cc b/chrome/browser/ui/views/autofill/save_address_profile_view_unittest.cc
index 3abbc5d5..2d1d384 100644
--- a/chrome/browser/ui/views/autofill/save_address_profile_view_unittest.cc
+++ b/chrome/browser/ui/views/autofill/save_address_profile_view_unittest.cc
@@ -44,8 +44,6 @@
   void CreateViewAndShow();
 
   void SetUp() override {
-    feature_list_.InitAndEnableFeature(
-        features::kAutofillAddressProfileSavePrompt);
     ChromeViewsTestBase::SetUp();
 
     address_profile_to_save_ = test::GetFullProfile();
diff --git a/chrome/browser/ui/views/autofill/update_address_profile_view.cc b/chrome/browser/ui/views/autofill/update_address_profile_view.cc
index c633b31..6a702704 100644
--- a/chrome/browser/ui/views/autofill/update_address_profile_view.cc
+++ b/chrome/browser/ui/views/autofill/update_address_profile_view.cc
@@ -151,8 +151,6 @@
     SaveUpdateAddressProfileBubbleController* controller)
     : LocationBarBubbleDelegateView(anchor_view, web_contents),
       controller_(controller) {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kAutofillAddressProfileSavePrompt));
   // Since this is an update prompt, original profile must be set. Otherwise, it
   // would have been a save prompt.
   DCHECK(controller_->GetOriginalProfile());
diff --git a/chrome/browser/ui/views/autofill/update_address_profile_view_unittest.cc b/chrome/browser/ui/views/autofill/update_address_profile_view_unittest.cc
index 41a1c1e9..467492b6 100644
--- a/chrome/browser/ui/views/autofill/update_address_profile_view_unittest.cc
+++ b/chrome/browser/ui/views/autofill/update_address_profile_view_unittest.cc
@@ -44,8 +44,6 @@
   void CreateViewAndShow();
 
   void SetUp() override {
-    feature_list_.InitAndEnableFeature(
-        features::kAutofillAddressProfileSavePrompt);
     ChromeViewsTestBase::SetUp();
 
     address_profile_to_save_ = test::GetFullProfile();
diff --git a/chrome/browser/ui/views/controls/rich_hover_button.h b/chrome/browser/ui/views/controls/rich_hover_button.h
index 22ba3fbc..57ee643d 100644
--- a/chrome/browser/ui/views/controls/rich_hover_button.h
+++ b/chrome/browser/ui/views/controls/rich_hover_button.h
@@ -67,6 +67,8 @@
 
   void SetSubtitleMultiline(bool is_multiline);
 
+  views::Label* secondary_label() { return secondary_label_; }
+
   const views::StyledLabel* GetTitleViewForTesting() const;
   const views::Label* GetSubTitleViewForTesting() const;
 
diff --git a/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc b/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc
index 23bb4f6..57d522d 100644
--- a/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc
+++ b/chrome/browser/ui/views/extensions/extension_install_dialog_view_supervised_browsertest.cc
@@ -56,8 +56,8 @@
   }
 
  private:
-  raw_ptr<const Extension> extension_;
-  raw_ptr<content::WebContents> web_contents_;
+  raw_ptr<const Extension, DanglingUntriaged> extension_;
+  raw_ptr<content::WebContents, DanglingUntriaged> web_contents_;
   std::unique_ptr<SupervisedUserExtensionsMetricsRecorder>
       supervised_user_extensions_metrics_recorder_;
 };
diff --git a/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.h b/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.h
index 271c6c2..53fa084 100644
--- a/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.h
+++ b/chrome/browser/ui/views/extensions/extensions_toolbar_interactive_uitest.h
@@ -105,7 +105,7 @@
   void WaitForAnimation();
 
  private:
-  raw_ptr<Browser> incognito_browser_ = nullptr;
+  raw_ptr<Browser, DanglingUntriaged> incognito_browser_ = nullptr;
   std::vector<scoped_refptr<const extensions::Extension>> extensions_;
 };
 
diff --git a/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.h b/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.h
index e6f84b1..8489a93 100644
--- a/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.h
+++ b/chrome/browser/ui/views/frame/desktop_browser_frame_lacros.h
@@ -32,7 +32,8 @@
   void TabDraggingKindChanged(TabDragKind tab_drag_kind) override;
 
  private:
-  raw_ptr<BrowserDesktopWindowTreeHostLacros> host_ = nullptr;
+  raw_ptr<BrowserDesktopWindowTreeHostLacros, DanglingUntriaged> host_ =
+      nullptr;
 };
 
 #endif  // CHROME_BROWSER_UI_VIEWS_FRAME_DESKTOP_BROWSER_FRAME_LACROS_H_
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view.cc b/chrome/browser/ui/views/frame/tab_strip_region_view.cc
index a8f7a6c..aabe30a 100644
--- a/chrome/browser/ui/views/frame/tab_strip_region_view.cc
+++ b/chrome/browser/ui/views/frame/tab_strip_region_view.cc
@@ -67,8 +67,10 @@
 
   tab_strip_ = tab_strip.get();
   if (base::FeatureList::IsEnabled(features::kScrollableTabStrip)) {
-    tab_strip_container_ = AddChildView(
-        std::make_unique<TabStripScrollContainer>(std::move(tab_strip)));
+    std::unique_ptr<TabStripScrollContainer> scroll_container =
+        std::make_unique<TabStripScrollContainer>(std::move(tab_strip));
+    tab_strip_scroll_container_ = scroll_container.get();
+    tab_strip_container_ = AddChildView(std::move(scroll_container));
     // Allow the |tab_strip_container_| to grow into the free space available in
     // the TabStripRegionView.
     const views::FlexSpecification tab_strip_container_flex_spec =
@@ -206,7 +208,10 @@
   new_tab_button_->FrameColorsChanged();
   if (tab_search_button_)
     tab_search_button_->FrameColorsChanged();
+
   tab_strip_->FrameColorsChanged();
+  if (tab_strip_scroll_container_)
+    tab_strip_scroll_container_->FrameColorsChanged();
   SchedulePaint();
 }
 
diff --git a/chrome/browser/ui/views/frame/tab_strip_region_view.h b/chrome/browser/ui/views/frame/tab_strip_region_view.h
index c989858..6a17cd4 100644
--- a/chrome/browser/ui/views/frame/tab_strip_region_view.h
+++ b/chrome/browser/ui/views/frame/tab_strip_region_view.h
@@ -19,6 +19,7 @@
 class TabSearchButton;
 class TabStrip;
 class TipMarqueeView;
+class TabStripScrollContainer;
 
 // Container for the tabstrip and the other views sharing space with it -
 // with the exception of the caption buttons.
@@ -75,9 +76,7 @@
   views::View* GetDefaultFocusableChild() override;
 
   views::FlexLayout* layout_manager_for_testing() { return layout_manager_; }
-  raw_ptr<views::View> GetTabStripContainerForTesting() {
-    return raw_ptr<views::View>(tab_strip_container_);
-  }
+  views::View* GetTabStripContainerForTesting() { return tab_strip_container_; }
 
  private:
   // Updates the border padding for |new_tab_button_|.  This should be called
@@ -85,9 +84,11 @@
   void UpdateNewTabButtonBorder();
 
   raw_ptr<views::FlexLayout, DanglingUntriaged> layout_manager_ = nullptr;
-  raw_ptr<views::View, DanglingUntriaged> tab_strip_container_;
-  raw_ptr<views::View, DanglingUntriaged> reserved_grab_handle_space_;
-  raw_ptr<TabStrip, DanglingUntriaged> tab_strip_;
+  raw_ptr<views::View, DanglingUntriaged> tab_strip_container_ = nullptr;
+  raw_ptr<views::View, DanglingUntriaged> reserved_grab_handle_space_ = nullptr;
+  raw_ptr<TabStrip, DanglingUntriaged> tab_strip_ = nullptr;
+  raw_ptr<TabStripScrollContainer, DanglingUntriaged>
+      tab_strip_scroll_container_ = nullptr;
   raw_ptr<NewTabButton, DanglingUntriaged> new_tab_button_ = nullptr;
   raw_ptr<TabSearchButton, DanglingUntriaged> tab_search_button_ = nullptr;
   raw_ptr<TipMarqueeView, DanglingUntriaged> tip_marquee_view_ = nullptr;
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc
index 3a5c12a..9f50be9 100644
--- a/chrome/browser/ui/views/location_bar/location_bar_view.cc
+++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc
@@ -344,12 +344,10 @@
       PageActionIconType::kVirtualCardManualFallback);
   params.types_enabled.push_back(PageActionIconType::kVirtualCardEnroll);
 
-  if (base::FeatureList::IsEnabled(
-          autofill::features::kAutofillAddressProfileSavePrompt)) {
-    // TODO(crbug.com/1167060): Place this in the proper order upon having
-    // final mocks.
-    params.types_enabled.push_back(PageActionIconType::kSaveAutofillAddress);
-  }
+  // TODO(crbug.com/1167060): Place this in the proper order upon having final
+  // mocks.
+  params.types_enabled.push_back(PageActionIconType::kSaveAutofillAddress);
+
   if (browser_) {
     if (sharing_hub::HasPageAction(profile_, is_popup_mode_))
       params.types_enabled.push_back(PageActionIconType::kSharingHub);
diff --git a/chrome/browser/ui/views/page_info/page_info_bubble_view_base.cc b/chrome/browser/ui/views/page_info/page_info_bubble_view_base.cc
index a71302a3..121f428b 100644
--- a/chrome/browser/ui/views/page_info/page_info_bubble_view_base.cc
+++ b/chrome/browser/ui/views/page_info/page_info_bubble_view_base.cc
@@ -67,7 +67,7 @@
 
 void PageInfoBubbleViewBase::RenderFrameDeleted(
     content::RenderFrameHost* render_frame_host) {
-  if (render_frame_host == web_contents()->GetPrimaryMainFrame()) {
+  if (render_frame_host->IsInPrimaryMainFrame()) {
     GetWidget()->Close();
   }
 }
diff --git a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc
index 1e5fd36..6beb8611 100644
--- a/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc
+++ b/chrome/browser/ui/views/page_info/safety_tip_page_info_bubble_view.cc
@@ -189,7 +189,7 @@
 
 void SafetyTipPageInfoBubbleView::RenderFrameDeleted(
     content::RenderFrameHost* render_frame_host) {
-  if (render_frame_host != web_contents()->GetPrimaryMainFrame()) {
+  if (!render_frame_host->IsInPrimaryMainFrame()) {
     return;
   }
 
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
index 1023b38..75519a4 100644
--- a/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_menu_view_browsertest.cc
@@ -390,7 +390,7 @@
 
  private:
   CoreAccountId account_id_;
-  raw_ptr<Profile> profile_ = nullptr;
+  raw_ptr<Profile, DanglingUntriaged> profile_ = nullptr;
 };
 
 #if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -848,7 +848,7 @@
   base::CallbackListSubscription test_signin_client_subscription_;
   base::HistogramTester histogram_tester_;
   std::unique_ptr<SyncServiceImplHarness> sync_harness_;
-  raw_ptr<Profile> profile_ = nullptr;
+  raw_ptr<Profile, DanglingUntriaged> profile_ = nullptr;
 };
 
 #define PROFILE_MENU_CLICK_TEST(actionable_item_list, test_case_name)     \
diff --git a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
index 8a03f49..8ad4a31 100644
--- a/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
+++ b/chrome/browser/ui/views/profiles/profile_picker_view_browsertest.cc
@@ -178,7 +178,7 @@
   }
 
   const size_t total_count_;
-  raw_ptr<Browser> browser_ = nullptr;
+  raw_ptr<Browser, DanglingUntriaged> browser_ = nullptr;
   base::RunLoop run_loop_;
 };
 
diff --git a/chrome/browser/ui/views/tabs/tab_container_impl.h b/chrome/browser/ui/views/tabs/tab_container_impl.h
index ef64edd..a16eaf6 100644
--- a/chrome/browser/ui/views/tabs/tab_container_impl.h
+++ b/chrome/browser/ui/views/tabs/tab_container_impl.h
@@ -342,7 +342,7 @@
   // This view is animated by `bounds_animator_` to guarantee that this
   // container's bounds change smoothly when tabs are animated into or out of
   // this container.
-  const raw_ref<views::View> overall_bounds_view_;
+  const raw_ref<views::View, DanglingUntriaged> overall_bounds_view_;
 
   // Responsible for animating tabs in response to model changes.
   views::BoundsAnimator bounds_animator_;
diff --git a/chrome/browser/ui/views/tabs/tab_strip.h b/chrome/browser/ui/views/tabs/tab_strip.h
index ddfa4da..a257fd42 100644
--- a/chrome/browser/ui/views/tabs/tab_strip.h
+++ b/chrome/browser/ui/views/tabs/tab_strip.h
@@ -93,9 +93,6 @@
   void AddObserver(TabStripObserver* observer);
   void RemoveObserver(TabStripObserver* observer);
 
-  // Called when the colors of the frame change.
-  void FrameColorsChanged();
-
   // Sets |background_offset_| and schedules a paint.
   void SetBackgroundOffset(int background_offset);
 
@@ -317,6 +314,9 @@
   void ShiftGroupRight(const tab_groups::TabGroupId& group) override;
   const Browser* GetBrowser() const override;
 
+  // Update the background colors when frame active state changes.
+  void FrameColorsChanged();
+
   // views::View:
   views::SizeBounds GetAvailableSize(const View* child) const override;
   gfx::Size GetMinimumSize() const override;
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scroll_container.h b/chrome/browser/ui/views/tabs/tab_strip_scroll_container.h
index fd9e0b5..dd90e7d 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_scroll_container.h
+++ b/chrome/browser/ui/views/tabs/tab_strip_scroll_container.h
@@ -46,6 +46,9 @@
     return trailing_scroll_button_;
   }
 
+  // Update the background colors when frame active state changes.
+  void FrameColorsChanged();
+
  private:
   int GetTabStripAvailableWidth() const;
 
@@ -58,8 +61,6 @@
   // Subscription for scrolling of content view
   base::CallbackListSubscription on_contents_scrolled_subscription_;
 
-  void FrameColorsChanged();
-
   // views::View
   void OnThemeChanged() override;
 
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc b/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc
index 535562c1..43ccdc75 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc
+++ b/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.cc
@@ -3,15 +3,29 @@
 // found in the LICENSE file.
 
 #include "chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.h"
+
 #include "cc/paint/paint_shader.h"
 #include "chrome/browser/ui/views/frame/browser_non_client_frame_view.h"
 #include "chrome/browser/ui/views/tabs/tab_strip.h"
 #include "chrome/browser/ui/views/tabs/tab_strip_controller.h"
+#include "chrome/browser/ui/views/tabs/tab_style_views.h"
 #include "third_party/skia/include/core/SkColor.h"
 #include "ui/gfx/canvas.h"
 #include "ui/views/controls/scroll_view.h"
 #include "ui/views/view_utils.h"
 
+namespace {
+
+// Must be kept the same as kTabScrollingButtonPositionVariations values
+enum OverflowFeatureFlag {
+  kNone = 0,
+  kDivider = 1,
+  kFade = 2,
+  kShadow = 3,
+};
+
+}  // anonymous namespace
+
 TabStripScrollingOverflowIndicatorStrategy::
     TabStripScrollingOverflowIndicatorStrategy(views::ScrollView* scroll_view,
                                                TabStrip* tab_strip)
@@ -138,3 +152,50 @@
   left_overflow_indicator()->SetShadowColor(shadow_color);
   right_overflow_indicator()->SetShadowColor(shadow_color);
 }
+
+FadeOverflowIndicatorStrategy::FadeOverflowIndicatorStrategy(
+    views::ScrollView* scroll_view,
+    TabStrip* tab_strip)
+    : GradientOverflowIndicatorStrategy(scroll_view, tab_strip) {}
+
+void FadeOverflowIndicatorStrategy::Init() {
+  scroll_view()->SetDrawOverflowIndicator(true);
+
+  std::unique_ptr<GradientIndicatorView> left_overflow_indicator =
+      std::make_unique<GradientIndicatorView>(
+          views::OverflowIndicatorAlignment::kLeft);
+  left_overflow_indicator_ = left_overflow_indicator.get();
+
+  std::unique_ptr<GradientIndicatorView> right_overflow_indicator =
+      std::make_unique<GradientIndicatorView>(
+          views::OverflowIndicatorAlignment::kRight);
+  right_overflow_indicator_ = right_overflow_indicator.get();
+
+  int min_tab_width = TabStyleViews::GetMinimumInactiveWidth();
+
+  left_overflow_indicator_->SetShadowBlurWidth(std::min(64, min_tab_width * 2));
+  right_overflow_indicator_->SetShadowBlurWidth(
+      std::min(64, min_tab_width * 2));
+
+  scroll_view()->SetCustomOverflowIndicator(
+      views::OverflowIndicatorAlignment::kLeft,
+      std::move(left_overflow_indicator),
+      left_overflow_indicator_->GetTotalWidth(), false);
+
+  scroll_view()->SetCustomOverflowIndicator(
+      views::OverflowIndicatorAlignment::kRight,
+      std::move(right_overflow_indicator),
+      right_overflow_indicator_->GetTotalWidth(), false);
+}
+
+void FadeOverflowIndicatorStrategy::FrameColorsChanged() {
+  SkColor4f frame_color =
+      SkColor4f::FromColor(tab_strip()->controller()->GetFrameColor(
+          BrowserFrameActiveState::kUseCurrent));
+
+  left_overflow_indicator()->SetFrameColor(frame_color);
+  right_overflow_indicator()->SetFrameColor(frame_color);
+
+  left_overflow_indicator()->SetShadowColor(frame_color);
+  right_overflow_indicator()->SetShadowColor(frame_color);
+}
diff --git a/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.h b/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.h
index 27e5b279..44d55f3fd 100644
--- a/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.h
+++ b/chrome/browser/ui/views/tabs/tab_strip_scrolling_overflow_indicator_strategy.h
@@ -5,7 +5,6 @@
 #ifndef CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_SCROLLING_OVERFLOW_INDICATOR_STRATEGY_H_
 #define CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_SCROLLING_OVERFLOW_INDICATOR_STRATEGY_H_
 
-#include "base/callback_list.h"
 #include "base/memory/raw_ptr.h"
 #include "chrome/browser/ui/ui_features.h"
 #include "ui/base/metadata/metadata_header_macros.h"
@@ -50,13 +49,12 @@
 
 class GradientIndicatorView : public views::View {
  public:
-  METADATA_HEADER(GradientIndicatorView);
+  explicit GradientIndicatorView(views::OverflowIndicatorAlignment side);
   GradientIndicatorView(views::OverflowIndicatorAlignment side,
                         int opaque_width,
                         int shadow_opaque_width,
                         int shadow_blur_width);
-
-  explicit GradientIndicatorView(views::OverflowIndicatorAlignment side);
+  METADATA_HEADER(GradientIndicatorView);
 
   // Making this smaller than the margin provided by the leftmost/rightmost
   // tab's tail (TabStyle::kTabOverlap / 2) makes the transition in and out of
@@ -72,10 +70,19 @@
   // views::View overrides:
   void OnPaint(gfx::Canvas* canvas) override;
 
-  // Functions to update the colors for the overflow
+  // Mutators for colors for the overflow.
   void SetShadowColor(SkColor4f new_shadow_color);
   void SetFrameColor(SkColor4f new_frame_color);
 
+  // Mutators for widths for the overflow.
+  void SetOpaqueWidth(int opaque_width) { opaque_width_ = opaque_width; }
+  void SetShadowOpaqueWidth(int shadow_opaque_width) {
+    shadow_opaque_width_ = shadow_opaque_width;
+  }
+  void SetShadowBlurWidth(int shadow_blur_width) {
+    shadow_blur_width_ = shadow_blur_width;
+  }
+
   // Accessor for the full width of the GradientView
   int GetTotalWidth() {
     return opaque_width_ + shadow_opaque_width_ + shadow_blur_width_;
@@ -115,7 +122,7 @@
     return right_overflow_indicator_;
   }
 
- private:
+ protected:
   // The views, owned by |scroll_view_|, that indicate that there are more
   // tabs overflowing to the left or right.
   raw_ptr<GradientIndicatorView> left_overflow_indicator_;
@@ -132,4 +139,14 @@
   void FrameColorsChanged() override;
 };
 
+class FadeOverflowIndicatorStrategy : public GradientOverflowIndicatorStrategy {
+ public:
+  FadeOverflowIndicatorStrategy(views::ScrollView* scroll_view,
+                                TabStrip* tab_strip);
+  ~FadeOverflowIndicatorStrategy() override = default;
+
+  void Init() override;
+  void FrameColorsChanged() override;
+};
+
 #endif  // CHROME_BROWSER_UI_VIEWS_TABS_TAB_STRIP_SCROLLING_OVERFLOW_INDICATOR_STRATEGY_H_
diff --git a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
index f228227..4457be3 100644
--- a/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
+++ b/chrome/browser/ui/web_applications/web_share_target_browsertest.cc
@@ -148,7 +148,7 @@
       override {}
   void CloseBubble(const std::string& window_id) override {}
 
-  raw_ptr<Profile> profile_ = nullptr;
+  raw_ptr<Profile, DanglingUntriaged> profile_ = nullptr;
   web_app::AppId selected_app_id_;
 };
 #endif  // BUILDFLAG(IS_CHROMEOS_LACROS)
diff --git a/chrome/browser/ui/webui/access_code_cast/access_code_cast_dialog.h b/chrome/browser/ui/webui/access_code_cast/access_code_cast_dialog.h
index 569d68d..3b1ef7317 100644
--- a/chrome/browser/ui/webui/access_code_cast/access_code_cast_dialog.h
+++ b/chrome/browser/ui/webui/access_code_cast/access_code_cast_dialog.h
@@ -119,7 +119,7 @@
   // use of the media_route_starter_ pointer after c'tor.
   std::unique_ptr<media_router::MediaRouteStarter> media_route_starter_;
 
-  const raw_ptr<content::WebContents> web_contents_;
+  const raw_ptr<content::WebContents, DanglingUntriaged> web_contents_;
   const raw_ptr<Profile> context_;
   base::Time dialog_creation_timestamp_;
   bool closing_dialog_ = false;
diff --git a/chrome/browser/ui/webui/ash/crostini_installer/crostini_installer_page_handler.cc b/chrome/browser/ui/webui/ash/crostini_installer/crostini_installer_page_handler.cc
index 2b88c63..54ecdf8 100644
--- a/chrome/browser/ui/webui/ash/crostini_installer/crostini_installer_page_handler.cc
+++ b/chrome/browser/ui/webui/ash/crostini_installer/crostini_installer_page_handler.cc
@@ -8,7 +8,6 @@
 #include <utility>
 #include <vector>
 
-#include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/task/task_traits.h"
@@ -74,9 +73,7 @@
 void CrostiniInstallerPageHandler::Install(int64_t disk_size_bytes,
                                            const std::string& username) {
   crostini::CrostiniManager::RestartOptions options{};
-  if (base::FeatureList::IsEnabled(features::kCrostiniDiskResizing)) {
-    options.disk_size_bytes = disk_size_bytes;
-  }
+  options.disk_size_bytes = disk_size_bytes;
   options.container_username = username;
   installer_ui_delegate_->Install(
       std::move(options),
diff --git a/chrome/browser/ui/webui/ash/crostini_installer/crostini_installer_ui.cc b/chrome/browser/ui/webui/ash/crostini_installer/crostini_installer_ui.cc
index efc0810..831a3ca8 100644
--- a/chrome/browser/ui/webui/ash/crostini_installer/crostini_installer_ui.cc
+++ b/chrome/browser/ui/webui/ash/crostini_installer/crostini_installer_ui.cc
@@ -7,7 +7,6 @@
 #include <string>
 #include <utility>
 
-#include "ash/constants/ash_features.h"
 #include "base/bind.h"
 #include "base/callback_helpers.h"
 #include "base/strings/utf_string_conversions.h"
@@ -80,7 +79,6 @@
       {"diskSizeHint", IDS_CROSTINI_INSTALLER_DISK_SIZE_HINT},
       {"insufficientDiskError", IDS_CROSTINI_INSTALLER_INSUFFICIENT_DISK_ERROR},
       {"usernameLabel", IDS_CROSTINI_INSTALLER_USERNAME_LABEL},
-      {"usernameMessage", IDS_CROSTINI_INSTALLER_USERNAME_MESSAGE},
       {"usernameInvalidFirstCharacterError",
        IDS_CROSTINI_INSTALLER_USERNAME_INVALID_FIRST_CHARACTER_ERROR},
       {"usernameInvalidCharactersError",
@@ -140,9 +138,6 @@
   auto* profile = Profile::FromWebUI(web_ui);
   webui::SetJSModuleDefaults(source);
   AddStringResources(source);
-  source->AddBoolean(
-      "diskResizingEnabled",
-      base::FeatureList::IsEnabled(features::kCrostiniDiskResizing));
   source->AddString("defaultContainerUsername",
                     crostini::DefaultContainerUserNameForProfile(profile));
 
diff --git a/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc b/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc
index 90560e4..67fcf064 100644
--- a/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc
+++ b/chrome/browser/ui/webui/invalidations/invalidations_message_handler.cc
@@ -117,7 +117,7 @@
     dict.Set("totalCount", topic_item.second);
     list_of_objects.Append(std::move(dict));
   }
-  FireWebUIListener("update-ids", base::Value(handler_name), list_of_objects);
+  FireWebUIListener("ids-updated", base::Value(handler_name), list_of_objects);
 }
 void InvalidationsMessageHandler::OnDebugMessage(
     const base::Value::Dict& details) {}
diff --git a/chrome/browser/ui/webui/password_manager/password_manager_ui.cc b/chrome/browser/ui/webui/password_manager/password_manager_ui.cc
index 35a63860..9d216d50 100644
--- a/chrome/browser/ui/webui/password_manager/password_manager_ui.cc
+++ b/chrome/browser/ui/webui/password_manager/password_manager_ui.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/url_constants.h"
 #include "chrome/common/webui_url_constants.h"
+#include "chrome/grit/browser_resources.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/grit/password_manager_resources.h"
 #include "chrome/grit/password_manager_resources_map.h"
@@ -20,6 +21,10 @@
 #include "ui/base/resource/resource_bundle.h"
 #include "ui/base/webui/web_ui_util.h"
 
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+#include "chrome/grit/chrome_unscaled_resources.h"
+#endif
+
 namespace {
 
 content::WebUIDataSource* CreatePasswordsUIHTMLSource(Profile* profile) {
@@ -82,6 +87,14 @@
           IDS_PASSWORD_MANAGER_UI_PASSWORDS_DESCRIPTION,
           base::ASCIIToUTF16(chrome::kPasswordManagerLearnMoreURL)));
 
+#if BUILDFLAG(GOOGLE_CHROME_BRANDING)
+  // Overwrite ubranded logo for Chrome-branded builds.
+  // This path is used in the manifest of the PasswordManager web app
+  // (chrome/browser/resources/password_manager/manifest.webmanifest).
+  source->AddResourcePath("images/password_manager_logo.svg",
+                          IDR_CHROME_PASSWORD_MANAGER_LOGO);
+#endif
+
   return source;
 }
 
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
index c33c820..cf3d9b6 100644
--- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
+++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
@@ -81,7 +81,7 @@
                           bool prompt_user);
 
   // The print preview web contents. Protected so unit tests can access it.
-  const raw_ptr<content::WebContents> preview_web_contents_;
+  const raw_ptr<content::WebContents, DanglingUntriaged> preview_web_contents_;
 
   // The underlying dialog object. Protected so unit tests can access it.
   scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
@@ -102,7 +102,7 @@
   // Return save location as the Drive mount or fetch from Download Preferences.
   base::FilePath GetSaveLocation() const;
 
-  const raw_ptr<Profile> profile_;
+  const raw_ptr<Profile, DanglingUntriaged> profile_;
   const raw_ptr<PrintPreviewStickySettings> sticky_settings_;
 
   // Holds the path to the print to pdf request. It is empty if no such request
diff --git a/chrome/browser/ui/webui/settings/ash/crostini_section.cc b/chrome/browser/ui/webui/settings/ash/crostini_section.cc
index d1ec956..6f10f658 100644
--- a/chrome/browser/ui/webui/settings/ash/crostini_section.cc
+++ b/chrome/browser/ui/webui/settings/ash/crostini_section.cc
@@ -216,10 +216,6 @@
   return base::FeatureList::IsEnabled(features::kArcAdbSideloadingFeature);
 }
 
-bool IsDiskResizingAllowed() {
-  return base::FeatureList::IsEnabled(features::kCrostiniDiskResizing);
-}
-
 }  // namespace
 
 CrostiniSection::CrostiniSection(Profile* profile,
@@ -401,17 +397,10 @@
   };
   html_source->AddLocalizedStrings(kLocalizedStrings);
 
-  if (base::FeatureList::IsEnabled(features::kCrostiniBullseyeUpgrade)) {
-    html_source->AddString(
-        "crostiniContainerUpgrade",
-        l10n_util::GetStringUTF16(
-            IDS_SETTINGS_CROSTINI_CONTAINER_UPGRADE_BULLSEYE_MESSAGE));
-  } else {
-    html_source->AddString(
-        "crostiniContainerUpgrade",
-        l10n_util::GetStringUTF16(
-            IDS_SETTINGS_CROSTINI_CONTAINER_UPGRADE_MESSAGE));
-  }
+  html_source->AddString(
+      "crostiniContainerUpgrade",
+      l10n_util::GetStringUTF16(
+          IDS_SETTINGS_CROSTINI_CONTAINER_UPGRADE_BULLSEYE_MESSAGE));
 
   if (auto* pretty_name_value = guest_os::GetContainerPrefValue(
           profile_, crostini::DefaultContainerId(),
@@ -496,7 +485,6 @@
                           IsDeviceManaged() || IsProfileManaged(profile_));
   html_source->AddBoolean("showCrostiniContainerUpgrade",
                           IsContainerUpgradeAllowed());
-  html_source->AddBoolean("showCrostiniDiskResize", IsDiskResizingAllowed());
 }
 
 void CrostiniSection::AddHandlers(content::WebUI* web_ui) {
@@ -666,8 +654,7 @@
   if (IsContainerUpgradeAllowed())
     updater.AddSearchTags(GetCrostiniContainerUpgradeSearchConcepts());
 
-  if (IsDiskResizingAllowed())
-    updater.AddSearchTags(GetCrostiniDiskResizingSearchConcepts());
+  updater.AddSearchTags(GetCrostiniDiskResizingSearchConcepts());
 
   // TODO(crbug:1261319): search concepts for extras containers.
 }
diff --git a/chrome/browser/ui/webui/settings/settings_ui.cc b/chrome/browser/ui/webui/settings/settings_ui.cc
index 9f3ad64..8da25a5 100644
--- a/chrome/browser/ui/webui/settings/settings_ui.cc
+++ b/chrome/browser/ui/webui/settings/settings_ui.cc
@@ -413,7 +413,6 @@
   webui::SetupWebUIDataSource(
       html_source, base::make_span(kSettingsResources, kSettingsResourcesSize),
       IDR_SETTINGS_SETTINGS_HTML);
-  webui::EnableTrustedTypesCSP(html_source);
 
   AddLocalizedStrings(html_source, profile, web_ui->GetWebContents());
 
diff --git a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
index a318f4c..4d39f9e 100644
--- a/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
+++ b/chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_ui.cc
@@ -8,7 +8,6 @@
 #include <utility>
 
 #include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/ui_features.h"
 #include "chrome/browser/ui/webui/side_panel/customize_chrome/customize_chrome_page_handler.h"
 #include "chrome/browser/ui/webui/webui_util.h"
 #include "chrome/common/webui_url_constants.h"
@@ -26,6 +25,14 @@
       chrome::kChromeUICustomizeChromeSidePanelHost);
 
   static constexpr webui::LocalizedString kLocalizedStrings[] = {
+      {"customizeThisPage", IDS_NTP_CUSTOM_BG_CUSTOMIZE_NTP_LABEL},
+      {"mostVisited", IDS_NTP_CUSTOMIZE_MOST_VISITED_LABEL},
+      {"myShortcuts", IDS_NTP_CUSTOMIZE_MY_SHORTCUTS_LABEL},
+      {"shortcutsCurated", IDS_NTP_CUSTOMIZE_MY_SHORTCUTS_DESC},
+      {"shortcutsMenuItem", IDS_NTP_CUSTOMIZE_MENU_SHORTCUTS_LABEL},
+      {"shortcutsOption", IDS_NTP_CUSTOMIZE_MENU_SHORTCUTS_LABEL},
+      {"shortcutsSuggested", IDS_NTP_CUSTOMIZE_MOST_VISITED_DESC},
+      {"showToggleTitle", IDS_NTP_CUSTOMIZE_SHOW_SHORTCUTS_LABEL},
       {"title", IDS_SIDE_PANEL_CUSTOMIZE_CHROME_TITLE},
   };
   source->AddLocalizedStrings(kLocalizedStrings);
diff --git a/chrome/browser/ui/webui/webui_util.cc b/chrome/browser/ui/webui/webui_util.cc
index 0e87f4c..d5196a2 100644
--- a/chrome/browser/ui/webui/webui_util.cc
+++ b/chrome/browser/ui/webui/webui_util.cc
@@ -69,8 +69,7 @@
   source->OverrideContentSecurityPolicy(
       network::mojom::CSPDirectiveName::TrustedTypes,
       "trusted-types parse-html-subset sanitize-inner-html static-types "
-      // Add TrustedTypes policies used during tests.
-      "webui-test-script webui-test-html "
+      "webui-test-script "
       // Add TrustedTypes policies necessary for using Polymer.
       "polymer-html-literal polymer-template-event-attribute-policy;");
 }
diff --git a/chrome/browser/upgrade_detector/get_installed_version_fuchsia.cc b/chrome/browser/upgrade_detector/get_installed_version_fuchsia.cc
index 2fa7f48f..619e463 100644
--- a/chrome/browser/upgrade_detector/get_installed_version_fuchsia.cc
+++ b/chrome/browser/upgrade_detector/get_installed_version_fuchsia.cc
@@ -11,7 +11,7 @@
 #include "components/version_info/version_info.h"
 
 void GetInstalledVersion(InstalledVersionCallback callback) {
-  // TODO(crbug.com/1235293): Check to see if a different version has been
+  // TODO(crbug.com/1318672): Check to see if a different version has been
   // installed on the device and is awaiting a restart. For the time being,
   // unconditionally return the currently-running version.
   NOTIMPLEMENTED_LOG_ONCE();
diff --git a/chrome/browser/upgrade_detector/installed_version_monitor_fuchsia.cc b/chrome/browser/upgrade_detector/installed_version_monitor_fuchsia.cc
index e37263c..657e3a6 100644
--- a/chrome/browser/upgrade_detector/installed_version_monitor_fuchsia.cc
+++ b/chrome/browser/upgrade_detector/installed_version_monitor_fuchsia.cc
@@ -10,7 +10,7 @@
 namespace {
 class FuchsiaInstalledVersionMonitor : public InstalledVersionMonitor {
   void Start(Callback callback) override {
-    // TODO(crbug.com/1235293)
+    // TODO(crbug.com/1318672)
     NOTIMPLEMENTED_LOG_ONCE();
   }
 };
@@ -18,7 +18,7 @@
 
 // static
 std::unique_ptr<InstalledVersionMonitor> InstalledVersionMonitor::Create() {
-  // TODO(crbug.com/1235293)
+  // TODO(crbug.com/1318672)
   NOTIMPLEMENTED_LOG_ONCE();
   return std::make_unique<FuchsiaInstalledVersionMonitor>();
 }
diff --git a/chrome/browser/web_applications/app_service/web_app_publisher_helper.h b/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
index 924f7d8..04f7ca3 100644
--- a/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
+++ b/chrome/browser/web_applications/app_service/web_app_publisher_helper.h
@@ -425,9 +425,9 @@
       bool allowed,
       bool remember_user_choice);
 
-  const raw_ptr<Profile> profile_;
+  const raw_ptr<Profile, DanglingUntriaged> profile_;
 
-  const raw_ptr<WebAppProvider> provider_;
+  const raw_ptr<WebAppProvider, DanglingUntriaged> provider_;
   // nullptr for Lacros Chrome, valid pointer otherwise.
   const raw_ptr<ash::SystemWebAppManager> swa_manager_;
 
@@ -435,7 +435,7 @@
   // are serving from Lacros, and the app type is kWeb for all other cases.
   const apps::AppType app_type_;
 
-  const raw_ptr<Delegate> delegate_;
+  const raw_ptr<Delegate, DanglingUntriaged> delegate_;
 
   base::ScopedObservation<WebAppRegistrar, AppRegistrarObserver>
       registrar_observation_{this};
@@ -461,7 +461,7 @@
 
   apps::AppNotifications app_notifications_;
 
-  raw_ptr<badging::BadgeManager> badge_manager_ = nullptr;
+  raw_ptr<badging::BadgeManager, DanglingUntriaged> badge_manager_ = nullptr;
 
   base::ScopedObservation<MediaCaptureDevicesDispatcher,
                           MediaCaptureDevicesDispatcher::Observer>
diff --git a/chrome/browser/web_applications/externally_installed_web_app_prefs.h b/chrome/browser/web_applications/externally_installed_web_app_prefs.h
index 0142ea1..754d2c54 100644
--- a/chrome/browser/web_applications/externally_installed_web_app_prefs.h
+++ b/chrome/browser/web_applications/externally_installed_web_app_prefs.h
@@ -106,7 +106,7 @@
   static void LogDataMetrics(bool data_exists_in_pref,
                              bool data_exists_in_registrar);
 
-  const raw_ptr<PrefService> pref_service_;
+  const raw_ptr<PrefService, DanglingUntriaged> pref_service_;
 };
 
 }  // namespace web_app
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry.cc
index 2d85e2e..63fe5ca 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry.cc
@@ -10,6 +10,7 @@
 #include "base/callback.h"
 #include "base/functional/overloaded.h"
 #include "base/memory/weak_ptr.h"
+#include "base/metrics/histogram_functions.h"
 #include "base/ranges/algorithm.h"
 #include "base/strings/stringprintf.h"
 #include "base/time/time.h"
@@ -62,22 +63,31 @@
   DCHECK_EQ(web_bundle_id.type(),
             web_package::SignedWebBundleId::Type::kEd25519PublicKey);
 
-  if (auto cache_entry_it = reader_cache_.Find(web_bundle_path);
-      cache_entry_it != reader_cache_.End()) {
-    switch (cache_entry_it->second.state) {
-      case Cache::Entry::State::kPending:
-        // If integrity block and metadata are still being read, then the
-        // `SignedWebBundleReader` is not yet ready to be used for serving
-        // responses. Queue the request and callback in this case.
-        cache_entry_it->second.pending_requests.emplace_back(
-            resource_request, std::move(callback));
-        return;
-      case Cache::Entry::State::kReady:
-        // If integrity block and metadata have already been read, read the
-        // response from the cached `SignedWebBundleReader`.
-        DoReadResponse(cache_entry_it->second.GetReader(), resource_request,
-                       std::move(callback));
-        return;
+  {
+    auto cache_entry_it = reader_cache_.Find(web_bundle_path);
+    bool found = cache_entry_it != reader_cache_.End();
+
+    base::UmaHistogramEnumeration(
+        "WebApp.Isolated.ResponseReaderCacheState",
+        found ? cache_entry_it->second.AsReaderCacheState()
+              : ReaderCacheState::kNotCached);
+
+    if (found) {
+      switch (cache_entry_it->second.state) {
+        case Cache::Entry::State::kPending:
+          // If integrity block and metadata are still being read, then the
+          // `SignedWebBundleReader` is not yet ready to be used for serving
+          // responses. Queue the request and callback in this case.
+          cache_entry_it->second.pending_requests.emplace_back(
+              resource_request, std::move(callback));
+          return;
+        case Cache::Entry::State::kReady:
+          // If integrity block and metadata have already been read, read
+          // the response from the cached `SignedWebBundleReader`.
+          DoReadResponse(cache_entry_it->second.GetReader(), resource_request,
+                         std::move(callback));
+          return;
+      }
     }
   }
 
@@ -157,59 +167,36 @@
     const base::FilePath& web_bundle_path,
     const web_package::SignedWebBundleId& web_bundle_id,
     absl::optional<SignedWebBundleReader::ReadIntegrityBlockAndMetadataError>
-        read_error) {
+        read_integrity_block_and_metadata_error) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
 
   auto cache_entry_it = reader_cache_.Find(web_bundle_path);
   DCHECK(cache_entry_it != reader_cache_.End());
   DCHECK_EQ(cache_entry_it->second.state, Cache::Entry::State::kPending);
 
-  // Get all pending requests and set the pending requests of the cache entry to
-  // an empty vector.
-  std::vector<std::pair<network::ResourceRequest, ReadResponseCallback>>
-      pending_requests;
-  cache_entry_it->second.pending_requests.swap(pending_requests);
-
-  if (read_error.has_value()) {
-    std::string error_message = absl::visit(
-        base::Overloaded{
-            [](const web_package::mojom::BundleIntegrityBlockParseErrorPtr&
-                   error) {
-              return base::StringPrintf("Failed to parse integrity block: %s",
-                                        error->message.c_str());
-            },
-            [](const SignedWebBundleReader::AbortedByCaller& error) {
-              return base::StringPrintf(
-                  "Public keys of the Isolated Web App are untrusted: %s",
-                  error.message.c_str());
-            },
-            [](const web_package::SignedWebBundleSignatureVerifier::Error&
-                   error) {
-              return base::StringPrintf("Failed to verify signatures: %s",
-                                        error.message.c_str());
-            },
-            [](const web_package::mojom::BundleMetadataParseErrorPtr& error) {
-              return base::StringPrintf("Failed to parse metadata: %s",
-                                        error->message.c_str());
-            }},
-        *read_error);
-    for (auto& [resource_request, callback] : pending_requests) {
-      std::move(callback).Run(
-          base::unexpected(ReadResponseError::ForOtherError(error_message)));
-    }
-    reader_cache_.Erase(cache_entry_it);
-    return;
+  absl::optional<ReadResponseError> error;
+  if (read_integrity_block_and_metadata_error.has_value()) {
+    error =
+        ReadResponseError::ForError(*read_integrity_block_and_metadata_error);
   }
 
   SignedWebBundleReader& reader = cache_entry_it->second.GetReader();
 
-  if (auto error = validator_->ValidateMetadata(
-          web_bundle_id, reader.GetPrimaryURL(), reader.GetEntries());
-      error.has_value()) {
+  if (!error.has_value()) {
+    if (auto error_message = validator_->ValidateMetadata(
+            web_bundle_id, reader.GetPrimaryURL(), reader.GetEntries());
+        error_message.has_value()) {
+      error = ReadResponseError::ForMetadataValidationError(*error_message);
+    }
+  }
+
+  std::vector<std::pair<network::ResourceRequest, ReadResponseCallback>>
+      pending_requests =
+          std::exchange(cache_entry_it->second.pending_requests, {});
+
+  if (error.has_value()) {
     for (auto& [resource_request, callback] : pending_requests) {
-      std::move(callback).Run(
-          base::unexpected(ReadResponseError::ForOtherError(base::StringPrintf(
-              "Failed to validate metadata: %s", error->c_str()))));
+      std::move(callback).Run(base::unexpected(*error));
     }
     reader_cache_.Erase(cache_entry_it);
     return;
@@ -263,20 +250,9 @@
     base::expected<web_package::mojom::BundleResponsePtr,
                    SignedWebBundleReader::ReadResponseError> response_head) {
   if (!response_head.has_value()) {
-    switch (response_head.error().type) {
-      case SignedWebBundleReader::ReadResponseError::Type::kParserInternalError:
-      case SignedWebBundleReader::ReadResponseError::Type::kFormatError:
-        std::move(callback).Run(
-            base::unexpected(ReadResponseError::ForOtherError(
-                base::StringPrintf("Failed to parse response head: %s",
-                                   response_head.error().message.c_str()))));
-        return;
-      case SignedWebBundleReader::ReadResponseError::Type::kResponseNotFound:
-        std::move(callback).Run(
-            base::unexpected(ReadResponseError::ForResponseNotFound(
-                response_head.error().message)));
-        return;
-    }
+    std::move(callback).Run(
+        base::unexpected(ReadResponseError::ForError(response_head.error())));
+    return;
   }
   // Since `this` owns `reader`, we only pass a weak reference to it to the
   // `Response` object. If `this` deletes `reader`, it makes sense that the
@@ -309,6 +285,58 @@
                             std::move(callback));
 }
 
+// static
+IsolatedWebAppReaderRegistry::ReadResponseError
+IsolatedWebAppReaderRegistry::ReadResponseError::ForError(
+    const SignedWebBundleReader::ReadIntegrityBlockAndMetadataError& error) {
+  return ForOtherError(absl::visit(
+      base::Overloaded{
+          [](const web_package::mojom::BundleIntegrityBlockParseErrorPtr&
+                 error) {
+            return base::StringPrintf("Failed to parse integrity block: %s",
+                                      error->message.c_str());
+          },
+          [](const SignedWebBundleReader::AbortedByCaller& error) {
+            return base::StringPrintf("Failed to validate integrity block: %s",
+                                      error.message.c_str());
+          },
+          [](const web_package::SignedWebBundleSignatureVerifier::Error&
+                 error) {
+            return base::StringPrintf("Failed to verify signatures: %s",
+                                      error.message.c_str());
+          },
+          [](const web_package::mojom::BundleMetadataParseErrorPtr& error) {
+            return base::StringPrintf("Failed to parse metadata: %s",
+                                      error->message.c_str());
+          }},
+      error));
+}
+
+// static
+IsolatedWebAppReaderRegistry::ReadResponseError
+IsolatedWebAppReaderRegistry::ReadResponseError::ForMetadataValidationError(
+    const std::string& error) {
+  return ForOtherError(
+      base::StringPrintf("Failed to validate metadata: %s", error.c_str()));
+}
+
+// static
+IsolatedWebAppReaderRegistry::ReadResponseError
+IsolatedWebAppReaderRegistry::ReadResponseError::ForError(
+    const SignedWebBundleReader::ReadResponseError& error) {
+  switch (error.type) {
+    case SignedWebBundleReader::ReadResponseError::Type::kParserInternalError:
+      return ForOtherError(base::StringPrintf(
+          "Failed to parse response head: %s", error.message.c_str()));
+    case SignedWebBundleReader::ReadResponseError::Type::kFormatError:
+      return ForOtherError(base::StringPrintf(
+          "Failed to parse response head: %s", error.message.c_str()));
+    case SignedWebBundleReader::ReadResponseError::Type::kResponseNotFound:
+      return ForResponseNotFound(base::StringPrintf(
+          "Failed to read response: %s", error.message.c_str()));
+  }
+}
+
 IsolatedWebAppReaderRegistry::Cache::Cache() = default;
 IsolatedWebAppReaderRegistry::Cache::~Cache() = default;
 
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry.h b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry.h
index e38b8cee..aba69d5c 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry.h
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry.h
@@ -10,6 +10,7 @@
 #include "base/callback_forward.h"
 #include "base/containers/flat_map.h"
 #include "base/files/file_path.h"
+#include "base/gtest_prod_util.h"
 #include "base/memory/weak_ptr.h"
 #include "base/sequence_checker.h"
 #include "base/time/time.h"
@@ -89,6 +90,19 @@
       kResponseNotFound,
     };
 
+    static ReadResponseError ForError(
+        const SignedWebBundleReader::ReadIntegrityBlockAndMetadataError& error);
+
+    static ReadResponseError ForMetadataValidationError(
+        const std::string& error);
+
+    static ReadResponseError ForError(
+        const SignedWebBundleReader::ReadResponseError& error);
+
+    Type type;
+    std::string message;
+
+   private:
     static ReadResponseError ForOtherError(const std::string& message) {
       return ReadResponseError(Type::kOtherError, message);
     }
@@ -97,10 +111,6 @@
       return ReadResponseError(Type::kResponseNotFound, message);
     }
 
-    Type type;
-    std::string message;
-
-   private:
     ReadResponseError(Type type, const std::string& message)
         : type(type), message(message) {}
   };
@@ -118,6 +128,9 @@
                     ReadResponseCallback callback);
 
  private:
+  FRIEND_TEST_ALL_PREFIXES(IsolatedWebAppReaderRegistryTest,
+                           TestConcurrentRequests);
+
   void OnIntegrityBlockRead(
       const base::FilePath& web_bundle_path,
       const web_package::SignedWebBundleId& web_bundle_id,
@@ -137,7 +150,7 @@
       const base::FilePath& web_bundle_path,
       const web_package::SignedWebBundleId& web_bundle_id,
       absl::optional<SignedWebBundleReader::ReadIntegrityBlockAndMetadataError>
-          read_error);
+          read_integrity_block_and_metadata_error);
 
   void DoReadResponse(SignedWebBundleReader& reader,
                       network::ResourceRequest resource_request,
@@ -149,6 +162,8 @@
       base::expected<web_package::mojom::BundleResponsePtr,
                      SignedWebBundleReader::ReadResponseError> response_head);
 
+  enum class ReaderCacheState;
+
   // A thin wrapper around `base::flat_map<base::FilePath, Cache::Entry>` that
   // automatically removes entries from the cache if they have not been accessed
   // for some time. This makes sure that `SignedWebBundleReader`s are not kept
@@ -198,6 +213,15 @@
 
       const base::TimeTicks last_access() const { return last_access_; }
 
+      ReaderCacheState AsReaderCacheState() {
+        switch (state) {
+          case State::kPending:
+            return ReaderCacheState::kCachedPending;
+          case State::kReady:
+            return ReaderCacheState::kCachedReady;
+        }
+      }
+
       enum class State { kPending, kReady };
 
       State state = State::kPending;
@@ -223,6 +247,15 @@
     SEQUENCE_CHECKER(sequence_checker_);
   };
 
+  // These values are persisted to logs. Entries should not be renumbered and
+  // numeric values should never be reused.
+  enum class ReaderCacheState {
+    kNotCached = 0,
+    kCachedReady = 1,
+    kCachedPending = 2,
+    kMaxValue = kCachedPending
+  };
+
   Cache reader_cache_;
 
   // A set of files whose signatures have been verified successfully during the
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry_unittest.cc
index 697bdb7..b67d2c1 100644
--- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry_unittest.cc
+++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_reader_registry_unittest.cc
@@ -15,6 +15,7 @@
 #include "base/strings/stringprintf.h"
 #include "base/task/sequenced_task_runner.h"
 #include "base/test/bind.h"
+#include "base/test/metrics/histogram_tester.h"
 #include "base/test/scoped_feature_list.h"
 #include "base/test/task_environment.h"
 #include "base/test/test_future.h"
@@ -29,12 +30,15 @@
 #include "content/public/common/content_features.h"
 #include "services/data_decoder/public/cpp/test_support/in_process_data_decoder.h"
 #include "services/network/public/cpp/resource_request.h"
+#include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
 
 namespace web_app {
 
 namespace {
 
+using testing::ElementsAre;
+
 constexpr uint8_t kEd25519PublicKey[32] = {0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0,
                                            0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0,
                                            0, 0, 0, 0, 2, 2, 2, 0, 0, 0};
@@ -289,7 +293,8 @@
       result.error().type,
       IsolatedWebAppReaderRegistry::ReadResponseError::Type::kResponseNotFound);
   EXPECT_EQ(result.error().message,
-            "The Web Bundle does not contain a response for the provided URL: "
+            "Failed to read response: The Web Bundle does not contain a "
+            "response for the provided URL: "
             "isolated-app://"
             "aaaaaaacaibaaaaaaaaaaaaaaiaaeaaaaaaaaaaaaabaeaqaaaaaaaic/foo");
 }
@@ -432,7 +437,7 @@
             "Failed to parse integrity block: test error");
 }
 
-TEST_F(IsolatedWebAppReaderRegistryTest, TestUntrustedPublicKeys) {
+TEST_F(IsolatedWebAppReaderRegistryTest, TestInvalidIntegrityBlockContents) {
   network::ResourceRequest resource_request;
   resource_request.url = kPrimaryUrl;
 
@@ -455,7 +460,7 @@
   EXPECT_EQ(result.error().type,
             IsolatedWebAppReaderRegistry::ReadResponseError::Type::kOtherError);
   EXPECT_EQ(result.error().message,
-            "Public keys of the Isolated Web App are untrusted: test error");
+            "Failed to validate integrity block: test error");
 }
 
 class IsolatedWebAppReaderRegistrySignatureVerificationErrorTest
@@ -612,6 +617,9 @@
 }
 
 TEST_F(IsolatedWebAppReaderRegistryTest, TestConcurrentRequests) {
+  using ReaderCacheState = IsolatedWebAppReaderRegistry::ReaderCacheState;
+  base::HistogramTester histogram_tester;
+
   network::ResourceRequest resource_request;
   resource_request.url = kPrimaryUrl;
 
@@ -619,10 +627,21 @@
   base::test::TestFuture<ReadResult> read_response_future_1;
   registry_->ReadResponse(web_bundle_path_, kWebBundleId, resource_request,
                           read_response_future_1.GetCallback());
+
+  histogram_tester.GetAllSamples("WebApp.Isolated.ResponseReaderCacheState"),
+      ElementsAre(base::Bucket(ReaderCacheState::kNotCached, 1),
+                  base::Bucket(ReaderCacheState::kCachedReady, 0),
+                  base::Bucket(ReaderCacheState::kCachedPending, 0));
+
   base::test::TestFuture<ReadResult> read_response_future_2;
   registry_->ReadResponse(web_bundle_path_, kWebBundleId, resource_request,
                           read_response_future_2.GetCallback());
 
+  histogram_tester.GetAllSamples("WebApp.Isolated.ResponseReaderCacheState"),
+      ElementsAre(base::Bucket(ReaderCacheState::kNotCached, 1),
+                  base::Bucket(ReaderCacheState::kCachedReady, 0),
+                  base::Bucket(ReaderCacheState::kCachedPending, 1));
+
   FulfillIntegrityBlock();
   FulfillMetadata();
   FulfillResponse(resource_request);
@@ -655,6 +674,11 @@
   registry_->ReadResponse(web_bundle_path_, kWebBundleId, resource_request,
                           read_response_future_3.GetCallback());
 
+  histogram_tester.GetAllSamples("WebApp.Isolated.ResponseReaderCacheState"),
+      ElementsAre(base::Bucket(ReaderCacheState::kNotCached, 1),
+                  base::Bucket(ReaderCacheState::kCachedReady, 1),
+                  base::Bucket(ReaderCacheState::kCachedPending, 1));
+
   FulfillResponse(resource_request);
   {
     ReadResult result = read_response_future_3.Take();
diff --git a/chrome/browser/web_applications/manifest_update_manager.h b/chrome/browser/web_applications/manifest_update_manager.h
index 8d17005..11108b2 100644
--- a/chrome/browser/web_applications/manifest_update_manager.h
+++ b/chrome/browser/web_applications/manifest_update_manager.h
@@ -175,17 +175,19 @@
                     const absl::optional<AppId>& app_id,
                     ManifestUpdateResult result);
 
-  raw_ptr<WebAppRegistrar> registrar_ = nullptr;
-  raw_ptr<WebAppIconManager> icon_manager_ = nullptr;
+  raw_ptr<WebAppRegistrar, DanglingUntriaged> registrar_ = nullptr;
+  raw_ptr<WebAppIconManager, DanglingUntriaged> icon_manager_ = nullptr;
   raw_ptr<WebAppUiManager, DanglingUntriaged> ui_manager_ = nullptr;
-  raw_ptr<WebAppInstallFinalizer> install_finalizer_ = nullptr;
-  raw_ptr<const ash::SystemWebAppDelegateMap> system_web_apps_delegate_map_ =
+  raw_ptr<WebAppInstallFinalizer, DanglingUntriaged> install_finalizer_ =
       nullptr;
+  raw_ptr<const ash::SystemWebAppDelegateMap, DanglingUntriaged>
+      system_web_apps_delegate_map_ = nullptr;
   raw_ptr<OsIntegrationManager, DanglingUntriaged> os_integration_manager_ =
       nullptr;
-  raw_ptr<WebAppSyncBridge> sync_bridge_ = nullptr;
+  raw_ptr<WebAppSyncBridge, DanglingUntriaged> sync_bridge_ = nullptr;
   raw_ptr<WebAppInstallManager, DanglingUntriaged> install_manager_ = nullptr;
-  raw_ptr<WebAppCommandScheduler> command_scheduler_ = nullptr;
+  raw_ptr<WebAppCommandScheduler, DanglingUntriaged> command_scheduler_ =
+      nullptr;
 
   base::ScopedObservation<WebAppInstallManager, WebAppInstallManagerObserver>
       install_manager_observation_{this};
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt
index ae3dfc3..b37aef5 100644
--- a/chrome/build/linux.pgo.txt
+++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@
-chrome-linux-main-1668556793-fbaaed4615e98a907acf0b919833948d64fca44b.profdata
+chrome-linux-main-1668578082-b0eee736161271db0f75641695c07f9dcdf42317.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 1d197bf..3a2c81382 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1668556793-232904ea6cc3d186c1f0251f967e74e4deaa8308.profdata
+chrome-mac-arm-main-1668578082-c2361f5132c4d28de2c0da43aa0350aa9892f9a5.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index fc75b73..fb9c763d 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1668556793-a5718d309252ea01e56da2b0c414ece22d83bf4b.profdata
+chrome-mac-main-1668578082-3fca691b150d93719c04306c28ec808cc1820840.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 1844015c..259d88a 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1668535201-2af78ac7fa8a1d3e69566f44163f326729c78077.profdata
+chrome-win32-main-1668578082-32e3fc11b8739a810535ae7996c90a33ebe45244.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index 204b596..8f65fdb6 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1668535201-29eac2f149149a9645e9194655e00d0639794e61.profdata
+chrome-win64-main-1668578082-cf05e74035dd10afb7c94223d78978f82b294cfb.profdata
diff --git a/chrome/common/chromeos/extensions/api/diagnostics.idl b/chrome/common/chromeos/extensions/api/diagnostics.idl
index 44a5e4b..4565be87 100644
--- a/chrome/common/chromeos/extensions/api/diagnostics.idl
+++ b/chrome/common/chromeos/extensions/api/diagnostics.idl
@@ -26,7 +26,9 @@
     lan_connectivity,
     signal_strength,
     dns_resolver_present,
-    gateway_can_be_pinged
+    gateway_can_be_pinged,
+    sensitive_sensor,
+    nvme_self_test
   };
 
   enum RoutineStatus {
@@ -115,6 +117,15 @@
     long file_size_mb;
   };
 
+  enum NvmeSelfTestType {
+    short_test,
+    long_test
+  };
+
+  dictionary RunNvmeSelfTestRequest {
+    NvmeSelfTestType test_type;
+  };
+
   dictionary RunNvmeWearLevelRequest {
     long wear_level_threshold;
   };
@@ -175,9 +186,13 @@
 
     [supportsPromises] static void runMemoryRoutine(RunRoutineCallback callback);
 
+    [supportsPromises] static void runNvmeSelfTestRoutine(RunNvmeSelfTestRequest request, RunRoutineCallback callback);
+
     [supportsPromises] static void runNvmeWearLevelRoutine(RunNvmeWearLevelRequest request,
                                                            RunRoutineCallback callback);
 
+    [supportsPromises] static void runSensitiveSensorRoutine(RunRoutineCallback callback);
+
     [supportsPromises] static void runSignalStrengthRoutine(RunRoutineCallback callback);
 
     [supportsPromises] static void runSmartctlCheckRoutine(RunRoutineCallback callback);
diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json
index 43aa825c..f1984596 100644
--- a/chrome/common/extensions/api/_permission_features.json
+++ b/chrome/common/extensions/api/_permission_features.json
@@ -565,7 +565,8 @@
       "4AC2B6C63C6480D150DFDA13E4A5956EB1D0DDBB",  // http://crbug.com/891460
       "81986D4F846CEDDDB962643FA501D1780DD441BB",  // http://crbug.com/891460
       "A9A9FC0228ADF541F0334F22BEFB8F9C245B21D7"   // http://crbug.com/891460
-    ]
+    ],
+    "platforms": ["chromeos", "lacros"]
   },
   "management": [
     {
diff --git a/chrome/common/extensions/api/terminal_private.json b/chrome/common/extensions/api/terminal_private.json
index 7cd01a24..d487fcd 100644
--- a/chrome/common/extensions/api/terminal_private.json
+++ b/chrome/common/extensions/api/terminal_private.json
@@ -250,10 +250,6 @@
                   "description": "True if SFTP / mount is enabled.",
                   "type": "boolean"
                 },
-                "tast": {
-                  "description": "True if tast extension is installed.",
-                  "type": "boolean"
-                },
                 "tmux_integration": {
                   "description": "True if tmux control mode integration is enabled.",
                   "type": "boolean"
diff --git a/chrome/common/extensions/manifest_unittest.cc b/chrome/common/extensions/manifest_unittest.cc
index 074eb46..777a828 100644
--- a/chrome/common/extensions/manifest_unittest.cc
+++ b/chrome/common/extensions/manifest_unittest.cc
@@ -57,12 +57,11 @@
   void MutateManifest(std::unique_ptr<Manifest>* manifest,
                       const std::string& key,
                       std::unique_ptr<base::Value> value) {
-    auto manifest_value = base::DictionaryValue::From(
-        base::Value::ToUniquePtrValue(manifest->get()->value()->Clone()));
+    base::Value::Dict manifest_value = (*manifest)->value()->GetDict().Clone();
     if (value)
-      manifest_value->SetPath(key, std::move(*value));
+      manifest_value.SetByDottedPath(key, std::move(*value));
     else
-      manifest_value->RemovePath(key);
+      manifest_value.RemoveByDottedPath(key);
     ExtensionId extension_id = manifest->get()->extension_id();
     *manifest = std::make_unique<Manifest>(
         ManifestLocation::kInternal, std::move(manifest_value), extension_id);
@@ -72,8 +71,7 @@
   // and uses the |for_login_screen| during creation to determine its type.
   void MutateManifestForLoginScreen(std::unique_ptr<Manifest>* manifest,
                                     bool for_login_screen) {
-    auto manifest_value = base::DictionaryValue::From(
-        base::Value::ToUniquePtrValue(manifest->get()->value()->Clone()));
+    auto manifest_value = (*manifest)->value()->GetDict().Clone();
     ExtensionId extension_id = manifest->get()->extension_id();
     if (for_login_screen) {
       *manifest = Manifest::CreateManifestForLoginScreen(
@@ -90,13 +88,12 @@
 
 // Verifies that extensions can access the correct keys.
 TEST_F(ManifestUnitTest, Extension) {
-  std::unique_ptr<base::DictionaryValue> manifest_value(
-      new base::DictionaryValue());
-  manifest_value->SetString(keys::kName, "extension");
-  manifest_value->SetString(keys::kVersion, "1");
-  manifest_value->SetInteger(keys::kManifestVersion, 2);
-  manifest_value->SetString(keys::kBackgroundPage, "bg.html");
-  manifest_value->SetString("unknown_key", "foo");
+  base::Value::Dict manifest_value;
+  manifest_value.Set(keys::kName, "extension");
+  manifest_value.Set(keys::kVersion, "1");
+  manifest_value.Set(keys::kManifestVersion, 2);
+  manifest_value.SetByDottedPath(keys::kBackgroundPage, "bg.html");
+  manifest_value.Set("unknown_key", "foo");
 
   std::unique_ptr<Manifest> manifest(
       new Manifest(ManifestLocation::kInternal, std::move(manifest_value),
@@ -122,9 +119,7 @@
 
   // Test EqualsForTesting.
   auto manifest2 = std::make_unique<Manifest>(
-      ManifestLocation::kInternal,
-      base::DictionaryValue::From(
-          base::Value::ToUniquePtrValue(manifest->value()->Clone())),
+      ManifestLocation::kInternal, manifest->value()->GetDict().Clone(),
       crx_file::id_util::GenerateId("extid"));
   EXPECT_TRUE(manifest->EqualsForTesting(*manifest2));
   EXPECT_TRUE(manifest2->EqualsForTesting(*manifest));
@@ -134,9 +129,9 @@
 
 // Verifies that key restriction based on type works.
 TEST_F(ManifestUnitTest, ExtensionTypes) {
-  std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue());
-  value->SetStringKey(keys::kName, "extension");
-  value->SetStringKey(keys::kVersion, "1");
+  base::Value::Dict value;
+  value.Set(keys::kName, "extension");
+  value.Set(keys::kVersion, "1");
 
   std::unique_ptr<Manifest> manifest(
       new Manifest(ManifestLocation::kInternal, std::move(value),
@@ -197,12 +192,11 @@
 // Verifies that the getters filter restricted keys taking into account the
 // manifest version.
 TEST_F(ManifestUnitTest, RestrictedKeys_ManifestVersion) {
-  std::unique_ptr<base::DictionaryValue> value =
-      DictionaryBuilder()
-          .Set(keys::kName, "extension")
-          .Set(keys::kVersion, "1")
-          .Set(keys::kManifestVersion, 2)
-          .Build();
+  base::Value::Dict value = DictionaryBuilder()
+                                .Set(keys::kName, "extension")
+                                .Set(keys::kVersion, "1")
+                                .Set(keys::kManifestVersion, 2)
+                                .BuildDict();
 
   auto manifest =
       std::make_unique<Manifest>(ManifestLocation::kInternal, std::move(value),
@@ -228,14 +222,12 @@
 // Verifies that the getters filter restricted keys taking into account the
 // item type.
 TEST_F(ManifestUnitTest, RestrictedKeys_ItemType) {
-  std::unique_ptr<base::DictionaryValue> value =
-      DictionaryBuilder()
-          .Set(keys::kName, "item")
-          .Set(keys::kVersion, "1")
-          .Set(keys::kManifestVersion, 2)
-          .Set(keys::kPageAction,
-               std::make_unique<base::Value>(base::Value::Type::DICTIONARY))
-          .Build();
+  base::Value::Dict value = DictionaryBuilder()
+                                .Set(keys::kName, "item")
+                                .Set(keys::kVersion, "1")
+                                .Set(keys::kManifestVersion, 2)
+                                .Set(keys::kPageAction, base::Value::Dict())
+                                .BuildDict();
 
   auto manifest =
       std::make_unique<Manifest>(ManifestLocation::kInternal, std::move(value),
diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h
index c8a1ffb68..9d56f67 100644
--- a/chrome/test/base/in_process_browser_test.h
+++ b/chrome/test/base/in_process_browser_test.h
@@ -366,7 +366,8 @@
   base::test::ScopedFeatureList scoped_feature_list_;
 
 #if BUILDFLAG(IS_MAC)
-  raw_ptr<base::mac::ScopedNSAutoreleasePool> autorelease_pool_ = nullptr;
+  raw_ptr<base::mac::ScopedNSAutoreleasePool, DanglingUntriaged>
+      autorelease_pool_ = nullptr;
   std::unique_ptr<ScopedBundleSwizzlerMac> bundle_swizzler_;
 
   // Enable fake full keyboard access by default, so that tests don't depend on
diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h
index 1d03c56..70d2bdf 100644
--- a/chrome/test/base/testing_profile.h
+++ b/chrome/test/base/testing_profile.h
@@ -520,7 +520,8 @@
   std::unique_ptr<policy::PolicyService> policy_service_;
 
 #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
-  raw_ptr<TestingPrefStore> supervised_user_pref_store_ = nullptr;
+  raw_ptr<TestingPrefStore, DanglingUntriaged> supervised_user_pref_store_ =
+      nullptr;
 #endif  // BUILDFLAG(ENABLE_SUPERVISED_USERS)
 
   scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
diff --git a/chrome/test/data/webui/settings/BUILD.gn b/chrome/test/data/webui/settings/BUILD.gn
index f3510a3..b02a47b 100644
--- a/chrome/test/data/webui/settings/BUILD.gn
+++ b/chrome/test/data/webui/settings/BUILD.gn
@@ -143,7 +143,6 @@
   "test_search_engines_browser_proxy.ts",
   "test_site_settings_prefs_browser_proxy.ts",
   "test_util.ts",
-  "trusted_html.ts",
   "zoom_levels_tests.ts",
 ]
 
diff --git a/chrome/test/data/webui/settings/idle_load_tests.ts b/chrome/test/data/webui/settings/idle_load_tests.ts
index 36bcf4d3..6c9aef2b 100644
--- a/chrome/test/data/webui/settings/idle_load_tests.ts
+++ b/chrome/test/data/webui/settings/idle_load_tests.ts
@@ -4,8 +4,6 @@
 
 // #clang-format off
 import 'chrome://settings/settings.js';
-
-import {getTrustedHTML} from 'chrome://settings/settings.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 // #clang-format on
 
@@ -18,7 +16,7 @@
 
 suite('Settings idle load tests', function() {
   setup(function() {
-    document.body.innerHTML = getTrustedHTML`
+    document.body.innerHTML = `
       <settings-idle-load>
         <template>
           <div></div>
diff --git a/chrome/test/data/webui/settings/privacy_page_test.ts b/chrome/test/data/webui/settings/privacy_page_test.ts
index 7609ae07..781eea4 100644
--- a/chrome/test/data/webui/settings/privacy_page_test.ts
+++ b/chrome/test/data/webui/settings/privacy_page_test.ts
@@ -518,7 +518,7 @@
     Router.getInstance().navigateTo(routes.SITE_SETTINGS_NOTIFICATIONS);
     siteSettingsBrowserProxy = new TestSiteSettingsPrefsBrowserProxy();
     SiteSettingsPrefsBrowserProxyImpl.setInstance(siteSettingsBrowserProxy);
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    document.body.innerHTML = '';
   });
 
   teardown(function() {
diff --git a/chrome/test/data/webui/settings/search_settings_test.ts b/chrome/test/data/webui/settings/search_settings_test.ts
index 33e0397..61ebd7d5 100644
--- a/chrome/test/data/webui/settings/search_settings_test.ts
+++ b/chrome/test/data/webui/settings/search_settings_test.ts
@@ -4,11 +4,9 @@
 
 // clang-format off
 import {html, PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js';
-import {BaseMixin, getSearchManager, SearchManager, getTrustedHTML as getTrustedStaticHtml} from 'chrome://settings/settings.js';
+import {BaseMixin, getSearchManager, SearchManager} from 'chrome://settings/settings.js';
 import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 
-import {getTrustedHtml} from './trusted_html.js';
-
 // clang-format on
 
 suite('SearchSettingsTest', function() {
@@ -26,10 +24,9 @@
   test('normal highlighting', function() {
     const optionText = 'FooSettingsFoo';
 
-    document.body.innerHTML =
-        getTrustedHtml(`<settings-section hidden-by-search>
+    document.body.innerHTML = `<settings-section hidden-by-search>
            <div id="mydiv">${optionText}</div>
-         </settings-section>`);
+         </settings-section>`;
 
     const section = document.querySelector('settings-section')!;
     const div = document.querySelector('#mydiv')!;
@@ -69,8 +66,7 @@
    * bubble.
    */
   test('<select> highlighting', function() {
-    document.body.innerHTML =
-        getTrustedStaticHtml`<settings-section hidden-by-search>
+    document.body.innerHTML = `<settings-section hidden-by-search>
            <select>
              <option>Foo</option>
              <option>Settings</option>
@@ -103,8 +99,7 @@
 
   test('ignored elements are ignored', function() {
     const text = 'hello';
-    document.body.innerHTML =
-        getTrustedHtml(`<settings-section hidden-by-search>
+    document.body.innerHTML = `<settings-section hidden-by-search>
            <cr-action-menu>${text}</cr-action-menu>
            <cr-dialog>${text}</cr-dialog>
            <cr-icon-button>${text}</cr-icon-button>
@@ -118,7 +113,7 @@
            <content>${text}</content>
            <style>${text}</style>
            <template>${text}</template>
-         </settings-section>`);
+         </settings-section>`;
 
     const section = document.querySelector('settings-section')!;
     assertTrue(section.hiddenBySearch);
@@ -171,8 +166,7 @@
 
     const text = 'hello';
 
-    document.body.innerHTML =
-        getTrustedStaticHtml`<dummy-test-element></dummy-test-element>`;
+    document.body.innerHTML = `<dummy-test-element></dummy-test-element>`;
 
     const element =
         document.body.querySelector<DummyTestElement>('dummy-test-element')!;
@@ -203,8 +197,7 @@
   // Test that multiple requests for the same text correctly highlight their
   // corresponding part of the tree without affecting other parts of the tree.
   test('multiple simultaneous requests for the same text', function() {
-    document.body.innerHTML =
-        getTrustedStaticHtml`<settings-section hidden-by-search>
+    document.body.innerHTML = `<settings-section hidden-by-search>
            <div><span>Hello there</span></div>
          </settings-section>
          <settings-section hidden-by-search>
@@ -231,10 +224,9 @@
   test('highlight removed when text is changed', function() {
     const originalText = 'FooSettingsFoo';
 
-    document.body.innerHTML =
-        getTrustedHtml(`<settings-section hidden-by-search>
+    document.body.innerHTML = `<settings-section hidden-by-search>
           <div id="mydiv">${originalText}</div>
-        </settings-section>`);
+        </settings-section>`;
 
     const section = document.querySelector('settings-section')!;
     const div = document.querySelector('#mydiv')!;
@@ -261,7 +253,7 @@
   });
 
   test('match text outside of a settings section', async function() {
-    document.body.innerHTML = getTrustedStaticHtml`
+    document.body.innerHTML = `
         <div id="mydiv">Match</div>
         <settings-section></settings-section>`;
 
@@ -280,7 +272,7 @@
   });
 
   test('associated control causes search highlight bubble', async () => {
-    document.body.innerHTML = getTrustedStaticHtml`
+    document.body.innerHTML = `
         <settings-section>
           <button></button>
           <settings-subpage>
@@ -296,7 +288,7 @@
   });
 
   test('bubble result count', async () => {
-    document.body.innerHTML = getTrustedStaticHtml`
+    document.body.innerHTML = `
         <settings-section>
           <select>
             <option>nohello</option>
@@ -323,7 +315,7 @@
   });
 
   test('diacritics', async () => {
-    document.body.innerHTML = getTrustedStaticHtml`
+    document.body.innerHTML = `
         <settings-section>
           <select>
             <option>año de oro</option>
diff --git a/chrome/test/data/webui/settings/settings_animated_pages_test.ts b/chrome/test/data/webui/settings/settings_animated_pages_test.ts
index 53b4c01b..b4416fb 100644
--- a/chrome/test/data/webui/settings/settings_animated_pages_test.ts
+++ b/chrome/test/data/webui/settings/settings_animated_pages_test.ts
@@ -8,7 +8,6 @@
 import {eventToPromise} from 'chrome://webui-test/test_util.js';
 
 import {setupPopstateListener} from './test_util.js';
-import {getTrustedHtml} from './trusted_html.js';
 
 // clang-format on
 
@@ -47,13 +46,13 @@
   // Test simple case where the |focusConfig| key captures only the previous
   // route.
   test('FocusSubpageTrigger_SimpleKey', async function() {
-    document.body.innerHTML = getTrustedHtml(`
+    document.body.innerHTML = `
       <settings-animated-pages section="${testRoutes.SEARCH_ENGINES.section}">
         <div route-path="default">
           <button id="subpage-trigger"></button>
         </div>
         <div route-path="${testRoutes.SEARCH_ENGINES.path}"></div>
-      </settings-animated-pages>`);
+      </settings-animated-pages>`;
 
     const animatedPages =
         document.body.querySelector('settings-animated-pages')!;
@@ -76,7 +75,7 @@
   // route, to differentiate cases where a subpage can have multiple entry
   // points.
   test('FocusSubpageTrigger_FromToKey', async function() {
-    document.body.innerHTML = getTrustedHtml(`
+    document.body.innerHTML = `
       <settings-animated-pages section="${testRoutes.PRIVACY.section}">
         <div route-path="default">
           <button id="subpage-trigger1"></button>
@@ -85,7 +84,7 @@
           <button id="subpage-trigger2"></button>
         </div>
         <div route-path="${testRoutes.SITE_SETTINGS_COOKIES.path}"></div>
-      </settings-animated-pages>`);
+      </settings-animated-pages>`;
 
     const animatedPages =
         document.body.querySelector('settings-animated-pages')!;
@@ -122,13 +121,13 @@
   });
 
   test('IgnoresBubblingIronSelect', async function() {
-    document.body.innerHTML = getTrustedHtml(`
+    document.body.innerHTML = `
       <settings-animated-pages section="${testRoutes.PRIVACY.section}">
         <div route-path="default"></div>
         <settings-subpage route-path="${testRoutes.SITE_SETTINGS.path}">
           <div></div>
         </settings-subpage>
-      </settings-animated-pages>`);
+      </settings-animated-pages>`;
 
     const subpage = document.body.querySelector('settings-subpage')!;
     let counter = 0;
diff --git a/chrome/test/data/webui/settings/settings_performance_menu_test.ts b/chrome/test/data/webui/settings/settings_performance_menu_test.ts
index 60f625c7..233bcb1 100644
--- a/chrome/test/data/webui/settings/settings_performance_menu_test.ts
+++ b/chrome/test/data/webui/settings/settings_performance_menu_test.ts
@@ -16,7 +16,7 @@
   }
 
   setup(function() {
-    document.body.innerHTML = window.trustedTypes!.emptyHTML;
+    document.body.innerHTML = '';
     Router.getInstance().navigateTo(routes.PERFORMANCE, undefined);
     settingsMenu = document.createElement('settings-menu');
     settingsMenu.pageVisibility = pageVisibility;
@@ -54,4 +54,4 @@
         getPerformanceMenuItem()!.hidden,
         'performance menu item should be hidden when pageVisibility is false');
   });
-});
+});
\ No newline at end of file
diff --git a/chrome/test/data/webui/settings/trusted_html.ts b/chrome/test/data/webui/settings/trusted_html.ts
deleted file mode 100644
index 98d861a..0000000
--- a/chrome/test/data/webui/settings/trusted_html.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2022 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview Provides a way to create TrustedHTML for HTML code that is
- * injected during tests and can't leverage
- * ui/webui/resources/js/static_types.ts because the HTML is not fully static.
- */
-
-let policy: TrustedTypePolicy|null = null;
-
-export function getTrustedHtml(html: string): TrustedHTML {
-  if (policy === null) {
-    policy = window.trustedTypes!.createPolicy('webui-test-html', {
-      // Policy only used in test code, no need for any sanitization. DO NOT use
-      // in prod code.
-      createHTML: html => html,
-      createScriptURL: () => '',
-      createScript: () => '',
-    });
-  }
-
-  return policy.createHTML(html);
-}
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/shortcuts_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/shortcuts_test.ts
index 483092f..d8c5e73 100644
--- a/chrome/test/data/webui/side_panel/customize_chrome/shortcuts_test.ts
+++ b/chrome/test/data/webui/side_panel/customize_chrome/shortcuts_test.ts
@@ -8,7 +8,7 @@
 import {CustomizeChromePageHandlerRemote} from 'chrome://customize-chrome-side-panel.top-chrome/customize_chrome.mojom-webui.js';
 import {CustomizeChromeApiProxy} from 'chrome://customize-chrome-side-panel.top-chrome/customize_chrome_api_proxy.js';
 import {ShortcutsElement} from 'chrome://customize-chrome-side-panel.top-chrome/shortcuts.js';
-import {assertTrue} from 'chrome://webui-test/chai_assert.js';
+import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js';
 import {TestBrowserProxy} from 'chrome://webui-test/test_browser_proxy.js';
 
 import {installMock} from './test_support.js';
@@ -36,10 +36,67 @@
     await handler.whenCalled('getMostVisitedSettings');
   }
 
-  test('shortcut element added to side panel', async () => {
-    // We set initial settings in this test to demonstrate how to use the
-    // handler. It does not affect the assertion in this test.
-    setInitialSettings(true, true);
-    assertTrue(document.body.contains(customizeShortcuts));
+  function assertShown(shown: boolean) {
+    assertEquals(shown, customizeShortcuts.$.showToggle.checked);
+  }
+
+  function assertCustomLinksEnabled() {
+    assertEquals(
+        'customLinksOption',
+        customizeShortcuts.$.shortcutsRadioSelection.selected);
+    assertShown(true);
+  }
+
+  function assertUseMostVisited() {
+    assertEquals(
+        'mostVisitedOption',
+        customizeShortcuts.$.shortcutsRadioSelection.selected);
+    assertShown(true);
+  }
+
+  test('selections are mutually exclusive', async () => {
+    await setInitialSettings(
+        /* customLinksEnabled= */ true, /* shortcutsVisible= */ false);
+    assertShown(false);
+    customizeShortcuts.$.showToggle.click();
+    assertCustomLinksEnabled();
+    customizeShortcuts.$.mostVisitedButton.click();
+    assertUseMostVisited();
+    customizeShortcuts.$.showToggle.click();
+    assertShown(false);
+    customizeShortcuts.$.showToggle.click();
+    assertUseMostVisited();
+  });
+
+  test('toggling show shortcuts on calls setMostVisitedSettings', async () => {
+    await setInitialSettings(
+        /* customLinksEnabled= */ false, /* shortcutsVisible= */ false);
+    const setSettingsCalled = handler.whenCalled('setMostVisitedSettings');
+    customizeShortcuts.$.showToggle.click();
+    const [customLinksEnabled, visible] = await setSettingsCalled;
+    assertFalse(customLinksEnabled);
+    assertTrue(visible);
+  });
+
+  test('enable custom links calls setMostVisitedSettings', async () => {
+    await setInitialSettings(
+        /* customLinksEnabled= */ false, /* shortcutsVisible= */ true);
+    assertUseMostVisited();
+    customizeShortcuts.$.customLinksButton.click();
+    const setSettingsCalled = handler.whenCalled('setMostVisitedSettings');
+    const [customLinksEnabled, visible] = await setSettingsCalled;
+    assertTrue(customLinksEnabled);
+    assertTrue(visible);
+  });
+
+  test('enable most visited calls setMostVisitedSettings', async () => {
+    await setInitialSettings(
+        /* customLinksEnabled= */ true, /* shortcutsVisible= */ true);
+    assertCustomLinksEnabled();
+    customizeShortcuts.$.mostVisitedButton.click();
+    const setSettingsCalled = handler.whenCalled('setMostVisitedSettings');
+    const [customLinksEnabled, visible] = await setSettingsCalled;
+    assertFalse(customLinksEnabled);
+    assertTrue(visible);
   });
 });
diff --git a/chromeos/ash/components/network/managed_cellular_pref_handler.cc b/chromeos/ash/components/network/managed_cellular_pref_handler.cc
index 563fb538..da9a0f9 100644
--- a/chromeos/ash/components/network/managed_cellular_pref_handler.cc
+++ b/chromeos/ash/components/network/managed_cellular_pref_handler.cc
@@ -16,6 +16,7 @@
 void ManagedCellularPrefHandler::RegisterLocalStatePrefs(
     PrefRegistrySimple* registry) {
   registry->RegisterDictionaryPref(prefs::kManagedCellularIccidSmdpPair);
+  registry->RegisterDictionaryPref(prefs::kApnMigratedIccids);
 }
 
 ManagedCellularPrefHandler::ManagedCellularPrefHandler() = default;
@@ -96,4 +97,36 @@
   return iccid_smdp_pairs.FindString(iccid);
 }
 
+void ManagedCellularPrefHandler::AddApnMigratedIccid(const std::string& iccid) {
+  if (!device_prefs_) {
+    NET_LOG(ERROR) << "Device pref not available yet.";
+    return;
+  }
+  if (ContainsApnMigratedIccid(iccid)) {
+    NET_LOG(ERROR)
+        << "AddApnMigratedIccid: Called with already migrated network, iccid: "
+        << iccid;
+    return;
+  }
+
+  NET_LOG(EVENT)
+      << "AddApnMigratedIccid: Adding migrated network to device pref, iccid: "
+      << iccid;
+  ScopedDictPrefUpdate update(device_prefs_, prefs::kApnMigratedIccids);
+  update->SetByDottedPath(iccid, true);
+  network_state_handler_->SyncStubCellularNetworks();
+  NotifyManagedCellularPrefChanged();
+}
+
+bool ManagedCellularPrefHandler::ContainsApnMigratedIccid(
+    const std::string& iccid) const {
+  if (!device_prefs_) {
+    NET_LOG(ERROR) << "Device pref not available yet.";
+    return false;
+  }
+  const base::Value::Dict& apn_migrated_iccids =
+      device_prefs_->GetDict(prefs::kApnMigratedIccids);
+  return apn_migrated_iccids.FindBool(iccid).value_or(false);
+}
+
 }  // namespace ash
diff --git a/chromeos/ash/components/network/managed_cellular_pref_handler.h b/chromeos/ash/components/network/managed_cellular_pref_handler.h
index fa1abaf..620bd0a 100644
--- a/chromeos/ash/components/network/managed_cellular_pref_handler.h
+++ b/chromeos/ash/components/network/managed_cellular_pref_handler.h
@@ -50,6 +50,13 @@
   // |iccid|.
   void RemovePairWithIccid(const std::string& iccid);
 
+  // Marks cellular network with iccid |iccid| as migrated to the APN revamp
+  // feature. See (b/162365553).
+  void AddApnMigratedIccid(const std::string& iccid);
+
+  // Return true if the |iccid| has been migrated to the APN Revamp feature.
+  bool ContainsApnMigratedIccid(const std::string& iccid) const;
+
   // Returns the corresponding SMDP+ address for the given |iccid|. Returns
   // nullptr if no such |iccid| is found.
   const std::string* GetSmdpAddressFromIccid(const std::string& iccid) const;
diff --git a/chromeos/ash/components/network/managed_cellular_pref_handler_unittest.cc b/chromeos/ash/components/network/managed_cellular_pref_handler_unittest.cc
index e515c8e..9c49215 100644
--- a/chromeos/ash/components/network/managed_cellular_pref_handler_unittest.cc
+++ b/chromeos/ash/components/network/managed_cellular_pref_handler_unittest.cc
@@ -13,8 +13,9 @@
 
 namespace {
 
-const char kIccid[] = "1234567890";
-const char kSmdpAddress[] = "LPA:1$SmdpAddress$ActivationCode";
+constexpr char kIccid1[] = "1234567890";
+constexpr char kIccid2[] = "0987654321";
+constexpr char kSmdpAddress[] = "LPA:1$SmdpAddress$ActivationCode";
 
 class FakeObserver : public ManagedCellularPrefHandler::Observer {
  public:
@@ -77,6 +78,14 @@
     return managed_cellular_pref_handler_->GetSmdpAddressFromIccid(iccid);
   }
 
+  void AddApnMigratedIccid(const std::string& iccid) {
+    managed_cellular_pref_handler_->AddApnMigratedIccid(iccid);
+  }
+
+  bool ContainsApnMigratedIccid(const std::string& iccid) {
+    return managed_cellular_pref_handler_->ContainsApnMigratedIccid(iccid);
+  }
+
   int NumObserverEvents() { return observer_.change_count(); }
 
  private:
@@ -95,30 +104,56 @@
 
   // Add a pair of ICCID - SMDP address pair to pref and verify that the correct
   // value can be retrieved.
-  AddIccidSmdpPair(kIccid, kSmdpAddress);
+  AddIccidSmdpPair(kIccid1, kSmdpAddress);
   EXPECT_EQ(1, NumObserverEvents());
-  const std::string* smdp_address = GetSmdpAddressFromIccid(kIccid);
+  const std::string* smdp_address = GetSmdpAddressFromIccid(kIccid1);
   EXPECT_TRUE(smdp_address);
   EXPECT_EQ(kSmdpAddress, *smdp_address);
-  EXPECT_FALSE(GetSmdpAddressFromIccid("00000000000"));
-  RemovePairForIccid(kIccid);
+  EXPECT_FALSE(GetSmdpAddressFromIccid(kIccid2));
+  RemovePairForIccid(kIccid1);
   EXPECT_EQ(2, NumObserverEvents());
-  smdp_address = GetSmdpAddressFromIccid(kIccid);
+  smdp_address = GetSmdpAddressFromIccid(kIccid1);
   EXPECT_FALSE(smdp_address);
 }
 
+TEST_F(ManagedCellularPrefHandlerTest, AddApnMigratedIccid) {
+  Init();
+  SetDevicePrefs();
+
+  EXPECT_FALSE(ContainsApnMigratedIccid(kIccid1));
+
+  // Add APN migrated ICCIDs to pref and verify that the prefs store these
+  // values.
+  AddApnMigratedIccid(kIccid1);
+  EXPECT_EQ(1, NumObserverEvents());
+  EXPECT_TRUE(ContainsApnMigratedIccid(kIccid1));
+  EXPECT_FALSE(ContainsApnMigratedIccid(kIccid2));
+
+  AddApnMigratedIccid(kIccid2);
+  EXPECT_EQ(2, NumObserverEvents());
+  EXPECT_TRUE(ContainsApnMigratedIccid(kIccid1));
+  EXPECT_TRUE(ContainsApnMigratedIccid(kIccid2));
+}
+
 TEST_F(ManagedCellularPrefHandlerTest, NoDevicePrefSet) {
   Init();
   SetDevicePrefs(/*set_to_null=*/true);
 
   // Verify that when there's no device prefs, no SMDP address can be
   // retrieved.
-  const std::string* smdp_address = GetSmdpAddressFromIccid(kIccid);
+  const std::string* smdp_address = GetSmdpAddressFromIccid(kIccid1);
   EXPECT_FALSE(smdp_address);
-  AddIccidSmdpPair(kIccid, kSmdpAddress);
+  AddIccidSmdpPair(kIccid1, kSmdpAddress);
   EXPECT_EQ(0, NumObserverEvents());
-  smdp_address = GetSmdpAddressFromIccid(kIccid);
+  smdp_address = GetSmdpAddressFromIccid(kIccid1);
   EXPECT_FALSE(smdp_address);
+
+  // Verify that when there's no device prefs, no APN migrated ICCIDs can be
+  // retrieved.
+  EXPECT_FALSE(ContainsApnMigratedIccid(kIccid1));
+  AddApnMigratedIccid(kIccid1);
+  EXPECT_EQ(0, NumObserverEvents());
+  EXPECT_FALSE(ContainsApnMigratedIccid(kIccid1));
 }
 
 }  // namespace ash
diff --git a/chromeos/ash/components/smbfs/smbfs_mounter.cc b/chromeos/ash/components/smbfs/smbfs_mounter.cc
index af74704..57d6dab 100644
--- a/chromeos/ash/components/smbfs/smbfs_mounter.cc
+++ b/chromeos/ash/components/smbfs/smbfs_mounter.cc
@@ -98,7 +98,7 @@
 
   std::vector<std::string> mount_options;
   if (options_.enable_verbose_logging) {
-    mount_options.emplace_back("log-level=-1");
+    mount_options.emplace_back("log-level=-2");
   }
 
   ash::disks::MountPoint::Mount(
diff --git a/chromeos/crosapi/mojom/diagnostics_service.mojom b/chromeos/crosapi/mojom/diagnostics_service.mojom
index f4d5525..52dd6d5 100644
--- a/chromeos/crosapi/mojom/diagnostics_service.mojom
+++ b/chromeos/crosapi/mojom/diagnostics_service.mojom
@@ -16,7 +16,7 @@
 
 // Interface for exposing diagnostics service. Implemented in ash-chrome.
 //
-// Next ID: 21
+// Next ID: 22
 [Stable, Uuid="14bc6194-c059-4048-9bea-ca6823eeda82",
 RenamedFrom="ash.health.mojom.DiagnosticsService"]
 interface DiagnosticsService {
@@ -330,11 +330,25 @@
   // * |response| - contains a unique identifier and status for the created
   //                routine.
   RunDnsResolverPresentRoutine@20() => (DiagnosticsRunRoutineResponse response);
+
+  // Requests that the SensitiveSensor routine is created and started on the
+  // platform. This routine checks that the device's sensors are working
+  // correctly by monitoring the sensor sample data without user interaction.
+  // This routine only support sensitive sensors including accelerometers,
+  // gyro sensors, gravity sensors and magnetometers.
+  // The availability of this routine can be determined by checking that
+  // kSensitiveSensor is returned by GetAvailableRoutines.
+  //
+  // The response:
+  // * |response| - contains a unique identifier and status for the created
+  //                routine.
+  RunSensitiveSensorRoutine@21()
+      => (DiagnosticsRunRoutineResponse response);
 };
 
 // Enumeration of each of the diagnostics routines the platform may support.
 //
-// Next ID: 20
+// Next ID: 21
 [Stable, Extensible, RenamedFrom="ash.health.mojom.DiagnosticRoutineEnum"]
 enum DiagnosticsRoutineEnum {
   [Default] kUnknown = 15,
@@ -357,6 +371,7 @@
   kSignalStrength = 17,
   kGatewayCanBePinged = 18,
   kDnsResolverPresent = 19,
+  kSensitiveSensor = 20,
 };
 
 // Enumeration of each of the possible statuses for a diagnostics routine.
diff --git a/chromeos/dbus/power/fake_power_manager_client.cc b/chromeos/dbus/power/fake_power_manager_client.cc
index d55fe6d..cbabeb35 100644
--- a/chromeos/dbus/power/fake_power_manager_client.cc
+++ b/chromeos/dbus/power/fake_power_manager_client.cc
@@ -162,10 +162,7 @@
       base::BindOnce(std::move(callback), keyboard_brightness_percent_));
 }
 
-void FakePowerManagerClient::SetKeyboardBacklightToggledOff(bool toggled_off) {}
-
-void FakePowerManagerClient::GetKeyboardBacklightToggledOff(
-    DBusMethodCallback<bool> callback) {}
+void FakePowerManagerClient::ToggleKeyboardBacklight() {}
 
 const absl::optional<power_manager::PowerSupplyProperties>&
 FakePowerManagerClient::GetLastStatus() {
diff --git a/chromeos/dbus/power/fake_power_manager_client.h b/chromeos/dbus/power/fake_power_manager_client.h
index c4ff0f9..8506b19 100644
--- a/chromeos/dbus/power/fake_power_manager_client.h
+++ b/chromeos/dbus/power/fake_power_manager_client.h
@@ -108,9 +108,7 @@
   void IncreaseKeyboardBrightness() override;
   void GetKeyboardBrightnessPercent(
       DBusMethodCallback<double> callback) override;
-  void SetKeyboardBacklightToggledOff(bool toggled_off) override;
-  void GetKeyboardBacklightToggledOff(
-      DBusMethodCallback<bool> callback) override;
+  void ToggleKeyboardBacklight() override;
   const absl::optional<power_manager::PowerSupplyProperties>& GetLastStatus()
       override;
   void RequestStatusUpdate() override;
diff --git a/chromeos/dbus/power/power_manager_client.cc b/chromeos/dbus/power/power_manager_client.cc
index adf9bc3..502a0ba 100644
--- a/chromeos/dbus/power/power_manager_client.cc
+++ b/chromeos/dbus/power/power_manager_client.cc
@@ -491,28 +491,14 @@
                        weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
   }
 
-  void SetKeyboardBacklightToggledOff(bool toggled_off) override {
-    dbus::MethodCall method_call(
-        power_manager::kPowerManagerInterface,
-        power_manager::kSetKeyboardBacklightToggledOffMethod);
-    dbus::MessageWriter(&method_call).AppendBool(toggled_off);
+  void ToggleKeyboardBacklight() override {
+    dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
+                                 power_manager::kToggleKeyboardBacklightMethod);
     power_manager_proxy_->CallMethod(&method_call,
                                      dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
                                      base::DoNothing());
   }
 
-  void GetKeyboardBacklightToggledOff(
-      DBusMethodCallback<bool> callback) override {
-    dbus::MethodCall method_call(
-        power_manager::kPowerManagerInterface,
-        power_manager::kGetKeyboardBacklightToggledOffMethod);
-    power_manager_proxy_->CallMethod(
-        &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
-        base::BindOnce(
-            &PowerManagerClientImpl::OnGetKeyboardBacklightToggledOff,
-            weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
-  }
-
   void GetSwitchStates(DBusMethodCallback<SwitchStates> callback) override {
     dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
                                  power_manager::kGetSwitchStatesMethod);
@@ -935,25 +921,6 @@
     std::move(callback).Run(state);
   }
 
-  void OnGetKeyboardBacklightToggledOff(DBusMethodCallback<bool> callback,
-                                        dbus::Response* response) {
-    if (!response) {
-      POWER_LOG(ERROR) << "Error calling "
-                       << power_manager::kGetKeyboardBacklightToggledOffMethod;
-      std::move(callback).Run(absl::nullopt);
-      return;
-    }
-    dbus::MessageReader reader(response);
-    bool toggled_off = false;
-    if (!reader.PopBool(&toggled_off)) {
-      POWER_LOG(ERROR) << "Error reading response from powerd: "
-                       << response->ToString();
-      std::move(callback).Run(absl::nullopt);
-      return;
-    }
-    std::move(callback).Run(toggled_off);
-  }
-
   void CheckAmbientColorSupport() {
     dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
                                  power_manager::kHasAmbientColorDeviceMethod);
diff --git a/chromeos/dbus/power/power_manager_client.h b/chromeos/dbus/power/power_manager_client.h
index a0d02c7..3537553 100644
--- a/chromeos/dbus/power/power_manager_client.h
+++ b/chromeos/dbus/power/power_manager_client.h
@@ -246,12 +246,8 @@
   virtual void GetKeyboardBrightnessPercent(
       DBusMethodCallback<double> callback) = 0;
 
-  // Set the toggled-off state of the keyboard backlight.
-  virtual void SetKeyboardBacklightToggledOff(bool toggled_off) = 0;
-
-  // Get the toggled-off state of the keyboard backlight.
-  virtual void GetKeyboardBacklightToggledOff(
-      DBusMethodCallback<bool> callback) = 0;
+  // Toggle the keyboard backlight on or off.
+  virtual void ToggleKeyboardBacklight() = 0;
 
   // Returns the last power status that was received from D-Bus, if any.
   virtual const absl::optional<power_manager::PowerSupplyProperties>&
diff --git a/chromeos/services/network_config/cros_network_config.cc b/chromeos/services/network_config/cros_network_config.cc
index 14cc8e0..0dc3cd5 100644
--- a/chromeos/services/network_config/cros_network_config.cc
+++ b/chromeos/services/network_config/cros_network_config.cc
@@ -3628,17 +3628,9 @@
 
   network_metadata_store->SetCustomApnList(network_guid, new_apns.Clone());
 
-  base::Value::Dict onc;
-  onc.Set(::onc::network_config::kGUID, network_guid);
-  const std::string& onc_type =
-      MojoNetworkTypeToOnc(mojom::NetworkType::kCellular);
-  onc.Set(::onc::network_config::kType, onc_type);
-  base::Value::Dict type_dict;
-  type_dict.Set(::onc::cellular::kUserAPNList, std::move(new_apns));
-  onc.Set(onc_type, std::move(type_dict));
-
   SetPropertiesInternal(
-      network_guid, *network, std::move(onc),
+      network_guid, *network,
+      UserApnListToOnc(network_guid, std::move(new_apns)),
       base::BindOnce(
           [](const std::string& guid, bool success,
              const std::string& message) {
diff --git a/chromeos/services/network_config/public/cpp/BUILD.gn b/chromeos/services/network_config/public/cpp/BUILD.gn
index 4a251ea7..f0ece19c 100644
--- a/chromeos/services/network_config/public/cpp/BUILD.gn
+++ b/chromeos/services/network_config/public/cpp/BUILD.gn
@@ -14,6 +14,7 @@
 
   deps = [
     "//chromeos/services/network_config/public/mojom",
+    "//components/onc",
     "//services/network/public/cpp:ip_address_mojom_support",
   ]
 }
diff --git a/chromeos/services/network_config/public/cpp/cros_network_config_util.cc b/chromeos/services/network_config/public/cpp/cros_network_config_util.cc
index bbc1b07..c788311 100644
--- a/chromeos/services/network_config/public/cpp/cros_network_config_util.cc
+++ b/chromeos/services/network_config/public/cpp/cros_network_config_util.cc
@@ -3,9 +3,9 @@
 // found in the LICENSE file.
 
 #include "chromeos/services/network_config/public/cpp/cros_network_config_util.h"
+#include "components/onc/onc_constants.h"
 
-namespace chromeos {
-namespace network_config {
+namespace chromeos::network_config {
 
 // This matches logic in NetworkTypePattern and should be kept in sync.
 bool NetworkTypeMatchesType(mojom::NetworkType network_type,
@@ -75,5 +75,15 @@
   return device->inhibit_reason != mojom::InhibitReason::kNotInhibited;
 }
 
-}  // namespace network_config
-}  // namespace chromeos
+base::Value::Dict UserApnListToOnc(const std::string& network_guid,
+                                   base::Value::List user_apn_list) {
+  base::Value::Dict onc;
+  onc.Set(::onc::network_config::kGUID, network_guid);
+  onc.Set(::onc::network_config::kType, ::onc::network_type::kCellular);
+  base::Value::Dict type_dict;
+  type_dict.Set(::onc::cellular::kUserAPNList, std::move(user_apn_list));
+  onc.Set(::onc::network_type::kCellular, std::move(type_dict));
+  return onc;
+}
+
+}  // namespace chromeos::network_config
diff --git a/chromeos/services/network_config/public/cpp/cros_network_config_util.h b/chromeos/services/network_config/public/cpp/cros_network_config_util.h
index 7a5aaec..98fbc9f 100644
--- a/chromeos/services/network_config/public/cpp/cros_network_config_util.h
+++ b/chromeos/services/network_config/public/cpp/cros_network_config_util.h
@@ -29,6 +29,12 @@
 // but kNotInhibited.
 bool IsInhibited(const mojom::DeviceStateProperties* device);
 
+// Returns an ONC dictionary for network with guid |network_guid| containing a
+// configuration of the network's user APN list. Takes ownership of
+// |user_apn_list|.
+base::Value::Dict UserApnListToOnc(const std::string& network_guid,
+                                   base::Value::List user_apn_list);
+
 }  // namespace network_config
 }  // namespace chromeos
 
diff --git a/components/account_manager_core/BUILD.gn b/components/account_manager_core/BUILD.gn
index fa018d1..d3138eb 100644
--- a/components/account_manager_core/BUILD.gn
+++ b/components/account_manager_core/BUILD.gn
@@ -83,6 +83,7 @@
 
   sources = [
     "account_manager_facade_impl_unittest.cc",
+    "account_manager_util_unittest.cc",
     "chromeos/account_manager_mojo_service_unittest.cc",
     "chromeos/account_manager_unittest.cc",
   ]
diff --git a/components/account_manager_core/account_addition_result.h b/components/account_manager_core/account_addition_result.h
index bf0c540..83579c4 100644
--- a/components/account_manager_core/account_addition_result.h
+++ b/components/account_manager_core/account_addition_result.h
@@ -29,7 +29,12 @@
     kUnexpectedResponse = 4,
     // The sign-in was blocked by policy for this user.
     kBlockedByPolicy = 5,
-    kMaxValue = kBlockedByPolicy,
+    // Mojo remote to Account Manager is disconnected.
+    kMojoRemoteDisconnected = 6,
+    // Remote and receiver have incompatible Mojo versions.
+    kIncompatibleMojoVersions = 7,
+
+    kMaxValue = kIncompatibleMojoVersions,
   };
 
   // Creates result with `status` different from `kSuccess` and `kNetworkError`.
diff --git a/components/account_manager_core/account_manager_facade_impl.cc b/components/account_manager_core/account_manager_facade_impl.cc
index 4bf9767..1a4d4b1 100644
--- a/components/account_manager_core/account_manager_facade_impl.cc
+++ b/components/account_manager_core/account_manager_facade_impl.cc
@@ -379,15 +379,23 @@
     AccountAdditionSource source,
     base::OnceCallback<
         void(const account_manager::AccountAdditionResult& result)> callback) {
-  if (!account_manager_remote_ ||
-      remote_version_ < RemoteMinVersions::kShowAddAccountDialogMinVersion) {
+  if (!account_manager_remote_) {
+    LOG(WARNING) << "Account Manager remote disconnected";
+    FinishAddAccount(
+        std::move(callback),
+        AccountAdditionResult::FromStatus(
+            AccountAdditionResult::Status::kMojoRemoteDisconnected));
+    return;
+  }
+
+  if (remote_version_ < RemoteMinVersions::kShowAddAccountDialogMinVersion) {
     LOG(WARNING) << "Found remote at: " << remote_version_ << ", expected: "
                  << RemoteMinVersions::kShowAddAccountDialogMinVersion
                  << " for ShowAddAccountDialog.";
-    FinishAddAccount(std::move(callback),
-                     account_manager::AccountAdditionResult::FromStatus(
-                         account_manager::AccountAdditionResult::Status::
-                             kUnexpectedResponse));
+    FinishAddAccount(
+        std::move(callback),
+        AccountAdditionResult::FromStatus(
+            AccountAdditionResult::Status::kIncompatibleMojoVersions));
     return;
   }
 
@@ -521,9 +529,8 @@
       account_manager::FromMojoAccountAdditionResult(mojo_result);
   if (!result.has_value()) {
     FinishAddAccount(std::move(callback),
-                     account_manager::AccountAdditionResult::FromStatus(
-                         account_manager::AccountAdditionResult::Status::
-                             kUnexpectedResponse));
+                     AccountAdditionResult::FromStatus(
+                         AccountAdditionResult::Status::kUnexpectedResponse));
     return;
   }
   FinishAddAccount(std::move(callback), result.value());
diff --git a/components/account_manager_core/account_manager_facade_impl_unittest.cc b/components/account_manager_core/account_manager_facade_impl_unittest.cc
index 896c2a4..74c9fdc 100644
--- a/components/account_manager_core/account_manager_facade_impl_unittest.cc
+++ b/components/account_manager_core/account_manager_facade_impl_unittest.cc
@@ -8,6 +8,7 @@
 #include <memory>
 
 #include "base/callback_helpers.h"
+#include "base/functional/callback_forward.h"
 #include "base/notreached.h"
 #include "base/run_loop.h"
 #include "base/scoped_observation.h"
@@ -576,6 +577,54 @@
       /*sample=*/result.status(), /*expected_count=*/1);
 }
 
+TEST_F(AccountManagerFacadeImplTest,
+       ShowAddAccountDialogReturnsAnErrorIfMojoRemoteIsDisconnected) {
+  auto account_manager_facade = std::make_unique<AccountManagerFacadeImpl>(
+      mojo::Remote<crosapi::mojom::AccountManager>(),
+      /*remote_version=*/std::numeric_limits<uint32_t>::max(),
+      /*account_manager_for_tests=*/nullptr);
+
+  base::RunLoop run_loop;
+  base::OnceCallback<void(const account_manager::AccountAdditionResult&)>
+      callback = base::BindLambdaForTesting(
+          [&run_loop](
+              const account_manager::AccountAdditionResult& result) -> void {
+            EXPECT_EQ(account_manager::AccountAdditionResult::Status::
+                          kMojoRemoteDisconnected,
+                      result.status());
+            run_loop.Quit();
+          });
+  account_manager_facade->ShowAddAccountDialog(
+      account_manager::AccountManagerFacade::AccountAdditionSource::
+          kSettingsAddAccountButton,
+      std::move(callback));
+  run_loop.Run();
+}
+
+TEST_F(AccountManagerFacadeImplTest,
+       ShowAddAccountDialogReturnsAnErrorIfMojoVersionIsIncompatible) {
+  auto account_manager_facade = std::make_unique<AccountManagerFacadeImpl>(
+      account_manager().CreateRemote(),
+      /*remote_version=*/1,
+      /*account_manager_for_tests=*/nullptr);
+
+  base::RunLoop run_loop;
+  base::OnceCallback<void(const account_manager::AccountAdditionResult&)>
+      callback = base::BindLambdaForTesting(
+          [&run_loop](
+              const account_manager::AccountAdditionResult& result) -> void {
+            EXPECT_EQ(account_manager::AccountAdditionResult::Status::
+                          kIncompatibleMojoVersions,
+                      result.status());
+            run_loop.Quit();
+          });
+  account_manager_facade->ShowAddAccountDialog(
+      account_manager::AccountManagerFacade::AccountAdditionSource::
+          kSettingsAddAccountButton,
+      std::move(callback));
+  run_loop.Run();
+}
+
 TEST_F(AccountManagerFacadeImplTest, ShowReauthAccountDialogCallsMojo) {
   std::unique_ptr<AccountManagerFacadeImpl> account_manager_facade =
       CreateFacade();
diff --git a/components/account_manager_core/account_manager_util.cc b/components/account_manager_core/account_manager_util.cc
index 6634972..2dc58110 100644
--- a/components/account_manager_core/account_manager_util.cc
+++ b/components/account_manager_core/account_manager_util.cc
@@ -4,6 +4,7 @@
 
 #include "components/account_manager_core/account_manager_util.h"
 
+#include "base/notreached.h"
 #include "components/account_manager_core/account.h"
 #include "components/account_manager_core/account_addition_options.h"
 #include "components/account_manager_core/account_addition_result.h"
@@ -134,6 +135,18 @@
       return cm::AccountAdditionResult::Status::kUnexpectedResponse;
     case account_manager::AccountAdditionResult::Status::kBlockedByPolicy:
       return cm::AccountAdditionResult::Status::kBlockedByPolicy;
+    case account_manager::AccountAdditionResult::Status::
+        kMojoRemoteDisconnected:
+    case account_manager::AccountAdditionResult::Status::
+        kIncompatibleMojoVersions:
+      // `kMojoRemoteDisconnected` and `kIncompatibleMojoVersions` are generated
+      // entirely on the remote side when the receiver can't even be reached.
+      // They do not have any Mojo equivalent since they are never passed over
+      // the wire in the first place.
+      NOTREACHED() << "These statuses should not be passed over the wire";
+      // Return something to make the compiler happy. This should never happen
+      // in production.
+      return cm::AccountAdditionResult::Status::kUnexpectedResponse;
   }
 }
 
@@ -297,6 +310,10 @@
     case account_manager::AccountAdditionResult::Status::kAlreadyInProgress:
     case account_manager::AccountAdditionResult::Status::kCancelledByUser:
     case account_manager::AccountAdditionResult::Status::kUnexpectedResponse:
+    case account_manager::AccountAdditionResult::Status::
+        kMojoRemoteDisconnected:
+    case account_manager::AccountAdditionResult::Status::
+        kIncompatibleMojoVersions:
       return account_manager::AccountAdditionResult::FromStatus(status.value());
     case account_manager::AccountAdditionResult::Status::kBlockedByPolicy:
       return account_manager::AccountAdditionResult::FromStatus(status.value());
diff --git a/components/account_manager_core/account_manager_util_unittest.cc b/components/account_manager_core/account_manager_util_unittest.cc
new file mode 100644
index 0000000..e21f925
--- /dev/null
+++ b/components/account_manager_core/account_manager_util_unittest.cc
@@ -0,0 +1,27 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/account_manager_core/account_manager_util.h"
+
+#include "base/test/gtest_util.h"
+#include "components/account_manager_core/account_addition_result.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace account_manager {
+
+TEST(AccountManagerUtilDeathTest,
+     ToMojoAccountAdditionResultDiesForRemoteDisconnectedStatus) {
+  EXPECT_DCHECK_DEATH(
+      ToMojoAccountAdditionResult(AccountAdditionResult::FromStatus(
+          AccountAdditionResult::Status::kMojoRemoteDisconnected)));
+}
+
+TEST(AccountManagerUtilDeathTest,
+     ToMojoAccountAdditionResultDiesForIncompatibleMojoVersionsStatus) {
+  EXPECT_DCHECK_DEATH(
+      ToMojoAccountAdditionResult(AccountAdditionResult::FromStatus(
+          AccountAdditionResult::Status::kIncompatibleMojoVersions)));
+}
+
+}  // namespace account_manager
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index e60abd8..9be166a 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -560,7 +560,6 @@
     "//components/translate/core/common",
     "//components/variations",
     "//components/variations/net",
-    "//components/variations/service:service",
     "//components/version_info",
     "//components/webdata/common",
     "//crypto",
diff --git a/components/autofill/core/browser/address_profile_save_manager.cc b/components/autofill/core/browser/address_profile_save_manager.cc
index 892d730..9c78f09 100644
--- a/components/autofill/core/browser/address_profile_save_manager.cc
+++ b/components/autofill/core/browser/address_profile_save_manager.cc
@@ -65,9 +65,7 @@
   // behavior and directly import the observed profile without recording any
   // additional metrics. However, if only silent updates are allowed, proceed
   // with the profile import process.
-  if ((!base::FeatureList::IsEnabled(
-           features::kAutofillAddressProfileSavePrompt) ||
-       personal_data_manager_->auto_accept_address_imports_for_testing()) &&
+  if (personal_data_manager_->auto_accept_address_imports_for_testing() &&
       !allow_only_silent_updates) {
     personal_data_manager_->SaveImportedProfile(observed_profile);
     AddMultiStepComplementCandidate(client_->GetFormDataImporter(),
diff --git a/components/autofill/core/browser/address_profile_save_manager_unittest.cc b/components/autofill/core/browser/address_profile_save_manager_unittest.cc
index 5b8cff9..0ca31e40 100644
--- a/components/autofill/core/browser/address_profile_save_manager_unittest.cc
+++ b/components/autofill/core/browser/address_profile_save_manager_unittest.cc
@@ -197,10 +197,6 @@
                                                    : PhoneImportStatus::kValid,
                         .did_import_from_unrecognized_autocomplete_field =
                             std::get<3>(GetParam())};
-    // Enable both explicit save prompts and structured names.
-    // The latter is needed to test the concept of silent updates.
-    scoped_feature_list_.InitAndEnableFeature(
-        features::kAutofillAddressProfileSavePrompt);
   }
 
   void BlockProfileForUpdates(const std::string& guid) {
@@ -224,7 +220,6 @@
   base::test::TaskEnvironment task_environment_;
   TestAutofillClient autofill_client_;
   MockPersonalDataManager mock_personal_data_manager_;
-  base::test::ScopedFeatureList scoped_feature_list_;
   ProfileImportMetadata import_metadata_;
 };
 
@@ -1232,21 +1227,6 @@
   TestImportScenario(test_scenario);
 }
 
-TEST_P(AddressProfileSaveManagerTest, SaveProfileWhenNoSavePrompt) {
-  base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitAndDisableFeature(
-      features::kAutofillAddressProfileSavePrompt);
-
-  AddressProfileSaveManager save_manager(&autofill_client_,
-                                         &mock_personal_data_manager_);
-  AutofillProfile test_profile = test::GetFullProfile();
-  EXPECT_CALL(mock_personal_data_manager_, SaveImportedProfile(test_profile));
-  save_manager.ImportProfileFromForm(test_profile, "en_US",
-                                     GURL("https://www.noprompt.com"),
-                                     /*allow_only_silent_updates=*/false,
-                                     /*import_metadata=*/{});
-}
-
 // Tests that a new profile is not imported when only silent updates are
 // allowed.
 TEST_P(AddressProfileSaveManagerTest, SilentlyUpdateProfile_SaveNewProfile) {
diff --git a/components/autofill/core/browser/autofill_profile_save_strike_database.cc b/components/autofill/core/browser/autofill_profile_save_strike_database.cc
index 6c35552..0fc9d14 100644
--- a/components/autofill/core/browser/autofill_profile_save_strike_database.cc
+++ b/components/autofill/core/browser/autofill_profile_save_strike_database.cc
@@ -16,6 +16,12 @@
 // Once the limit of domains is reached, delete 50 to create a bit of headroom.
 constexpr size_t kMaxStrikeEntitiesAfterCleanup = 150;
 
+// The number of days it takes for strikes to expire.
+constexpr int kNumberOfDaysToExpire = 180;
+
+// The strike limit for suppressing save prompts.
+constexpr int kStrikeLimit = 3;
+
 AutofillProfileSaveStrikeDatabase::AutofillProfileSaveStrikeDatabase(
     StrikeDatabaseBase* strike_database)
     : StrikeDatabaseIntegratorBase(strike_database) {
@@ -40,15 +46,12 @@
 }
 
 int AutofillProfileSaveStrikeDatabase::GetMaxStrikesLimit() const {
-  // The default limit for strikes is 3.
-  return features::kAutofillAutoBlockSaveAddressProfilePromptStrikeLimit.Get();
+  return kStrikeLimit;
 }
 
 absl::optional<base::TimeDelta>
 AutofillProfileSaveStrikeDatabase::GetExpiryTimeDelta() const {
-  // Expiry time is 180 days by default.
-  return base::Days(
-      features::kAutofillAutoBlockSaveAddressProfilePromptExpirationDays.Get());
+  return base::Days(kNumberOfDaysToExpire);
 }
 
 bool AutofillProfileSaveStrikeDatabase::UniqueIdsRequired() const {
diff --git a/components/autofill/core/browser/autofill_profile_update_strike_database.cc b/components/autofill/core/browser/autofill_profile_update_strike_database.cc
index 4704156b..d6ea21f 100644
--- a/components/autofill/core/browser/autofill_profile_update_strike_database.cc
+++ b/components/autofill/core/browser/autofill_profile_update_strike_database.cc
@@ -15,6 +15,12 @@
 // Once the limit of profiles is reached, delete 30 to create a bit of headroom.
 constexpr size_t kMaxStrikeEntitiesAfterCleanup = 70;
 
+// The number of days it takes for strikes to expire.
+constexpr int kNumberOfDaysToExpire = 180;
+
+// The strike limit for suppressing update prompts.
+constexpr int kStrikeLimit = 3;
+
 AutofillProfileUpdateStrikeDatabase::AutofillProfileUpdateStrikeDatabase(
     StrikeDatabaseBase* strike_database)
     : StrikeDatabaseIntegratorBase(strike_database) {
@@ -39,17 +45,12 @@
 }
 
 int AutofillProfileUpdateStrikeDatabase::GetMaxStrikesLimit() const {
-  // The default limit for strikes is 3.
-  return features::kAutofillAutoBlockUpdateAddressProfilePromptStrikeLimit
-      .Get();
+  return kStrikeLimit;
 }
 
 absl::optional<base::TimeDelta>
 AutofillProfileUpdateStrikeDatabase::GetExpiryTimeDelta() const {
-  // Expiry time is 180 days by default.
-  return base::Days(
-      features::kAutofillAutoBlockUpdateAddressProfilePromptExpirationDays
-          .Get());
+  return base::Days(kNumberOfDaysToExpire);
 }
 
 bool AutofillProfileUpdateStrikeDatabase::UniqueIdsRequired() const {
diff --git a/components/autofill/core/browser/data_model/autofill_profile.cc b/components/autofill/core/browser/data_model/autofill_profile.cc
index 4171159..b2700f6e 100644
--- a/components/autofill/core/browser/data_model/autofill_profile.cc
+++ b/components/autofill/core/browser/data_model/autofill_profile.cc
@@ -619,12 +619,6 @@
 
 bool AutofillProfile::MergeDataFrom(const AutofillProfile& profile,
                                     const std::string& app_locale) {
-  // Verified profiles should never be overwritten with unverified data.
-  // This is not true anymore when explicit save prompts are used.
-  DCHECK(!IsVerified() || profile.IsVerified() ||
-         base::FeatureList::IsEnabled(
-             features::kAutofillAddressProfileSavePrompt));
-
   AutofillProfileComparator comparator(app_locale);
   DCHECK(comparator.AreMergeable(*this, profile));
 
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc
index 634a0c0..b6829bd 100644
--- a/components/autofill/core/browser/form_data_importer.cc
+++ b/components/autofill/core/browser/form_data_importer.cc
@@ -43,8 +43,6 @@
 #include "components/autofill/core/common/autofill_internals/logging_scope.h"
 #include "components/autofill/core/common/autofill_payments_features.h"
 #include "components/autofill/core/common/autofill_util.h"
-#include "components/variations/service/variations_field_trial_creator.h"
-#include "components/variations/service/variations_service.h"
 
 namespace autofill {
 
@@ -219,9 +217,7 @@
 bool FormDataImporter::ComplementCountry(
     AutofillProfile& profile,
     const std::string& predicted_country_code) {
-  bool should_complement_country =
-      !profile.HasRawInfo(ADDRESS_HOME_COUNTRY) &&
-      base::FeatureList::IsEnabled(features::kAutofillAddressProfileSavePrompt);
+  bool should_complement_country = !profile.HasRawInfo(ADDRESS_HOME_COUNTRY);
   return should_complement_country &&
          profile.SetInfoWithVerificationStatus(
              AutofillType(ADDRESS_HOME_COUNTRY),
@@ -690,8 +686,7 @@
   // At this point, no credit card prompt was shown. Initiate the import of
   // addresses is possible.
   int imported_profiles = 0;
-  if (allow_prompt || !base::FeatureList::IsEnabled(
-                          features::kAutofillAddressProfileSavePrompt)) {
+  if (allow_prompt) {
     for (const auto& candidate : address_profile_import_candidates) {
       // First try to import a single complete profile.
       if (!candidate.all_requirements_fulfilled)
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index 08ffbbd..3c5cd19 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -611,12 +611,6 @@
                              const FormStructure& form,
                              bool skip_waiting_on_pdm = false,
                              bool allow_save_prompts = true) {
-    // This parameter has no effect unless save prompts for addresses are
-    // enabled.
-    allow_save_prompts =
-        allow_save_prompts || !base::FeatureList::IsEnabled(
-                                  features::kAutofillAddressProfileSavePrompt);
-
     std::vector<FormDataImporter::AddressProfileImportCandidate>
         address_profile_import_candidates;
 
@@ -1175,26 +1169,12 @@
 // Test that the storage is prevented if the structured address prompt feature
 // is enabled, but address prompts are not allowed.
 TEST_P(FormDataImporterTest, ImportAddressProfiles_DontAllowPrompt) {
-  base::test::ScopedFeatureList save_prompt_feature;
-  save_prompt_feature.InitAndEnableFeature(
-      features::kAutofillAddressProfileSavePrompt);
-
   std::unique_ptr<FormStructure> form_structure =
       ConstructDefaultProfileFormStructure();
   ImportAddressProfiles(/*extraction_successful=*/true, *form_structure,
                         /*skip_waiting_on_pdm=*/true,
                         /*allow_save_prompts=*/false);
   VerifyExpectationForImportedAddressProfiles({});
-
-  save_prompt_feature.Reset();
-  save_prompt_feature.InitAndDisableFeature(
-      features::kAutofillAddressProfileSavePrompt);
-
-  // Verify that the behavior changes when prompts are disabled.
-  ImportAddressProfiles(/*extraction_successful=*/true, *form_structure,
-                        /*skip_waiting_on_pdm=*/false,
-                        /*allow_save_prompts=*/false);
-  VerifyExpectationForImportedAddressProfiles({ConstructDefaultProfile()});
 }
 
 TEST_P(FormDataImporterTest, ImportAddressProfileFromUnifiedSection) {
@@ -4157,10 +4137,8 @@
     FormDataImporterTest,
     SilentlyUpdateExistingProfileByIncompleteProfile_DespiteDisallowedPrompts) {
   base::test::ScopedFeatureList scoped_feature_list;
-  scoped_feature_list.InitWithFeatures(
-      {features::kAutofillSilentProfileUpdateForInsufficientImport,
-       features::kAutofillAddressProfileSavePrompt},
-      {});
+  scoped_feature_list.InitAndEnableFeature(
+      features::kAutofillSilentProfileUpdateForInsufficientImport);
 
   AutofillProfile profile(base::GenerateGUID(), test::kEmptyOrigin);
   test::SetProfileInfo(&profile, "Marion", "Mitchell", "Morrison",
diff --git a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h b/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h
index bcb380c..3455a52 100644
--- a/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h
+++ b/components/autofill/core/browser/payments/payments_requests/migrate_cards_request.h
@@ -48,7 +48,7 @@
                            const std::string& pan_field_name);
 
   const PaymentsClient::MigrationRequestDetails request_details_;
-  const raw_ref<const std::vector<MigratableCreditCard>>
+  const raw_ref<const std::vector<MigratableCreditCard>, DanglingUntriaged>
       migratable_credit_cards_;
   const bool full_sync_enabled_;
   MigrateCardsCallback callback_;
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 72fe9ec..6503de3 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1631,8 +1631,7 @@
 
 bool PersonalDataManager::IsNewProfileImportBlockedForDomain(
     const GURL& url) const {
-  if (!GetProfileSaveStrikeDatabase() || !url.is_valid() || !url.has_host() ||
-      !features::kAutofillAutoBlockSaveAddressProfilePrompt.Get()) {
+  if (!GetProfileSaveStrikeDatabase() || !url.is_valid() || !url.has_host()) {
     return false;
   }
 
@@ -1641,8 +1640,7 @@
 
 void PersonalDataManager::AddStrikeToBlockNewProfileImportForDomain(
     const GURL& url) {
-  if (!GetProfileSaveStrikeDatabase() || !url.is_valid() || !url.has_host() ||
-      !features::kAutofillAutoBlockSaveAddressProfilePrompt.Get()) {
+  if (!GetProfileSaveStrikeDatabase() || !url.is_valid() || !url.has_host()) {
     return;
   }
   GetProfileSaveStrikeDatabase()->AddStrike(url.host());
@@ -1658,8 +1656,7 @@
 
 bool PersonalDataManager::IsProfileUpdateBlocked(
     const std::string& guid) const {
-  if (!GetProfileUpdateStrikeDatabase() ||
-      !features::kAutofillAutoBlockUpdateAddressProfilePrompt.Get()) {
+  if (!GetProfileUpdateStrikeDatabase()) {
     return false;
   }
 
@@ -1668,10 +1665,9 @@
 
 void PersonalDataManager::AddStrikeToBlockProfileUpdate(
     const std::string& guid) {
-  if (!GetProfileUpdateStrikeDatabase() ||
-      !features::kAutofillAutoBlockUpdateAddressProfilePrompt.Get()) {
+  if (!GetProfileUpdateStrikeDatabase())
     return;
-  }
+
   GetProfileUpdateStrikeDatabase()->AddStrike(guid);
 }
 
diff --git a/components/autofill/core/browser/personal_data_manager_test_base.cc b/components/autofill/core/browser/personal_data_manager_test_base.cc
index 1aebcbb2..d930a52c 100644
--- a/components/autofill/core/browser/personal_data_manager_test_base.cc
+++ b/components/autofill/core/browser/personal_data_manager_test_base.cc
@@ -111,7 +111,8 @@
                                            : signin::ConsentLevel::kSync;
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
   identity_test_env_.ClearPrimaryAccount();
-  account_info = identity_test_env_.SetPrimaryAccount(email, consent_level);
+  account_info =
+      identity_test_env_.MakePrimaryAccountAvailable(email, consent_level);
 #else
   // In ChromeOS-Ash, clearing/resetting the primary account is not supported.
   // So if an account already exists, reuse it (and make sure it matches).
@@ -120,7 +121,8 @@
         consent_level);
     ASSERT_EQ(account_info.email, email);
   } else {
-    account_info = identity_test_env_.SetPrimaryAccount(email, consent_level);
+    account_info =
+        identity_test_env_.MakePrimaryAccountAvailable(email, consent_level);
   }
 #endif
   sync_service_.SetAccountInfo(account_info);
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 8bc85db4..dc598b7b 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -1370,8 +1370,8 @@
   EXPECT_EQ(1U, personal_data_->GetCreditCards().size());
 
   // Sign in.
-  identity_test_env_.SetPrimaryAccount("test@gmail.com",
-                                       signin::ConsentLevel::kSync);
+  identity_test_env_.MakePrimaryAccountAvailable("test@gmail.com",
+                                                 signin::ConsentLevel::kSync);
   sync_service_.SetHasSyncConsent(true);
   sync_service_.GetUserSettings()->SetSelectedTypes(
       /*sync_everything=*/false,
@@ -5810,8 +5810,8 @@
   ///////////////////////////////////////////////////////////
   // kSignedInAndSyncFeature
   ///////////////////////////////////////////////////////////
-  identity_test_env_.SetPrimaryAccount(active_info.email,
-                                       signin::ConsentLevel::kSync);
+  identity_test_env_.MakePrimaryAccountAvailable(active_info.email,
+                                                 signin::ConsentLevel::kSync);
   sync_service_.SetHasSyncConsent(true);
   {
     EXPECT_EQ(AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled,
diff --git a/components/autofill/core/common/autofill_features.cc b/components/autofill/core/common/autofill_features.cc
index 8c011ed..46c2f4b 100644
--- a/components/autofill/core/common/autofill_features.cc
+++ b/components/autofill/core/common/autofill_features.cc
@@ -15,47 +15,6 @@
              "AutofillAcrossIframes",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-// TODO(crbug.com/1135188): Remove this feature flag after the explicit save
-// prompts for address profiles is complete.
-// When enabled, a save prompt will be shown to user upon form submission before
-// storing any detected address profile.
-BASE_FEATURE(kAutofillAddressProfileSavePrompt,
-             "AutofillAddressProfileSavePrompt",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
-// This parameter controls if save profile prompts are automatically blocked for
-// a given domain after N (default is 3) subsequent declines.
-const base::FeatureParam<bool> kAutofillAutoBlockSaveAddressProfilePrompt{
-    &kAutofillAddressProfileSavePrompt, "save_profile_prompt_auto_block", true};
-// The auto blocking feature is based on a strike model. This parameter defines
-// the months before such strikes expire.
-const base::FeatureParam<int>
-    kAutofillAutoBlockSaveAddressProfilePromptExpirationDays{
-        &kAutofillAddressProfileSavePrompt,
-        "save_profile_prompt_auto_block_strike_expiration_days", 180};
-// The number of strikes before the prompt gets blocked.
-const base::FeatureParam<int>
-    kAutofillAutoBlockSaveAddressProfilePromptStrikeLimit{
-        &kAutofillAddressProfileSavePrompt,
-        "save_profile_prompt_auto_block_strike_limit", 3};
-
-// Same as above but for update bubbles.
-const base::FeatureParam<bool> kAutofillAutoBlockUpdateAddressProfilePrompt{
-    &kAutofillAddressProfileSavePrompt, "update_profile_prompt_auto_block",
-    true};
-// Same as above but for update bubbles.
-const base::FeatureParam<int>
-    kAutofillAutoBlockUpdateAddressProfilePromptExpirationDays{
-        &kAutofillAddressProfileSavePrompt,
-        "update_profile_prompt_auto_block_strike_expiration_days", 180};
-// Same as above but for update bubbles.
-const base::FeatureParam<int>
-    kAutofillAutoBlockUpdateAddressProfilePromptStrikeLimit{
-        &kAutofillAddressProfileSavePrompt,
-        "update_profile_prompt_auto_block_strike_limit", 3};
-
-// TODO(crbug.com/1135188): Remove this feature flag after the explicit save
-// prompts for address profiles is complete.
 // When enabled, address data will be verified and autocorrected in the
 // save/update prompt before saving an address profile. Relevant only if the
 // AutofillAddressProfileSavePrompt feature is enabled.
diff --git a/components/autofill/core/common/autofill_features.h b/components/autofill/core/common/autofill_features.h
index f08d337b3..384cb26 100644
--- a/components/autofill/core/common/autofill_features.h
+++ b/components/autofill/core/common/autofill_features.h
@@ -16,26 +16,6 @@
 // All features in alphabetical order.
 COMPONENT_EXPORT(AUTOFILL) BASE_DECLARE_FEATURE(kAutofillAcrossIframes);
 COMPONENT_EXPORT(AUTOFILL)
-BASE_DECLARE_FEATURE(kAutofillAddressProfileSavePrompt);
-COMPONENT_EXPORT(AUTOFILL)
-extern const base::FeatureParam<bool>
-    kAutofillAutoBlockSaveAddressProfilePrompt;
-COMPONENT_EXPORT(AUTOFILL)
-extern const base::FeatureParam<int>
-    kAutofillAutoBlockSaveAddressProfilePromptExpirationDays;
-COMPONENT_EXPORT(AUTOFILL)
-extern const base::FeatureParam<int>
-    kAutofillAutoBlockSaveAddressProfilePromptStrikeLimit;
-COMPONENT_EXPORT(AUTOFILL)
-extern const base::FeatureParam<bool>
-    kAutofillAutoBlockUpdateAddressProfilePrompt;
-COMPONENT_EXPORT(AUTOFILL)
-extern const base::FeatureParam<int>
-    kAutofillAutoBlockUpdateAddressProfilePromptExpirationDays;
-COMPONENT_EXPORT(AUTOFILL)
-extern const base::FeatureParam<int>
-    kAutofillAutoBlockUpdateAddressProfilePromptStrikeLimit;
-COMPONENT_EXPORT(AUTOFILL)
 BASE_DECLARE_FEATURE(
     kAutofillAddressProfileSavePromptAddressVerificationSupport);
 COMPONENT_EXPORT(AUTOFILL)
diff --git a/components/autofill_assistant/browser/wait_for_document_operation.h b/components/autofill_assistant/browser/wait_for_document_operation.h
index 545b624..98c083c 100644
--- a/components/autofill_assistant/browser/wait_for_document_operation.h
+++ b/components/autofill_assistant/browser/wait_for_document_operation.h
@@ -47,7 +47,8 @@
   raw_ptr<ScriptExecutorDelegate> script_executor_delegate_;
   base::TimeDelta max_wait_time_;
   DocumentReadyState min_ready_state_;
-  const raw_ref<const ElementFinderResult> optional_frame_element_;
+  const raw_ref<const ElementFinderResult, DanglingUntriaged>
+      optional_frame_element_;
   Callback callback_;
   base::OneShotTimer timer_;
 
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
index 042514e9..2b34ce3 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/ContentSettingsResources.java
@@ -88,7 +88,7 @@
     /**
      * Returns the ResourceItem for a ContentSettingsType.
      * @param delegate A site settings delegate to check feature states. Only needs to be passed
-     *                 to access Cookie icon or title.
+     *                 to access Cookie icon, title or summary.
      */
     private static ResourceItem getResourceItem(int contentType, SiteSettingsDelegate delegate) {
         switch (contentType) {
@@ -147,17 +147,22 @@
                         R.string.website_settings_category_clipboard_blocked);
 
             case ContentSettingsType.COOKIES:
-                return new ResourceItem(delegate == null
-                                ? 0
-                                : (delegate.isPrivacySandboxSettings4Enabled()
-                                                ? R.drawable.gm_database_24
-                                                : R.drawable.permission_cookie),
-                        delegate == null ? 0
-                                         : (delegate.isPrivacySandboxSettings4Enabled()
-                                                         ? R.string.site_data_page_title
-                                                         : R.string.cookies_title),
+                if (delegate == null) {
+                    return new ResourceItem(
+                            0, 0, ContentSettingValues.ALLOW, ContentSettingValues.BLOCK, 0, 0);
+                }
+                return new ResourceItem(delegate.isPrivacySandboxSettings4Enabled()
+                                ? R.drawable.gm_database_24
+                                : R.drawable.permission_cookie,
+                        delegate.isPrivacySandboxSettings4Enabled() ? R.string.site_data_page_title
+                                                                    : R.string.cookies_title,
                         ContentSettingValues.ALLOW, ContentSettingValues.BLOCK,
-                        R.string.website_settings_category_cookie_allowed, 0);
+                        delegate.isPrivacySandboxSettings4Enabled()
+                                ? R.string.website_settings_category_site_data_page_allow_radio_label
+                                : R.string.website_settings_category_cookie_allowed,
+                        delegate.isPrivacySandboxSettings4Enabled()
+                                ? R.string.website_settings_category_site_data_page_block_radio_label
+                                : 0);
 
             case ContentSettingsType.REQUEST_DESKTOP_SITE:
                 return new ResourceItem(R.drawable.ic_desktop_windows, R.string.desktop_site_title,
@@ -466,15 +471,15 @@
     /**
      * Returns the summary (resource id) to show when the content type is enabled.
      */
-    public static int getEnabledSummary(int contentType) {
-        return getResourceItem(contentType, null).getEnabledSummary();
+    public static int getEnabledSummary(int contentType, SiteSettingsDelegate delegate) {
+        return getResourceItem(contentType, delegate).getEnabledSummary();
     }
 
     /**
      * Returns the summary (resource id) to show when the content type is disabled.
      */
-    public static int getDisabledSummary(int contentType) {
-        return getResourceItem(contentType, null).getDisabledSummary();
+    public static int getDisabledSummary(int contentType, SiteSettingsDelegate delegate) {
+        return getResourceItem(contentType, delegate).getDisabledSummary();
     }
 
     /**
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
index 0269c19..8ded397e 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/SingleCategorySettings.java
@@ -352,8 +352,8 @@
         int contentType = mCategory.getContentSettingsType();
         mRequiresTriStateSetting =
                 WebsitePreferenceBridge.requiresTriStateContentSetting(contentType);
-        mRequiresFourStateSetting =
-                WebsitePreferenceBridge.requiresFourStateContentSetting(contentType);
+        mRequiresFourStateSetting = WebsitePreferenceBridge.requiresFourStateContentSetting(
+                contentType, getSiteSettingsDelegate());
 
         ViewGroup view = (ViewGroup) super.onCreateView(inflater, container, savedInstanceState);
 
@@ -626,6 +626,11 @@
                         ? R.string.website_settings_add_site_description_cookies_block
                         : R.string.website_settings_add_site_description_cookies_allow;
             }
+        } else if (mCategory.getType() == SiteSettingsCategory.Type.SITE_DATA) {
+            resource = WebsitePreferenceBridge.isCategoryEnabled(
+                               browserContextHandle, ContentSettingsType.COOKIES)
+                    ? R.string.website_settings_add_site_description_site_data_block
+                    : R.string.website_settings_add_site_description_site_data_allow;
         } else if (mCategory.getType() == SiteSettingsCategory.Type.AUTO_DARK_WEB_CONTENT) {
             assert WebsitePreferenceBridge.isCategoryEnabled(
                     browserContextHandle, ContentSettingsType.AUTO_DARK_WEB_CONTENT);
@@ -723,27 +728,29 @@
 
         BrowserContextHandle browserContextHandle =
                 getSiteSettingsDelegate().getBrowserContextHandle();
+        @ContentSettingsType
+        int type = mCategory.getContentSettingsType();
         boolean allowSpecifyingExceptions = false;
-        if (mCategory.getType() == SiteSettingsCategory.Type.SOUND) {
-            allowSpecifyingExceptions = true;
-        } else if (mCategory.getType() == SiteSettingsCategory.Type.JAVASCRIPT) {
-            allowSpecifyingExceptions = true;
-        } else if (mCategory.getType() == SiteSettingsCategory.Type.COOKIES) {
-            allowSpecifyingExceptions = true;
-        } else if (mCategory.getType() == SiteSettingsCategory.Type.BACKGROUND_SYNC
-                && !WebsitePreferenceBridge.isCategoryEnabled(
-                        browserContextHandle, ContentSettingsType.BACKGROUND_SYNC)) {
-            allowSpecifyingExceptions = true;
-        } else if (mCategory.getType() == SiteSettingsCategory.Type.AUTOMATIC_DOWNLOADS
-                && !WebsitePreferenceBridge.isCategoryEnabled(
-                        browserContextHandle, ContentSettingsType.AUTOMATIC_DOWNLOADS)) {
-            allowSpecifyingExceptions = true;
-        } else if (mCategory.getType() == SiteSettingsCategory.Type.FEDERATED_IDENTITY_API) {
-            allowSpecifyingExceptions = true;
-        } else if (mCategory.getType() == SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE
-                && ContentFeatureList.isEnabled(
-                        ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS)) {
-            allowSpecifyingExceptions = true;
+
+        switch (mCategory.getType()) {
+            case SiteSettingsCategory.Type.SOUND:
+            case SiteSettingsCategory.Type.JAVASCRIPT:
+            case SiteSettingsCategory.Type.COOKIES:
+            case SiteSettingsCategory.Type.SITE_DATA:
+            case SiteSettingsCategory.Type.FEDERATED_IDENTITY_API:
+                allowSpecifyingExceptions = true;
+                break;
+            case SiteSettingsCategory.Type.BACKGROUND_SYNC:
+            case SiteSettingsCategory.Type.AUTOMATIC_DOWNLOADS:
+                allowSpecifyingExceptions =
+                        !WebsitePreferenceBridge.isCategoryEnabled(browserContextHandle, type);
+                break;
+            case SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE:
+                allowSpecifyingExceptions = ContentFeatureList.isEnabled(
+                        ContentFeatureList.REQUEST_DESKTOP_SITE_EXCEPTIONS);
+                break;
+            default:
+                break;
         }
         if (allowSpecifyingExceptions) {
             getPreferenceScreen().addPreference(new AddExceptionPreference(getStyledContext(),
@@ -1118,9 +1125,11 @@
                 && WebsitePreferenceBridge.isLocationAllowedByPolicy(browserContextHandle)) {
             binaryToggle.setSummaryOn(ContentSettingsResources.getGeolocationAllowedSummary());
         } else {
-            binaryToggle.setSummaryOn(ContentSettingsResources.getEnabledSummary(contentType));
+            binaryToggle.setSummaryOn(ContentSettingsResources.getEnabledSummary(
+                    contentType, getSiteSettingsDelegate()));
         }
-        binaryToggle.setSummaryOff(ContentSettingsResources.getDisabledSummary(contentType));
+        binaryToggle.setSummaryOff(ContentSettingsResources.getDisabledSummary(
+                contentType, getSiteSettingsDelegate()));
 
         binaryToggle.setManagedPreferenceDelegate(new SingleCategoryManagedPreferenceDelegate(
                 getSiteSettingsDelegate().getManagedPreferenceDelegate()));
diff --git a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
index 8be35c09..0f89b34 100644
--- a/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
+++ b/components/browser_ui/site_settings/android/java/src/org/chromium/components/browser_ui/site_settings/WebsitePreferenceBridge.java
@@ -253,7 +253,8 @@
      * (Allow/BlockThirdPartyIncognito/BlockThirdParty/Block) setting.
      */
     public static boolean requiresFourStateContentSetting(
-            @ContentSettingsType int contentSettingsType) {
+            @ContentSettingsType int contentSettingsType, SiteSettingsDelegate delegate) {
+        if (delegate.isPrivacySandboxSettings4Enabled()) return false;
         return contentSettingsType == ContentSettingsType.COOKIES;
     }
 
diff --git a/components/browser_ui/strings/android/site_settings.grdp b/components/browser_ui/strings/android/site_settings.grdp
index b4c770c4..1a27925 100644
--- a/components/browser_ui/strings/android/site_settings.grdp
+++ b/components/browser_ui/strings/android/site_settings.grdp
@@ -387,11 +387,23 @@
   <message name="IDS_WEBSITE_SETTINGS_CATEGORY_COOKIE_ALLOWED" desc="Summary text explaining that sites are allowed to use cookies and that it is the recommended setting.">
     Allow sites to save and read cookie data (recommended)
   </message>
+  <message name="IDS_WEBSITE_SETTINGS_CATEGORY_SITE_DATA_PAGE_ALLOW_RADIO_LABEL" desc="Summary text explaining that sites are allowed to use cookies." translateable="false">
+    Sites can save data on your device
+  </message>
+  <message name="IDS_WEBSITE_SETTINGS_CATEGORY_SITE_DATA_PAGE_BLOCK_RADIO_LABEL" desc="Summary text explaining that sites are blocked from using cookies and that it is not a recommended setting." translateable="false">
+    Don't allow sites to save data on your device (not recommended)
+  </message>
   <message name="IDS_WEBSITE_SETTINGS_ADD_SITE_DESCRIPTION_COOKIES_ALLOW" desc="The description for the allow Cookies for website dialog.">
     Allow cookies for a specific site.
   </message>
   <message name="IDS_WEBSITE_SETTINGS_ADD_SITE_DESCRIPTION_COOKIES_BLOCK" desc="The description for the block Cookies for website dialog.">
-   Block cookies for a specific site.
+    Block cookies for a specific site.
+  </message>
+  <message name="IDS_WEBSITE_SETTINGS_ADD_SITE_DESCRIPTION_SITE_DATA_ALLOW" desc="The description for the allow site data for website dialog." translateable="false">
+    Allow site data for a specific site.
+  </message>
+  <message name="IDS_WEBSITE_SETTINGS_ADD_SITE_DESCRIPTION_SITE_DATA_BLOCK" desc="The description for the block site data for website dialog." translateable="false">
+    Block site data for a specific site.
   </message>
   <message name="IDS_WEBSITE_SETTINGS_COOKIE_INFO" desc="Text describing cookie and third-party cookie settings.">
     A site you visit can embed content from other sites, for example images, ads, and text. Any of these sites can save cookies and other data to personalize your experience.
diff --git a/components/captive_portal/content/captive_portal_login_detector.h b/components/captive_portal/content/captive_portal_login_detector.h
index 79cc643..cba70e6 100644
--- a/components/captive_portal/content/captive_portal_login_detector.h
+++ b/components/captive_portal/content/captive_portal_login_detector.h
@@ -37,7 +37,7 @@
   void SetIsLoginTab();
 
  private:
-  raw_ptr<CaptivePortalService> captive_portal_service_;
+  raw_ptr<CaptivePortalService, DanglingUntriaged> captive_portal_service_;
 
   // True if this is a login tab.  Set manually, automatically cleared once
   // login is detected.
diff --git a/components/content_settings/core/browser/content_settings_default_provider.cc b/components/content_settings/core/browser/content_settings_default_provider.cc
index 783839c7..41e8cd4 100644
--- a/components/content_settings/core/browser/content_settings_default_provider.cc
+++ b/components/content_settings/core/browser/content_settings_default_provider.cc
@@ -425,6 +425,11 @@
           GetPrefName(ContentSettingsType::BLUETOOTH_GUARD))),
       CONTENT_SETTING_NUM_SETTINGS);
   base::UmaHistogramEnumeration(
+      "ContentSettings.RegularProfile.DefaultBackgroundSyncSetting",
+      IntToContentSetting(prefs_->GetInteger(
+          GetPrefName(ContentSettingsType::BACKGROUND_SYNC))),
+      CONTENT_SETTING_NUM_SETTINGS);
+  base::UmaHistogramEnumeration(
       "ContentSettings.RegularProfile.DefaultAutoplaySetting",
       IntToContentSetting(
           prefs_->GetInteger(GetPrefName(ContentSettingsType::AUTOPLAY))),
diff --git a/components/crash/core/app/breakpad_linux_impl.h b/components/crash/core/app/breakpad_linux_impl.h
index e1ef986..0b6eb7b0 100644
--- a/components/crash/core/app/breakpad_linux_impl.h
+++ b/components/crash/core/app/breakpad_linux_impl.h
@@ -56,7 +56,9 @@
   uint64_t process_start_time;     // Uptime of the crashing process.
   size_t oom_size;                 // Amount of memory requested if OOM.
   uint64_t pid;                    // PID where applicable.
-  raw_ptr<crash_reporter::internal::TransitionalCrashKeyStorage> crash_keys;
+  raw_ptr<crash_reporter::internal::TransitionalCrashKeyStorage,
+          DanglingUntriaged>
+      crash_keys;
 };
 
 extern void HandleCrashDump(const BreakpadInfo& info);
diff --git a/components/endpoint_fetcher/endpoint_fetcher.h b/components/endpoint_fetcher/endpoint_fetcher.h
index 6616c3d8..215c6049 100644
--- a/components/endpoint_fetcher/endpoint_fetcher.h
+++ b/components/endpoint_fetcher/endpoint_fetcher.h
@@ -163,7 +163,7 @@
 
   // Members set in constructor
   const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
-  const raw_ptr<signin::IdentityManager> identity_manager_;
+  const raw_ptr<signin::IdentityManager, DanglingUntriaged> identity_manager_;
   bool sanitize_response_;
   bool is_stable_channel_;
 
diff --git a/components/feed/core/v2/launch_reliability_logger.h b/components/feed/core/v2/launch_reliability_logger.h
index f2baf0f..89c81e4 100644
--- a/components/feed/core/v2/launch_reliability_logger.h
+++ b/components/feed/core/v2/launch_reliability_logger.h
@@ -58,7 +58,7 @@
       feedwire::DiscoverLaunchResult result);
 
  private:
-  raw_ptr<StreamSurfaceSet> surfaces_;
+  raw_ptr<StreamSurfaceSet, DanglingUntriaged> surfaces_;
   NetworkRequestId::Generator request_id_gen_;
 };
 
diff --git a/components/feed/core/v2/stream/info_card_tracker.h b/components/feed/core/v2/stream/info_card_tracker.h
index d0de816b..7d5bc959 100644
--- a/components/feed/core/v2/stream/info_card_tracker.h
+++ b/components/feed/core/v2/stream/info_card_tracker.h
@@ -56,7 +56,7 @@
   void SetState(int info_card_type,
                 const feedwire::InfoCardTrackingState& state);
 
-  raw_ptr<PrefService> profile_prefs_;
+  raw_ptr<PrefService, DanglingUntriaged> profile_prefs_;
 };
 
 }  // namespace feed
diff --git a/components/fuchsia_component_support/BUILD.gn b/components/fuchsia_component_support/BUILD.gn
index c41b8ee..928ac9f 100644
--- a/components/fuchsia_component_support/BUILD.gn
+++ b/components/fuchsia_component_support/BUILD.gn
@@ -11,6 +11,7 @@
   # Only for use by Fuchsia Components.
   visibility += [
     ":unit_tests",
+    "//chrome/browser",
     "//chromecast/internal/*",
     "//fuchsia_web/runners/*",
     "//fuchsia_web/webengine/*",
diff --git a/components/js_injection/browser/js_to_browser_messaging.cc b/components/js_injection/browser/js_to_browser_messaging.cc
index 4f21a0d..f8abe03 100644
--- a/components/js_injection/browser/js_to_browser_messaging.cc
+++ b/components/js_injection/browser/js_to_browser_messaging.cc
@@ -112,8 +112,7 @@
 
   if (!host_) {
     const std::string origin_string = GetOriginString(source_origin);
-    const bool is_main_frame =
-        web_contents->GetPrimaryMainFrame() == render_frame_host_;
+    const bool is_main_frame = render_frame_host_->IsInPrimaryMainFrame();
 
     host_ = connection_factory_->CreateHost(origin_string, is_main_frame,
                                             reply_proxy_.get());
@@ -128,8 +127,7 @@
   // PostMessage() has been received.
 #if DCHECK_IS_ON()
   DCHECK_EQ(GetOriginString(source_origin), origin_string_);
-  DCHECK_EQ(is_main_frame_,
-            web_contents->GetPrimaryMainFrame() == render_frame_host_);
+  DCHECK_EQ(is_main_frame_, render_frame_host_->IsInPrimaryMainFrame());
 #endif
   std::unique_ptr<WebMessage> web_message = std::make_unique<WebMessage>();
   web_message->message = std::move(message);
diff --git a/components/mirroring/service/openscreen_session_host.cc b/components/mirroring/service/openscreen_session_host.cc
index a9f55e0..aee47b96 100644
--- a/components/mirroring/service/openscreen_session_host.cc
+++ b/components/mirroring/service/openscreen_session_host.cc
@@ -467,10 +467,14 @@
     media_remoter_->OnMirroringResumed();
   }
 
-  session_->RequestCapabilities();
+  if (initially_starting_session) {
+    // We should only request capabilities once, in order to avoid instantiating
+    // the media remoter multiple times.
+    session_->RequestCapabilities();
 
-  if (initially_starting_session && observer_) {
-    observer_->DidStart();
+    if (observer_) {
+      observer_->DidStart();
+    }
   }
 
   LogInfoMessage(base::StringPrintf(
@@ -494,6 +498,12 @@
     const openscreen::cast::SenderSession* session,
     openscreen::cast::RemotingCapabilities capabilities) {
   DCHECK_EQ(session_.get(), session);
+
+  // This method should only be called once, in order to avoid issues with
+  // multiple media remoters getting instantiated and attempting to fulfill the
+  // mojom interface. Generally speaking, receivers do not update their remoting
+  // capabilities during a single session.
+  DCHECK(!media_remoter_);
   if (state_ == State::kStopped)
     return;
 
diff --git a/components/omnibox/browser/in_memory_url_index.h b/components/omnibox/browser/in_memory_url_index.h
index 75c4e4b..29526d0 100644
--- a/components/omnibox/browser/in_memory_url_index.h
+++ b/components/omnibox/browser/in_memory_url_index.h
@@ -136,7 +136,8 @@
     void DoneRunOnMainThread() override;
 
    private:
-    raw_ptr<InMemoryURLIndex> index_;  // Call back to this index at completion.
+    raw_ptr<InMemoryURLIndex, DanglingUntriaged>
+        index_;                   // Call back to this index at completion.
     SchemeSet scheme_allowlist_;  // Schemes to be indexed.
     bool succeeded_;  // Indicates if the rebuild was successful.
     scoped_refptr<URLIndexPrivateData> data_;  // The rebuilt private data.
diff --git a/components/openscreen_platform/trace_logging_platform.cc b/components/openscreen_platform/trace_logging_platform.cc
index 9afda54d..f1f6d0d 100644
--- a/components/openscreen_platform/trace_logging_platform.cc
+++ b/components/openscreen_platform/trace_logging_platform.cc
@@ -6,7 +6,7 @@
 
 namespace openscreen {
 
-bool IsTraceLoggingEnabled(TraceCategory::Value category) {
+bool IsTraceLoggingEnabled(TraceCategory category) {
   return false;
 }
 
diff --git a/components/optimization_guide/content/browser/page_content_annotations_model_manager.cc b/components/optimization_guide/content/browser/page_content_annotations_model_manager.cc
index a6ddef2..e854ee87 100644
--- a/components/optimization_guide/content/browser/page_content_annotations_model_manager.cc
+++ b/components/optimization_guide/content/browser/page_content_annotations_model_manager.cc
@@ -111,14 +111,13 @@
   if (!features::PageVisibilityBatchAnnotationsEnabled())
     return;
 
-  if (page_visibility_model_executor_)
+  if (page_visibility_model_handler_)
     return;
 
-  page_visibility_model_executor_ =
-      std::make_unique<PageVisibilityModelExecutor>(
-          optimization_guide_model_provider,
-          base::ThreadPool::CreateSequencedTaskRunner(GetTaskTraits()),
-          absl::nullopt);
+  page_visibility_model_handler_ = std::make_unique<PageVisibilityModelHandler>(
+      optimization_guide_model_provider,
+      base::ThreadPool::CreateSequencedTaskRunner(GetTaskTraits()),
+      absl::nullopt);
 }
 
 void PageContentAnnotationsModelManager::GetMetadataForEntityId(
@@ -151,8 +150,8 @@
     // No-op if the executor is already setup.
     SetUpPageVisibilityModel(optimization_guide_model_provider_);
 
-    if (page_visibility_model_executor_) {
-      page_visibility_model_executor_->AddOnModelUpdatedCallback(
+    if (page_visibility_model_handler_) {
+      page_visibility_model_handler_->AddOnModelUpdatedCallback(
           base::BindOnce(std::move(callback), true));
       return;
     }
@@ -179,8 +178,8 @@
     return page_topics_model_executor_->GetModelInfo();
   }
   if (type == AnnotationType::kContentVisibility &&
-      page_visibility_model_executor_) {
-    return page_visibility_model_executor_->GetModelInfo();
+      page_visibility_model_handler_) {
+    return page_visibility_model_handler_->GetModelInfo();
   }
   if (type == AnnotationType::kPageEntities && page_entities_model_executor_) {
     return page_entities_model_executor_->GetModelInfo();
@@ -223,8 +222,8 @@
     if (page_topics_model_executor_) {
       page_topics_model_executor_->UnloadModel();
     }
-    if (page_visibility_model_executor_) {
-      page_visibility_model_executor_->UnloadModel();
+    if (page_visibility_model_handler_) {
+      page_visibility_model_handler_->UnloadModel();
     }
     return;
   }
@@ -246,8 +245,8 @@
     page_topics_model_executor_->UnloadModel();
   }
   if (job->type() != AnnotationType::kContentVisibility &&
-      page_visibility_model_executor_) {
-    page_visibility_model_executor_->UnloadModel();
+      page_visibility_model_handler_) {
+    page_visibility_model_handler_->UnloadModel();
   }
 
   if (job->type() == AnnotationType::kPageTopics) {
@@ -264,14 +263,14 @@
   }
 
   if (job->type() == AnnotationType::kContentVisibility) {
-    if (!page_visibility_model_executor_) {
+    if (!page_visibility_model_handler_) {
       job->FillWithNullOutputs();
       job->OnComplete();
       job.reset();
       std::move(on_job_complete_callback).Run();
       return;
     }
-    page_visibility_model_executor_->ExecuteJob(
+    page_visibility_model_handler_->ExecuteJob(
         std::move(on_job_complete_callback), std::move(job));
     return;
   }
diff --git a/components/optimization_guide/content/browser/page_content_annotations_model_manager.h b/components/optimization_guide/content/browser/page_content_annotations_model_manager.h
index c8e8b8d..0bd5f65 100644
--- a/components/optimization_guide/content/browser/page_content_annotations_model_manager.h
+++ b/components/optimization_guide/content/browser/page_content_annotations_model_manager.h
@@ -12,7 +12,7 @@
 #include "components/optimization_guide/core/page_content_annotation_job.h"
 #include "components/optimization_guide/core/page_content_annotations_common.h"
 #include "components/optimization_guide/core/page_topics_model_executor.h"
-#include "components/optimization_guide/core/page_visibility_model_executor.h"
+#include "components/optimization_guide/core/page_visibility_model_handler.h"
 #include "net/base/priority_queue.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 
@@ -116,8 +116,8 @@
   // model.
   std::unique_ptr<PageTopicsModelExecutor> page_topics_model_executor_;
 
-  // The model executor responsible for executing the page visibility model.
-  std::unique_ptr<PageVisibilityModelExecutor> page_visibility_model_executor_;
+  // The model handler for the page visibility model.
+  std::unique_ptr<PageVisibilityModelHandler> page_visibility_model_handler_;
 
   // The model executor responsible for executing the page entities model.
   //
diff --git a/components/optimization_guide/content/browser/page_content_annotations_model_manager_unittest.cc b/components/optimization_guide/content/browser/page_content_annotations_model_manager_unittest.cc
index 2b034a9..1b00336 100644
--- a/components/optimization_guide/content/browser/page_content_annotations_model_manager_unittest.cc
+++ b/components/optimization_guide/content/browser/page_content_annotations_model_manager_unittest.cc
@@ -167,7 +167,7 @@
         AnnotationType::kContentVisibility, base::DoNothing());
     // If the feature flag is disabled, the executor won't have been created so
     // skip everything else.
-    if (!model_manager()->page_visibility_model_executor_)
+    if (!model_manager()->page_visibility_model_handler_)
       return;
 
     base::FilePath source_root_dir;
@@ -182,7 +182,7 @@
             .SetModelFilePath(model_file_path)
             .SetModelMetadata(model_metadata)
             .Build();
-    model_manager()->page_visibility_model_executor_->OnModelUpdated(
+    model_manager()->page_visibility_model_handler_->OnModelUpdated(
         proto::OPTIMIZATION_TARGET_PAGE_VISIBILITY, *model_info);
     RunUntilIdle();
   }
diff --git a/components/optimization_guide/core/BUILD.gn b/components/optimization_guide/core/BUILD.gn
index cd6f46f..29444c9b 100644
--- a/components/optimization_guide/core/BUILD.gn
+++ b/components/optimization_guide/core/BUILD.gn
@@ -55,6 +55,8 @@
       "bert_model_executor.cc",
       "bert_model_executor.h",
       "model_execution_timeout_watchdog.h",
+      "page_visibility_model_executor.cc",
+      "page_visibility_model_executor.h",
       "tflite_model_executor.h",
     ]
   }
@@ -75,6 +77,7 @@
   }
   deps = [
     ":features",
+    ":machine_learning",
     "//base",
     "//components/optimization_guide/proto:optimization_guide_proto",
     "//net",
@@ -91,12 +94,15 @@
 if (build_with_tflite_lib) {
   static_library("machine_learning") {
     sources = [
+      "page_visibility_op_resolver.cc",
+      "page_visibility_op_resolver.h",
       "tflite_op_resolver.cc",
       "tflite_op_resolver.h",
     ]
     deps = [
       ":features",
       "//components/optimization_guide:machine_learning_tflite_buildflags",
+      "//third_party/tensorflow_models:tflite_custom_ops",
       "//third_party/tflite",
       "//third_party/tflite:tflite_public_headers",
     ]
@@ -203,8 +209,8 @@
       "page_entities_model_executor.h",
       "page_topics_model_executor.cc",
       "page_topics_model_executor.h",
-      "page_visibility_model_executor.cc",
-      "page_visibility_model_executor.h",
+      "page_visibility_model_handler.cc",
+      "page_visibility_model_handler.h",
     ]
     if (build_with_internal_optimization_guide) {
       sources += [
@@ -391,7 +397,7 @@
       "model_validator_unittest.cc",
       "page_content_annotation_job_executor_unittest.cc",
       "page_topics_model_executor_unittest.cc",
-      "page_visibility_model_executor_unittest.cc",
+      "page_visibility_model_handler_unittest.cc",
       "tflite_model_executor_unittest.cc",
     ]
     if (build_with_internal_optimization_guide) {
diff --git a/components/optimization_guide/core/DEPS b/components/optimization_guide/core/DEPS
index b84cfa537..00b93be 100644
--- a/components/optimization_guide/core/DEPS
+++ b/components/optimization_guide/core/DEPS
@@ -6,6 +6,7 @@
   "+crypto",
   "+mojo/public/cpp",
   "+services/metrics/public/cpp",
+  "+third_party/tensorflow_models/src",
   "+third_party/zlib/google",
   "+ui/base/l10n",
 ]
diff --git a/components/optimization_guide/core/page_visibility_model_executor.cc b/components/optimization_guide/core/page_visibility_model_executor.cc
index 6505e5d..45e89d4 100644
--- a/components/optimization_guide/core/page_visibility_model_executor.cc
+++ b/components/optimization_guide/core/page_visibility_model_executor.cc
@@ -1,87 +1,81 @@
-// Copyright 2021 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #include "components/optimization_guide/core/page_visibility_model_executor.h"
 
-#include "components/optimization_guide/core/optimization_guide_model_provider.h"
-#include "components/optimization_guide/proto/models.pb.h"
-#include "components/optimization_guide/proto/page_topics_model_metadata.pb.h"
+#include "base/trace_event/trace_event.h"
+#include "components/optimization_guide/core/model_util.h"
+#include "components/optimization_guide/core/optimization_guide_features.h"
+#include "components/optimization_guide/core/page_visibility_op_resolver.h"
+#include "components/optimization_guide/core/tflite_op_resolver.h"
+#include "third_party/tflite_support/src/tensorflow_lite_support/cc/task/text/nlclassifier/nl_classifier.h"
+#include "third_party/tflite_support/src/tensorflow_lite_support/cc/task/text/proto/nl_classifier_options.pb.h"
 
 namespace optimization_guide {
 
-PageVisibilityModelExecutor::PageVisibilityModelExecutor(
-    OptimizationGuideModelProvider* model_provider,
-    scoped_refptr<base::SequencedTaskRunner> background_task_runner,
-    const absl::optional<proto::Any>& model_metadata)
-    : BertModelHandler(model_provider,
-                       background_task_runner,
-                       proto::OPTIMIZATION_TARGET_PAGE_VISIBILITY,
-                       model_metadata) {
-  SetShouldUnloadModelOnComplete(false);
-}
+PageVisibilityModelExecutor::PageVisibilityModelExecutor()
+    : num_threads_(features::OverrideNumThreadsForOptTarget(
+                       proto::OPTIMIZATION_TARGET_PAGE_VISIBILITY)
+                       .value_or(-1)) {}
 PageVisibilityModelExecutor::~PageVisibilityModelExecutor() = default;
 
-void PageVisibilityModelExecutor::ExecuteOnSingleInput(
-    AnnotationType annotation_type,
-    const std::string& input,
-    base::OnceCallback<void(const BatchAnnotationResult&)> callback) {
-  ExecuteModelWithInput(
-      base::BindOnce(&PageVisibilityModelExecutor::
-                         PostprocessCategoriesToBatchAnnotationResult,
-                     weak_ptr_factory_.GetWeakPtr(), std::move(callback),
-                     annotation_type, input),
-      input);
+absl::optional<std::vector<tflite::task::core::Category>>
+PageVisibilityModelExecutor::Execute(ModelExecutionTask* execution_task,
+                                     ExecutionStatus* out_status,
+                                     const std::string& input) {
+  if (input.empty()) {
+    *out_status = ExecutionStatus::kErrorEmptyOrInvalidInput;
+    return absl::nullopt;
+  }
+  TRACE_EVENT2("browser", "PageVisibilityModelExecutor::Execute",
+               "optimization_target",
+               GetStringNameForOptimizationTarget(
+                   proto::OPTIMIZATION_TARGET_PAGE_VISIBILITY),
+               "input_length", input.size());
+
+  auto status_or_result =
+      static_cast<tflite::task::text::nlclassifier::NLClassifier*>(
+          execution_task)
+          ->ClassifyText(input);
+  if (absl::IsCancelled(status_or_result.status())) {
+    *out_status = ExecutionStatus::kErrorCancelled;
+    return absl::nullopt;
+  }
+  if (!status_or_result.ok()) {
+    *out_status = ExecutionStatus::kErrorUnknown;
+    return absl::nullopt;
+  }
+  *out_status = ExecutionStatus::kSuccess;
+  return *status_or_result;
 }
 
-void PageVisibilityModelExecutor::PostprocessCategoriesToBatchAnnotationResult(
-    base::OnceCallback<void(const BatchAnnotationResult&)> callback,
-    AnnotationType annotation_type,
-    const std::string& input,
-    const absl::optional<std::vector<tflite::task::core::Category>>& output) {
-  DCHECK_EQ(annotation_type, AnnotationType::kContentVisibility);
+std::unique_ptr<PageVisibilityModelExecutor::ModelExecutionTask>
+PageVisibilityModelExecutor::BuildModelExecutionTask(
+    base::MemoryMappedFile* model_file,
+    ExecutionStatus* out_status) {
+  tflite::task::text::NLClassifierOptions options;
+  *options.mutable_base_options()
+       ->mutable_model_file()
+       ->mutable_file_content() = std::string(
+      reinterpret_cast<const char*>(model_file->data()), model_file->length());
+  options.mutable_base_options()
+      ->mutable_compute_settings()
+      ->mutable_tflite_settings()
+      ->mutable_cpu_settings()
+      ->set_num_threads(num_threads_);
+  options.set_output_score_tensor_name("batched_predictions");
+  options.set_output_label_tensor_name("batched_prediction_labels");
 
-  absl::optional<double> visibility_score;
-  if (output) {
-    visibility_score = ExtractContentVisibilityFromModelOutput(*output);
-  }
-  std::move(callback).Run(BatchAnnotationResult::CreateContentVisibilityResult(
-      input, visibility_score));
-}
-
-absl::optional<double>
-PageVisibilityModelExecutor::ExtractContentVisibilityFromModelOutput(
-    const std::vector<tflite::task::core::Category>& model_output) const {
-  absl::optional<proto::PageTopicsModelMetadata> model_metadata =
-      ParsedSupportedFeaturesForLoadedModel<proto::PageTopicsModelMetadata>();
-  if (!model_metadata) {
-    return absl::nullopt;
-  }
-
-  if (!model_metadata->output_postprocessing_params().has_visibility_params()) {
-    return absl::nullopt;
-  }
-
-  if (!model_metadata->output_postprocessing_params()
-           .visibility_params()
-           .has_category_name()) {
-    return absl::nullopt;
-  }
-
-  std::string visibility_category_name =
-      model_metadata->output_postprocessing_params()
-          .visibility_params()
-          .category_name();
-
-  for (const auto& category : model_output) {
-    if (category.class_name == visibility_category_name) {
-      return 1.0 - category.score;
-    }
-  }
-
-  // -1 is a sentinel value that means the visibility of the page was not
-  // evaluated.
-  return -1.0;
+  auto maybe_nl_classifier =
+      tflite::task::text::nlclassifier::NLClassifier::CreateFromOptions(
+          std::move(options), std::make_unique<PageVisibilityOpResolver>());
+  if (maybe_nl_classifier.ok())
+    return std::move(maybe_nl_classifier.value());
+  *out_status = ExecutionStatus::kErrorModelFileNotValid;
+  DLOG(ERROR) << "Unable to load NL model: "
+              << maybe_nl_classifier.status().ToString();
+  return nullptr;
 }
 
 }  // namespace optimization_guide
diff --git a/components/optimization_guide/core/page_visibility_model_executor.h b/components/optimization_guide/core/page_visibility_model_executor.h
index 2aa5fe1..33ec443 100644
--- a/components/optimization_guide/core/page_visibility_model_executor.h
+++ b/components/optimization_guide/core/page_visibility_model_executor.h
@@ -1,54 +1,42 @@
-// Copyright 2021 The Chromium Authors
+// Copyright 2022 The Chromium Authors
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
 #ifndef COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_MODEL_EXECUTOR_H_
 #define COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_MODEL_EXECUTOR_H_
 
-#include "base/callback.h"
-#include "base/memory/weak_ptr.h"
-#include "components/optimization_guide/core/bert_model_handler.h"
-#include "components/optimization_guide/core/page_content_annotation_job.h"
-#include "components/optimization_guide/core/page_content_annotation_job_executor.h"
-#include "components/optimization_guide/core/page_content_annotations_common.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "components/optimization_guide/core/tflite_model_executor.h"
+#include "third_party/tflite_support/src/tensorflow_lite_support/cc/task/core/category.h"
 
 namespace optimization_guide {
 
-// A BERT-based mode executor for page visibility annotations.
-class PageVisibilityModelExecutor : public PageContentAnnotationJobExecutor,
-                                    public BertModelHandler {
+// A full implementation of a ModelExecutor that executes the page visibility
+// model, which needs some special API calls to the TFLite Task library.
+class PageVisibilityModelExecutor
+    : public TFLiteModelExecutor<std::vector<tflite::task::core::Category>,
+                                 const std::string&> {
  public:
-  PageVisibilityModelExecutor(
-      OptimizationGuideModelProvider* model_provider,
-      scoped_refptr<base::SequencedTaskRunner> background_task_runner,
-      const absl::optional<proto::Any>& model_metadata);
+  PageVisibilityModelExecutor();
   ~PageVisibilityModelExecutor() override;
 
-  // PageContentAnnotationJobExecutor:
-  void ExecuteOnSingleInput(
-      AnnotationType annotation_type,
-      const std::string& input,
-      base::OnceCallback<void(const BatchAnnotationResult&)> callback) override;
+  using ModelExecutionTask =
+      tflite::task::core::BaseTaskApi<std::vector<tflite::task::core::Category>,
+                                      const std::string&>;
 
-  // Creates a BatchAnnotationResult from the output of the model, calling
-  // |ExtractContentVisibilityFromModelOutput| in the process.
-  // Public for testing.
-  void PostprocessCategoriesToBatchAnnotationResult(
-      base::OnceCallback<void(const BatchAnnotationResult&)> callback,
-      AnnotationType annotation_type,
-      const std::string& input,
-      const absl::optional<std::vector<tflite::task::core::Category>>& output);
-
-  // Extracts the visibility score from the output of the model.
-  // Public for testing.
-  absl::optional<double> ExtractContentVisibilityFromModelOutput(
-      const std::vector<tflite::task::core::Category>& model_output) const;
+  // ModelExecutor:
+  absl::optional<std::vector<tflite::task::core::Category>> Execute(
+      ModelExecutionTask* execution_task,
+      ExecutionStatus* out_status,
+      const std::string& input) override;
+  std::unique_ptr<ModelExecutionTask> BuildModelExecutionTask(
+      base::MemoryMappedFile* model_file,
+      ExecutionStatus* out_status) override;
 
  private:
-  base::WeakPtrFactory<PageVisibilityModelExecutor> weak_ptr_factory_{this};
+  // -1 tells TFLite to use its own default number of threads.
+  const int num_threads_ = -1;
 };
 
 }  // namespace optimization_guide
 
-#endif  // COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_MODEL_EXECUTOR_H_
+#endif  // COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_MODEL_EXECUTOR_H_
\ No newline at end of file
diff --git a/components/optimization_guide/core/page_visibility_model_executor_unittest.cc b/components/optimization_guide/core/page_visibility_model_executor_unittest.cc
deleted file mode 100644
index a1795f2..0000000
--- a/components/optimization_guide/core/page_visibility_model_executor_unittest.cc
+++ /dev/null
@@ -1,251 +0,0 @@
-// Copyright 2021 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/optimization_guide/core/page_visibility_model_executor.h"
-
-#include "base/containers/flat_map.h"
-#include "base/path_service.h"
-#include "base/task/thread_pool.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/test/task_environment.h"
-#include "components/optimization_guide/core/optimization_guide_features.h"
-#include "components/optimization_guide/core/optimization_guide_model_provider.h"
-#include "components/optimization_guide/core/page_entities_model_executor.h"
-#include "components/optimization_guide/core/test_model_info_builder.h"
-#include "components/optimization_guide/core/test_optimization_guide_model_provider.h"
-#include "components/optimization_guide/proto/models.pb.h"
-#include "components/optimization_guide/proto/page_topics_model_metadata.pb.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace optimization_guide {
-
-class ModelObserverTracker : public TestOptimizationGuideModelProvider {
- public:
-  void AddObserverForOptimizationTargetModel(
-      proto::OptimizationTarget target,
-      const absl::optional<proto::Any>& model_metadata,
-      OptimizationTargetModelObserver* observer) override {
-    registered_model_metadata_.insert_or_assign(target, model_metadata);
-  }
-
-  bool DidRegisterForTarget(
-      proto::OptimizationTarget target,
-      absl::optional<proto::Any>* out_model_metadata) const {
-    auto it = registered_model_metadata_.find(target);
-    if (it == registered_model_metadata_.end())
-      return false;
-    *out_model_metadata = registered_model_metadata_.at(target);
-    return true;
-  }
-
- private:
-  base::flat_map<proto::OptimizationTarget, absl::optional<proto::Any>>
-      registered_model_metadata_;
-};
-
-class PageVisibilityModelExecutorTest : public testing::Test {
- public:
-  PageVisibilityModelExecutorTest() {
-    scoped_feature_list_.InitAndEnableFeature(
-        features::kPageContentAnnotations);
-  }
-  ~PageVisibilityModelExecutorTest() override = default;
-
-  void SetUp() override {
-    model_observer_tracker_ = std::make_unique<ModelObserverTracker>();
-    model_executor_ = std::make_unique<PageVisibilityModelExecutor>(
-        model_observer_tracker_.get(),
-        base::ThreadPool::CreateSequencedTaskRunner({base::MayBlock()}),
-        /*model_metadata=*/absl::nullopt);
-  }
-
-  void TearDown() override {
-    model_executor_.reset();
-    model_observer_tracker_.reset();
-    RunUntilIdle();
-  }
-
-  void SendPageVisibilityModelToExecutor(
-      const absl::optional<proto::Any>& model_metadata) {
-    base::FilePath source_root_dir;
-    base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root_dir);
-    base::FilePath model_file_path =
-        source_root_dir.AppendASCII("components")
-            .AppendASCII("test")
-            .AppendASCII("data")
-            .AppendASCII("optimization_guide")
-            .AppendASCII("bert_page_topics_model.tflite");
-    std::unique_ptr<ModelInfo> model_info =
-        TestModelInfoBuilder()
-            .SetModelFilePath(model_file_path)
-            .SetModelMetadata(model_metadata)
-            .Build();
-    model_executor()->OnModelUpdated(proto::OPTIMIZATION_TARGET_PAGE_VISIBILITY,
-                                     *model_info);
-    RunUntilIdle();
-  }
-
-  ModelObserverTracker* model_observer_tracker() const {
-    return model_observer_tracker_.get();
-  }
-
-  PageVisibilityModelExecutor* model_executor() const {
-    return model_executor_.get();
-  }
-
-  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
-
- private:
-  base::test::TaskEnvironment task_environment_;
-  base::test::ScopedFeatureList scoped_feature_list_;
-  std::unique_ptr<ModelObserverTracker> model_observer_tracker_;
-  std::unique_ptr<PageVisibilityModelExecutor> model_executor_;
-};
-
-TEST_F(PageVisibilityModelExecutorTest, NoModelMetadataNoOutput) {
-  // Note that |SendPageVisibilityModelToExecutor| is not called so no metadata
-  // has been loaded.
-
-  std::vector<tflite::task::core::Category> model_output = {
-      {"VISIBILITY_HERE", 0.3},
-  };
-
-  absl::optional<double> score =
-      model_executor()->ExtractContentVisibilityFromModelOutput(model_output);
-  EXPECT_FALSE(score);
-}
-
-TEST_F(PageVisibilityModelExecutorTest, NoParamsNoOutput) {
-  proto::PageTopicsModelMetadata model_metadata;
-  model_metadata.set_version(123);
-
-  proto::Any any_metadata;
-  any_metadata.set_type_url(
-      "type.googleapis.com/com.foo.PageTopicsModelMetadata");
-  model_metadata.SerializeToString(any_metadata.mutable_value());
-  SendPageVisibilityModelToExecutor(any_metadata);
-
-  std::vector<tflite::task::core::Category> model_output = {
-      {"VISIBILITY_HERE", 0.3},
-  };
-
-  absl::optional<double> score =
-      model_executor()->ExtractContentVisibilityFromModelOutput(model_output);
-  EXPECT_FALSE(score);
-}
-
-TEST_F(PageVisibilityModelExecutorTest, VisibilityNotEvaluated) {
-  proto::PageTopicsModelMetadata model_metadata;
-  model_metadata.set_version(123);
-  model_metadata.mutable_output_postprocessing_params()
-      ->mutable_visibility_params()
-      ->set_category_name("VISIBILITY_HERE");
-
-  proto::Any any_metadata;
-  any_metadata.set_type_url(
-      "type.googleapis.com/com.foo.PageTopicsModelMetadata");
-  model_metadata.SerializeToString(any_metadata.mutable_value());
-  SendPageVisibilityModelToExecutor(any_metadata);
-
-  std::vector<tflite::task::core::Category> model_output = {
-      {"something else", 0.3},
-  };
-
-  absl::optional<double> score =
-      model_executor()->ExtractContentVisibilityFromModelOutput(model_output);
-  ASSERT_TRUE(score);
-  EXPECT_THAT(*score, testing::DoubleEq(-1));
-}
-
-TEST_F(PageVisibilityModelExecutorTest, SuccessCase) {
-  proto::PageTopicsModelMetadata model_metadata;
-  model_metadata.set_version(123);
-  model_metadata.mutable_output_postprocessing_params()
-      ->mutable_visibility_params()
-      ->set_category_name("VISIBILITY_HERE");
-
-  proto::Any any_metadata;
-  any_metadata.set_type_url(
-      "type.googleapis.com/com.foo.PageTopicsModelMetadata");
-  model_metadata.SerializeToString(any_metadata.mutable_value());
-  SendPageVisibilityModelToExecutor(any_metadata);
-
-  std::vector<tflite::task::core::Category> model_output = {
-      {"VISIBILITY_HERE", 0.3},
-      {"0", 0.4},
-      {"1", 0.5},
-  };
-
-  absl::optional<double> score =
-      model_executor()->ExtractContentVisibilityFromModelOutput(model_output);
-  ASSERT_TRUE(score);
-  EXPECT_THAT(*score, testing::DoubleEq(0.7));
-}
-
-TEST_F(PageVisibilityModelExecutorTest,
-       PostprocessCategoriesToBatchAnnotationResult) {
-  proto::PageTopicsModelMetadata model_metadata;
-  model_metadata.set_version(123);
-  model_metadata.mutable_output_postprocessing_params()
-      ->mutable_visibility_params()
-      ->set_category_name("VISIBILITY_HERE");
-
-  proto::Any any_metadata;
-  any_metadata.set_type_url(
-      "type.googleapis.com/com.foo.PageTopicsModelMetadata");
-  model_metadata.SerializeToString(any_metadata.mutable_value());
-  SendPageVisibilityModelToExecutor(any_metadata);
-
-  std::vector<tflite::task::core::Category> model_output = {
-      {"0", 0.3},
-      {"1", 0.25},
-      {"2", 0.4},
-      {"3", 0.05},
-      {"VISIBILITY_HERE", 0.4},
-  };
-
-  BatchAnnotationResult viz_result =
-      BatchAnnotationResult::CreateEmptyAnnotationsResult("");
-  model_executor()->PostprocessCategoriesToBatchAnnotationResult(
-      base::BindOnce(
-          [](BatchAnnotationResult* out_result,
-             const BatchAnnotationResult& in_result) {
-            *out_result = in_result;
-          },
-          &viz_result),
-      AnnotationType::kContentVisibility, "input", model_output);
-  EXPECT_EQ(viz_result,
-            BatchAnnotationResult::CreateContentVisibilityResult("input", 0.6));
-}
-
-TEST_F(PageVisibilityModelExecutorTest,
-       NullPostprocessCategoriesToBatchAnnotationResult) {
-  proto::PageTopicsModelMetadata model_metadata;
-  model_metadata.set_version(123);
-  model_metadata.mutable_output_postprocessing_params()
-      ->mutable_visibility_params()
-      ->set_category_name("VISIBILITY_HERE");
-
-  proto::Any any_metadata;
-  any_metadata.set_type_url(
-      "type.googleapis.com/com.foo.PageTopicsModelMetadata");
-  model_metadata.SerializeToString(any_metadata.mutable_value());
-  SendPageVisibilityModelToExecutor(any_metadata);
-
-  BatchAnnotationResult viz_result =
-      BatchAnnotationResult::CreateEmptyAnnotationsResult("");
-  model_executor()->PostprocessCategoriesToBatchAnnotationResult(
-      base::BindOnce(
-          [](BatchAnnotationResult* out_result,
-             const BatchAnnotationResult& in_result) {
-            *out_result = in_result;
-          },
-          &viz_result),
-      AnnotationType::kContentVisibility, "input", absl::nullopt);
-  EXPECT_EQ(viz_result, BatchAnnotationResult::CreateContentVisibilityResult(
-                            "input", absl::nullopt));
-}
-
-}  // namespace optimization_guide
\ No newline at end of file
diff --git a/components/optimization_guide/core/page_visibility_model_handler.cc b/components/optimization_guide/core/page_visibility_model_handler.cc
new file mode 100644
index 0000000..1148624
--- /dev/null
+++ b/components/optimization_guide/core/page_visibility_model_handler.cc
@@ -0,0 +1,78 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/optimization_guide/core/page_visibility_model_handler.h"
+
+#include <algorithm>
+
+#include "base/containers/contains.h"
+#include "components/optimization_guide/core/optimization_guide_features.h"
+#include "components/optimization_guide/core/optimization_guide_model_provider.h"
+#include "components/optimization_guide/core/page_content_annotations_common.h"
+#include "components/optimization_guide/core/page_visibility_model_executor.h"
+#include "components/optimization_guide/proto/models.pb.h"
+
+namespace optimization_guide {
+
+namespace {
+
+const char kNotSensitiveCategory[] = "NOT-SENSITIVE";
+
+}  // namespace
+
+PageVisibilityModelHandler::PageVisibilityModelHandler(
+    OptimizationGuideModelProvider* model_provider,
+    scoped_refptr<base::SequencedTaskRunner> background_task_runner,
+    const absl::optional<proto::Any>& model_metadata)
+    : ModelHandler<std::vector<tflite::task::core::Category>,
+                   const std::string&>(
+          model_provider,
+          background_task_runner,
+          std::make_unique<PageVisibilityModelExecutor>(),
+          /*model_inference_timeout=*/absl::nullopt,
+          proto::OPTIMIZATION_TARGET_PAGE_VISIBILITY,
+          model_metadata) {
+  SetShouldUnloadModelOnComplete(false);
+}
+PageVisibilityModelHandler::~PageVisibilityModelHandler() = default;
+
+void PageVisibilityModelHandler::ExecuteOnSingleInput(
+    AnnotationType annotation_type,
+    const std::string& input,
+    base::OnceCallback<void(const BatchAnnotationResult&)> callback) {
+  ExecuteModelWithInput(
+      base::BindOnce(&PageVisibilityModelHandler::
+                         PostprocessCategoriesToBatchAnnotationResult,
+                     weak_ptr_factory_.GetWeakPtr(), std::move(callback),
+                     annotation_type, input),
+      input);
+}
+
+void PageVisibilityModelHandler::PostprocessCategoriesToBatchAnnotationResult(
+    base::OnceCallback<void(const BatchAnnotationResult&)> callback,
+    AnnotationType annotation_type,
+    const std::string& input,
+    const absl::optional<std::vector<tflite::task::core::Category>>& output) {
+  DCHECK_EQ(annotation_type, AnnotationType::kContentVisibility);
+
+  absl::optional<double> visibility_score;
+  if (output) {
+    visibility_score = ExtractContentVisibilityFromModelOutput(*output);
+  }
+  std::move(callback).Run(BatchAnnotationResult::CreateContentVisibilityResult(
+      input, visibility_score));
+}
+
+absl::optional<double>
+PageVisibilityModelHandler::ExtractContentVisibilityFromModelOutput(
+    const std::vector<tflite::task::core::Category>& model_output) const {
+  for (const auto& category : model_output) {
+    if (category.class_name == kNotSensitiveCategory) {
+      return category.score;
+    }
+  }
+  return absl::nullopt;
+}
+
+}  // namespace optimization_guide
diff --git a/components/optimization_guide/core/page_visibility_model_handler.h b/components/optimization_guide/core/page_visibility_model_handler.h
new file mode 100644
index 0000000..87b596af
--- /dev/null
+++ b/components/optimization_guide/core/page_visibility_model_handler.h
@@ -0,0 +1,57 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_MODEL_HANDLER_H_
+#define COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_MODEL_HANDLER_H_
+
+#include "base/callback.h"
+#include "base/memory/weak_ptr.h"
+#include "components/optimization_guide/core/model_handler.h"
+#include "components/optimization_guide/core/page_content_annotation_job.h"
+#include "components/optimization_guide/core/page_content_annotation_job_executor.h"
+#include "components/optimization_guide/core/page_content_annotations_common.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+#include "third_party/tflite_support/src/tensorflow_lite_support/cc/task/core/category.h"
+
+namespace optimization_guide {
+
+// A NL-based model handler for page visibility annotations.
+class PageVisibilityModelHandler
+    : public PageContentAnnotationJobExecutor,
+      public ModelHandler<std::vector<tflite::task::core::Category>,
+                          const std::string&> {
+ public:
+  PageVisibilityModelHandler(
+      OptimizationGuideModelProvider* model_provider,
+      scoped_refptr<base::SequencedTaskRunner> background_task_runner,
+      const absl::optional<proto::Any>& model_metadata);
+  ~PageVisibilityModelHandler() override;
+
+  // PageContentAnnotationJobExecutor:
+  void ExecuteOnSingleInput(
+      AnnotationType annotation_type,
+      const std::string& input,
+      base::OnceCallback<void(const BatchAnnotationResult&)> callback) override;
+
+  // Creates a BatchAnnotationResult from the output of the model, calling
+  // |ExtractContentVisibilityFromModelOutput| in the process.
+  // Public for testing.
+  void PostprocessCategoriesToBatchAnnotationResult(
+      base::OnceCallback<void(const BatchAnnotationResult&)> callback,
+      AnnotationType annotation_type,
+      const std::string& input,
+      const absl::optional<std::vector<tflite::task::core::Category>>& output);
+
+  // Extracts the visibility score from the output of the model, 0 is less
+  // visible, 1 is more visible. Public for testing.
+  absl::optional<double> ExtractContentVisibilityFromModelOutput(
+      const std::vector<tflite::task::core::Category>& model_output) const;
+
+ private:
+  base::WeakPtrFactory<PageVisibilityModelHandler> weak_ptr_factory_{this};
+};
+
+}  // namespace optimization_guide
+
+#endif  // COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_MODEL_HANDLER_H_
diff --git a/components/optimization_guide/core/page_visibility_model_handler_unittest.cc b/components/optimization_guide/core/page_visibility_model_handler_unittest.cc
new file mode 100644
index 0000000..3569563
--- /dev/null
+++ b/components/optimization_guide/core/page_visibility_model_handler_unittest.cc
@@ -0,0 +1,72 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/optimization_guide/core/page_visibility_model_handler.h"
+
+#include "base/test/task_environment.h"
+#include "components/optimization_guide/core/optimization_guide_features.h"
+#include "components/optimization_guide/core/test_optimization_guide_model_provider.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace optimization_guide {
+
+class PageVisibilityModelHandlerTest : public testing::Test {
+ public:
+  PageVisibilityModelHandlerTest() = default;
+  ~PageVisibilityModelHandlerTest() override = default;
+
+  void SetUp() override {
+    model_provider_ = std::make_unique<TestOptimizationGuideModelProvider>();
+    model_handler_ = std::make_unique<PageVisibilityModelHandler>(
+        model_provider_.get(), task_environment_.GetMainThreadTaskRunner(),
+        /*model_metadata=*/absl::nullopt);
+  }
+
+  void TearDown() override {
+    model_handler_.reset();
+    model_provider_.reset();
+    RunUntilIdle();
+  }
+
+  PageVisibilityModelHandler* model_handler() const {
+    return model_handler_.get();
+  }
+
+  void RunUntilIdle() { task_environment_.RunUntilIdle(); }
+
+ private:
+  base::test::TaskEnvironment task_environment_;
+  std::unique_ptr<TestOptimizationGuideModelProvider> model_provider_;
+  std::unique_ptr<PageVisibilityModelHandler> model_handler_;
+};
+
+TEST_F(PageVisibilityModelHandlerTest, NotSensitiveNotFound) {
+  PageVisibilityModelHandler* executor = model_handler();
+
+  absl::optional<double> visibility_score =
+      executor->ExtractContentVisibilityFromModelOutput(
+          std::vector<tflite::task::core::Category>{
+              {"BLAH-BLAH-BLAH", 0.3},
+              {"SENSITIVE", 0.7},
+          });
+
+  EXPECT_FALSE(visibility_score);
+}
+
+TEST_F(PageVisibilityModelHandlerTest, HasScore) {
+  PageVisibilityModelHandler* executor = model_handler();
+
+  absl::optional<double> visibility_score =
+      executor->ExtractContentVisibilityFromModelOutput(
+          std::vector<tflite::task::core::Category>{
+              {"NOT-SENSITIVE", 0.9},
+              {"SENSITIVE", 0.1},
+          });
+
+  ASSERT_TRUE(visibility_score);
+  EXPECT_EQ(*visibility_score, 0.9);
+}
+
+}  // namespace optimization_guide
\ No newline at end of file
diff --git a/components/optimization_guide/core/page_visibility_op_resolver.cc b/components/optimization_guide/core/page_visibility_op_resolver.cc
new file mode 100644
index 0000000..e9493a3
--- /dev/null
+++ b/components/optimization_guide/core/page_visibility_op_resolver.cc
@@ -0,0 +1,21 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+#include "components/optimization_guide/core/page_visibility_op_resolver.h"
+
+#include "third_party/tensorflow_models/src/research/seq_flow_lite/tflite_ops/denylist_skipgram.h"
+#include "third_party/tensorflow_models/src/research/seq_flow_lite/tflite_ops/sequence_string_projection.h"
+#include "third_party/tensorflow_models/src/research/seq_flow_lite/tflite_ops/tflite_qrnn_pooling.h"
+
+namespace optimization_guide {
+
+PageVisibilityOpResolver::PageVisibilityOpResolver() {
+  AddCustom("SequenceStringProjection",
+            seq_flow_lite::ops::custom::Register_SEQUENCE_STRING_PROJECTION());
+  AddCustom("PoolingOp", seq_flow_lite::ops::custom::Register_QRNN_POOLING());
+  AddCustom("SkipgramDenylist",
+            seq_flow_lite::ops::custom::Register_SKIPGRAM_DENYLIST());
+}
+PageVisibilityOpResolver::~PageVisibilityOpResolver() = default;
+
+}  // namespace optimization_guide
diff --git a/components/optimization_guide/core/page_visibility_op_resolver.h b/components/optimization_guide/core/page_visibility_op_resolver.h
new file mode 100644
index 0000000..4026f314
--- /dev/null
+++ b/components/optimization_guide/core/page_visibility_op_resolver.h
@@ -0,0 +1,20 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_OP_RESOLVER_H_
+#define COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_OP_RESOLVER_H_
+
+#include "components/optimization_guide/core/tflite_op_resolver.h"
+
+namespace optimization_guide {
+
+class PageVisibilityOpResolver : public TFLiteOpResolver {
+ public:
+  PageVisibilityOpResolver();
+  ~PageVisibilityOpResolver() override;
+};
+
+}  // namespace optimization_guide
+
+#endif  // COMPONENTS_OPTIMIZATION_GUIDE_CORE_PAGE_VISIBILITY_OP_RESOLVER_H_
diff --git a/components/page_info/core/about_this_site_validation_unittest.cc b/components/page_info/core/about_this_site_validation_unittest.cc
index 7c558cc..5e2e8055 100644
--- a/components/page_info/core/about_this_site_validation_unittest.cc
+++ b/components/page_info/core/about_this_site_validation_unittest.cc
@@ -155,6 +155,9 @@
 }
 
 TEST(AboutThisSiteValidation, MissingMoreAbout_FeatureDisabled) {
+  base::test::ScopedFeatureList features;
+  features.InitAndDisableFeature(kPageInfoAboutThisSiteMoreInfo);
+
   proto::AboutThisSiteMetadata meta_data = GetSampleMetaData();
   EXPECT_EQ(ValidateMetadata(meta_data, /*allow_missing_description=*/true),
             AboutThisSiteStatus::kValid);
diff --git a/components/page_info/core/features.cc b/components/page_info/core/features.cc
index 7177360..9370d37 100644
--- a/components/page_info/core/features.cc
+++ b/components/page_info/core/features.cc
@@ -37,7 +37,11 @@
 
 BASE_FEATURE(kPageInfoAboutThisSiteMoreInfo,
              "PageInfoAboutThisSiteMoreInfo",
+#if BUILDFLAG(IS_ANDROID)
+             base::FEATURE_ENABLED_BY_DEFAULT);
+#else
              base::FEATURE_DISABLED_BY_DEFAULT);
+#endif
 
 BASE_FEATURE(kPageInfoAboutThisSiteDescriptionPlaceholder,
              "PageInfoAboutThisSiteDescriptionPlaceholder",
diff --git a/components/permissions/permission_request_manager.cc b/components/permissions/permission_request_manager.cc
index 8ef849a3..b94ce1f 100644
--- a/components/permissions/permission_request_manager.cc
+++ b/components/permissions/permission_request_manager.cc
@@ -213,7 +213,7 @@
   // any other renderer-side nav initiations?). Double-check this for
   // correct behavior on interstitials -- we probably want to basically queue
   // any request for which GetVisibleURL != GetLastCommittedURL.
-  CHECK_EQ(source_frame->GetMainFrame(), web_contents()->GetPrimaryMainFrame());
+  CHECK(source_frame->GetMainFrame()->IsInPrimaryMainFrame());
   const GURL main_frame_origin =
       PermissionUtil::GetLastCommittedOriginAsURL(source_frame->GetMainFrame());
   bool is_main_frame =
diff --git a/components/power_bookmarks/core/power_bookmark_service.h b/components/power_bookmarks/core/power_bookmark_service.h
index c566e69..687bc1cb 100644
--- a/components/power_bookmarks/core/power_bookmark_service.h
+++ b/components/power_bookmarks/core/power_bookmark_service.h
@@ -45,6 +45,14 @@
 
   ~PowerBookmarkService() override;
 
+  // Initializes the power bookmarks backend.
+  // Should only be called in cases where the power is meant to be displayed
+  // to the user. This will also initialize sync for the power bookmarks data
+  // type in cases where another feature hasn't already called this. This
+  // should be called at startup to register the data type with sync as soon
+  // as possible. If this isn't called, then an in-memory database will be
+  // used instead. None of the data will be persisted/synced when using the
+  // in-memory database.
   void InitPowerBookmarkDatabase();
 
   // Returns a vector of Powers for the given `url` through the given
diff --git a/components/safe_browsing/core/browser/password_protection/password_protection_request.h b/components/safe_browsing/core/browser/password_protection/password_protection_request.h
index 7e18b1a..afde9c2 100644
--- a/components/safe_browsing/core/browser/password_protection/password_protection_request.h
+++ b/components/safe_browsing/core/browser/password_protection/password_protection_request.h
@@ -232,7 +232,7 @@
   const GURL password_form_frame_url_;
 
   // The contents MIME type.
-  const raw_ref<const std::string> mime_type_;
+  const raw_ref<const std::string, DanglingUntriaged> mime_type_;
 
   // The username of the reused password hash. The username can be an email or
   // a username for a non-GAIA or saved-password reuse. No validation has been
diff --git a/components/segmentation_platform/internal/execution/model_executor_impl.cc b/components/segmentation_platform/internal/execution/model_executor_impl.cc
index 78f4f5f..6836ef4 100644
--- a/components/segmentation_platform/internal/execution/model_executor_impl.cc
+++ b/components/segmentation_platform/internal/execution/model_executor_impl.cc
@@ -30,7 +30,8 @@
                            const ModelExecutorImpl::ExecutionState& state);
   ~ModelExecutionTraceEvent();
 
-  const raw_ref<const ModelExecutorImpl::ExecutionState> state;
+  const raw_ref<const ModelExecutorImpl::ExecutionState, DanglingUntriaged>
+      state;
 };
 
 struct ModelExecutorImpl::ExecutionState {
diff --git a/components/services/screen_ai/proto/visual_annotator_proto_convertor.cc b/components/services/screen_ai/proto/visual_annotator_proto_convertor.cc
index 385c5a4..621e80c 100644
--- a/components/services/screen_ai/proto/visual_annotator_proto_convertor.cc
+++ b/components/services/screen_ai/proto/visual_annotator_proto_convertor.cc
@@ -399,11 +399,11 @@
     return update;
   }
 
-  if (features::IsScreenAIUseLayoutExtractionEnabled()) {
-    visual_annotation.clear_lines();
-  } else {
+  // TODO(https://crbug.com/1278249): After updating the service to explicitly
+  // use one of the OCR or Layout Extraction functions, remove this line and
+  // add a DCHECK that ensures either |lines| or |ui_components| exists.
+  if (visual_annotation.lines_size())
     visual_annotation.clear_ui_component();
-  }
 
   // TODO(https://crbug.com/1278249): Create an AXTreeSource and create the
   // update using AXTreeSerializer.
diff --git a/components/services/screen_ai/proto/visual_annotator_proto_convertor_unittest.cc b/components/services/screen_ai/proto/visual_annotator_proto_convertor_unittest.cc
index a62ba424..c2a792e 100644
--- a/components/services/screen_ai/proto/visual_annotator_proto_convertor_unittest.cc
+++ b/components/services/screen_ai/proto/visual_annotator_proto_convertor_unittest.cc
@@ -6,10 +6,8 @@
 
 #include <string>
 
-#include "base/test/scoped_feature_list.h"
 #include "components/services/screen_ai/proto/chrome_screen_ai.pb.h"
 #include "testing/gtest/include/gtest/gtest.h"
-#include "ui/accessibility/accessibility_features.h"
 #include "ui/accessibility/ax_tree_update.h"
 
 namespace screen_ai {
@@ -22,10 +20,6 @@
   gfx::Rect snapshot_bounds(800, 900);
 
   screen_ai::ResetNodeIDForTesting();
-  base::test::ScopedFeatureList feature_list;
-  feature_list.InitWithFeatures(
-      /*enabled_features=*/{features::kScreenAIUseLayoutExtraction},
-      /*disabled_features=*/{});
 
   {
     chrome_screen_ai::UIComponent* component_0 = annotation.add_ui_component();
@@ -73,9 +67,6 @@
   gfx::Rect snapshot_bounds(800, 900);
 
   screen_ai::ResetNodeIDForTesting();
-  base::test::ScopedFeatureList feature_list;
-  feature_list.InitWithFeatures(/*enabled_features=*/{}, /*disabled_features=*/{
-                                    features::kScreenAIUseLayoutExtraction});
 
   {
     chrome_screen_ai::LineBox* line_0 = annotation.add_lines();
diff --git a/components/services/screen_ai/screen_ai_service_impl.cc b/components/services/screen_ai/screen_ai_service_impl.cc
index 6e88fcae..b13c3f8 100644
--- a/components/services/screen_ai/screen_ai_service_impl.cc
+++ b/components/services/screen_ai/screen_ai_service_impl.cc
@@ -59,19 +59,21 @@
   return buffer;
 }
 
-#if !BUILDFLAG(IS_WIN)
 NO_SANITIZE("cfi-icall")
 bool CallInitVisualAnnotationsFunction(LibraryFunctions* library_functions,
                                        const base::FilePath& models_folder) {
+  DCHECK(library_functions);
+  DCHECK(library_functions->init_visual_annotation_);
   return library_functions->init_visual_annotation_(
       models_folder.MaybeAsASCII().c_str());
 }
-#endif
 
 NO_SANITIZE("cfi-icall")
 bool CallInitMainContentExtractionFunction(LibraryFunctions* library_functions,
                                            base::File& model_config_file,
                                            base::File& model_tflite_file) {
+  DCHECK(library_functions);
+  DCHECK(library_functions->init_main_content_extraction_);
   std::vector<char> model_config = LoadModelFile(model_config_file);
   std::vector<char> model_tflite = LoadModelFile(model_tflite_file);
   if (model_config.empty() || model_tflite.empty())
@@ -97,10 +99,9 @@
 
   if (features::IsScreenAIDebugModeEnabled())
     CallEnableDebugMode(library_functions.get());
+
   bool init_ok = true;
-#if !BUILDFLAG(IS_WIN)
-  if (features::IsPdfOcrEnabled() ||
-      features::IsScreenAIVisualAnnotationsEnabled()) {
+  if (features::IsPdfOcrEnabled() || features::IsLayoutExtractionEnabled()) {
     if (!CallInitVisualAnnotationsFunction(library_functions.get(),
                                            library_path.DirName())) {
       init_ok = false;
@@ -109,7 +110,6 @@
           ScreenAILoadLibraryResult::kVisualAnnotationFailed);
     }
   }
-#endif
 
   if (init_ok && features::IsReadAnythingWithScreen2xEnabled()) {
     if (!CallInitMainContentExtractionFunction(library_functions.get(),
@@ -154,24 +154,30 @@
   DCHECK(enable_debug_mode_);
 
   // Main Content Extraction functions.
-  init_main_content_extraction_ = reinterpret_cast<InitMainContentExtraction>(
-      library_.GetFunctionPointer("InitMainContentExtraction"));
-  DCHECK(init_main_content_extraction_);
-  extract_main_content_ = reinterpret_cast<ExtractMainContent>(
-      library_.GetFunctionPointer("ExtractMainContent"));
-  DCHECK(extract_main_content_);
+  if (features::IsReadAnythingWithScreen2xEnabled()) {
+    init_main_content_extraction_ = reinterpret_cast<InitMainContentExtraction>(
+        library_.GetFunctionPointer("InitMainContentExtraction"));
+    DCHECK(init_main_content_extraction_);
+    extract_main_content_ = reinterpret_cast<ExtractMainContent>(
+        library_.GetFunctionPointer("ExtractMainContent"));
+    DCHECK(extract_main_content_);
+  } else {
+    init_main_content_extraction_ = nullptr;
+    extract_main_content_ = nullptr;
+  }
 
-// Visual Annotation functions.
-// TODO(https://crbug.com/1278249): Enable when ScreenAI is supported on
-// Windows.
-#if !BUILDFLAG(IS_WIN)
-  init_visual_annotation_ = reinterpret_cast<InitVisualAnnotations>(
-      library_.GetFunctionPointer("InitVisualAnnotations"));
-  DCHECK(init_visual_annotation_);
-  annotate_ =
-      reinterpret_cast<Annotate>(library_.GetFunctionPointer("Annotate"));
-  DCHECK(annotate_);
-#endif  // !BUILDFLAG(IS_WIN)
+  // Visual Annotation functions.
+  if (features::IsPdfOcrEnabled() || features::IsLayoutExtractionEnabled()) {
+    init_visual_annotation_ = reinterpret_cast<InitVisualAnnotations>(
+        library_.GetFunctionPointer("InitVisualAnnotations"));
+    DCHECK(init_visual_annotation_);
+    annotate_ =
+        reinterpret_cast<Annotate>(library_.GetFunctionPointer("Annotate"));
+    DCHECK(annotate_);
+  } else {
+    init_visual_annotation_ = nullptr;
+    annotate_ = nullptr;
+  }
 }
 
 void ScreenAIService::LoadLibrary(base::File model_config,
@@ -286,14 +292,10 @@
     const SkBitmap& image,
     char*& annotation_proto,
     uint32_t& annotation_proto_length) {
-#if BUILDFLAG(IS_WIN)
-  NOTIMPLEMENTED();
-  return false;
-#else
   DCHECK(library_functions_);
+  DCHECK(library_functions_->annotate_);
   return library_functions_->annotate_(image, annotation_proto,
                                        annotation_proto_length);
-#endif
 }
 
 void ScreenAIService::ExtractMainContent(const ui::AXTreeUpdate& snapshot,
@@ -350,6 +352,7 @@
     int32_t*& node_ids,
     uint32_t& nodes_count) {
   DCHECK(library_functions_);
+  DCHECK(library_functions_->extract_main_content_);
   return library_functions_->extract_main_content_(
       serialized_snapshot, serialized_snapshot_length, node_ids, nodes_count);
 }
diff --git a/components/services/screen_ai/screen_ai_service_impl.h b/components/services/screen_ai/screen_ai_service_impl.h
index 5607926..34d1f9f9 100644
--- a/components/services/screen_ai/screen_ai_service_impl.h
+++ b/components/services/screen_ai/screen_ai_service_impl.h
@@ -33,7 +33,6 @@
   LibraryFunctions& operator=(const LibraryFunctions&) = delete;
   ~LibraryFunctions() = default;
 
-#if !BUILDFLAG(IS_WIN)
   // Initializes the pipeline for layout extraction and OCR.
   // |models_folder| is a null terminated string pointing to the
   // folder that includes model files for layout extraction and OCR.
@@ -51,7 +50,6 @@
                            char*& /*serialized_visual_annotation*/,
                            uint32_t& /*serialized_visual_annotation_length*/);
   Annotate annotate_ = nullptr;
-#endif
 
   // Initializes the pipeline for main content extraction.
   // |model_config| and |model_tflite| pass content of the required files to
diff --git a/components/sqlite_proto/table_manager.h b/components/sqlite_proto/table_manager.h
index 5ef4bf30..aae1ae60 100644
--- a/components/sqlite_proto/table_manager.h
+++ b/components/sqlite_proto/table_manager.h
@@ -69,7 +69,7 @@
   friend class base::RefCountedThreadSafe<TableManager>;
 
   scoped_refptr<base::SequencedTaskRunner> db_task_runner_;
-  raw_ptr<sql::Database> db_;
+  raw_ptr<sql::Database, DanglingUntriaged> db_;
 };
 
 }  // namespace sqlite_proto
diff --git a/components/sync/OWNERS b/components/sync/OWNERS
index 31072fc30..9483611 100644
--- a/components/sync/OWNERS
+++ b/components/sync/OWNERS
@@ -1,8 +1,8 @@
-# Unless you want a specific reviewer's expertise, send to:
-#   chromium-sync-reviews@google.com
+# Unless you want a specific reviewer's expertise, send to the email below.
+chromium-sync-reviews@google.com
 
-mastiz@chromium.org
-mmoskvitin@google.com
-rushans@google.com
-treib@chromium.org
-victorvianna@google.com
+mastiz@chromium.org      #{LAST_RESORT_SUGGESTION}
+mmoskvitin@google.com    #{LAST_RESORT_SUGGESTION}
+rushans@google.com       #{LAST_RESORT_SUGGESTION}
+treib@chromium.org       #{LAST_RESORT_SUGGESTION}
+victorvianna@google.com  #{LAST_RESORT_SUGGESTION}
diff --git a/components/sync/base/features.cc b/components/sync/base/features.cc
index 6b47d97..75d252d 100644
--- a/components/sync/base/features.cc
+++ b/components/sync/base/features.cc
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 #include "components/sync/base/features.h"
+
 #include "base/feature_list.h"
 
 namespace syncer {
@@ -143,4 +144,8 @@
              "SyncEnforceBookmarksCountLimit",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
+BASE_FEATURE(kSyncIgnoreAccountWithoutRefreshToken,
+             "SyncIgnoreAccountWithoutRefreshToken",
+             base::FEATURE_ENABLED_BY_DEFAULT);
+
 }  // namespace syncer
diff --git a/components/sync/base/features.h b/components/sync/base/features.h
index 6a9135f..89703ff 100644
--- a/components/sync/base/features.h
+++ b/components/sync/base/features.h
@@ -167,6 +167,10 @@
 // If enabled, issues error and disables bookmarks sync when limit is crossed.
 BASE_DECLARE_FEATURE(kSyncEnforceBookmarksCountLimit);
 
+// If enabled, Sync will not use a primary account that doesn't have a refresh
+// token. (This state should only ever occur temporarily during signout.)
+BASE_DECLARE_FEATURE(kSyncIgnoreAccountWithoutRefreshToken);
+
 }  // namespace syncer
 
 #endif  // COMPONENTS_SYNC_BASE_FEATURES_H_
diff --git a/components/sync/driver/sync_auth_manager.cc b/components/sync/driver/sync_auth_manager.cc
index 9ecf7dd..648548b5 100644
--- a/components/sync/driver/sync_auth_manager.cc
+++ b/components/sync/driver/sync_auth_manager.cc
@@ -387,6 +387,9 @@
     return;
   }
 
+  // TODO(crbug.com/1383912): If kSyncIgnoreAccountWithoutRefreshToken sticks,
+  // the code below can be removed.
+
   // If we're still here, then that means Chrome is still signed in to this
   // account. Keep Sync alive but set an auth error.
   DCHECK_EQ(
diff --git a/components/sync/driver/sync_auth_manager_unittest.cc b/components/sync/driver/sync_auth_manager_unittest.cc
index 3909286..f7978e9d 100644
--- a/components/sync/driver/sync_auth_manager_unittest.cc
+++ b/components/sync/driver/sync_auth_manager_unittest.cc
@@ -179,15 +179,15 @@
   });
   identity_env()->ClearPrimaryAccount();
   // After the signout is complete, the access token should be gone.
-  EXPECT_TRUE(
+  EXPECT_TRUE(auth_manager->GetCredentials().access_token.empty());
+  ASSERT_TRUE(
       auth_manager->GetActiveAccountInfo().account_info.account_id.empty());
 }
 #endif  // !BUILDFLAG(IS_CHROMEOS_ASH)
 
-// Unconsented primary accounts (aka secondary accounts) are only supported on
-// Win/Mac/Linux.
+// Unconsented primary accounts are only supported on Win/Mac/Linux.
 #if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
-TEST_F(SyncAuthManagerTest, ForwardsSecondaryAccountEvents) {
+TEST_F(SyncAuthManagerTest, ForwardsUnconsentedAccountEvents) {
   base::MockCallback<AccountStateChangedCallback> account_state_changed;
   base::MockCallback<CredentialsChangedCallback> credentials_changed;
   EXPECT_CALL(account_state_changed, Run()).Times(0);
@@ -199,7 +199,7 @@
   ASSERT_TRUE(
       auth_manager->GetActiveAccountInfo().account_info.account_id.empty());
 
-  // Make a non-primary account available with both a refresh token and cookie.
+  // Make a primary account available without Sync consent.
   EXPECT_CALL(account_state_changed, Run());
   AccountInfo account_info = identity_env()->MakePrimaryAccountAvailable(
       "test@email.com", signin::ConsentLevel::kSignin);
@@ -208,7 +208,7 @@
   EXPECT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id,
             account_info.account_id);
 
-  // Make the account primary.
+  // Make the account Sync-consented.
   EXPECT_CALL(account_state_changed, Run());
   signin::PrimaryAccountMutator* primary_account_mutator =
       identity_env()->identity_manager()->GetPrimaryAccountMutator();
@@ -222,7 +222,7 @@
 
 // ChromeOS doesn't support sign-out.
 #if !BUILDFLAG(IS_CHROMEOS_ASH)
-TEST_F(SyncAuthManagerTest, ClearsAuthErrorOnSignout) {
+TEST_F(SyncAuthManagerTest, ClearsAuthErrorOnSignoutWithRefreshTokenRemoval) {
   // Start out already signed in before the SyncAuthManager is created.
   CoreAccountId account_id =
       identity_env()
@@ -242,14 +242,46 @@
   // Sign out of the account.
   // The ordering of removing the refresh token and the actual sign-out is
   // undefined, see comment on IdentityManager::Observer. Here, explicitly
-  // revoke the refresh token first to force an auth error.
+  // revoke the refresh token first (see also other test below which does *not*
+  // remove the refresh token first).
   identity_env()->RemoveRefreshTokenForPrimaryAccount();
 
-  ASSERT_NE(auth_manager->GetLastAuthError().state(),
+  // Note: Things are now in an intermediate state, where the primary account
+  // still exists, but doesn't have a refresh token anymore. It doesn't really
+  // matter whether the auth error is still there at this point.
+
+  // Actually signing out, i.e. removing the primary account, should clear the
+  // auth error, since it's now not meaningful anymore.
+  identity_env()->ClearPrimaryAccount();
+  EXPECT_EQ(auth_manager->GetLastAuthError().state(),
+            GoogleServiceAuthError::NONE);
+}
+
+TEST_F(SyncAuthManagerTest,
+       ClearsAuthErrorOnSignoutWithoutRefreshTokenRemoval) {
+  // Start out already signed in before the SyncAuthManager is created.
+  CoreAccountId account_id =
+      identity_env()
+          ->MakePrimaryAccountAvailable("test@email.com",
+                                        signin::ConsentLevel::kSync)
+          .account_id;
+
+  std::unique_ptr<SyncAuthManager> auth_manager = CreateAuthManager();
+
+  auth_manager->RegisterForAuthNotifications();
+
+  ASSERT_EQ(auth_manager->GetActiveAccountInfo().account_info.account_id,
+            account_id);
+  ASSERT_EQ(auth_manager->GetLastAuthError().state(),
             GoogleServiceAuthError::NONE);
 
-  // Now actually sign out, i.e. remove the primary account. This should clear
-  // the auth error, since it's now not meaningful anymore.
+  // Sign out of the account.
+  // The ordering of removing the refresh token and the actual sign-out is
+  // undefined, see comment on IdentityManager::Observer. Here, do *not* remove
+  // the refresh token first (see also other test above which does remove it).
+
+  // Signing out, i.e. removing the primary account, should clear the auth
+  // error, since it's now not meaningful anymore.
   identity_env()->ClearPrimaryAccount();
   EXPECT_EQ(auth_manager->GetLastAuthError().state(),
             GoogleServiceAuthError::NONE);
@@ -276,7 +308,7 @@
   auth_manager->ConnectionOpened();
 
   // Force an auth error by revoking the refresh token.
-  identity_env()->RemoveRefreshTokenForPrimaryAccount();
+  identity_env()->SetInvalidRefreshTokenForPrimaryAccount();
   ASSERT_NE(auth_manager->GetLastAuthError().state(),
             GoogleServiceAuthError::NONE);
 
@@ -330,8 +362,11 @@
 
   // Revoking the refresh token should also cause the access token to get
   // dropped.
-  EXPECT_CALL(credentials_changed, Run());
-  identity_env()->RemoveRefreshTokenForPrimaryAccount();
+  // Note: On ChromeOS-Ash, setting an invalid refresh token causes 2
+  // "credentials changed" events, one for the token change itself, and another
+  // one for the auth error caused by the invalid token.
+  EXPECT_CALL(credentials_changed, Run()).Times(testing::AtLeast(1));
+  identity_env()->SetInvalidRefreshTokenForPrimaryAccount();
   EXPECT_TRUE(auth_manager->GetCredentials().access_token.empty());
 }
 
@@ -668,7 +703,7 @@
   EXPECT_CALL(access_token_requested, Run()).Times(0);
   identity_env()->SetCallbackForNextAccessTokenRequest(
       access_token_requested.Get());
-  identity_env()->RemoveRefreshTokenForPrimaryAccount();
+  identity_env()->SetInvalidRefreshTokenForPrimaryAccount();
 
   // Should immediately drop the access token and expose an auth error.
   EXPECT_TRUE(auth_manager->GetCredentials().access_token.empty());
@@ -864,7 +899,7 @@
 
 #if !BUILDFLAG(IS_CHROMEOS_ASH) && !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS)
 // Primary account with no sync consent is not supported on Android and iOS.
-// On crOS the unconsented primary account can't be changed or removed, but can
+// On CrOS the unconsented primary account can't be changed or removed, but can
 // be granted sync consent.
 TEST_F(SyncAuthManagerTest, PicksNewPrimaryAccountWithSyncConsent) {
   std::unique_ptr<SyncAuthManager> auth_manager = CreateAuthManager();
diff --git a/components/sync/driver/sync_auth_util.cc b/components/sync/driver/sync_auth_util.cc
index 6e72200b..bcef006ca 100644
--- a/components/sync/driver/sync_auth_util.cc
+++ b/components/sync/driver/sync_auth_util.cc
@@ -4,9 +4,10 @@
 
 #include "components/sync/driver/sync_auth_util.h"
 
+#include "base/feature_list.h"
 #include "components/signin/public/base/consent_level.h"
-#include "components/signin/public/identity_manager/accounts_in_cookie_jar_info.h"
 #include "components/signin/public/identity_manager/identity_manager.h"
+#include "components/sync/base/features.h"
 
 namespace syncer {
 
@@ -18,6 +19,18 @@
 
 SyncAccountInfo DetermineAccountToUse(
     signin::IdentityManager* identity_manager) {
+  // TODO(crbug.com/1383977): During signout, it can happen that the primary
+  // account temporarily doesn't have a refresh token (before the account
+  // itself gets removed). As a workaround for crbug.com/1383912 /
+  // crbug.com/897628, do *not* use the account for Sync in this case. This
+  // ensures that Sync metadata gets properly cleared during signout.
+  if (identity_manager->AreRefreshTokensLoaded() &&
+      !identity_manager->HasPrimaryAccountWithRefreshToken(
+          signin::ConsentLevel::kSignin) &&
+      base::FeatureList::IsEnabled(kSyncIgnoreAccountWithoutRefreshToken)) {
+    return SyncAccountInfo();
+  }
+
   return SyncAccountInfo(
       identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin),
       /*is_sync_consented=*/identity_manager->HasPrimaryAccount(
diff --git a/components/sync/driver/sync_service_impl_startup_unittest.cc b/components/sync/driver/sync_service_impl_startup_unittest.cc
index 089ef02d..f7adb44a 100644
--- a/components/sync/driver/sync_service_impl_startup_unittest.cc
+++ b/components/sync/driver/sync_service_impl_startup_unittest.cc
@@ -77,6 +77,20 @@
         kEmail, signin::ConsentLevel::kSync);
   }
 
+  void SimulateRefreshTokensNotLoadedYet() {
+    // First, wait for the actual refresh token load to complete if necessary.
+    // Otherwise, if it was still ongoing, it might reset the state back to
+    // "everything loaded" once it completes.
+    sync_service_impl_bundle_.identity_test_env()->WaitForRefreshTokensLoaded();
+    sync_service_impl_bundle_.identity_test_env()
+        ->ResetToAccountsNotYetLoadedFromDiskState();
+  }
+
+  void SimulateRefreshTokensLoad() {
+    sync_service_impl_bundle_.identity_test_env()->ReloadAccountsFromDisk();
+    sync_service_impl_bundle_.identity_test_env()->WaitForRefreshTokensLoaded();
+  }
+
   void SimulateTestUserSigninWithoutRefreshToken() {
     // Set the primary account *without* providing an OAuth token.
     sync_service_impl_bundle_.identity_test_env()->SetPrimaryAccount(
@@ -222,6 +236,7 @@
 
 TEST_F(SyncServiceImplStartupTest, StartNoCredentials) {
   // We're already signed in, but don't have a refresh token.
+  SimulateRefreshTokensNotLoadedYet();
   SimulateTestUserSigninWithoutRefreshToken();
   sync_prefs()->SetFirstSetupComplete();
 
@@ -365,6 +380,7 @@
 
   // On ChromeOS, the user is always immediately signed in, but a refresh token
   // isn't necessarily available yet.
+  SimulateRefreshTokensNotLoadedYet();
   SimulateTestUserSigninWithoutRefreshToken();
 
   CreateSyncService(SyncServiceImpl::AUTO_START);
@@ -383,16 +399,15 @@
 }
 
 TEST_F(SyncServiceImplStartupTest, StartCrosFirstTime) {
-  // On ChromeOS, the user is always immediately signed in, but a refresh token
-  // isn't necessarily available yet.
-  SimulateTestUserSigninWithoutRefreshToken();
-
-  CreateSyncService(SyncServiceImpl::AUTO_START);
+  // We've never completed Sync startup.
   ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
 
-  // The primary account is already populated, all that's left to do is provide
-  // a refresh token.
-  UpdateCredentials();
+  // There is already a signed-in user.
+  SimulateTestUserSignin();
+
+  // Sync should become active, even though IsFirstSetupComplete wasn't set yet,
+  // due to AUTO_START.
+  CreateSyncService(SyncServiceImpl::AUTO_START);
   sync_service()->Initialize();
   base::RunLoop().RunUntilIdle();
   EXPECT_EQ(SyncService::TransportState::ACTIVE,
diff --git a/components/sync/engine/loopback_server/loopback_server.cc b/components/sync/engine/loopback_server/loopback_server.cc
index 937b420..c061973a 100644
--- a/components/sync/engine/loopback_server/loopback_server.cc
+++ b/components/sync/engine/loopback_server/loopback_server.cc
@@ -792,17 +792,14 @@
   return sync_entities;
 }
 
-std::unique_ptr<base::DictionaryValue>
-LoopbackServer::GetEntitiesAsDictionaryValue() {
+std::unique_ptr<base::Value::Dict> LoopbackServer::GetEntitiesAsDict() {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  std::unique_ptr<base::DictionaryValue> dictionary(
-      new base::DictionaryValue());
+  auto dictionary = std::make_unique<base::Value::Dict>();
 
   // Initialize an empty Value::List for all ModelTypes.
   ModelTypeSet all_types = ModelTypeSet::All();
   for (ModelType type : all_types) {
-    dictionary->SetKey(ModelTypeToDebugString(type),
-                       base::Value(base::Value::Type::LIST));
+    dictionary->Set(ModelTypeToDebugString(type), base::Value::List());
   }
 
   for (const auto& [id, entity] : entities_) {
@@ -812,11 +809,12 @@
       // consider them.
       continue;
     }
-    base::Value* list_value;
-    if (!dictionary->Get(ModelTypeToDebugString(entity->GetModelType()),
-                         &list_value)) {
+
+    base::Value::List* list_value =
+        dictionary->FindList(ModelTypeToDebugString(entity->GetModelType()));
+    if (!list_value)
       return nullptr;
-    }
+
     // TODO(pvalenzuela): Store more data for each entity so additional
     // verification can be performed. One example of additional verification
     // is checking the correctness of the bookmark hierarchy.
diff --git a/components/sync/engine/loopback_server/loopback_server.h b/components/sync/engine/loopback_server/loopback_server.h
index 0bd8dcb6..cd068250 100644
--- a/components/sync/engine/loopback_server/loopback_server.h
+++ b/components/sync/engine/loopback_server/loopback_server.h
@@ -183,12 +183,12 @@
   std::vector<sync_pb::SyncEntity> GetPermanentSyncEntitiesByModelType(
       syncer::ModelType model_type);
 
-  // Creates a DictionaryValue representation of all entities present in the
+  // Creates a `base::Value::Dict` representation of all entities present in the
   // server. The dictionary keys are the strings generated by
   // ModelTypeToDebugString and the values are Value::Lists containing
   // StringValue versions of entity names. Permanent entities are excluded. Used
   // by test to verify the contents of the server state.
-  std::unique_ptr<base::DictionaryValue> GetEntitiesAsDictionaryValue();
+  std::unique_ptr<base::Value::Dict> GetEntitiesAsDict();
 
   // Modifies the entity on the server with the given |id|. The entity's
   // EntitySpecifics are replaced with |updated_specifics| and its version is
diff --git a/components/sync/engine/sync_engine.h b/components/sync/engine/sync_engine.h
index c368875..4370f9b 100644
--- a/components/sync/engine/sync_engine.h
+++ b/components/sync/engine/sync_engine.h
@@ -59,7 +59,7 @@
 
     ~InitParams();
 
-    raw_ptr<SyncEngineHost> host = nullptr;
+    raw_ptr<SyncEngineHost, DanglingUntriaged> host = nullptr;
     std::unique_ptr<SyncEncryptionHandler::Observer> encryption_observer_proxy;
     scoped_refptr<ExtensionsActivity> extensions_activity;
     GURL service_url;
diff --git a/components/sync/test/fake_server.cc b/components/sync/test/fake_server.cc
index 720b5bf..96d0bd5 100644
--- a/components/sync/test/fake_server.cc
+++ b/components/sync/test/fake_server.cc
@@ -365,10 +365,9 @@
   loopback_server_->OverrideResponseType(std::move(response_type_override));
 }
 
-std::unique_ptr<base::DictionaryValue>
-FakeServer::GetEntitiesAsDictionaryValue() {
+std::unique_ptr<base::Value::Dict> FakeServer::GetEntitiesAsDict() {
   DCHECK(thread_checker_.CalledOnValidThread());
-  return loopback_server_->GetEntitiesAsDictionaryValue();
+  return loopback_server_->GetEntitiesAsDict();
 }
 
 std::vector<sync_pb::SyncEntity> FakeServer::GetSyncEntitiesByModelType(
diff --git a/components/sync/test/fake_server.h b/components/sync/test/fake_server.h
index 1c31adc..59157ee 100644
--- a/components/sync/test/fake_server.h
+++ b/components/sync/test/fake_server.h
@@ -98,11 +98,11 @@
   bool GetLastCommitMessage(sync_pb::ClientToServerMessage* message);
   bool GetLastGetUpdatesMessage(sync_pb::ClientToServerMessage* message);
 
-  // Creates a DictionaryValue representation of all entities present in the
+  // Creates a `base::Value::Dict` representation of all entities present in the
   // server. The dictionary keys are the strings generated by
   // ModelTypeToDebugString and the values are Value::Lists containing
   // StringValue versions of entity names.
-  std::unique_ptr<base::DictionaryValue> GetEntitiesAsDictionaryValue();
+  std::unique_ptr<base::Value::Dict> GetEntitiesAsDict();
 
   // Returns all entities stored by the server of the given |model_type|.
   // This method returns SyncEntity protocol buffer objects (instead of
diff --git a/components/sync/test/fake_server_verifier.cc b/components/sync/test/fake_server_verifier.cc
index 736651d7..c013703c 100644
--- a/components/sync/test/fake_server_verifier.cc
+++ b/components/sync/test/fake_server_verifier.cc
@@ -50,9 +50,7 @@
                             << "; Expected contents: " << expected.ToString();
 }
 
-// Caller maintains ownership of |entities|.
-string ConvertFakeServerContentsToString(
-    const base::DictionaryValue& entities) {
+string ConvertFakeServerContentsToString(const base::Value::Dict& entities) {
   string entities_str;
   if (!JSONWriter::WriteWithOptions(entities, JSONWriter::OPTIONS_PRETTY_PRINT,
                                     &entities_str)) {
@@ -71,16 +69,14 @@
 AssertionResult FakeServerVerifier::VerifyEntityCountByType(
     size_t expected_count,
     syncer::ModelType model_type) const {
-  std::unique_ptr<base::DictionaryValue> entities =
-      fake_server_->GetEntitiesAsDictionaryValue();
+  std::unique_ptr<base::Value::Dict> entities =
+      fake_server_->GetEntitiesAsDict();
   if (!entities) {
     return DictionaryCreationAssertionFailure();
   }
-  base::DictAdapterForMigration entities_dict =
-      base::DictAdapterForMigration(*entities);
   string model_type_string = ModelTypeToDebugString(model_type);
-  const base::Value::List* entity_list;
-  entity_list = entities_dict.FindList(model_type_string);
+  const base::Value::List* entity_list = entities->FindList(model_type_string);
+  DCHECK(entity_list);
   if (expected_count != entity_list->size()) {
     return VerificationCountAssertionFailure(entity_list->size(),
                                              expected_count)
@@ -95,18 +91,14 @@
     size_t expected_count,
     syncer::ModelType model_type,
     const string& name) const {
-  std::unique_ptr<base::DictionaryValue> entities =
-      fake_server_->GetEntitiesAsDictionaryValue();
+  std::unique_ptr<base::Value::Dict> entities =
+      fake_server_->GetEntitiesAsDict();
   if (!entities) {
     return DictionaryCreationAssertionFailure();
   }
 
-  base::DictAdapterForMigration entities_dict =
-      base::DictAdapterForMigration(*entities);
-
   string model_type_string = ModelTypeToDebugString(model_type);
-  const base::Value::List* entity_list;
-  entity_list = entities_dict.FindList(model_type_string);
+  const base::Value::List* entity_list = entities->FindList(model_type_string);
   size_t actual_count = 0;
   base::Value name_value(name);
 
diff --git a/components/test/data/optimization_guide/visibility_test_model.tflite b/components/test/data/optimization_guide/visibility_test_model.tflite
new file mode 100644
index 0000000..350f94f4
--- /dev/null
+++ b/components/test/data/optimization_guide/visibility_test_model.tflite
Binary files differ
diff --git a/components/ukm/ukm_test_helper.h b/components/ukm/ukm_test_helper.h
index ddabed5..4fa1f5f 100644
--- a/components/ukm/ukm_test_helper.h
+++ b/components/ukm/ukm_test_helper.h
@@ -59,7 +59,7 @@
   bool HasUnsentLogs();
 
  private:
-  const raw_ptr<UkmService> ukm_service_;
+  const raw_ptr<UkmService, DanglingUntriaged> ukm_service_;
 };
 
 }  // namespace ukm
diff --git a/components/user_education/common/tutorial_service.h b/components/user_education/common/tutorial_service.h
index 73ac9d4a..acec27a8 100644
--- a/components/user_education/common/tutorial_service.h
+++ b/components/user_education/common/tutorial_service.h
@@ -89,7 +89,7 @@
     TutorialCreationParams(TutorialDescription* description,
                            ui::ElementContext context);
 
-    raw_ptr<TutorialDescription> description_;
+    raw_ptr<TutorialDescription, DanglingUntriaged> description_;
     ui::ElementContext context_;
   };
 
diff --git a/components/webapps/browser/installable/installable_data.h b/components/webapps/browser/installable/installable_data.h
index a3cbe7e..68d06f97 100644
--- a/components/webapps/browser/installable/installable_data.h
+++ b/components/webapps/browser/installable/installable_data.h
@@ -81,13 +81,13 @@
 
   // The URL of the the web app manifest. Empty if the site has no
   // <link rel="manifest"> tag.
-  const raw_ref<const GURL> manifest_url;
+  const raw_ref<const GURL, DanglingUntriaged> manifest_url;
 
   // The parsed web app manifest.
-  const raw_ref<const blink::mojom::Manifest> manifest;
+  const raw_ref<const blink::mojom::Manifest, DanglingUntriaged> manifest;
 
   // The URL of the chosen primary icon.
-  const raw_ref<const GURL> primary_icon_url;
+  const raw_ref<const GURL, DanglingUntriaged> primary_icon_url;
 
   // nullptr if the most appropriate primary icon couldn't be determined or
   // downloaded. The underlying primary icon is owned by the InstallableManager;
@@ -99,7 +99,7 @@
   const bool has_maskable_primary_icon;
 
   // The URL of the chosen splash icon.
-  const raw_ref<const GURL> splash_icon_url;
+  const raw_ref<const GURL, DanglingUntriaged> splash_icon_url;
 
   // nullptr if the most appropriate splash icon couldn't be determined or
   // downloaded. The underlying splash icon is owned by the InstallableManager;
@@ -114,7 +114,7 @@
   const bool has_maskable_splash_icon;
 
   // The screenshots to show in the install UI.
-  const raw_ref<const std::vector<Screenshot>> screenshots;
+  const raw_ref<const std::vector<Screenshot>, DanglingUntriaged> screenshots;
 
   // true if the site has a valid, installable web app manifest. If
   // |valid_manifest| or |worker_check_passed| was true and the site isn't
diff --git a/content/browser/browser_plugin/browser_plugin_embedder.h b/content/browser/browser_plugin/browser_plugin_embedder.h
index d067340..ad5f1925 100644
--- a/content/browser/browser_plugin/browser_plugin_embedder.h
+++ b/content/browser/browser_plugin/browser_plugin_embedder.h
@@ -64,7 +64,7 @@
   static bool GuestCurrentlyAudibleCallback(WebContents* guest);
 
   // Pointer to the WebContentsImpl that owns this object.
-  raw_ptr<WebContentsImpl> web_contents_;
+  raw_ptr<WebContentsImpl, DanglingUntriaged> web_contents_;
 };
 
 }  // namespace content
diff --git a/content/browser/interest_group/auction_worklet_manager.h b/content/browser/interest_group/auction_worklet_manager.h
index 18ba9e2d2..aefcce5 100644
--- a/content/browser/interest_group/auction_worklet_manager.h
+++ b/content/browser/interest_group/auction_worklet_manager.h
@@ -174,7 +174,8 @@
     FatalErrorCallback fatal_error_callback_;
 
     // Never null, owned by InterestGroupAuction / InterestGroupAuctionReporter.
-    const raw_ptr<const SubresourceUrlBuilder> subresource_url_builder_;
+    const raw_ptr<const SubresourceUrlBuilder, DanglingUntriaged>
+        subresource_url_builder_;
   };
 
   // `delegate` and `auction_process_manager` must outlive the created
diff --git a/content/browser/preloading/prerender/prerender_host.cc b/content/browser/preloading/prerender/prerender_host.cc
index 0ef3284..5f8ce907 100644
--- a/content/browser/preloading/prerender/prerender_host.cc
+++ b/content/browser/preloading/prerender/prerender_host.cc
@@ -417,9 +417,6 @@
   // frame_tree_->root(). Do not add any code between here and
   // frame_tree_.reset() that calls into observer functions to minimize the
   // duration of current_frame_host being null.
-  //
-  // TODO(https://crbug.com/1176148): Investigate how to combine taking the
-  // prerendered page and frame_tree_ destruction.
   std::unique_ptr<StoredPage> page =
       frame_tree_->root()->render_manager()->TakePrerenderedPage();
 
@@ -474,6 +471,9 @@
     subframe_node->SetFrameTree(target_frame_tree);
   }
 
+  frame_tree_->Shutdown();
+  frame_tree_.reset();
+
   page->render_frame_host()->ForEachRenderFrameHostIncludingSpeculative(
       [this](RenderFrameHostImpl* rfh) {
         // The visibility state of the prerendering page has not been
@@ -485,9 +485,6 @@
             web_contents_->GetPageVisibilityState());
       });
 
-  frame_tree_->Shutdown();
-  frame_tree_.reset();
-
   for (auto& observer : observers_)
     observer.OnActivated();
 
diff --git a/content/browser/reduce_accept_language/reduce_accept_language_utils.h b/content/browser/reduce_accept_language/reduce_accept_language_utils.h
index 6bd154c..3dc8510d 100644
--- a/content/browser/reduce_accept_language/reduce_accept_language_utils.h
+++ b/content/browser/reduce_accept_language/reduce_accept_language_utils.h
@@ -160,7 +160,7 @@
 
   // The delegate is owned by the BrowserContext, which should always outlive
   // this utility class.
-  raw_ref<ReduceAcceptLanguageControllerDelegate> delegate_;
+  raw_ref<ReduceAcceptLanguageControllerDelegate, DanglingUntriaged> delegate_;
 };
 
 }  // namespace content
diff --git a/content/browser/renderer_host/cursor_manager.h b/content/browser/renderer_host/cursor_manager.h
index 220df45e..229475d 100644
--- a/content/browser/renderer_host/cursor_manager.h
+++ b/content/browser/renderer_host/cursor_manager.h
@@ -54,7 +54,7 @@
 
   // The view currently underneath the cursor, which corresponds to the cursor
   // currently displayed.
-  raw_ptr<RenderWidgetHostViewBase> view_under_cursor_;
+  raw_ptr<RenderWidgetHostViewBase, DanglingUntriaged> view_under_cursor_;
 
   // The root view is the target for DisplayCursor calls whenever the active
   // cursor needs to change.
diff --git a/content/browser/service_worker/service_worker_ping_controller.h b/content/browser/service_worker/service_worker_ping_controller.h
index e247b91..485dd16 100644
--- a/content/browser/service_worker/service_worker_ping_controller.h
+++ b/content/browser/service_worker/service_worker_ping_controller.h
@@ -46,7 +46,7 @@
   void ClearLastPingTime();
 
   enum class PingState { kNotPinging, kPinging, kPingTimedOut };
-  raw_ptr<ServiceWorkerVersion> version_;  // Owns |this|.
+  raw_ptr<ServiceWorkerVersion, DanglingUntriaged> version_;  // Owns |this|.
   // The time the most recent ping was sent.
   base::TimeTicks last_ping_time_;
   PingState ping_state_ = PingState::kNotPinging;
diff --git a/content/browser/site_per_process_browsertest.cc b/content/browser/site_per_process_browsertest.cc
index a1c1872..233e456 100644
--- a/content/browser/site_per_process_browsertest.cc
+++ b/content/browser/site_per_process_browsertest.cc
@@ -8496,7 +8496,7 @@
     }
 
    private:
-    const raw_ref<RenderFrameHost> requesting_rfh_;
+    const raw_ref<RenderFrameHost, DanglingUntriaged> requesting_rfh_;
   };
 
   // Set up a test page with a same-site child frame.
diff --git a/content/services/auction_worklet/auction_v8_helper.h b/content/services/auction_worklet/auction_v8_helper.h
index 871bcb7..bc7016c7 100644
--- a/content/services/auction_worklet/auction_v8_helper.h
+++ b/content/services/auction_worklet/auction_v8_helper.h
@@ -138,7 +138,7 @@
 
    private:
     friend class AuctionV8Helper;
-    raw_ptr<uint8_t> buffer_;
+    raw_ptr<uint8_t, DanglingUntriaged> buffer_;
     size_t size_;
   };
 
diff --git a/content/test/data/gpu/pixel_webgpu_display_p3.html b/content/test/data/gpu/pixel_webgpu_display_p3.html
new file mode 100644
index 0000000..f067aa4e
--- /dev/null
+++ b/content/test/data/gpu/pixel_webgpu_display_p3.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<html>
+<!--
+Clears a WebGGPU canvas to the value (0.91749, 0.20029, 0.13856, 1.0). When
+interpreted in Display P3, this appears the same as rgb(100% 0% 0%). Display
+the canvas next to the correct color and a likely incorrect color.
+-->
+<head>
+  <style type="text/css">
+    .nomargin {
+      margin: 0;
+    }
+  </style>
+  <script type="text/javascript">
+    var g_swapsBeforeAck = 15;
+
+    function waitForFinish() {
+      if (g_swapsBeforeAck == 0) {
+        sendResult("SUCCESS");
+      } else {
+        g_swapsBeforeAck--;
+        window.requestAnimationFrame(waitForFinish);
+      }
+    }
+
+    function sendResult(status) {
+      if (window.domAutomationController) {
+        window.domAutomationController.send(status);
+      } else {
+        console.log(status);
+      }
+    }
+
+    var g_swapsBeforeAck = 15;
+    function waitForFinish() {
+      if (g_swapsBeforeAck == 0) {
+        sendResult("SUCCESS");
+      } else {
+        g_swapsBeforeAck--;
+        window.requestAnimationFrame(waitForFinish);
+      }
+    }
+
+    async function main() {
+      const canvas = document.getElementById('canvas_gpu');
+      const adapter = await navigator.gpu?.requestAdapter();
+      const device = await adapter?.requestDevice();
+      const context = canvas.getContext('webgpu');
+      if (!device || !context) {
+        console.error("Failed to initialize WebGPU");
+        sendResult("FAILURE");
+      }
+
+      context.configure({
+        device: device,
+        format: 'bgra8unorm',
+        usage: GPUTextureUsage.RENDER_ATTACHMENT,
+        alphaMode: 'opaque',
+        colorSpace: 'display-p3',
+      });
+
+      const renderPassDescriptor = {
+        colorAttachments: [
+          {
+            view: context.getCurrentTexture().createView(),
+            clearValue: { r: 0.91749, g: 0.20029, b: 0.13856, a: 1.0 },
+            loadOp: 'clear',
+            storeOp: 'store',
+          },
+        ],
+      };
+
+      const commandEncoder = device.createCommandEncoder();
+      const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
+      passEncoder.end();
+      device.queue.submit([commandEncoder.finish()]);
+
+      waitForFinish();
+    }
+  </script>
+</head>
+
+<body onload="main()" style="background:white;">
+  <canvas id="canvas_gpu" style="width:150px; height:150px; position:absolute; top:0px; left:0px; background: rgb(0% 100% 0%);"></canvas>
+  <div style="width:150px; height:150px; position:absolute; top:150px; left:0px; background: rgb(91.749% 20.029% 13.856%);">
+    <p>The canvas above SHOULD NOT match this color</p>
+  </div>
+  <div style="width:150px; height:150px; position:absolute; top:0px; left:150px; background: rgb(100% 0% 0%);">
+    <p>The canvas to the left SHOULD match this color</p>
+  </div>
+</body>
+
+</html>
diff --git a/content/test/gpu/gpu_tests/pixel_test_pages.py b/content/test/gpu/gpu_tests/pixel_test_pages.py
index 00af39b..ef1a1d3 100644
--- a/content/test/gpu/gpu_tests/pixel_test_pages.py
+++ b/content/test/gpu/gpu_tests/pixel_test_pages.py
@@ -506,6 +506,10 @@
                         base_name + '_WebGPUCopyExternalImageWebGPUCanvas',
                         test_rect=[0, 0, 400, 200],
                         browser_args=webgpu_args),
+          PixelTestPage('pixel_webgpu_display_p3.html',
+                        base_name + '_WebGPUDisplayP3',
+                        test_rect=[0, 0, 300, 300],
+                        browser_args=webgpu_args),
       ]
 
     return (webgpu_pages_helper(base_name, mode=Mode.WEBGPU_DEFAULT) +
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
index 60ec7e47..e40734b 100644
--- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
+++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -508,7 +508,6 @@
 crbug.com/1286830 [ android android-pixel-6 arm ] WebglExtension_WEBGL_draw_buffers [ Failure ]
 crbug.com/1286924 [ android android-pixel-6 arm ] conformance/textures/video/* [ Failure ]
 crbug.com/1286924 [ android android-pixel-6 arm passthrough ] conformance/glsl/bugs/constant-precision-qualifier.html [ Failure ]
-crbug.com/1287249 [ android android-pixel-6 passthrough ] conformance/extensions/oes-texture-half-float-with-video.html [ Failure ]
 crbug.com/1287249 [ android android-pixel-6 no-passthrough ] conformance/glsl/bugs/constant-precision-qualifier.html [ Failure ]
 crbug.com/1287280 [ android android-pixel-6 no-passthrough ] conformance/more/conformance/quickCheckAPI-A.html [ Failure ]
 crbug.com/1287280 [ android android-pixel-6 no-passthrough ] conformance/offscreencanvas/context-lost-restored-worker.html [ Failure ]
diff --git a/device/bluetooth/dbus/fake_bluetooth_advertisement_monitor_manager_client.h b/device/bluetooth/dbus/fake_bluetooth_advertisement_monitor_manager_client.h
index 85fbbc3d..6db39f9 100644
--- a/device/bluetooth/dbus/fake_bluetooth_advertisement_monitor_manager_client.h
+++ b/device/bluetooth/dbus/fake_bluetooth_advertisement_monitor_manager_client.h
@@ -67,7 +67,8 @@
   void OnPropertyChanged(const dbus::ObjectPath& object_path,
                          const std::string& property_name);
 
-  raw_ptr<FakeBluetoothAdvertisementMonitorApplicationServiceProvider>
+  raw_ptr<FakeBluetoothAdvertisementMonitorApplicationServiceProvider,
+          DanglingUntriaged>
       application_provider_ = nullptr;
   std::unique_ptr<Properties> properties_;
 
diff --git a/extensions/browser/api/BUILD.gn b/extensions/browser/api/BUILD.gn
index 41e6dd7..6dfdc7e 100644
--- a/extensions/browser/api/BUILD.gn
+++ b/extensions/browser/api/BUILD.gn
@@ -113,7 +113,10 @@
   ]
 
   if (is_chromeos) {
-    public_deps += [ "//extensions/browser/api/virtual_keyboard" ]
+    public_deps += [
+      "//extensions/browser/api/virtual_keyboard",
+      "//extensions/browser/api/webcam_private",
+    ]
   }
 
   if (is_chromeos_ash) {
@@ -122,7 +125,6 @@
       "//extensions/browser/api/diagnostics",
       "//extensions/browser/api/lock_screen_data",
       "//extensions/browser/api/media_perception_private",
-      "//extensions/browser/api/webcam_private",
     ]
   }
 }
diff --git a/extensions/browser/api/system_display/system_display_apitest.cc b/extensions/browser/api/system_display/system_display_apitest.cc
index d3fd820..0c5c149 100644
--- a/extensions/browser/api/system_display/system_display_apitest.cc
+++ b/extensions/browser/api/system_display/system_display_apitest.cc
@@ -20,6 +20,7 @@
 #include "extensions/common/extension_builder.h"
 #include "extensions/shell/test/shell_apitest.h"
 #include "extensions/test/result_catcher.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/display/screen.h"
 
 namespace extensions {
@@ -68,8 +69,7 @@
       api_test_utils::RunFunctionAndReturnError(
           set_info_function.get(), "[\"display_id\", {}]", browser_context()));
 
-  std::unique_ptr<base::DictionaryValue> set_info =
-      provider_->GetSetInfoValue();
+  absl::optional<base::Value::Dict> set_info = provider_->GetSetInfoValue();
   EXPECT_FALSE(set_info);
 }
 
@@ -97,18 +97,16 @@
       "}]",
       browser_context()));
 
-  std::unique_ptr<base::DictionaryValue> set_info_value =
-      provider_->GetSetInfoValue();
-  ASSERT_TRUE(set_info_value);
-  base::Value::Dict set_info = std::move(*set_info_value).TakeDict();
+  absl::optional<base::Value::Dict> set_info = provider_->GetSetInfoValue();
+  ASSERT_TRUE(set_info);
 
-  EXPECT_TRUE(api_test_utils::GetBoolean(set_info, "isPrimary"));
+  EXPECT_TRUE(api_test_utils::GetBoolean(*set_info, "isPrimary"));
   EXPECT_EQ("mirroringId",
-            api_test_utils::GetString(set_info, "mirroringSourceId"));
-  EXPECT_EQ(100, api_test_utils::GetInteger(set_info, "boundsOriginX"));
-  EXPECT_EQ(200, api_test_utils::GetInteger(set_info, "boundsOriginY"));
-  EXPECT_EQ(90, api_test_utils::GetInteger(set_info, "rotation"));
-  base::Value::Dict overscan = api_test_utils::GetDict(set_info, "overscan");
+            api_test_utils::GetString(*set_info, "mirroringSourceId"));
+  EXPECT_EQ(100, api_test_utils::GetInteger(*set_info, "boundsOriginX"));
+  EXPECT_EQ(200, api_test_utils::GetInteger(*set_info, "boundsOriginY"));
+  EXPECT_EQ(90, api_test_utils::GetInteger(*set_info, "rotation"));
+  base::Value::Dict overscan = api_test_utils::GetDict(*set_info, "overscan");
   EXPECT_EQ(1, api_test_utils::GetInteger(overscan, "left"));
   EXPECT_EQ(2, api_test_utils::GetInteger(overscan, "top"));
   EXPECT_EQ(3, api_test_utils::GetInteger(overscan, "right"));
diff --git a/extensions/browser/api/webcam_private/BUILD.gn b/extensions/browser/api/webcam_private/BUILD.gn
index 400c9c3..c1b6aa885 100644
--- a/extensions/browser/api/webcam_private/BUILD.gn
+++ b/extensions/browser/api/webcam_private/BUILD.gn
@@ -7,7 +7,7 @@
 
 assert(enable_extensions,
        "Cannot depend on extensions because enable_extensions=false.")
-assert(is_chromeos_ash)
+assert(is_chromeos)
 
 source_set("webcam_private") {
   sources = [
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 0f6034d..7cc68648 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1793,6 +1793,8 @@
   PASSWORDSPRIVATE_REQUESTCREDENTIALSDETAILS = 1730,
   PASSWORDSPRIVATE_GETCREDENTIALGROUPS = 1731,
   AUTOTESTPRIVATE_GETLAUNCHERSSEARCHBOXSTATE = 1732,
+  OS_DIAGNOSTICS_RUNSENSITIVESENSORROUTINE = 1733,
+  OS_DIAGNOSTICS_RUNNVMESELFTESTROUTINE = 1734,
   // Last entry: Add new entries above, then run:
   // tools/metrics/histograms/update_extension_histograms.py
   ENUM_BOUNDARY
diff --git a/extensions/browser/extension_prefs.cc b/extensions/browser/extension_prefs.cc
index fc03065..a0dca12 100644
--- a/extensions/browser/extension_prefs.cc
+++ b/extensions/browser/extension_prefs.cc
@@ -1976,10 +1976,10 @@
       // we could instead initialize the controlled preferences when the
       // extension is more finalized, but this also needs to happen sufficiently
       // before other subsystems are notified about the extension being loaded.
-      Manifest::Type type =
-          info->extension_manifest
-              ? Manifest::GetTypeFromManifestValue(*info->extension_manifest)
-              : Manifest::TYPE_UNKNOWN;
+      Manifest::Type type = info->extension_manifest
+                                ? Manifest::GetTypeFromManifestValue(
+                                      info->extension_manifest->GetDict())
+                                : Manifest::TYPE_UNKNOWN;
       bool is_theme = type == Manifest::TYPE_THEME;
       // Erase the entry if the extension won't be loaded.
       return !Manifest::ShouldAlwaysLoadExtension(info->extension_location,
@@ -2604,7 +2604,7 @@
     // We only want to migrate extensions we can actually withhold permissions
     // from.
     Manifest::Type type =
-        Manifest::GetTypeFromManifestValue(*info->extension_manifest);
+        Manifest::GetTypeFromManifestValue(info->extension_manifest->GetDict());
     ManifestLocation location = info->extension_location;
     if (!util::CanWithholdPermissionsFromExtension(extension_id, type,
                                                    location))
diff --git a/extensions/browser/mock_display_info_provider.cc b/extensions/browser/mock_display_info_provider.cc
index 503061b..5a8ab523 100644
--- a/extensions/browser/mock_display_info_provider.cc
+++ b/extensions/browser/mock_display_info_provider.cc
@@ -27,8 +27,7 @@
     ErrorCallback callback) {
   // Should get called only once per test case.
   DCHECK(!set_info_value_);
-  set_info_value_ = base::DictionaryValue::From(
-      base::Value::ToUniquePtrValue(base::Value(properties.ToValue())));
+  set_info_value_ = properties.ToValue();
   set_info_display_id_ = display_id;
   base::ThreadTaskRunnerHandle::Get()->PostTask(
       FROM_HERE, base::BindOnce(std::move(callback), absl::nullopt));
diff --git a/extensions/browser/mock_display_info_provider.h b/extensions/browser/mock_display_info_provider.h
index 66e93e79..1652e2f 100644
--- a/extensions/browser/mock_display_info_provider.h
+++ b/extensions/browser/mock_display_info_provider.h
@@ -15,6 +15,7 @@
 #include "extensions/browser/api/system_display/display_info_provider.h"
 #include "extensions/browser/mock_screen.h"
 #include "extensions/common/api/system_display.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
 
 namespace extensions {
 
@@ -50,7 +51,7 @@
                      ErrorCallback callback) override;
 
   // Helpers, accessors.
-  std::unique_ptr<base::DictionaryValue> GetSetInfoValue() {
+  absl::optional<base::Value::Dict> GetSetInfoValue() {
     return std::move(set_info_value_);
   }
 
@@ -78,7 +79,7 @@
       const std::vector<display::Display>& displays,
       DisplayUnitInfoList& units) const override;
 
-  std::unique_ptr<base::DictionaryValue> set_info_value_;
+  absl::optional<base::Value::Dict> set_info_value_;
   std::string set_info_display_id_;
   bool unified_desktop_enabled_ = false;
   std::set<std::string> overscan_started_;
diff --git a/extensions/browser/zipfile_installer.cc b/extensions/browser/zipfile_installer.cc
index 9eb7e36..bee12ea 100644
--- a/extensions/browser/zipfile_installer.cc
+++ b/extensions/browser/zipfile_installer.cc
@@ -171,21 +171,13 @@
     const base::FilePath& unzip_dir,
     absl::optional<base::Value> result,
     const absl::optional<std::string>& error) {
-  if (!result) {
-    ReportFailure(std::string(kExtensionHandlerFileUnzipError));
-    return;
-  }
-
-  std::unique_ptr<base::DictionaryValue> manifest_dictionary =
-      base::DictionaryValue::From(
-          base::Value::ToUniquePtrValue(std::move(*result)));
-  if (!manifest_dictionary) {
+  if (!result || !result->is_dict()) {
     ReportFailure(std::string(kExtensionHandlerFileUnzipError));
     return;
   }
 
   Manifest::Type manifest_type =
-      Manifest::GetTypeFromManifestValue(*manifest_dictionary);
+      Manifest::GetTypeFromManifestValue(result->GetDict());
 
   unzip::UnzipFilterCallback filter = base::BindRepeating(
       [](bool is_theme, const base::FilePath& file_path) -> bool {
diff --git a/extensions/common/api/schema.gni b/extensions/common/api/schema.gni
index f46621a..cbdeaae 100644
--- a/extensions/common/api/schema.gni
+++ b/extensions/common/api/schema.gni
@@ -78,10 +78,13 @@
     "diagnostics.idl",
     "lock_screen_data.idl",
     "media_perception_private.idl",
-    "webcam_private.idl",
   ]
 }
 
+if (is_chromeos) {
+  extensions_api_schema_files_ += [ "webcam_private.idl" ]
+}
+
 extensions_api_schema_files =
     get_path_info(extensions_api_schema_files_, "abspath")
 
diff --git a/extensions/common/extension.cc b/extensions/common/extension.cc
index 13c985e8..49557d8 100644
--- a/extensions/common/extension.cc
+++ b/extensions/common/extension.cc
@@ -264,13 +264,11 @@
   }
 
   std::unique_ptr<extensions::Manifest> manifest;
-  auto value_clone = base::DictionaryValue::From(
-      base::Value::ToUniquePtrValue(base::Value(value.Clone())));
   if (flags & FOR_LOGIN_SCREEN) {
-    manifest = Manifest::CreateManifestForLoginScreen(
-        location, std::move(value_clone), std::move(extension_id));
+    manifest = Manifest::CreateManifestForLoginScreen(location, value.Clone(),
+                                                      std::move(extension_id));
   } else {
-    manifest = std::make_unique<Manifest>(location, std::move(value_clone),
+    manifest = std::make_unique<Manifest>(location, value.Clone(),
                                           std::move(extension_id));
   }
 
diff --git a/extensions/common/manifest.cc b/extensions/common/manifest.cc
index 0b75e8e..5dc2390 100644
--- a/extensions/common/manifest.cc
+++ b/extensions/common/manifest.cc
@@ -12,6 +12,7 @@
 #include "base/notreached.h"
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/value_iterators.h"
 #include "extensions/common/api/shared_module.h"
 #include "extensions/common/error_utils.h"
 #include "extensions/common/features/feature.h"
@@ -96,11 +97,11 @@
   return rank;
 }
 
-int GetManifestVersion(const base::DictionaryValue& manifest_value,
+int GetManifestVersion(const base::Value::Dict& manifest_value,
                        Manifest::Type type) {
   // Platform apps were launched after manifest version 2 was the preferred
   // version, so they default to that.
-  return manifest_value.FindIntKey(keys::kManifestVersion)
+  return manifest_value.FindInt(keys::kManifestVersion)
       .value_or(type == Manifest::TYPE_PLATFORM_APP ? 2 : 1);
 }
 
@@ -108,21 +109,20 @@
 class AvailableValuesFilter {
  public:
   // Filters `manifest.values()` removing any unavailable keys.
-  static base::Value Filter(const Manifest& manifest) {
-    return FilterInternal(manifest, *manifest.value(), "");
+  static base::Value::Dict Filter(const Manifest& manifest) {
+    return FilterInternal(manifest, manifest.value()->GetDict(), "");
   }
 
  private:
-  // Returns a DictionaryValue corresponding to |input_dict| for the given
+  // Returns a base::Value::Dict corresponding to |input_dict| for the given
   // |manifest|, with all unavailable keys removed.
-  static base::Value FilterInternal(const Manifest& manifest,
-                                    const base::Value& input_dict,
-                                    std::string current_path) {
-    base::Value output_dict(base::Value::Type::DICTIONARY);
-    DCHECK(input_dict.is_dict());
+  static base::Value::Dict FilterInternal(const Manifest& manifest,
+                                          const base::Value::Dict& input_dict,
+                                          std::string current_path) {
+    base::Value::Dict output_dict;
     DCHECK(CanAccessFeature(manifest, current_path));
 
-    for (auto it : input_dict.DictItems()) {
+    for (auto it : input_dict) {
       std::string child_path = CombineKeys(current_path, it.first);
 
       // Unavailable key, skip it.
@@ -132,13 +132,13 @@
       // If |child_path| corresponds to a leaf node, copy it.
       bool is_leaf_node = !it.second.is_dict();
       if (is_leaf_node) {
-        output_dict.SetKey(it.first, it.second.Clone());
+        output_dict.Set(it.first, it.second.Clone());
         continue;
       }
 
       // Child dictionary. Populate it recursively.
-      output_dict.SetKey(it.first,
-                         FilterInternal(manifest, it.second, child_path));
+      output_dict.Set(
+          it.first, FilterInternal(manifest, it.second.GetDict(), child_path));
     }
     return output_dict;
   }
@@ -201,23 +201,23 @@
 
 // static
 Manifest::Type Manifest::GetTypeFromManifestValue(
-    const base::DictionaryValue& value,
+    const base::Value::Dict& value,
     bool for_login_screen) {
   Type type = TYPE_UNKNOWN;
-  if (value.FindKey(keys::kTheme)) {
+  if (value.Find(keys::kTheme)) {
     type = TYPE_THEME;
-  } else if (value.FindKey(api::shared_module::ManifestKeys::kExport)) {
+  } else if (value.Find(api::shared_module::ManifestKeys::kExport)) {
     type = TYPE_SHARED_MODULE;
-  } else if (value.FindKey(keys::kApp)) {
-    if (value.Get(keys::kWebURLs, nullptr) ||
-        value.Get(keys::kLaunchWebURL, nullptr)) {
+  } else if (value.Find(keys::kApp)) {
+    if (value.FindByDottedPath(keys::kWebURLs) ||
+        value.FindByDottedPath(keys::kLaunchWebURL)) {
       type = TYPE_HOSTED_APP;
-    } else if (value.Get(keys::kPlatformAppBackground, nullptr)) {
+    } else if (value.FindByDottedPath(keys::kPlatformAppBackground)) {
       type = TYPE_PLATFORM_APP;
     } else {
       type = TYPE_LEGACY_PACKAGED_APP;
     }
-  } else if (value.FindKey(keys::kChromeOSSystemExtension)) {
+  } else if (value.Find(keys::kChromeOSSystemExtension)) {
     type = TYPE_CHROMEOS_SYSTEM_EXTENSION;
   } else if (for_login_screen) {
     type = TYPE_LOGIN_SCREEN_EXTENSION;
@@ -248,7 +248,7 @@
 // static
 std::unique_ptr<Manifest> Manifest::CreateManifestForLoginScreen(
     ManifestLocation location,
-    std::unique_ptr<base::DictionaryValue> value,
+    base::Value::Dict value,
     ExtensionId extension_id) {
   CHECK(IsPolicyLocation(location));
   // Use base::WrapUnique + new because the constructor is private.
@@ -257,24 +257,23 @@
 }
 
 Manifest::Manifest(ManifestLocation location,
-                   std::unique_ptr<base::DictionaryValue> value,
+                   base::Value::Dict value,
                    ExtensionId extension_id)
     : Manifest(location, std::move(value), std::move(extension_id), false) {}
 
 Manifest::Manifest(ManifestLocation location,
-                   std::unique_ptr<base::DictionaryValue> value,
+                   base::Value::Dict value,
                    ExtensionId extension_id,
                    bool for_login_screen)
     : extension_id_(std::move(extension_id)),
       hashed_id_(HashedExtensionId(extension_id_)),
       location_(location),
       value_(std::move(value)),
-      type_(GetTypeFromManifestValue(*value_, for_login_screen)),
-      manifest_version_(GetManifestVersion(*value_, type_)) {
+      type_(GetTypeFromManifestValue(value_.GetDict(), for_login_screen)),
+      manifest_version_(GetManifestVersion(value_.GetDict(), type_)) {
   DCHECK(!extension_id_.empty());
 
-  available_values_ = base::DictionaryValue::From(
-      base::Value::ToUniquePtrValue(AvailableValuesFilter::Filter(*this)));
+  available_values_ = base::Value(AvailableValuesFilter::Filter(*this));
 }
 
 Manifest::~Manifest() = default;
@@ -291,8 +290,7 @@
   const FeatureProvider* manifest_feature_provider =
       FeatureProvider::GetManifestFeatures();
   for (const auto& map_entry : manifest_feature_provider->GetAllFeatures()) {
-    // Use Get instead of HasKey because the former uses path expansion.
-    if (!value_->Get(map_entry.first, nullptr))
+    if (!value_.GetDict().FindByDottedPath(map_entry.first))
       continue;
 
     Feature::Availability result = map_entry.second->IsAvailableToManifest(
@@ -302,7 +300,7 @@
   }
 
   // Also generate warnings for keys that are not features.
-  for (const auto item : value_->GetDict()) {
+  for (const auto item : value_.GetDict()) {
     if (!manifest_feature_provider->GetFeature(item.first)) {
       warnings->push_back(InstallWarning(
           ErrorUtils::FormatErrorMessage(
@@ -312,7 +310,8 @@
   }
 
   if (IsUnpackedLocation(location_) &&
-      value_->FindPath(manifest_keys::kDifferentialFingerprint)) {
+      value_.GetDict().FindByDottedPath(
+          manifest_keys::kDifferentialFingerprint)) {
     warnings->push_back(
         InstallWarning(manifest_errors::kHasDifferentialFingerprint,
                        manifest_keys::kDifferentialFingerprint));
@@ -321,50 +320,55 @@
 }
 
 const base::Value* Manifest::FindKey(base::StringPiece key) const {
-  return available_values_->FindKey(key);
+  return available_values_.GetDict().Find(key);
 }
 
 const base::Value* Manifest::FindPath(base::StringPiece path) const {
-  return available_values_->FindPath(path);
+  return available_values_.GetDict().FindByDottedPath(path);
 }
 
 absl::optional<bool> Manifest::FindBoolPath(base::StringPiece path) const {
-  return available_values_->FindBoolPath(path);
+  return available_values_.GetDict().FindBoolByDottedPath(path);
 }
 
 absl::optional<int> Manifest::FindIntPath(base::StringPiece path) const {
-  return available_values_->FindIntPath(path);
+  return available_values_.GetDict().FindIntByDottedPath(path);
 }
 
 const std::string* Manifest::FindStringPath(base::StringPiece path) const {
-  return available_values_->FindStringPath(path);
+  return available_values_.GetDict().FindStringByDottedPath(path);
 }
 
 bool Manifest::GetDictionary(
     const std::string& path, const base::DictionaryValue** out_value) const {
-  return available_values_->GetDictionary(path, out_value);
+  const base::Value* value;
+  if (!GetDictionary(path, &value)) {
+    return false;
+  }
+  *out_value = &base::Value::AsDictionaryValue(*value);
+  return true;
 }
 
 bool Manifest::GetDictionary(const std::string& path,
                              const base::Value** out_value) const {
-  const std::vector<base::StringPiece> components =
-      manifest_handler_helpers::TokenizeDictionaryPath(path);
-  *out_value = available_values_->FindPathOfType(components,
-                                                 base::Value::Type::DICTIONARY);
-  return *out_value != nullptr;
+  const base::Value* value = available_values_.GetDict().FindByDottedPath(path);
+  if (!value || !value->is_dict())
+    return false;
+  *out_value = value;
+  return true;
 }
 
 bool Manifest::GetList(const std::string& path,
                        const base::Value** out_value) const {
-  const std::vector<base::StringPiece> components =
-      manifest_handler_helpers::TokenizeDictionaryPath(path);
-  *out_value =
-      available_values_->FindPathOfType(components, base::Value::Type::LIST);
-  return *out_value != nullptr;
+  const base::Value* value = available_values_.GetDict().FindByDottedPath(path);
+  if (!value || !value->is_list())
+    return false;
+  *out_value = value;
+  return true;
 }
 
 bool Manifest::EqualsForTesting(const Manifest& other) const {
-  return *value_ == *other.value() && location_ == other.location_ &&
+  return value_ == other.value_ && location_ == other.location_ &&
          extension_id_ == other.extension_id_;
 }
 
diff --git a/extensions/common/manifest.h b/extensions/common/manifest.h
index 6baaaf99..63b65156 100644
--- a/extensions/common/manifest.h
+++ b/extensions/common/manifest.h
@@ -11,19 +11,15 @@
 #include <string>
 #include <vector>
 
+#include "base/values.h"
 #include "extensions/common/extension_id.h"
 #include "extensions/common/hashed_extension_id.h"
 #include "extensions/common/mojom/manifest.mojom-shared.h"
 
-namespace base {
-class DictionaryValue;
-class Value;
-}  // namespace base
-
 namespace extensions {
 struct InstallWarning;
 
-// Wraps the DictionaryValue form of extension's manifest. Enforces access to
+// Wraps the base::Value::Dict form of extension's manifest. Enforces access to
 // properties of the manifest using ManifestFeatureProvider.
 class Manifest final {
  public:
@@ -105,7 +101,7 @@
   }
 
   // Returns the Manifest::Type for the given |value|.
-  static Type GetTypeFromManifestValue(const base::DictionaryValue& value,
+  static Type GetTypeFromManifestValue(const base::Value::Dict& value,
                                        bool for_login_screen = false);
 
   // Returns true if an item with the given |location| should always be loaded,
@@ -118,11 +114,11 @@
   // (like platform apps) may be installed in the same login screen profile.
   static std::unique_ptr<Manifest> CreateManifestForLoginScreen(
       mojom::ManifestLocation location,
-      std::unique_ptr<base::DictionaryValue> value,
+      base::Value::Dict value,
       ExtensionId extension_id);
 
   Manifest(mojom::ManifestLocation location,
-           std::unique_ptr<base::DictionaryValue> value,
+           base::Value::Dict value,
            ExtensionId extension_id);
 
   Manifest(const Manifest&) = delete;
@@ -188,17 +184,19 @@
 
   // Gets the underlying DictionaryValue representing the manifest.
   // Note: only use this when you KNOW you don't need the validation.
-  const base::DictionaryValue* value() const { return value_.get(); }
+  const base::DictionaryValue* value() const {
+    return &base::Value::AsDictionaryValue(value_);
+  }
 
   // Gets the underlying DictionaryValue representing the manifest with all
   // unavailable manifest keys removed.
   const base::DictionaryValue& available_values() const {
-    return *available_values_;
+    return base::Value::AsDictionaryValue(available_values_);
   }
 
  private:
   Manifest(mojom::ManifestLocation location,
-           std::unique_ptr<base::DictionaryValue> value,
+           base::Value::Dict value,
            ExtensionId extension_id,
            bool for_login_screen);
 
@@ -216,10 +214,14 @@
   const mojom::ManifestLocation location_;
 
   // The underlying dictionary representation of the manifest.
-  const std::unique_ptr<const base::DictionaryValue> value_;
+  // TODO(https://crbug.com/1366865): Make base::Value::Dict when callers of
+  // `value()` are migrated.
+  const base::Value value_;
 
   // Same as |value_| but comprises only of keys available to this manifest.
-  std::unique_ptr<const base::DictionaryValue> available_values_;
+  // TODO(https://crbug.com/1366865): Make base::Value::Dict when callers of
+  // `available_value()` are migrated.
+  base::Value available_values_;
 
   const Type type_;
 
diff --git a/extensions/common/manifest_fuzzer.cc b/extensions/common/manifest_fuzzer.cc
index 73a8b7f9..353e162 100644
--- a/extensions/common/manifest_fuzzer.cc
+++ b/extensions/common/manifest_fuzzer.cc
@@ -95,10 +95,7 @@
     return 0;
 
   for (auto location : kLocations) {
-    Manifest manifest(location,
-                      base::DictionaryValue::From(
-                          base::Value::ToUniquePtrValue(parsed_json->Clone())),
-                      extension_id);
+    Manifest manifest(location, parsed_json->GetDict().Clone(), extension_id);
 
     std::string error;
     std::vector<InstallWarning> install_warning;
diff --git a/extensions/common/manifest_unittest.cc b/extensions/common/manifest_unittest.cc
index a3bd5fd..731621ff 100644
--- a/extensions/common/manifest_unittest.cc
+++ b/extensions/common/manifest_unittest.cc
@@ -25,7 +25,7 @@
   Manifest(ManifestLocation::kUnpacked,
            DictionaryBuilder()
                .Set(manifest_keys::kDifferentialFingerprint, "")
-               .Build(),
+               .BuildDict(),
            crx_file::id_util::GenerateId("extid"))
       .ValidateManifest(&error, &warnings);
   EXPECT_EQ("", error);
@@ -39,7 +39,7 @@
   Manifest(ManifestLocation::kCommandLine,
            DictionaryBuilder()
                .Set(manifest_keys::kDifferentialFingerprint, "")
-               .Build(),
+               .BuildDict(),
            crx_file::id_util::GenerateId("extid"))
       .ValidateManifest(&error, &warnings);
   EXPECT_EQ("", error);
@@ -53,7 +53,7 @@
   Manifest(ManifestLocation::kInternal,
            DictionaryBuilder()
                .Set(manifest_keys::kDifferentialFingerprint, "")
-               .Build(),
+               .BuildDict(),
            crx_file::id_util::GenerateId("extid"))
       .ValidateManifest(&error, &warnings);
   EXPECT_EQ("", error);
@@ -63,7 +63,7 @@
 TEST(ManifestTest, ValidateSilentOnNoDiffFingerprintKeyUnpacked) {
   std::string error;
   std::vector<InstallWarning> warnings;
-  Manifest(ManifestLocation::kUnpacked, DictionaryBuilder().Build(),
+  Manifest(ManifestLocation::kUnpacked, DictionaryBuilder().BuildDict(),
            crx_file::id_util::GenerateId("extid"))
       .ValidateManifest(&error, &warnings);
   EXPECT_EQ("", error);
@@ -73,7 +73,7 @@
 TEST(ManifestTest, ValidateSilentOnNoDiffFingerprintKeyInternal) {
   std::string error;
   std::vector<InstallWarning> warnings;
-  Manifest(ManifestLocation::kInternal, DictionaryBuilder().Build(),
+  Manifest(ManifestLocation::kInternal, DictionaryBuilder().BuildDict(),
            crx_file::id_util::GenerateId("extid"))
       .ValidateManifest(&error, &warnings);
   EXPECT_EQ("", error);
@@ -143,8 +143,7 @@
     ASSERT_TRUE(manifest_value->is_dict()) << test_case.input_manifest;
 
     Manifest manifest(ManifestLocation::kInternal,
-                      base::DictionaryValue::From(base::Value::ToUniquePtrValue(
-                          std::move(*manifest_value))),
+                      std::move(*manifest_value).TakeDict(),
                       crx_file::id_util::GenerateId("extid"));
 
     absl::optional<base::Value> expected_value =
diff --git a/extensions/shell/browser/shell_desktop_controller_mac.h b/extensions/shell/browser/shell_desktop_controller_mac.h
index eca9516..1a67b09d 100644
--- a/extensions/shell/browser/shell_desktop_controller_mac.h
+++ b/extensions/shell/browser/shell_desktop_controller_mac.h
@@ -37,7 +37,8 @@
 
   // The desktop only supports a single app window.
   // TODO(yoz): Support multiple app windows, as we do in Aura.
-  raw_ptr<AppWindow> app_window_;  // NativeAppWindow::Close() deletes this.
+  raw_ptr<AppWindow, DanglingUntriaged>
+      app_window_;  // NativeAppWindow::Close() deletes this.
 
   display::ScopedNativeScreen screen_;
 };
diff --git a/fuchsia_web/webengine/BUILD.gn b/fuchsia_web/webengine/BUILD.gn
index f1c5f44..92c0bd9 100644
--- a/fuchsia_web/webengine/BUILD.gn
+++ b/fuchsia_web/webengine/BUILD.gn
@@ -113,7 +113,12 @@
 # that depends on those targets once this is correctly supported.
 _disallowed_deps =
     _disallowed_cast_deps + _disallowed_extensions_deps + _disallowed_pdf_deps +
-    _disallowed_ppapi_deps + _disallowed_printing_deps
+    _disallowed_ppapi_deps + _disallowed_printing_deps +
+    [
+      # Ensure WebEngine is not communicating with the Finch service until it
+      # is explicitly supported. See crbug.com/1155712.
+      "//components/variations/service",
+    ]
 
 source_set("web_engine_export_from_implementation") {
   public = [ "web_engine_export.h" ]
diff --git a/fuchsia_web/webengine/context_provider_main.cc b/fuchsia_web/webengine/context_provider_main.cc
index e8e0b7bdc..490b7ca 100644
--- a/fuchsia_web/webengine/context_provider_main.cc
+++ b/fuchsia_web/webengine/context_provider_main.cc
@@ -23,10 +23,12 @@
 
 namespace {
 
+// LINT.IfChange(web_engine_crash_product_name)
 // This must match the value in web_instance_host.cc
 constexpr char kCrashProductName[] = "FuchsiaWebEngine";
+// LINT.ThenChange(//fuchsia_web/webinstance_host/web_instance_host.cc:web_engine_crash_product_name)
 
-// TODO(https://fxbug.dev/51490): Use a programmatic mechanism to obtain this.
+// The URL cannot be obtained programmatically - see fxbug.dev/51490.
 constexpr char kComponentUrl[] =
     "fuchsia-pkg://fuchsia.com/web_engine#meta/context_provider.cm";
 constexpr char kComponentUrlCfv1[] =
diff --git a/fuchsia_web/webinstance_host/web_instance_host.cc b/fuchsia_web/webinstance_host/web_instance_host.cc
index e08131a..cff5befc 100644
--- a/fuchsia_web/webinstance_host/web_instance_host.cc
+++ b/fuchsia_web/webinstance_host/web_instance_host.cc
@@ -59,7 +59,7 @@
 namespace {
 
 // Production URL for web hosting Component instances.
-// TODO(fxbug.dev/51490): Use a programmatic mechanism to obtain this.
+// The URL cannot be obtained programmatically - see fxbug.dev/51490.
 const char kWebInstanceComponentUrl[] =
     "fuchsia-pkg://fuchsia.com/web_engine#meta/web_instance.cmx";
 
@@ -103,7 +103,10 @@
 // is available - see crbug.com/1211174). This should only be called once per
 // process, and the calling thread must have an async_dispatcher.
 void RegisterWebInstanceProductData() {
+  // LINT.IfChange(web_engine_crash_product_name)
   constexpr char kCrashProductName[] = "FuchsiaWebEngine";
+  // LINT.ThenChange(//fuchsia_web/webengine/context_provider_main.cc:web_engine_crash_product_name)
+
   constexpr char kFeedbackAnnotationsNamespace[] = "web-engine";
 
   fuchsia_component_support::RegisterProductDataForCrashReporting(
diff --git a/gpu/command_buffer/client/query_tracker.h b/gpu/command_buffer/client/query_tracker.h
index 19791cb4..8a241f5 100644
--- a/gpu/command_buffer/client/query_tracker.h
+++ b/gpu/command_buffer/client/query_tracker.h
@@ -60,7 +60,7 @@
 
     uint32_t index() const { return sync - bucket->syncs; }
 
-    raw_ptr<Bucket> bucket = nullptr;
+    raw_ptr<Bucket, DanglingUntriaged> bucket = nullptr;
     raw_ptr<QuerySync> sync = nullptr;
     int32_t submit_count = 0;
   };
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index ac782a6d..f0a9441 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -235,10 +235,10 @@
     "shared_image/compound_image_backing.h",
     "shared_image/gl_common_image_backing_factory.cc",
     "shared_image/gl_common_image_backing_factory.h",
-    "shared_image/gl_image_backing.cc",
-    "shared_image/gl_image_backing.h",
     "shared_image/gl_repack_utils.cc",
     "shared_image/gl_repack_utils.h",
+    "shared_image/gl_texture_common_representations.cc",
+    "shared_image/gl_texture_common_representations.h",
     "shared_image/gl_texture_image_backing.cc",
     "shared_image/gl_texture_image_backing.h",
     "shared_image/gl_texture_image_backing_factory.cc",
@@ -561,6 +561,8 @@
       "shared_image/dxgi_swap_chain_image_backing.h",
       "shared_image/dxgi_swap_chain_image_representation.cc",
       "shared_image/dxgi_swap_chain_image_representation.h",
+      "shared_image/gl_image_backing.cc",
+      "shared_image/gl_image_backing.h",
     ]
     libs = [ "dxguid.lib" ]
   }
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
index e773aed..a85bfe8b 100644
--- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
@@ -7,7 +7,7 @@
 
 #include "gpu/command_buffer/service/shared_context_state.h"
 #include "gpu/command_buffer/service/shared_image/gl_common_image_backing_factory.h"
-#include "gpu/command_buffer/service/shared_image/gl_image_backing.h"
+#include "gpu/command_buffer/service/shared_image/gl_texture_common_representations.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
 #include "third_party/skia/include/gpu/GrBackendSurface.h"
 
diff --git a/gpu/command_buffer/service/shared_image/gl_image_backing.cc b/gpu/command_buffer/service/shared_image/gl_image_backing.cc
index b336dfd..6ab1939 100644
--- a/gpu/command_buffer/service/shared_image/gl_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/gl_image_backing.cc
@@ -5,7 +5,6 @@
 #include "gpu/command_buffer/service/shared_image/gl_image_backing.h"
 
 #include "base/trace_event/memory_dump_manager.h"
-#include "build/build_config.h"
 #include "components/viz/common/resources/resource_format_utils.h"
 #include "components/viz/common/resources/resource_sizes.h"
 #include "gpu/command_buffer/common/shared_image_trace_utils.h"
@@ -34,236 +33,6 @@
 }  // namespace
 
 ///////////////////////////////////////////////////////////////////////////////
-// GLTextureGLCommonRepresentation
-
-// Representation of a GLTextureImageBacking as a GL Texture.
-GLTextureGLCommonRepresentation::GLTextureGLCommonRepresentation(
-    SharedImageManager* manager,
-    SharedImageBacking* backing,
-    GLTextureImageRepresentationClient* client,
-    MemoryTypeTracker* tracker,
-    gles2::Texture* texture)
-    : GLTextureImageRepresentation(manager, backing, tracker),
-      client_(client),
-      texture_(texture) {}
-
-GLTextureGLCommonRepresentation::~GLTextureGLCommonRepresentation() {
-  texture_ = nullptr;
-  if (client_)
-    client_->GLTextureImageRepresentationRelease(has_context());
-}
-
-gles2::Texture* GLTextureGLCommonRepresentation::GetTexture(int plane_index) {
-  DCHECK_EQ(plane_index, 0);
-  return texture_;
-}
-
-bool GLTextureGLCommonRepresentation::BeginAccess(GLenum mode) {
-  DCHECK(mode_ == 0);
-  mode_ = mode;
-  bool readonly = mode_ != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM;
-  if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
-    return client_->GLTextureImageRepresentationBeginAccess(readonly);
-  return true;
-}
-
-void GLTextureGLCommonRepresentation::EndAccess() {
-  DCHECK(mode_ != 0);
-  GLenum current_mode = mode_;
-  mode_ = 0;
-  if (client_)
-    return client_->GLTextureImageRepresentationEndAccess(
-        current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// GLTexturePassthroughGLCommonRepresentation
-
-GLTexturePassthroughGLCommonRepresentation::
-    GLTexturePassthroughGLCommonRepresentation(
-        SharedImageManager* manager,
-        SharedImageBacking* backing,
-        GLTextureImageRepresentationClient* client,
-        MemoryTypeTracker* tracker,
-        scoped_refptr<gles2::TexturePassthrough> texture_passthrough)
-    : GLTexturePassthroughImageRepresentation(manager, backing, tracker),
-      client_(client),
-      texture_passthrough_(std::move(texture_passthrough)) {
-  // TODO(https://crbug.com/1172769): Remove this CHECK.
-  CHECK(texture_passthrough_);
-}
-
-GLTexturePassthroughGLCommonRepresentation::
-    ~GLTexturePassthroughGLCommonRepresentation() {
-  texture_passthrough_.reset();
-  if (client_)
-    client_->GLTextureImageRepresentationRelease(has_context());
-}
-
-const scoped_refptr<gles2::TexturePassthrough>&
-GLTexturePassthroughGLCommonRepresentation::GetTexturePassthrough(
-    int plane_index) {
-  DCHECK_EQ(plane_index, 0);
-  return texture_passthrough_;
-}
-
-bool GLTexturePassthroughGLCommonRepresentation::BeginAccess(GLenum mode) {
-  DCHECK(mode_ == 0);
-  mode_ = mode;
-  bool readonly = mode_ != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM;
-  if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
-    return client_->GLTextureImageRepresentationBeginAccess(readonly);
-  return true;
-}
-
-void GLTexturePassthroughGLCommonRepresentation::EndAccess() {
-  DCHECK(mode_ != 0);
-  GLenum current_mode = mode_;
-  mode_ = 0;
-  if (client_)
-    return client_->GLTextureImageRepresentationEndAccess(
-        current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// SkiaGLCommonRepresentation
-
-SkiaGLCommonRepresentation::SkiaGLCommonRepresentation(
-    SharedImageManager* manager,
-    SharedImageBacking* backing,
-    GLTextureImageRepresentationClient* client,
-    scoped_refptr<SharedContextState> context_state,
-    sk_sp<SkPromiseImageTexture> promise_texture,
-    MemoryTypeTracker* tracker)
-    : SkiaImageRepresentation(manager, backing, tracker),
-      client_(client),
-      context_state_(std::move(context_state)),
-      promise_texture_(promise_texture) {
-  DCHECK(promise_texture_);
-#if DCHECK_IS_ON()
-  if (context_state_->GrContextIsGL())
-    context_ = gl::GLContext::GetCurrent();
-#endif
-}
-
-SkiaGLCommonRepresentation::~SkiaGLCommonRepresentation() {
-  if (write_surface_) {
-    DLOG(ERROR) << "SkiaImageRepresentation was destroyed while still "
-                << "open for write access.";
-  }
-  promise_texture_.reset();
-  if (client_) {
-    DCHECK(context_state_->GrContextIsGL());
-    client_->GLTextureImageRepresentationRelease(has_context());
-  }
-}
-
-std::vector<sk_sp<SkSurface>> SkiaGLCommonRepresentation::BeginWriteAccess(
-    int final_msaa_count,
-    const SkSurfaceProps& surface_props,
-    const gfx::Rect& update_rect,
-    std::vector<GrBackendSemaphore>* begin_semaphores,
-    std::vector<GrBackendSemaphore>* end_semaphores,
-    std::unique_ptr<GrBackendSurfaceMutableState>* end_state) {
-  CheckContext();
-  if (client_) {
-    DCHECK(context_state_->GrContextIsGL());
-    if (!client_->GLTextureImageRepresentationBeginAccess(
-            /*readonly=*/false)) {
-      return {};
-    }
-  }
-
-  if (write_surface_)
-    return {};
-
-  if (!promise_texture_)
-    return {};
-
-  SkColorType sk_color_type = viz::ResourceFormatToClosestSkColorType(
-      /*gpu_compositing=*/true, format());
-  // Gray is not a renderable single channel format, but alpha is.
-  if (sk_color_type == kGray_8_SkColorType)
-    sk_color_type = kAlpha_8_SkColorType;
-  auto surface = SkSurface::MakeFromBackendTexture(
-      context_state_->gr_context(), promise_texture_->backendTexture(),
-      surface_origin(), final_msaa_count, sk_color_type,
-      backing()->color_space().GetAsFullRangeRGB().ToSkColorSpace(),
-      &surface_props);
-  write_surface_ = surface;
-
-  if (!surface)
-    return {};
-  return {surface};
-}
-
-std::vector<sk_sp<SkPromiseImageTexture>>
-SkiaGLCommonRepresentation::BeginWriteAccess(
-    std::vector<GrBackendSemaphore>* begin_semaphores,
-    std::vector<GrBackendSemaphore>* end_semaphores,
-    std::unique_ptr<GrBackendSurfaceMutableState>* end_state) {
-  CheckContext();
-  if (client_) {
-    DCHECK(context_state_->GrContextIsGL());
-    if (!client_->GLTextureImageRepresentationBeginAccess(
-            /*readonly=*/false)) {
-      return {};
-    }
-  }
-
-  if (!promise_texture_)
-    return {};
-  return {promise_texture_};
-}
-
-void SkiaGLCommonRepresentation::EndWriteAccess() {
-  if (write_surface_) {
-    DCHECK(write_surface_->unique());
-    CheckContext();
-    // TODO(ericrk): Keep the surface around for re-use.
-    write_surface_.reset();
-  }
-
-  if (client_)
-    client_->GLTextureImageRepresentationEndAccess(false /* readonly */);
-}
-
-std::vector<sk_sp<SkPromiseImageTexture>>
-SkiaGLCommonRepresentation::BeginReadAccess(
-    std::vector<GrBackendSemaphore>* begin_semaphores,
-    std::vector<GrBackendSemaphore>* end_semaphores,
-    std::unique_ptr<GrBackendSurfaceMutableState>* end_state) {
-  CheckContext();
-  if (client_) {
-    DCHECK(context_state_->GrContextIsGL());
-    if (!client_->GLTextureImageRepresentationBeginAccess(
-            /*readonly=*/true)) {
-      return {};
-    }
-  }
-
-  if (!promise_texture_)
-    return {};
-  return {promise_texture_};
-}
-
-void SkiaGLCommonRepresentation::EndReadAccess() {
-  if (client_)
-    client_->GLTextureImageRepresentationEndAccess(true /* readonly */);
-}
-
-bool SkiaGLCommonRepresentation::SupportsMultipleConcurrentReadAccess() {
-  return true;
-}
-
-void SkiaGLCommonRepresentation::CheckContext() {
-#if DCHECK_IS_ON()
-  if (!context_state_->context_lost() && context_)
-    DCHECK(gl::GLContext::GetCurrent() == context_);
-#endif
-}
-
-///////////////////////////////////////////////////////////////////////////////
 // OverlayGLImageRepresentation
 
 OverlayGLImageRepresentation::OverlayGLImageRepresentation(
@@ -291,11 +60,9 @@
   gl_backing->SetReleaseFence(std::move(release_fence));
 }
 
-#if BUILDFLAG(IS_WIN)
 gl::GLImage* OverlayGLImageRepresentation::GetGLImage() {
   return gl_image_.get();
 }
-#endif
 
 ///////////////////////////////////////////////////////////////////////////////
 // GLImageBacking
@@ -321,9 +88,9 @@
   params.target = texture_target;
 
   auto si_format = viz::SharedImageFormat::SinglePlane(format);
-  auto shared_image = std::make_unique<GLImageBacking>(
+  auto shared_image = base::WrapUnique<GLImageBacking>(new GLImageBacking(
       std::move(image), mailbox, si_format, size, color_space, surface_origin,
-      alpha_type, usage, params, true);
+      alpha_type, usage, params, true));
 
   shared_image->passthrough_texture_ = std::move(wrapped_gl_texture);
   shared_image->gl_texture_retained_for_legacy_mailbox_ = true;
@@ -359,9 +126,6 @@
       cleared_rect_(params.is_cleared ? gfx::Rect(size) : gfx::Rect()),
       weak_factory_(this) {
   DCHECK(image_);
-#if BUILDFLAG(IS_MAC)
-  NOTREACHED();
-#endif
 }
 
 GLImageBacking::~GLImageBacking() {
@@ -520,12 +284,8 @@
 std::unique_ptr<OverlayImageRepresentation> GLImageBacking::ProduceOverlay(
     SharedImageManager* manager,
     MemoryTypeTracker* tracker) {
-#if BUILDFLAG(IS_OZONE) || BUILDFLAG(IS_WIN)
   return std::make_unique<OverlayGLImageRepresentation>(manager, this, tracker,
                                                         image_);
-#else   // || BUILDFLAG(IS_OZONE) || BUILDFLAG(IS_WIN))
-  return SharedImageBacking::ProduceOverlay(manager, tracker);
-#endif  // BUILDFLAG(IS_OZONE) || BUILDFLAG(IS_WIN)
 }
 
 std::unique_ptr<DawnImageRepresentation> GLImageBacking::ProduceDawn(
diff --git a/gpu/command_buffer/service/shared_image/gl_image_backing.h b/gpu/command_buffer/service/shared_image/gl_image_backing.h
index 8d1d3fa..1376f010f 100644
--- a/gpu/command_buffer/service/shared_image/gl_image_backing.h
+++ b/gpu/command_buffer/service/shared_image/gl_image_backing.h
@@ -6,7 +6,7 @@
 #define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_GL_IMAGE_BACKING_H_
 
 #include "base/memory/raw_ptr.h"
-#include "build/build_config.h"
+#include "gpu/command_buffer/service/shared_image/gl_texture_common_representations.h"
 #include "gpu/command_buffer/service/shared_image/gl_texture_image_backing_helper.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
 #include "gpu/gpu_gles2_export.h"
@@ -15,117 +15,6 @@
 
 namespace gpu {
 
-// Interface through which a representation that has a GL texture calls into its
-// GLImage backing.
-class GLTextureImageRepresentationClient {
- public:
-  virtual bool GLTextureImageRepresentationBeginAccess(bool readonly) = 0;
-  virtual void GLTextureImageRepresentationEndAccess(bool readonly) = 0;
-  virtual void GLTextureImageRepresentationRelease(bool have_context) = 0;
-};
-
-// Representation of a GLTextureImageBacking or GLImageBacking
-// as a GL Texture.
-class GLTextureGLCommonRepresentation : public GLTextureImageRepresentation {
- public:
-  GLTextureGLCommonRepresentation(SharedImageManager* manager,
-                                  SharedImageBacking* backing,
-                                  GLTextureImageRepresentationClient* client,
-                                  MemoryTypeTracker* tracker,
-                                  gles2::Texture* texture);
-  ~GLTextureGLCommonRepresentation() override;
-
- private:
-  // GLTextureImageRepresentation:
-  gles2::Texture* GetTexture(int plane_index) override;
-  bool BeginAccess(GLenum mode) override;
-  void EndAccess() override;
-
-  const raw_ptr<GLTextureImageRepresentationClient> client_ = nullptr;
-  raw_ptr<gles2::Texture> texture_;
-  GLenum mode_ = 0;
-};
-
-// Representation of a GLTextureImageBacking or
-// GLTextureImageBackingPassthrough as a GL TexturePassthrough.
-class GLTexturePassthroughGLCommonRepresentation
-    : public GLTexturePassthroughImageRepresentation {
- public:
-  class Client {
-   public:
-    virtual bool OnGLTexturePassthroughBeginAccess(GLenum mode) = 0;
-  };
-  GLTexturePassthroughGLCommonRepresentation(
-      SharedImageManager* manager,
-      SharedImageBacking* backing,
-      GLTextureImageRepresentationClient* client,
-      MemoryTypeTracker* tracker,
-      scoped_refptr<gles2::TexturePassthrough> texture_passthrough);
-  ~GLTexturePassthroughGLCommonRepresentation() override;
-
- private:
-  // GLTexturePassthroughImageRepresentation:
-  const scoped_refptr<gles2::TexturePassthrough>& GetTexturePassthrough(
-      int plane_index) override;
-  bool BeginAccess(GLenum mode) override;
-  void EndAccess() override;
-
-  const raw_ptr<GLTextureImageRepresentationClient> client_ = nullptr;
-  scoped_refptr<gles2::TexturePassthrough> texture_passthrough_;
-  GLenum mode_ = 0;
-};
-
-// Skia representation for both GLTextureImageBackingHelper.
-class SkiaGLCommonRepresentation : public SkiaImageRepresentation {
- public:
-  class Client {
-   public:
-    virtual bool OnSkiaBeginReadAccess() = 0;
-    virtual bool OnSkiaBeginWriteAccess() = 0;
-  };
-  SkiaGLCommonRepresentation(SharedImageManager* manager,
-                             SharedImageBacking* backing,
-                             GLTextureImageRepresentationClient* client,
-                             scoped_refptr<SharedContextState> context_state,
-                             sk_sp<SkPromiseImageTexture> promise_texture,
-                             MemoryTypeTracker* tracker);
-  ~SkiaGLCommonRepresentation() override;
-
-  void SetBeginReadAccessCallback(
-      base::RepeatingClosure begin_read_access_callback);
-
- private:
-  // SkiaImageRepresentation:
-  std::vector<sk_sp<SkSurface>> BeginWriteAccess(
-      int final_msaa_count,
-      const SkSurfaceProps& surface_props,
-      const gfx::Rect& update_rect,
-      std::vector<GrBackendSemaphore>* begin_semaphores,
-      std::vector<GrBackendSemaphore>* end_semaphores,
-      std::unique_ptr<GrBackendSurfaceMutableState>* end_state) override;
-  std::vector<sk_sp<SkPromiseImageTexture>> BeginWriteAccess(
-      std::vector<GrBackendSemaphore>* begin_semaphores,
-      std::vector<GrBackendSemaphore>* end_semaphore,
-      std::unique_ptr<GrBackendSurfaceMutableState>* end_state) override;
-  void EndWriteAccess() override;
-  std::vector<sk_sp<SkPromiseImageTexture>> BeginReadAccess(
-      std::vector<GrBackendSemaphore>* begin_semaphores,
-      std::vector<GrBackendSemaphore>* end_semaphores,
-      std::unique_ptr<GrBackendSurfaceMutableState>* end_state) override;
-  void EndReadAccess() override;
-  bool SupportsMultipleConcurrentReadAccess() override;
-
-  void CheckContext();
-
-  const raw_ptr<GLTextureImageRepresentationClient> client_ = nullptr;
-  scoped_refptr<SharedContextState> context_state_;
-  sk_sp<SkPromiseImageTexture> promise_texture_;
-  sk_sp<SkSurface> write_surface_;
-#if DCHECK_IS_ON()
-  raw_ptr<gl::GLContext> context_ = nullptr;
-#endif
-};
-
 // Overlay representation for a GLImageBacking.
 class OverlayGLImageRepresentation : public OverlayImageRepresentation {
  public:
@@ -138,10 +27,7 @@
  private:
   bool BeginReadAccess(gfx::GpuFenceHandle& acquire_fence) override;
   void EndReadAccess(gfx::GpuFenceHandle release_fence) override;
-
-#if BUILDFLAG(IS_WIN)
   gl::GLImage* GetGLImage() override;
-#endif
 
   scoped_refptr<gl::GLImage> gl_image_;
 };
@@ -183,6 +69,16 @@
       GLenum texture_target,
       scoped_refptr<gles2::TexturePassthrough> wrapped_gl_texture);
 
+  GLImageBacking(const GLImageBacking& other) = delete;
+  GLImageBacking& operator=(const GLImageBacking& other) = delete;
+  ~GLImageBacking() override;
+
+  GLenum GetGLTarget() const;
+  GLuint GetGLServiceId() const;
+  std::unique_ptr<gfx::GpuFence> GetLastWriteGpuFence();
+  void SetReleaseFence(gfx::GpuFenceHandle release_fence);
+
+ private:
   GLImageBacking(
       scoped_refptr<gl::GLImage> image,
       const Mailbox& mailbox,
@@ -194,16 +90,7 @@
       uint32_t usage,
       const GLTextureImageBackingHelper::InitializeGLTextureParams& params,
       bool is_passthrough);
-  GLImageBacking(const GLImageBacking& other) = delete;
-  GLImageBacking& operator=(const GLImageBacking& other) = delete;
-  ~GLImageBacking() override;
 
-  GLenum GetGLTarget() const;
-  GLuint GetGLServiceId() const;
-  std::unique_ptr<gfx::GpuFence> GetLastWriteGpuFence();
-  void SetReleaseFence(gfx::GpuFenceHandle release_fence);
-
- private:
   // SharedImageBacking:
   scoped_refptr<gfx::NativePixmap> GetNativePixmap() override;
   void OnMemoryDump(const std::string& dump_name,
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_common_representations.cc b/gpu/command_buffer/service/shared_image/gl_texture_common_representations.cc
new file mode 100644
index 0000000..5280515
--- /dev/null
+++ b/gpu/command_buffer/service/shared_image/gl_texture_common_representations.cc
@@ -0,0 +1,247 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/shared_image/gl_texture_common_representations.h"
+
+#include "components/viz/common/resources/resource_format_utils.h"
+#include "components/viz/common/resources/resource_sizes.h"
+#include "gpu/command_buffer/service/shared_context_state.h"
+#include "gpu/command_buffer/service/skia_utils.h"
+#include "third_party/skia/include/core/SkColorSpace.h"
+#include "third_party/skia/include/core/SkPromiseImageTexture.h"
+#include "ui/gl/gl_context.h"
+
+namespace gpu {
+
+///////////////////////////////////////////////////////////////////////////////
+// GLTextureGLCommonRepresentation
+
+// Representation of a GLTextureImageBacking as a GL Texture.
+GLTextureGLCommonRepresentation::GLTextureGLCommonRepresentation(
+    SharedImageManager* manager,
+    SharedImageBacking* backing,
+    GLTextureImageRepresentationClient* client,
+    MemoryTypeTracker* tracker,
+    gles2::Texture* texture)
+    : GLTextureImageRepresentation(manager, backing, tracker),
+      client_(client),
+      texture_(texture) {}
+
+GLTextureGLCommonRepresentation::~GLTextureGLCommonRepresentation() {
+  texture_ = nullptr;
+  if (client_)
+    client_->GLTextureImageRepresentationRelease(has_context());
+}
+
+gles2::Texture* GLTextureGLCommonRepresentation::GetTexture(int plane_index) {
+  DCHECK_EQ(plane_index, 0);
+  return texture_;
+}
+
+bool GLTextureGLCommonRepresentation::BeginAccess(GLenum mode) {
+  DCHECK(mode_ == 0);
+  mode_ = mode;
+  bool readonly = mode_ != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM;
+  if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
+    return client_->GLTextureImageRepresentationBeginAccess(readonly);
+  return true;
+}
+
+void GLTextureGLCommonRepresentation::EndAccess() {
+  DCHECK(mode_ != 0);
+  GLenum current_mode = mode_;
+  mode_ = 0;
+  if (client_)
+    return client_->GLTextureImageRepresentationEndAccess(
+        current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// GLTexturePassthroughGLCommonRepresentation
+
+GLTexturePassthroughGLCommonRepresentation::
+    GLTexturePassthroughGLCommonRepresentation(
+        SharedImageManager* manager,
+        SharedImageBacking* backing,
+        GLTextureImageRepresentationClient* client,
+        MemoryTypeTracker* tracker,
+        scoped_refptr<gles2::TexturePassthrough> texture_passthrough)
+    : GLTexturePassthroughImageRepresentation(manager, backing, tracker),
+      client_(client),
+      texture_passthrough_(std::move(texture_passthrough)) {
+  // TODO(https://crbug.com/1172769): Remove this CHECK.
+  CHECK(texture_passthrough_);
+}
+
+GLTexturePassthroughGLCommonRepresentation::
+    ~GLTexturePassthroughGLCommonRepresentation() {
+  texture_passthrough_.reset();
+  if (client_)
+    client_->GLTextureImageRepresentationRelease(has_context());
+}
+
+const scoped_refptr<gles2::TexturePassthrough>&
+GLTexturePassthroughGLCommonRepresentation::GetTexturePassthrough(
+    int plane_index) {
+  DCHECK_EQ(plane_index, 0);
+  return texture_passthrough_;
+}
+
+bool GLTexturePassthroughGLCommonRepresentation::BeginAccess(GLenum mode) {
+  DCHECK(mode_ == 0);
+  mode_ = mode;
+  bool readonly = mode_ != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM;
+  if (client_ && mode != GL_SHARED_IMAGE_ACCESS_MODE_OVERLAY_CHROMIUM)
+    return client_->GLTextureImageRepresentationBeginAccess(readonly);
+  return true;
+}
+
+void GLTexturePassthroughGLCommonRepresentation::EndAccess() {
+  DCHECK(mode_ != 0);
+  GLenum current_mode = mode_;
+  mode_ = 0;
+  if (client_)
+    return client_->GLTextureImageRepresentationEndAccess(
+        current_mode != GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// SkiaGLCommonRepresentation
+
+SkiaGLCommonRepresentation::SkiaGLCommonRepresentation(
+    SharedImageManager* manager,
+    SharedImageBacking* backing,
+    GLTextureImageRepresentationClient* client,
+    scoped_refptr<SharedContextState> context_state,
+    sk_sp<SkPromiseImageTexture> promise_texture,
+    MemoryTypeTracker* tracker)
+    : SkiaImageRepresentation(manager, backing, tracker),
+      client_(client),
+      context_state_(std::move(context_state)),
+      promise_texture_(promise_texture) {
+  DCHECK(promise_texture_);
+#if DCHECK_IS_ON()
+  if (context_state_->GrContextIsGL())
+    context_ = gl::GLContext::GetCurrent();
+#endif
+}
+
+SkiaGLCommonRepresentation::~SkiaGLCommonRepresentation() {
+  if (write_surface_) {
+    DLOG(ERROR) << "SkiaImageRepresentation was destroyed while still "
+                << "open for write access.";
+  }
+  promise_texture_.reset();
+  if (client_) {
+    DCHECK(context_state_->GrContextIsGL());
+    client_->GLTextureImageRepresentationRelease(has_context());
+  }
+}
+
+std::vector<sk_sp<SkSurface>> SkiaGLCommonRepresentation::BeginWriteAccess(
+    int final_msaa_count,
+    const SkSurfaceProps& surface_props,
+    const gfx::Rect& update_rect,
+    std::vector<GrBackendSemaphore>* begin_semaphores,
+    std::vector<GrBackendSemaphore>* end_semaphores,
+    std::unique_ptr<GrBackendSurfaceMutableState>* end_state) {
+  CheckContext();
+  if (client_) {
+    DCHECK(context_state_->GrContextIsGL());
+    if (!client_->GLTextureImageRepresentationBeginAccess(
+            /*readonly=*/false)) {
+      return {};
+    }
+  }
+
+  if (write_surface_)
+    return {};
+
+  if (!promise_texture_)
+    return {};
+
+  SkColorType sk_color_type = viz::ResourceFormatToClosestSkColorType(
+      /*gpu_compositing=*/true, format());
+  // Gray is not a renderable single channel format, but alpha is.
+  if (sk_color_type == kGray_8_SkColorType)
+    sk_color_type = kAlpha_8_SkColorType;
+  auto surface = SkSurface::MakeFromBackendTexture(
+      context_state_->gr_context(), promise_texture_->backendTexture(),
+      surface_origin(), final_msaa_count, sk_color_type,
+      backing()->color_space().GetAsFullRangeRGB().ToSkColorSpace(),
+      &surface_props);
+  write_surface_ = surface;
+
+  if (!surface)
+    return {};
+  return {surface};
+}
+
+std::vector<sk_sp<SkPromiseImageTexture>>
+SkiaGLCommonRepresentation::BeginWriteAccess(
+    std::vector<GrBackendSemaphore>* begin_semaphores,
+    std::vector<GrBackendSemaphore>* end_semaphores,
+    std::unique_ptr<GrBackendSurfaceMutableState>* end_state) {
+  CheckContext();
+  if (client_) {
+    DCHECK(context_state_->GrContextIsGL());
+    if (!client_->GLTextureImageRepresentationBeginAccess(
+            /*readonly=*/false)) {
+      return {};
+    }
+  }
+
+  if (!promise_texture_)
+    return {};
+  return {promise_texture_};
+}
+
+void SkiaGLCommonRepresentation::EndWriteAccess() {
+  if (write_surface_) {
+    DCHECK(write_surface_->unique());
+    CheckContext();
+    // TODO(ericrk): Keep the surface around for re-use.
+    write_surface_.reset();
+  }
+
+  if (client_)
+    client_->GLTextureImageRepresentationEndAccess(false /* readonly */);
+}
+
+std::vector<sk_sp<SkPromiseImageTexture>>
+SkiaGLCommonRepresentation::BeginReadAccess(
+    std::vector<GrBackendSemaphore>* begin_semaphores,
+    std::vector<GrBackendSemaphore>* end_semaphores,
+    std::unique_ptr<GrBackendSurfaceMutableState>* end_state) {
+  CheckContext();
+  if (client_) {
+    DCHECK(context_state_->GrContextIsGL());
+    if (!client_->GLTextureImageRepresentationBeginAccess(
+            /*readonly=*/true)) {
+      return {};
+    }
+  }
+
+  if (!promise_texture_)
+    return {};
+  return {promise_texture_};
+}
+
+void SkiaGLCommonRepresentation::EndReadAccess() {
+  if (client_)
+    client_->GLTextureImageRepresentationEndAccess(true /* readonly */);
+}
+
+bool SkiaGLCommonRepresentation::SupportsMultipleConcurrentReadAccess() {
+  return true;
+}
+
+void SkiaGLCommonRepresentation::CheckContext() {
+#if DCHECK_IS_ON()
+  if (!context_state_->context_lost() && context_)
+    DCHECK(gl::GLContext::GetCurrent() == context_);
+#endif
+}
+
+}  // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_common_representations.h b/gpu/command_buffer/service/shared_image/gl_texture_common_representations.h
new file mode 100644
index 0000000..06b45fb5
--- /dev/null
+++ b/gpu/command_buffer/service/shared_image/gl_texture_common_representations.h
@@ -0,0 +1,129 @@
+// Copyright 2022 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_GL_TEXTURE_COMMON_REPRESENTATIONS_H_
+#define GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_GL_TEXTURE_COMMON_REPRESENTATIONS_H_
+
+#include "base/memory/raw_ptr.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
+#include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
+#include "gpu/command_buffer/service/texture_manager.h"
+#include "ui/gl/gl_context.h"
+
+namespace gpu {
+
+// Interface through which a representation that has a GL texture calls into its
+// GLImage backing.
+class GLTextureImageRepresentationClient {
+ public:
+  virtual bool GLTextureImageRepresentationBeginAccess(bool readonly) = 0;
+  virtual void GLTextureImageRepresentationEndAccess(bool readonly) = 0;
+  virtual void GLTextureImageRepresentationRelease(bool have_context) = 0;
+};
+
+// Representation of a GLTextureImageBacking or GLImageBacking
+// as a GL Texture.
+class GLTextureGLCommonRepresentation : public GLTextureImageRepresentation {
+ public:
+  GLTextureGLCommonRepresentation(SharedImageManager* manager,
+                                  SharedImageBacking* backing,
+                                  GLTextureImageRepresentationClient* client,
+                                  MemoryTypeTracker* tracker,
+                                  gles2::Texture* texture);
+  ~GLTextureGLCommonRepresentation() override;
+
+ private:
+  // GLTextureImageRepresentation:
+  gles2::Texture* GetTexture(int plane_index) override;
+  bool BeginAccess(GLenum mode) override;
+  void EndAccess() override;
+
+  const raw_ptr<GLTextureImageRepresentationClient> client_ = nullptr;
+  raw_ptr<gles2::Texture> texture_;
+  GLenum mode_ = 0;
+};
+
+// Representation of a GLTextureImageBacking or
+// GLTextureImageBackingPassthrough as a GL TexturePassthrough.
+class GLTexturePassthroughGLCommonRepresentation
+    : public GLTexturePassthroughImageRepresentation {
+ public:
+  class Client {
+   public:
+    virtual bool OnGLTexturePassthroughBeginAccess(GLenum mode) = 0;
+  };
+  GLTexturePassthroughGLCommonRepresentation(
+      SharedImageManager* manager,
+      SharedImageBacking* backing,
+      GLTextureImageRepresentationClient* client,
+      MemoryTypeTracker* tracker,
+      scoped_refptr<gles2::TexturePassthrough> texture_passthrough);
+  ~GLTexturePassthroughGLCommonRepresentation() override;
+
+ private:
+  // GLTexturePassthroughImageRepresentation:
+  const scoped_refptr<gles2::TexturePassthrough>& GetTexturePassthrough(
+      int plane_index) override;
+  bool BeginAccess(GLenum mode) override;
+  void EndAccess() override;
+
+  const raw_ptr<GLTextureImageRepresentationClient> client_ = nullptr;
+  scoped_refptr<gles2::TexturePassthrough> texture_passthrough_;
+  GLenum mode_ = 0;
+};
+
+// Skia representation for both GLTextureImageBackingHelper.
+class SkiaGLCommonRepresentation : public SkiaImageRepresentation {
+ public:
+  class Client {
+   public:
+    virtual bool OnSkiaBeginReadAccess() = 0;
+    virtual bool OnSkiaBeginWriteAccess() = 0;
+  };
+  SkiaGLCommonRepresentation(SharedImageManager* manager,
+                             SharedImageBacking* backing,
+                             GLTextureImageRepresentationClient* client,
+                             scoped_refptr<SharedContextState> context_state,
+                             sk_sp<SkPromiseImageTexture> promise_texture,
+                             MemoryTypeTracker* tracker);
+  ~SkiaGLCommonRepresentation() override;
+
+  void SetBeginReadAccessCallback(
+      base::RepeatingClosure begin_read_access_callback);
+
+ private:
+  // SkiaImageRepresentation:
+  std::vector<sk_sp<SkSurface>> BeginWriteAccess(
+      int final_msaa_count,
+      const SkSurfaceProps& surface_props,
+      const gfx::Rect& update_rect,
+      std::vector<GrBackendSemaphore>* begin_semaphores,
+      std::vector<GrBackendSemaphore>* end_semaphores,
+      std::unique_ptr<GrBackendSurfaceMutableState>* end_state) override;
+  std::vector<sk_sp<SkPromiseImageTexture>> BeginWriteAccess(
+      std::vector<GrBackendSemaphore>* begin_semaphores,
+      std::vector<GrBackendSemaphore>* end_semaphore,
+      std::unique_ptr<GrBackendSurfaceMutableState>* end_state) override;
+  void EndWriteAccess() override;
+  std::vector<sk_sp<SkPromiseImageTexture>> BeginReadAccess(
+      std::vector<GrBackendSemaphore>* begin_semaphores,
+      std::vector<GrBackendSemaphore>* end_semaphores,
+      std::unique_ptr<GrBackendSurfaceMutableState>* end_state) override;
+  void EndReadAccess() override;
+  bool SupportsMultipleConcurrentReadAccess() override;
+
+  void CheckContext();
+
+  const raw_ptr<GLTextureImageRepresentationClient> client_ = nullptr;
+  scoped_refptr<SharedContextState> context_state_;
+  sk_sp<SkPromiseImageTexture> promise_texture_;
+  sk_sp<SkSurface> write_surface_;
+#if DCHECK_IS_ON()
+  raw_ptr<gl::GLContext> context_ = nullptr;
+#endif
+};
+
+}  // namespace gpu
+
+#endif  // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_GL_TEXTURE_COMMON_REPRESENTATIONS_H_
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc b/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc
index d57c4c8..9883eb7 100644
--- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc
+++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing.cc
@@ -24,8 +24,8 @@
 #include "gpu/command_buffer/service/image_factory.h"
 #include "gpu/command_buffer/service/service_utils.h"
 #include "gpu/command_buffer/service/shared_context_state.h"
-#include "gpu/command_buffer/service/shared_image/gl_image_backing.h"
 #include "gpu/command_buffer/service/shared_image/gl_repack_utils.h"
+#include "gpu/command_buffer/service/shared_image/gl_texture_common_representations.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
diff --git a/gpu/ipc/service/dcomp_texture_win.cc b/gpu/ipc/service/dcomp_texture_win.cc
index 03294573..f09ba6c 100644
--- a/gpu/ipc/service/dcomp_texture_win.cc
+++ b/gpu/ipc/service/dcomp_texture_win.cc
@@ -16,7 +16,6 @@
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "gpu/command_buffer/service/scheduler.h"
 #include "gpu/command_buffer/service/scheduler_task_runner.h"
-#include "gpu/command_buffer/service/shared_image/gl_image_backing.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_backing.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_representation.h"
diff --git a/headless/test/headless_devtooled_browsertest.h b/headless/test/headless_devtooled_browsertest.h
index b77e683..dcefc63c 100644
--- a/headless/test/headless_devtooled_browsertest.h
+++ b/headless/test/headless_devtooled_browsertest.h
@@ -52,8 +52,8 @@
 
   void RunTest();
 
-  raw_ptr<HeadlessBrowserContext> browser_context_;
-  raw_ptr<HeadlessWebContents> web_contents_;
+  raw_ptr<HeadlessBrowserContext, DanglingUntriaged> browser_context_;
+  raw_ptr<HeadlessWebContents, DanglingUntriaged> web_contents_;
   simple_devtools_protocol_client::SimpleDevToolsProtocolClient
       devtools_client_;
   simple_devtools_protocol_client::SimpleDevToolsProtocolClient
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm
index c3839dd..e76ab4d 100644
--- a/ios/chrome/browser/flags/about_flags.mm
+++ b/ios/chrome/browser/flags/about_flags.mm
@@ -837,11 +837,6 @@
      FEATURE_VALUE_TYPE(
          autofill::features::
              kAutofillAddressProfileSavePromptAddressVerificationSupport)},
-    {"autofill-address-save-prompt",
-     flag_descriptions::kEnableAutofillAddressSavePromptName,
-     flag_descriptions::kEnableAutofillAddressSavePromptDescription,
-     flags_ui::kOsIos,
-     FEATURE_VALUE_TYPE(autofill::features::kAutofillAddressProfileSavePrompt)},
     {"filling-across-affiliated-websites",
      flag_descriptions::kFillingAcrossAffiliatedWebsitesName,
      flag_descriptions::kFillingAcrossAffiliatedWebsitesDescription,
@@ -1331,7 +1326,7 @@
     {"use-sf-symbols-omnibox", flag_descriptions::kUseSFSymbolsInOmniboxName,
      flag_descriptions::kUseSFSymbolsInOmniboxDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kUseSFSymbolsInOmnibox)},
-    {"tab-grid-recency-sort", flag_descriptions::kTabGridRecencySortName,
+    {"tab-grid-sort", flag_descriptions::kTabGridRecencySortName,
      flag_descriptions::kTabGridRecencySortDescription, flags_ui::kOsIos,
      FEATURE_VALUE_TYPE(kTabGridRecencySort)},
     {"enable-pinned-tabs", flag_descriptions::kEnablePinnedTabsName,
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
index 25392bd..f5dd71b 100644
--- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
+++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -819,9 +819,9 @@
     "when Google is the selected search engine, accessible from the omnibox or "
     "popup menu.";
 
-const char kTabGridRecencySortName[] = "Sort tabs by recency";
+const char kTabGridRecencySortName[] = "Change TabGrid sorting";
 const char kTabGridRecencySortDescription[] =
-    "When enabled, the tabs in the Tab Grid are sorted by last time used.";
+    "When enabled, the tabs in the Tab Grid are sorted differently.";
 
 const char kUseLoadSimulatedRequestForOfflinePageName[] =
     "Use loadSimulatedRequest:responseHTMLString: when displaying offline "
diff --git a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
index fa9dc04deb5..a625ccc3 100644
--- a/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
+++ b/ios/chrome/browser/ui/autofill/chrome_autofill_client_ios.mm
@@ -335,8 +335,6 @@
     const AutofillProfile* original_profile,
     SaveAddressProfilePromptOptions options,
     AddressProfileSavePromptCallback callback) {
-  DCHECK(base::FeatureList::IsEnabled(
-      features::kAutofillAddressProfileSavePrompt));
   // TODO(crbug.com/1167062): Respect SaveAddressProfilePromptOptions.
   for (size_t i = 0; i < infobar_manager_->infobar_count(); ++i) {
     AutofillSaveUpdateAddressProfileDelegateIOS* existing_delegate =
diff --git a/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm b/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm
index eec61a5..9d8112d 100644
--- a/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm
+++ b/ios/chrome/browser/ui/autofill/save_card_infobar_egtest.mm
@@ -112,8 +112,6 @@
       [self isRunningTest:@selector(testUserData_LocalSave_UserDeclines)] ||
       [self isRunningTest:@selector
             (testOfferLocalSave_FullData_PaymentsDeclines)]) {
-    config.features_disabled.push_back(
-        autofill::features::kAutofillAddressProfileSavePrompt);
   }
   return config;
 }
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
index e027ae1..9e67188b 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -3104,12 +3104,9 @@
   }
 
   [self.primaryToolbarCoordinator transitionToLocationBarFocusedState:YES];
-
-  _keyCommandsProvider.canDismissModals = YES;
 }
 
 - (void)locationBarDidResignFirstResponder {
-  _keyCommandsProvider.canDismissModals = NO;
   [_sideSwipeController setEnabled:YES];
 
   [self.ntpCoordinator locationBarDidResignFirstResponder];
diff --git a/ios/chrome/browser/ui/browser_view/key_commands_provider.h b/ios/chrome/browser/ui/browser_view/key_commands_provider.h
index 2168e5a..a03c5b5 100644
--- a/ios/chrome/browser/ui/browser_view/key_commands_provider.h
+++ b/ios/chrome/browser/ui/browser_view/key_commands_provider.h
@@ -31,10 +31,6 @@
     browserCoordinatorCommandsHandler;
 @property(nonatomic, weak) id<OmniboxCommands> omniboxHandler;
 
-// Set this flag to YES when the keyboard command bound to the Escape key should
-// dismiss modals.
-@property(nonatomic, assign) BOOL canDismissModals;
-
 - (instancetype)initWithBrowser:(Browser*)browser NS_DESIGNATED_INITIALIZER;
 - (instancetype)init NS_UNAVAILABLE;
 
diff --git a/ios/chrome/browser/ui/browser_view/key_commands_provider.mm b/ios/chrome/browser/ui/browser_view/key_commands_provider.mm
index b571c20c..c76253db 100644
--- a/ios/chrome/browser/ui/browser_view/key_commands_provider.mm
+++ b/ios/chrome/browser/ui/browser_view/key_commands_provider.mm
@@ -109,7 +109,6 @@
       UIKeyCommand.cr_showPreviousTab_2,
       UIKeyCommand.cr_showNextTab_3,
       UIKeyCommand.cr_showPreviousTab_3,
-      UIKeyCommand.cr_close,
       UIKeyCommand.cr_back_2,
       UIKeyCommand.cr_forward_2,
       UIKeyCommand.cr_showDownloads_2,
@@ -147,7 +146,6 @@
       UIKeyCommand.cr_forward_2,
       UIKeyCommand.cr_showHistory,
       UIKeyCommand.cr_voiceSearch,
-      UIKeyCommand.cr_close,
       UIKeyCommand.cr_openNewRegularTab,
       UIKeyCommand.cr_showSettings,
       UIKeyCommand.cr_stop,
@@ -216,9 +214,6 @@
       sel_isEqual(action, @selector(keyCommand_findPrevious))) {
     return [self isFindInPageActive];
   }
-  if (sel_isEqual(action, @selector(keyCommand_close))) {
-    return self.canDismissModals;
-  }
   if (sel_isEqual(action, @selector(keyCommand_showNextTab)) ||
       sel_isEqual(action, @selector(keyCommand_showPreviousTab))) {
     WebStateList* webStateList = self.browser->GetWebStateList();
@@ -406,11 +401,6 @@
   [_dispatcher startVoiceSearch];
 }
 
-- (void)keyCommand_close {
-  RecordAction(UserMetricsAction("MobileKeyCommandClose"));
-  [_dispatcher dismissModalDialogs];
-}
-
 - (void)keyCommand_showSettings {
   RecordAction(UserMetricsAction("MobileKeyCommandShowSettings"));
   [_dispatcher showSettingsFromViewController:_viewController];
diff --git a/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm b/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm
index 51ff165..700e876 100644
--- a/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm
+++ b/ios/chrome/browser/ui/browser_view/key_commands_provider_unittest.mm
@@ -353,16 +353,6 @@
 }
 
 // Checks whether KeyCommandsProvider can perform the actions that are only
-// available when canDismissModals is ON.
-TEST_F(KeyCommandsProviderTest, CanPerform_CanDismissModalsActions) {
-  ASSERT_FALSE(provider_.canDismissModals);
-  EXPECT_FALSE(CanPerform(@"keyCommand_close"));
-
-  provider_.canDismissModals = YES;
-  EXPECT_TRUE(CanPerform(@"keyCommand_close"));
-}
-
-// Checks whether KeyCommandsProvider can perform the actions that are only
 // available when there are at least two tabs.
 TEST_F(KeyCommandsProviderTest, CanPerform_ShowPreviousAndNextTab) {
   // No tabs.
@@ -533,7 +523,6 @@
   ExpectUMA(@"keyCommand_forward", "MobileKeyCommandForward");
   ExpectUMA(@"keyCommand_showHistory", "MobileKeyCommandShowHistory");
   ExpectUMA(@"keyCommand_voiceSearch", "MobileKeyCommandVoiceSearch");
-  ExpectUMA(@"keyCommand_close", "MobileKeyCommandClose");
   ExpectUMA(@"keyCommand_showSettings", "MobileKeyCommandShowSettings");
   ExpectUMA(@"keyCommand_stop", "MobileKeyCommandStop");
   ExpectUMA(@"keyCommand_showHelp", "MobileKeyCommandShowHelp");
@@ -579,7 +568,6 @@
   [provider_ keyCommand_forward];
   [provider_ keyCommand_showHistory];
   [provider_ keyCommand_voiceSearch];
-  [provider_ keyCommand_close];
   [provider_ keyCommand_showSettings];
   [provider_ keyCommand_stop];
   [provider_ keyCommand_showHelp];
diff --git a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm
index 0052012b..7c64106 100644
--- a/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm
+++ b/ios/chrome/browser/ui/infobars/modals/autofill_address_profile/infobar_save_address_profile_table_view_controller.mm
@@ -195,22 +195,18 @@
     didSelectRowAtIndexPath:(NSIndexPath*)indexPath {
   TableViewModel* model = self.tableViewModel;
   NSInteger itemType = [model itemTypeForIndexPath:indexPath];
-  if (base::FeatureList::IsEnabled(
-          autofill::features::
-              kAutofillAddressProfileSavePromptAddressVerificationSupport)) {
-    switch (itemType) {
-      case ItemTypeSaveAddress:
-      case ItemTypeSaveEmail:
-      case ItemTypeSavePhone:
-      case ItemTypeUpdateNameNew:
-      case ItemTypeUpdateAddressNew:
-      case ItemTypeUpdateEmailNew:
-      case ItemTypeUpdatePhoneNew:
-        [self ensureContextMenuShownForItemType:itemType atIndexPath:indexPath];
-        break;
-      default:
-        break;
-    }
+  switch (itemType) {
+    case ItemTypeSaveAddress:
+    case ItemTypeSaveEmail:
+    case ItemTypeSavePhone:
+    case ItemTypeUpdateNameNew:
+    case ItemTypeUpdateAddressNew:
+    case ItemTypeUpdateEmailNew:
+    case ItemTypeUpdatePhoneNew:
+      [self ensureContextMenuShownForItemType:itemType atIndexPath:indexPath];
+      break;
+    default:
+      break;
   }
 }
 
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn
index ab9e8a3..3bf838e 100644
--- a/ios/chrome/browser/ui/toolbar/BUILD.gn
+++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -114,6 +114,7 @@
     "//ios/chrome/browser/ui/fullscreen:ui",
     "//ios/chrome/browser/ui/gestures",
     "//ios/chrome/browser/ui/icons:symbols",
+    "//ios/chrome/browser/ui/keyboard",
     "//ios/chrome/browser/ui/ntp:ntp",
     "//ios/chrome/browser/ui/omnibox:features",
     "//ios/chrome/browser/ui/orchestrator",
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.mm
index e3dd51f..3a1c04f2 100644
--- a/ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.mm
+++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.mm
@@ -16,6 +16,7 @@
 #import "ios/chrome/browser/ntp/new_tab_page_tab_helper.h"
 #import "ios/chrome/browser/prerender/prerender_service.h"
 #import "ios/chrome/browser/prerender/prerender_service_factory.h"
+#import "ios/chrome/browser/ui/commands/application_commands.h"
 #import "ios/chrome/browser/ui/commands/command_dispatcher.h"
 #import "ios/chrome/browser/ui/commands/find_in_page_commands.h"
 #import "ios/chrome/browser/ui/commands/omnibox_commands.h"
@@ -60,6 +61,8 @@
 @property(nonatomic, strong) OmniboxFocusOrchestrator* orchestrator;
 // Whether the omnibox focusing should happen with animation.
 @property(nonatomic, assign) BOOL enableAnimationsForOmniboxFocus;
+// Whether the omnibox is currently focused.
+@property(nonatomic, assign) BOOL locationBarFocused;
 
 @end
 
@@ -164,6 +167,7 @@
                       toolbarExpanded:focused && !IsRegularXRegularSizeClass(
                                                      self.viewController)
                              animated:self.enableAnimationsForOmniboxFocus];
+  self.locationBarFocused = focused;
 }
 
 - (id<ViewRevealingAnimatee>)animatee {
@@ -239,6 +243,14 @@
     FullscreenController::FromBrowser(self.browser)->ExitFullscreen();
 }
 
+- (void)close {
+  if (self.locationBarFocused) {
+    id<ApplicationCommands> applicationCommandsHandler = HandlerForProtocol(
+        self.browser->GetCommandDispatcher(), ApplicationCommands);
+    [applicationCommandsHandler dismissModalDialogs];
+  }
+}
+
 #pragma mark - NewTabPageControllerDelegate
 
 - (UIResponder<UITextInput>*)fakeboxScribbleForwardingTarget {
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.h b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.h
index 373971d5..b1be265 100644
--- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.h
+++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.h
@@ -8,6 +8,7 @@
 #import "ios/chrome/browser/ui/activity_services/requirements/activity_service_positioner.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_ui_element.h"
 #import "ios/chrome/browser/ui/gestures/view_revealing_animatee.h"
+#import "ios/chrome/browser/ui/keyboard/key_command_actions.h"
 #import "ios/chrome/browser/ui/orchestrator/toolbar_animatee.h"
 #import "ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.h"
 
@@ -19,6 +20,7 @@
 @interface PrimaryToolbarViewController
     : AdaptiveToolbarViewController <ActivityServicePositioner,
                                      FullscreenUIElement,
+                                     KeyCommandActions,
                                      ToolbarAnimatee,
                                      ViewRevealingAnimatee>
 
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm
index cafe487e..11f217fb 100644
--- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm
+++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller.mm
@@ -9,10 +9,13 @@
 #import "base/check.h"
 #import "base/feature_list.h"
 #import "base/metrics/field_trial_params.h"
+#import "base/metrics/user_metrics.h"
+#import "base/metrics/user_metrics_action.h"
 #import "ios/chrome/browser/ui/commands/browser_commands.h"
 #import "ios/chrome/browser/ui/commands/omnibox_commands.h"
 #import "ios/chrome/browser/ui/fullscreen/fullscreen_animator.h"
 #import "ios/chrome/browser/ui/gestures/view_revealing_vertical_pan_handler.h"
+#import "ios/chrome/browser/ui/keyboard/UIKeyCommand+Chrome.h"
 #import "ios/chrome/browser/ui/omnibox/omnibox_ui_features.h"
 #import "ios/chrome/browser/ui/thumb_strip/thumb_strip_feature.h"
 #import "ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller+subclassing.h"
@@ -199,6 +202,17 @@
   [self updateLayoutForPreviousTraitCollection:previousTraitCollection];
 }
 
+#pragma mark - UIResponder
+
+- (NSArray<UIKeyCommand*>*)keyCommands {
+  return @[ UIKeyCommand.cr_close ];
+}
+
+- (void)keyCommand_close {
+  base::RecordAction(base::UserMetricsAction("MobileKeyCommandClose"));
+  [self.delegate close];
+}
+
 #pragma mark - Property accessors
 
 - (void)setLocationBarViewController:
diff --git a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller_delegate.h b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller_delegate.h
index 8b527287..613ad39 100644
--- a/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller_delegate.h
+++ b/ios/chrome/browser/ui/toolbar/primary_toolbar_view_controller_delegate.h
@@ -17,6 +17,10 @@
 // Exits fullscreen.
 - (void)exitFullscreen;
 
+// Called when the user requires to close the toolbar (typically with the ESC/⎋
+// keyboard shortcut).
+- (void)close;
+
 @end
 
 #endif  // IOS_CHROME_BROWSER_UI_TOOLBAR_PRIMARY_TOOLBAR_VIEW_CONTROLLER_DELEGATE_H_
diff --git a/ios/chrome/test/app/sync_test_util.mm b/ios/chrome/test/app/sync_test_util.mm
index cb56cd3..2b8524f 100644
--- a/ios/chrome/test/app/sync_test_util.mm
+++ b/ios/chrome/test/app/sync_test_util.mm
@@ -136,15 +136,12 @@
 }
 
 int GetNumberOfSyncEntities(syncer::ModelType type) {
-  std::unique_ptr<base::DictionaryValue> entities =
-      gSyncFakeServer->GetEntitiesAsDictionaryValue();
+  std::unique_ptr<base::Value::Dict> entities =
+      gSyncFakeServer->GetEntitiesAsDict();
 
-  std::string model_type_string = ModelTypeToDebugString(type);
-  base::ListValue* entity_list = NULL;
-  if (!entities->GetList(model_type_string, &entity_list)) {
-    return 0;
-  }
-  return entity_list->GetListDeprecated().size();
+  base::Value::List* entity_list =
+      entities->FindList(ModelTypeToDebugString(type));
+  return entity_list ? static_cast<int>(entity_list->size()) : 0;
 }
 
 BOOL VerifyNumberOfSyncEntitiesWithName(syncer::ModelType type,
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 c51a3ca..adb8d46 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 @@
-0f5cc6941f3d11b7f4a3ae4aface9dc359bd6c30
\ No newline at end of file
+f644da71b1badc97b700e1f39441698d0f807085
\ 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 aee61a3b..bbe14a4 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 @@
-a059a2cb30ff58495753e2098b7e715c3942a408
\ No newline at end of file
+87f0350abeae6847c015810ca486e5f61aa133d8
\ 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 d6dca25..7e23dfaf7 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 @@
-a162aa8b249d456c267d0894c450718c011f9eee
\ No newline at end of file
+b97840e08e063217fe013bf0c345ad8f55fe439d
\ 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 40f52c5..c36d55c 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 @@
-4eff299ede3d15c58c22f19dc00ffb3655face27
\ No newline at end of file
+4b5d35646d24066fd559b30f5574e1b2ad62d1f0
\ 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 4a76f83f..95ddc0c 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 @@
-e0c1992a70c0cc7b04359b12d6970dbf8d90bbe3
\ No newline at end of file
+2348c74c761a97dcea7241949573f8f60e5c56ad
\ 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 5d1a21f..d29a480 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 @@
-e65d6909ce5160607e87aeedcb95f86620f6c757
\ No newline at end of file
+75c2a7bd07b67cd9c583e52aa3e74f0f202abf36
\ 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 d3a89df..2ad9eef 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 @@
-66c7f4ccf7a610985b4bf7b3f04f8a4365851758
\ No newline at end of file
+a33dfcf9effc21e5b276ca9722ca660757a2cf18
\ 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 af459e5..86e9234 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 @@
-fb3f729c4c91538ff2e4de648103c5861ca235e9
\ No newline at end of file
+58ffb387e0b174fb8ab4f4cceb2d99f3fd089726
\ 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 4c04e45..add9790d 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 @@
-a61710c27f12cfdda5c1fec75e0c5c5194212a2c
\ No newline at end of file
+b9046422f6c4e1cb1afd2e1fb9b7f1109f94d53c
\ 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 6523d7af..81557b6 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 @@
-d385fb902fe3ebdf498c26b07945a46116e12598
\ No newline at end of file
+ac3d95bdbf65bee08d21ebda92ea9e6c30c93c24
\ 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 6842c4f..46ae8b5d 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 @@
-0a37225d94cb7c3187d9c7b53f29c3aad4847d92
\ No newline at end of file
+c2349acbbd445ea7ac95c4f790d3c831e0a0ef98
\ 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 daa07613..df21c9c42 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 @@
-abd7962dc032b58b52b9eeab3e5b6d9408fdb5e2
\ No newline at end of file
+1cd41144ff2201c9bcff61dd07adbb25f2870b1c
\ No newline at end of file
diff --git a/ipc/ipc_channel_mojo.cc b/ipc/ipc_channel_mojo.cc
index bd0d114..d6c78468 100644
--- a/ipc/ipc_channel_mojo.cc
+++ b/ipc/ipc_channel_mojo.cc
@@ -109,7 +109,8 @@
 
   const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
   const Forwarder forwarder_;
-  const raw_ref<mojo::AssociatedGroupController> group_controller_;
+  const raw_ref<mojo::AssociatedGroupController, DanglingUntriaged>
+      group_controller_;
 };
 
 base::ProcessId GetSelfPID() {
diff --git a/media/audio/audio_system_helper.h b/media/audio/audio_system_helper.h
index 35a0b65..4ef7e26 100644
--- a/media/audio/audio_system_helper.h
+++ b/media/audio/audio_system_helper.h
@@ -55,7 +55,7 @@
   absl::optional<AudioParameters> ComputeOutputParameters(
       const std::string& device_id);
 
-  const raw_ptr<AudioManager> audio_manager_;
+  const raw_ptr<AudioManager, DanglingUntriaged> audio_manager_;
 };
 
 }  // namespace media
diff --git a/media/base/bit_reader_core.h b/media/base/bit_reader_core.h
index d91b474..2cd778ab 100644
--- a/media/base/bit_reader_core.h
+++ b/media/base/bit_reader_core.h
@@ -107,7 +107,7 @@
   // Refill the current bit register from the next bit register.
   void RefillCurrentRegister();
 
-  const raw_ptr<ByteStreamProvider> byte_stream_provider_;
+  const raw_ptr<ByteStreamProvider, DanglingUntriaged> byte_stream_provider_;
 
   // Number of bits read so far.
   int bits_read_;
diff --git a/media/gpu/mac/vt_video_decode_accelerator_mac.cc b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
index 780f6ca8..12f30a4 100644
--- a/media/gpu/mac/vt_video_decode_accelerator_mac.cc
+++ b/media/gpu/mac/vt_video_decode_accelerator_mac.cc
@@ -44,7 +44,6 @@
 #include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/command_buffer/common/shared_image_usage.h"
-#include "gpu/command_buffer/service/shared_image/gl_image_backing.h"
 #include "gpu/command_buffer/service/shared_image/shared_image_factory.h"
 #include "gpu/ipc/service/shared_image_stub.h"
 #include "media/base/limits.h"
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
index 18c6c22..6c40d52 100644
--- a/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
+++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.cc
@@ -6,12 +6,6 @@
 
 #include "media/gpu/vaapi/va_surface.h"
 #include "media/gpu/vaapi/vaapi_wrapper.h"
-#include "ui/gfx/buffer_format_util.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-#include "ui/gfx/linux/native_pixmap_dmabuf.h"
-#include "ui/gfx/native_pixmap.h"
-#include "ui/gl/gl_bindings.h"
-#include "ui/gl/gl_image_native_pixmap.h"
 
 namespace media {
 
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap.h b/media/gpu/vaapi/vaapi_picture_native_pixmap.h
index 1961f4c..ec5d5e1a 100644
--- a/media/gpu/vaapi/vaapi_picture_native_pixmap.h
+++ b/media/gpu/vaapi/vaapi_picture_native_pixmap.h
@@ -10,13 +10,7 @@
 #include "base/memory/scoped_refptr.h"
 #include "media/gpu/vaapi/va_surface.h"
 #include "media/gpu/vaapi/vaapi_picture.h"
-#include "ui/gfx/buffer_types.h"
 #include "ui/gfx/geometry/size.h"
-#include "ui/gfx/gpu_memory_buffer.h"
-
-namespace gl {
-class GLImage;
-}
 
 namespace media {
 
@@ -47,9 +41,6 @@
   VASurfaceID va_surface_id() const override;
 
  protected:
-  // GLImage bound to the GL textures used by the VDA client.
-  scoped_refptr<gl::GLImage> gl_image_;
-
   // VASurface used to transfer from the decoder's pixel format.
   scoped_refptr<VASurface> va_surface_;
 };
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.cc
index a21495d..a7baafe5 100644
--- a/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.cc
+++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.cc
@@ -82,6 +82,14 @@
 
   if (x_pixmap_ != x11::Pixmap::None)
     x11::Connection::Get()->FreePixmap({x_pixmap_});
+
+  // Reset |va_surface_| before |gl_image_| to preserve the order of destruction
+  // before the refactoring done in
+  // https://chromium-review.googlesource.com/c/chromium/src/+/4025005.
+  // TODO(crbug.com/1366367): Determine whether preserving this order matters
+  // and remove these calls if not.
+  va_surface_.reset();
+  gl_image_.reset();
 }
 
 VaapiStatus VaapiPictureNativePixmapAngle::Allocate(gfx::BufferFormat format) {
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h b/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h
index 9535691..b7e95db 100644
--- a/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h
+++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_angle.h
@@ -15,6 +15,10 @@
 #include "ui/gfx/x/xproto.h"
 #include "ui/gl/gl_bindings.h"
 
+namespace gl {
+class GLImage;
+}
+
 namespace media {
 
 class VaapiWrapper;
@@ -51,6 +55,9 @@
 
  private:
   x11::Pixmap x_pixmap_ = x11::Pixmap::None;
+
+  // GLImage bound to the GL textures used by the VDA client.
+  scoped_refptr<gl::GLImage> gl_image_;
 };
 
 }  // namespace media
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc
index f17221a..93751dc 100644
--- a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc
+++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.cc
@@ -47,6 +47,14 @@
     gl_image_->ReleaseTexImage(texture_target_);
     DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR));
   }
+
+  // Reset |va_surface_| before |gl_image_| to preserve the order of destruction
+  // before the refactoring done in
+  // https://chromium-review.googlesource.com/c/chromium/src/+/4025005.
+  // TODO(crbug.com/1366367): Determine whether preserving this order matters
+  // and remove these calls if not.
+  va_surface_.reset();
+  gl_image_.reset();
 }
 
 VaapiStatus VaapiPictureNativePixmapEgl::Initialize(
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h
index 35a584bc..7f2385f3 100644
--- a/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h
+++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_egl.h
@@ -17,6 +17,10 @@
 class NativePixmap;
 }  // namespace gfx
 
+namespace gl {
+class GLImage;
+}
+
 namespace media {
 
 class VaapiWrapper;
@@ -50,6 +54,9 @@
 
  private:
   VaapiStatus Initialize(scoped_refptr<gfx::NativePixmap> pixmap);
+
+  // GLImage bound to the GL textures used by the VDA client.
+  scoped_refptr<gl::GLImage> gl_image_;
 };
 
 }  // namespace media
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc
index 01af004a9..122445c 100644
--- a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc
+++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.cc
@@ -53,6 +53,14 @@
     gl_image_->ReleaseTexImage(texture_target_);
     DCHECK_EQ(glGetError(), static_cast<GLenum>(GL_NO_ERROR));
   }
+
+  // Reset |va_surface_| before |gl_image_| to preserve the order of destruction
+  // before the refactoring done in
+  // https://chromium-review.googlesource.com/c/chromium/src/+/4025005.
+  // TODO(crbug.com/1366367): Determine whether preserving this order matters
+  // and remove these calls if not.
+  va_surface_.reset();
+  gl_image_.reset();
 }
 
 VaapiStatus VaapiPictureNativePixmapOzone::Initialize(
diff --git a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h
index 607a69ae..a2c1d2e 100644
--- a/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h
+++ b/media/gpu/vaapi/vaapi_picture_native_pixmap_ozone.h
@@ -17,6 +17,10 @@
 class NativePixmap;
 }  // namespace gfx
 
+namespace gl {
+class GLImage;
+}
+
 namespace media {
 
 class VaapiWrapper;
@@ -49,6 +53,9 @@
 
  private:
   VaapiStatus Initialize(scoped_refptr<gfx::NativePixmap> pixmap);
+
+  // GLImage bound to the GL textures used by the VDA client.
+  scoped_refptr<gl::GLImage> gl_image_;
 };
 
 }  // namespace media
diff --git a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc
index a370df7..fb1234814 100644
--- a/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc
+++ b/media/gpu/vaapi/vp9_vaapi_video_encoder_delegate.cc
@@ -29,25 +29,11 @@
 constexpr size_t kKFPeriod = 3000;
 
 // Quantization parameter. They are vp9 ac/dc indices and their ranges are
-// 0-255. Based on WebRTC's defaults.
-constexpr uint8_t kMinQP = 4;
-constexpr uint8_t kMaxQP = 112;
-// The upper limitation of the quantization parameter for the software rate
-// controller. This is larger than |kMaxQP| because a driver might ignore the
-// specified maximum quantization parameter when the driver determines the
-// value, but it doesn't ignore the quantization parameter by the software rate
-// controller.
-constexpr uint8_t kMaxQPForSoftwareRateCtrl = 224;
-
-// This stands for 31 as a real ac value (see rfc 8.6.1 table
-// ac_qlookup[3][256]). Note: This needs to be revisited once we have 10&12 bit
-// encoder support.
-constexpr uint8_t kDefaultQP = 24;
-
-// filter level may affect on quality at lower bitrates; for now,
-// we set a constant value (== 10) which is what other VA-API
-// implementations like libyami and gstreamer-vaapi are using.
-constexpr uint8_t kDefaultLfLevel = 10;
+// 0-255. These are based on WebRTC's defaults.
+constexpr uint8_t kMinQP = 8;
+constexpr uint8_t kMaxQP = 208;
+constexpr uint8_t kScreenMinQP = 32;
+constexpr uint8_t kScreenMaxQP = kMaxQP;
 
 // Convert Qindex, whose range is 0-255, to the quantizer parameter used in
 // libvpx vp9 rate control, whose range is 0-63.
@@ -195,6 +181,12 @@
   coded_size_ = gfx::Size(base::bits::AlignUp(visible_size_.width(), 16),
                           base::bits::AlignUp(visible_size_.height(), 16));
   current_params_ = EncodeParams();
+  if (config.content_type ==
+      VideoEncodeAccelerator::Config::ContentType::kDisplay) {
+    current_params_.min_qp = kScreenMinQP;
+    current_params_.max_qp = kScreenMaxQP;
+  }
+
   reference_frames_.Clear();
   frame_num_ = 0;
 
@@ -239,7 +231,6 @@
     }
     svc_layers_ = std::make_unique<VP9SVCLayers>(config.spatial_layers);
   }
-  current_params_.max_qp = kMaxQPForSoftwareRateCtrl;
 
   // Store layer size for vp9 simple stream.
   if (spatial_layer_resolutions.empty())
@@ -419,8 +410,6 @@
   hdr.frame_height = visible_size_.height();
   hdr.render_width = visible_size_.width();
   hdr.render_height = visible_size_.height();
-  hdr.quant_params.base_q_idx = kDefaultQP;
-  hdr.loop_filter.level = kDefaultLfLevel;
   hdr.show_frame = true;
   hdr.frame_type =
       keyframe ? Vp9FrameHeader::KEYFRAME : Vp9FrameHeader::INTERFRAME;
diff --git a/net/http/http_stream_factory_job_controller.h b/net/http/http_stream_factory_job_controller.h
index 4e4a621..3bf03bb 100644
--- a/net/http/http_stream_factory_job_controller.h
+++ b/net/http/http_stream_factory_job_controller.h
@@ -285,9 +285,9 @@
            (dns_alpn_h3_job_ ? 1 : 0);
   }
 
-  raw_ptr<HttpStreamFactory> factory_;
-  raw_ptr<HttpNetworkSession> session_;
-  raw_ptr<JobFactory> job_factory_;
+  raw_ptr<HttpStreamFactory, DanglingUntriaged> factory_;
+  raw_ptr<HttpNetworkSession, DanglingUntriaged> session_;
+  raw_ptr<JobFactory, DanglingUntriaged> job_factory_;
 
   // Request will be handed out to factory once created. This just keeps an
   // reference and is safe as |request_| will notify |this| JobController
@@ -295,7 +295,7 @@
   // |request_|.
   raw_ptr<HttpStreamRequest, DanglingUntriaged> request_ = nullptr;
 
-  const raw_ptr<HttpStreamRequest::Delegate> delegate_;
+  const raw_ptr<HttpStreamRequest::Delegate, DanglingUntriaged> delegate_;
 
   // True if this JobController is used to preconnect streams.
   const bool is_preconnect_;
diff --git a/net/test/embedded_test_server/http2_connection.cc b/net/test/embedded_test_server/http2_connection.cc
index 23e067d..3282973 100644
--- a/net/test/embedded_test_server/http2_connection.cc
+++ b/net/test/embedded_test_server/http2_connection.cc
@@ -117,7 +117,7 @@
 
  private:
   const raw_ptr<Http2Connection> connection_;
-  const raw_ref<const StreamId> stream_id_;
+  const raw_ref<const StreamId, DanglingUntriaged> stream_id_;
   std::queue<std::string> chunks_;
   bool last_frame_ = false;
   base::OnceClosure send_completion_callback_;
diff --git a/services/device/geolocation/location_arbitrator.h b/services/device/geolocation/location_arbitrator.h
index 5eb2227a..d51a9ef10 100644
--- a/services/device/geolocation/location_arbitrator.h
+++ b/services/device/geolocation/location_arbitrator.h
@@ -103,7 +103,7 @@
                            bool from_same_provider) const;
 
   const CustomLocationProviderCallback custom_location_provider_getter_;
-  const raw_ptr<GeolocationManager> geolocation_manager_;
+  const raw_ptr<GeolocationManager, DanglingUntriaged> geolocation_manager_;
   scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_;
   const scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
   const std::string api_key_;
diff --git a/services/device/usb/usb_context.cc b/services/device/usb/usb_context.cc
index a5cb8c09..f9f7fa9e 100644
--- a/services/device/usb/usb_context.cc
+++ b/services/device/usb/usb_context.cc
@@ -36,7 +36,7 @@
 
  private:
   base::subtle::Atomic32 running_;
-  raw_ptr<libusb_context> context_;
+  raw_ptr<libusb_context, DanglingUntriaged> context_;
 };
 
 UsbContext::UsbEventHandler::UsbEventHandler(libusb_context* context)
diff --git a/services/service_manager/public/cpp/interface_provider.h b/services/service_manager/public/cpp/interface_provider.h
index ffb5f14..683f357 100644
--- a/services/service_manager/public/cpp/interface_provider.h
+++ b/services/service_manager/public/cpp/interface_provider.h
@@ -52,7 +52,7 @@
     }
 
    private:
-    raw_ptr<InterfaceProvider> provider_;
+    raw_ptr<InterfaceProvider, DanglingUntriaged> provider_;
   };
 
   // Constructs an InterfaceProvider which is usable immediately despite not
diff --git a/services/video_capture/push_video_stream_subscription_impl.h b/services/video_capture/push_video_stream_subscription_impl.h
index 55b3477..5b969f9 100644
--- a/services/video_capture/push_video_stream_subscription_impl.h
+++ b/services/video_capture/push_video_stream_subscription_impl.h
@@ -70,7 +70,7 @@
   const media::VideoCaptureParams requested_settings_;
   mojom::VideoSource::CreatePushSubscriptionCallback creation_callback_;
   const raw_ptr<BroadcastingReceiver> broadcaster_;
-  raw_ptr<Device> device_;
+  raw_ptr<Device, DanglingUntriaged> device_;
   Status status_{Status::kCreationCallbackNotYetRun};
 
   // Client id handed out by |broadcaster_| when registering |this| as its
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index fd4d056..4ea62ebc 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -5875,9 +5875,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -5889,8 +5889,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -6041,9 +6041,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -6055,8 +6055,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -6192,9 +6192,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -6206,8 +6206,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 991246a..427c3e91 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -88083,9 +88083,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -88097,8 +88097,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -88219,9 +88219,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -88233,8 +88233,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com"
@@ -88345,9 +88345,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -88359,8 +88359,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com",
@@ -89700,9 +89700,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -89713,8 +89713,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -89866,9 +89866,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -89879,8 +89879,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -90017,9 +90017,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -90030,8 +90030,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -91552,9 +91552,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -91565,8 +91565,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -91718,9 +91718,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -91731,8 +91731,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -91869,9 +91869,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -91882,8 +91882,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -92681,9 +92681,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -92694,8 +92694,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index 2806cf0..4827b72 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -18562,10 +18562,10 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.filter;../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18577,8 +18577,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -18736,10 +18736,10 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18751,8 +18751,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
@@ -18892,10 +18892,10 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always"
         ],
-        "description": "Run with ash-chrome version 110.0.5421.0",
+        "description": "Run with ash-chrome version 110.0.5422.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18907,8 +18907,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v110.0.5421.0",
-              "revision": "version:110.0.5421.0"
+              "location": "lacros_version_skew_tests_v110.0.5422.0",
+              "revision": "version:110.0.5422.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 66bf0b0..2f16d30 100644
--- a/testing/buildbot/variants.pyl
+++ b/testing/buildbot/variants.pyl
@@ -22,16 +22,16 @@
   },
   'LACROS_VERSION_SKEW_CANARY': {
     'args': [
-      '--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5421.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v110.0.5422.0/test_ash_chrome',
     ],
-    'description': 'Run with ash-chrome version 110.0.5421.0',
+    'description': 'Run with ash-chrome version 110.0.5422.0',
     'identifier': 'Lacros version skew testing ash canary',
     'swarming': {
       'cipd_packages': [
         {
           'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip',
-          'location': 'lacros_version_skew_tests_v110.0.5421.0',
-          'revision': 'version:110.0.5421.0',
+          'location': 'lacros_version_skew_tests_v110.0.5422.0',
+          'revision': 'version:110.0.5422.0',
         },
       ],
     },
diff --git a/testing/test.gni b/testing/test.gni
index 60b6c3f..4f82d16 100644
--- a/testing/test.gni
+++ b/testing/test.gni
@@ -462,6 +462,9 @@
     }
 
     use_v2_script = use_v2_script_default
+    if (target_cpu == "x64") {
+      use_v2_script = false
+    }
     if (defined(invoker.fuchsia_legacy_script_required) &&
         invoker.fuchsia_legacy_script_required) {
       use_v2_script = false
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 901eb65..cb43a80 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -1240,6 +1240,27 @@
             ]
         }
     ],
+    "AutofillIgnoreInvalidCountryOnImport": [
+        {
+            "platforms": [
+                "android",
+                "chromeos",
+                "chromeos_lacros",
+                "ios",
+                "linux",
+                "mac",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "AutofillIgnoreInvalidCountryOnImport"
+                    ]
+                }
+            ]
+        }
+    ],
     "AutofillImprovedLabelForInference": [
         {
             "platforms": [
@@ -7026,6 +7047,24 @@
             ]
         }
     ],
+    "MojoIpcz": [
+        {
+            "platforms": [
+                "android",
+                "ios",
+                "linux",
+                "windows"
+            ],
+            "experiments": [
+                {
+                    "name": "Enabled",
+                    "enable_features": [
+                        "MojoIpcz"
+                    ]
+                }
+            ]
+        }
+    ],
     "MuteCompromisedPasswords": [
         {
             "platforms": [
diff --git a/third_party/blink/renderer/core/animation/string_keyframe.cc b/third_party/blink/renderer/core/animation/string_keyframe.cc
index 104c55e3c..fe3e319 100644
--- a/third_party/blink/renderer/core/animation/string_keyframe.cc
+++ b/third_party/blink/renderer/core/animation/string_keyframe.cc
@@ -55,9 +55,10 @@
   bool is_animation_tainted = true;
 
   auto* property_map = CreateCssPropertyValueSet();
-  MutableCSSPropertyValueSet::SetResult result = property_map->SetProperty(
-      custom_property_name, value, false, secure_context_mode,
-      style_sheet_contents, is_animation_tainted);
+  MutableCSSPropertyValueSet::SetResult result =
+      property_map->ParseAndSetCustomProperty(
+          custom_property_name, value, false, secure_context_mode,
+          style_sheet_contents, is_animation_tainted);
 
   const CSSValue* parsed_value =
       property_map->GetPropertyCSSValue(custom_property_name);
@@ -87,7 +88,7 @@
 
   auto* property_value_set = CreateCssPropertyValueSet();
   MutableCSSPropertyValueSet::SetResult result =
-      property_value_set->SetProperty(
+      property_value_set->ParseAndSetProperty(
           property_id, value, false, secure_context_mode, style_sheet_contents);
 
   // TODO(crbug.com/1132078): Add flag to CSSProperty to track if it is for a
@@ -154,9 +155,9 @@
     StyleSheetContents* style_sheet_contents) {
   DCHECK_NE(property.PropertyID(), CSSPropertyID::kInvalid);
   if (!CSSAnimations::IsAnimationAffectingProperty(property)) {
-    presentation_attribute_map_->SetProperty(property.PropertyID(), value,
-                                             false, secure_context_mode,
-                                             style_sheet_contents);
+    presentation_attribute_map_->ParseAndSetProperty(
+        property.PropertyID(), value, false, secure_context_mode,
+        style_sheet_contents);
   }
 }
 
@@ -282,7 +283,8 @@
     if (property_handle.IsCSSCustomProperty()) {
       CSSPropertyName property_name(property_handle.CustomPropertyName());
       const CSSValue* value = entry.value->CssValue();
-      css_property_map_->SetProperty(CSSPropertyValue(property_name, *value));
+      css_property_map_->SetLonghandProperty(
+          CSSPropertyValue(property_name, *value));
     } else {
       PropertyResolver* resolver = entry.value;
       if (resolver->IsLogical() || resolver->IsShorthand())
diff --git a/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc b/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
index 7a11fb59..6e6b1af9 100644
--- a/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
+++ b/third_party/blink/renderer/core/css/abstract_property_set_css_style_declaration.cc
@@ -232,13 +232,13 @@
     AtomicString atomic_name(custom_property_name);
 
     bool is_animation_tainted = IsKeyframeStyle();
-    result = PropertySet().SetProperty(atomic_name, value, important,
-                                       secure_context_mode, ContextStyleSheet(),
-                                       is_animation_tainted);
+    result = PropertySet().ParseAndSetCustomProperty(
+        atomic_name, value, important, secure_context_mode, ContextStyleSheet(),
+        is_animation_tainted);
   } else {
-    result =
-        PropertySet().SetProperty(unresolved_property, value, important,
-                                  secure_context_mode, ContextStyleSheet());
+    result = PropertySet().ParseAndSetProperty(unresolved_property, value,
+                                               important, secure_context_mode,
+                                               ContextStyleSheet());
   }
 
   if (result == MutableCSSPropertyValueSet::kParseError ||
diff --git a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc
index 2fb5f44e..ad3ace6b 100644
--- a/third_party/blink/renderer/core/css/css_math_expression_node_test.cc
+++ b/third_party/blink/renderer/core/css/css_math_expression_node_test.cc
@@ -76,8 +76,9 @@
 bool AccumulateLengthArray(String text, CSSLengthArray& length_array) {
   auto* property_set =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  property_set->SetProperty(CSSPropertyID::kLeft, text, /* important */ false,
-                            SecureContextMode::kInsecureContext);
+  property_set->ParseAndSetProperty(CSSPropertyID::kLeft, text,
+                                    /* important */ false,
+                                    SecureContextMode::kInsecureContext);
   return To<CSSPrimitiveValue>(
              property_set->GetPropertyCSSValue(CSSPropertyID::kLeft))
       ->AccumulateLengthArray(length_array);
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.cc b/third_party/blink/renderer/core/css/css_property_value_set.cc
index c3c73ae9..49c7279 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set.cc
+++ b/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -377,7 +377,8 @@
   return PropertyAt(found_property_index).IsImplicit();
 }
 
-MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
+MutableCSSPropertyValueSet::SetResult
+MutableCSSPropertyValueSet::ParseAndSetProperty(
     CSSPropertyID unresolved_property,
     const String& value,
     bool important,
@@ -401,7 +402,8 @@
                                secure_context_mode, context_style_sheet);
 }
 
-MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
+MutableCSSPropertyValueSet::SetResult
+MutableCSSPropertyValueSet::ParseAndSetCustomProperty(
     const AtomicString& custom_property_name,
     const String& value,
     bool important,
@@ -422,7 +424,7 @@
                                              bool important) {
   StylePropertyShorthand shorthand = shorthandForProperty(name.Id());
   if (!shorthand.length()) {
-    SetProperty(CSSPropertyValue(name, value, important));
+    SetLonghandProperty(CSSPropertyValue(name, value, important));
     return;
   }
 
@@ -442,9 +444,11 @@
   SetProperty(CSSPropertyName(property_id), value, important);
 }
 
-MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
+MutableCSSPropertyValueSet::SetResult
+MutableCSSPropertyValueSet::SetLonghandProperty(
     const CSSPropertyValue& property,
     CSSPropertyValue* slot) {
+  DCHECK_EQ(shorthandForProperty(property.Id()).length(), 0u);
   CSSPropertyValue* to_replace =
       slot ? slot : FindCSSPropertyWithName(property.Name());
   if (to_replace) {
@@ -479,12 +483,12 @@
   return kChangedPropertySet;
 }
 
-MutableCSSPropertyValueSet::SetResult MutableCSSPropertyValueSet::SetProperty(
-    CSSPropertyID property_id,
-    CSSValueID identifier,
-    bool important) {
+MutableCSSPropertyValueSet::SetResult
+MutableCSSPropertyValueSet::SetLonghandProperty(CSSPropertyID property_id,
+                                                CSSValueID identifier,
+                                                bool important) {
   CSSPropertyName name(property_id);
-  return SetProperty(CSSPropertyValue(
+  return SetLonghandProperty(CSSPropertyValue(
       name, *CSSIdentifierValue::Create(identifier), important));
 }
 
@@ -513,7 +517,7 @@
   SetResult changed = kUnchanged;
   property_vector_.reserve(property_vector_.size() + properties.size());
   for (unsigned i = 0; i < properties.size(); ++i)
-    changed = std::max(changed, SetProperty(properties[i]));
+    changed = std::max(changed, SetLonghandProperty(properties[i]));
   return changed;
 }
 
@@ -521,7 +525,7 @@
     const CSSPropertyValue& property) {
   // Only add properties that have no !important counterpart present
   if (!PropertyIsImportant(property.Id()) || property.IsImportant())
-    return SetProperty(property);
+    return SetLonghandProperty(property);
   return false;
 }
 
@@ -536,7 +540,7 @@
     PropertyReference to_merge = other->PropertyAt(n);
     CSSPropertyValue* old = FindCSSPropertyWithName(to_merge.Name());
     if (old) {
-      SetProperty(
+      SetLonghandProperty(
           CSSPropertyValue(to_merge.PropertyMetadata(), to_merge.Value()), old);
     } else {
       property_vector_.push_back(
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.h b/third_party/blink/renderer/core/css/css_property_value_set.h
index 3a9ba14..b1758f5 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set.h
+++ b/third_party/blink/renderer/core/css/css_property_value_set.h
@@ -267,34 +267,54 @@
     kChangedPropertySet = 3,
   };
 
+  // Wrapper around SetLonghandProperty() for setting multiple properties
+  // at a time.
   SetResult AddParsedProperties(const HeapVector<CSSPropertyValue, 64>&);
 
+  // Wrapper around SetLonghandProperty() that does nothing if the same property
+  // already exists with an !important declaration.
+  //
   // Returns whether this style set was changed.
   bool AddRespectingCascade(const CSSPropertyValue&);
 
-  // These expand shorthand properties into multiple properties.
-  SetResult SetProperty(CSSPropertyID unresolved_property,
-                        const String& value,
-                        bool important,
-                        SecureContextMode,
-                        StyleSheetContents* context_style_sheet = nullptr);
-  SetResult SetProperty(const AtomicString& custom_property_name,
-                        const String& value,
-                        bool important,
-                        SecureContextMode,
-                        StyleSheetContents* context_style_sheet,
-                        bool is_animation_tainted);
+  // Expands shorthand properties into multiple properties.
   void SetProperty(const CSSPropertyName&,
                    const CSSValue&,
                    bool important = false);
+
+  // Convenience wrapper around the above.
   void SetProperty(CSSPropertyID, const CSSValue&, bool important = false);
 
-  // These do not. FIXME: This is too messy, we can do better.
-  SetResult SetProperty(CSSPropertyID,
-                        CSSValueID identifier,
-                        bool important = false);
-  SetResult SetProperty(const CSSPropertyValue&,
-                        CSSPropertyValue* slot = nullptr);
+  // Also a convenience wrapper around SetProperty(), parsing the value from a
+  // string before setting it. If the value is empty, the property is removed.
+  // Only for non-custom properties.
+  SetResult ParseAndSetProperty(
+      CSSPropertyID unresolved_property,
+      const String& value,
+      bool important,
+      SecureContextMode,
+      StyleSheetContents* context_style_sheet = nullptr);
+
+  // Similar to ParseAndSetProperty(), but for custom properties instead.
+  // (By implementation quirk, it attempts shorthand expansion, even though
+  // custom properties can never be shorthands.) If the value is empty,
+  // the property is removed.
+  SetResult ParseAndSetCustomProperty(const AtomicString& custom_property_name,
+                                      const String& value,
+                                      bool important,
+                                      SecureContextMode,
+                                      StyleSheetContents* context_style_sheet,
+                                      bool is_animation_tainted);
+
+  // This one does not expand longhands, but is the most efficient form.
+  // All the other property setters eventually call down into this.
+  SetResult SetLonghandProperty(const CSSPropertyValue&,
+                                CSSPropertyValue* slot = nullptr);
+
+  // Convenience form of the above.
+  SetResult SetLonghandProperty(CSSPropertyID,
+                                CSSValueID identifier,
+                                bool important = false);
 
   template <typename T>  // CSSPropertyID or AtomicString
   bool RemoveProperty(const T& property, String* return_text = nullptr);
diff --git a/third_party/blink/renderer/core/css/css_property_value_set_test.cc b/third_party/blink/renderer/core/css/css_property_value_set_test.cc
index c067c81c..91f5744 100644
--- a/third_party/blink/renderer/core/css/css_property_value_set_test.cc
+++ b/third_party/blink/renderer/core/css/css_property_value_set_test.cc
@@ -92,67 +92,70 @@
 
 TEST_F(CSSPropertyValueSetTest, SetPropertyReturnValue) {
   MutableCSSPropertyValueSet properties(kHTMLStandardMode);
-  EXPECT_EQ(
-      MutableCSSPropertyValueSet::kChangedPropertySet,
-      properties.SetProperty(CSSPropertyID::kColor, "red", /*important=*/false,
-                             SecureContextMode::kInsecureContext,
-                             /*context_style_sheet=*/nullptr));
-  EXPECT_EQ(
-      MutableCSSPropertyValueSet::kUnchanged,
-      properties.SetProperty(CSSPropertyID::kColor, "red", /*important=*/false,
-                             SecureContextMode::kInsecureContext,
-                             /*context_style_sheet=*/nullptr));
   EXPECT_EQ(MutableCSSPropertyValueSet::kChangedPropertySet,
-            properties.SetProperty(CSSPropertyID::kBackgroundColor, "white",
-                                   /*important=*/false,
-                                   SecureContextMode::kInsecureContext,
-                                   /*context_style_sheet=*/nullptr));
+            properties.ParseAndSetProperty(CSSPropertyID::kColor, "red",
+                                           /*important=*/false,
+                                           SecureContextMode::kInsecureContext,
+                                           /*context_style_sheet=*/nullptr));
+  EXPECT_EQ(MutableCSSPropertyValueSet::kUnchanged,
+            properties.ParseAndSetProperty(CSSPropertyID::kColor, "red",
+                                           /*important=*/false,
+                                           SecureContextMode::kInsecureContext,
+                                           /*context_style_sheet=*/nullptr));
+  EXPECT_EQ(MutableCSSPropertyValueSet::kChangedPropertySet,
+            properties.ParseAndSetProperty(
+                CSSPropertyID::kBackgroundColor, "white",
+                /*important=*/false, SecureContextMode::kInsecureContext,
+                /*context_style_sheet=*/nullptr));
   EXPECT_EQ(MutableCSSPropertyValueSet::kModifiedExisting,
-            properties.SetProperty(CSSPropertyID::kColor, "green",
-                                   /*important=*/false,
-                                   SecureContextMode::kInsecureContext,
-                                   /*context_style_sheet=*/nullptr));
-  EXPECT_EQ(
-      MutableCSSPropertyValueSet::kChangedPropertySet,
-      properties.SetProperty(CSSPropertyID::kColor, "", /*important=*/false,
-                             SecureContextMode::kInsecureContext,
-                             /*context_style_sheet=*/nullptr));
+            properties.ParseAndSetProperty(CSSPropertyID::kColor, "green",
+                                           /*important=*/false,
+                                           SecureContextMode::kInsecureContext,
+                                           /*context_style_sheet=*/nullptr));
+  EXPECT_EQ(MutableCSSPropertyValueSet::kChangedPropertySet,
+            properties.ParseAndSetProperty(CSSPropertyID::kColor, "",
+                                           /*important=*/false,
+                                           SecureContextMode::kInsecureContext,
+                                           /*context_style_sheet=*/nullptr));
 }
 
 TEST_F(CSSPropertyValueSetTest, SetCustomPropertyReturnValue) {
   MutableCSSPropertyValueSet properties(kHTMLStandardMode);
   EXPECT_EQ(MutableCSSPropertyValueSet::kChangedPropertySet,
-            properties.SetProperty("--my-property", "red", /*important=*/false,
-                                   SecureContextMode::kInsecureContext,
-                                   /*context_style_sheet=*/nullptr,
-                                   /*is_animation_tainted=*/false));
+            properties.ParseAndSetCustomProperty(
+                "--my-property", "red", /*important=*/false,
+                SecureContextMode::kInsecureContext,
+                /*context_style_sheet=*/nullptr,
+                /*is_animation_tainted=*/false));
 
   // Custom property values are compared by instance rather than by value
   // (due to performance constraints), so we don't get a kUnchanged
   // return value here.
   EXPECT_EQ(MutableCSSPropertyValueSet::kModifiedExisting,
-            properties.SetProperty("--my-property", "red", /*important=*/false,
-                                   SecureContextMode::kInsecureContext,
-                                   /*context_style_sheet=*/nullptr,
-                                   /*is_animation_tainted=*/false));
+            properties.ParseAndSetCustomProperty(
+                "--my-property", "red", /*important=*/false,
+                SecureContextMode::kInsecureContext,
+                /*context_style_sheet=*/nullptr,
+                /*is_animation_tainted=*/false));
 
-  EXPECT_EQ(
-      MutableCSSPropertyValueSet::kChangedPropertySet,
-      properties.SetProperty("--your-property", "white", /*important=*/false,
-                             SecureContextMode::kInsecureContext,
-                             /*context_style_sheet=*/nullptr,
-                             /*is_animation_tainted=*/false));
-  EXPECT_EQ(MutableCSSPropertyValueSet::kModifiedExisting,
-            properties.SetProperty("--my-property", "green",
-                                   /*important=*/false,
-                                   SecureContextMode::kInsecureContext,
-                                   /*context_style_sheet=*/nullptr,
-                                   /*is_animation_tainted=*/false));
   EXPECT_EQ(MutableCSSPropertyValueSet::kChangedPropertySet,
-            properties.SetProperty("--my-property", "", /*important=*/false,
-                                   SecureContextMode::kInsecureContext,
-                                   /*context_style_sheet=*/nullptr,
-                                   /*is_animation_tainted=*/false));
+            properties.ParseAndSetCustomProperty(
+                "--your-property", "white",
+                /*important=*/false, SecureContextMode::kInsecureContext,
+                /*context_style_sheet=*/nullptr,
+                /*is_animation_tainted=*/false));
+  EXPECT_EQ(MutableCSSPropertyValueSet::kModifiedExisting,
+            properties.ParseAndSetCustomProperty(
+                "--my-property", "green",
+                /*important=*/false, SecureContextMode::kInsecureContext,
+                /*context_style_sheet=*/nullptr,
+                /*is_animation_tainted=*/false));
+  EXPECT_EQ(MutableCSSPropertyValueSet::kChangedPropertySet,
+            properties.ParseAndSetCustomProperty(
+                "--my-property", "", /*important=*/false,
+                SecureContextMode::kInsecureContext,
+                /*context_style_sheet=*/nullptr,
+                /*is_animation_tainted=*/false));
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/cssom/declared_style_property_map.cc b/third_party/blink/renderer/core/css/cssom/declared_style_property_map.cc
index 27eb21b..d19777f3 100644
--- a/third_party/blink/renderer/core/css/cssom/declared_style_property_map.cc
+++ b/third_party/blink/renderer/core/css/cssom/declared_style_property_map.cc
@@ -52,7 +52,7 @@
     SecureContextMode secure_context_mode) {
   DCHECK(CSSProperty::Get(property_id).IsShorthand());
   CSSStyleSheet::RuleMutationScope mutation_scope(owner_rule_);
-  const auto result = GetStyleRule()->MutableProperties().SetProperty(
+  const auto result = GetStyleRule()->MutableProperties().ParseAndSetProperty(
       property_id, value, false /* important */, secure_context_mode);
   return result != MutableCSSPropertyValueSet::kParseError;
 }
diff --git a/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc b/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc
index d8672a88..ec0b147 100644
--- a/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc
+++ b/third_party/blink/renderer/core/css/cssom/inline_style_property_map.cc
@@ -42,8 +42,9 @@
     const String& value,
     SecureContextMode secure_context_mode) {
   DCHECK(CSSProperty::Get(property_id).IsShorthand());
-  const auto result = owner_element_->EnsureMutableInlineStyle().SetProperty(
-      property_id, value, false /* important */, secure_context_mode);
+  const auto result =
+      owner_element_->EnsureMutableInlineStyle().ParseAndSetProperty(
+          property_id, value, false /* important */, secure_context_mode);
   return result != MutableCSSPropertyValueSet::kParseError;
 }
 
diff --git a/third_party/blink/renderer/core/css/parser/css_parser.cc b/third_party/blink/renderer/core/css/parser/css_parser.cc
index 953e5db3..f5fdee9e 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser.cc
@@ -157,7 +157,7 @@
   const CSSValue* value = CSSParserFastPaths::MaybeParseValue(
       resolved_property, string, parser_mode);
   if (value) {
-    return declaration->SetProperty(CSSPropertyValue(
+    return declaration->SetLonghandProperty(CSSPropertyValue(
         CSSPropertyName(resolved_property), *value, important));
   }
 
@@ -179,7 +179,7 @@
     value =
         CSSPropertyParser::ParseSingleValue(resolved_property, tokens, context);
     if (value != nullptr) {
-      return declaration->SetProperty(CSSPropertyValue(
+      return declaration->SetLonghandProperty(CSSPropertyValue(
           CSSPropertyName(resolved_property), *value, important));
     }
   }
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
index bbbfbe4..dabb7cc 100644
--- a/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_cascade_test.cc
@@ -329,10 +329,10 @@
                                                         String value) {
     CSSParserMode mode = kHTMLStandardMode;
     auto* set = MakeGarbageCollected<MutableCSSPropertyValueSet>(mode);
-    set->SetProperty(name, value, /* important */ false,
-                     SecureContextMode::kSecureContext,
-                     /* context_style_sheet */ nullptr,
-                     /* is_animation_tainted */ true);
+    set->ParseAndSetCustomProperty(name, value, /* important */ false,
+                                   SecureContextMode::kSecureContext,
+                                   /* context_style_sheet */ nullptr,
+                                   /* is_animation_tainted */ true);
     return set;
   }
 
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.cc b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
index 907293b..bcaa7a9 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -330,8 +330,8 @@
       Persistent<MutableCSSPropertyValueSet>, left_to_right_decl,
       (MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode)));
   if (left_to_right_decl->IsEmpty()) {
-    left_to_right_decl->SetProperty(CSSPropertyID::kDirection,
-                                    CSSValueID::kLtr);
+    left_to_right_decl->SetLonghandProperty(CSSPropertyID::kDirection,
+                                            CSSValueID::kLtr);
   }
   return left_to_right_decl;
 }
@@ -341,8 +341,8 @@
       Persistent<MutableCSSPropertyValueSet>, right_to_left_decl,
       (MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode)));
   if (right_to_left_decl->IsEmpty()) {
-    right_to_left_decl->SetProperty(CSSPropertyID::kDirection,
-                                    CSSValueID::kRtl);
+    right_to_left_decl->SetLonghandProperty(CSSPropertyID::kDirection,
+                                            CSSValueID::kRtl);
   }
   return right_to_left_decl;
 }
@@ -972,9 +972,10 @@
     state.SetStyle(ComputedStyle::Clone(*state.ParentStyle()));
   } else {
     // We use a different initial_style for img elements to match the overrides
-    // in html.css. This avoids allocation overhead from copy-on-write when these
-    // properties are set only via UA styles. The overhead shows up on motionmark
-    // which stress tests this code. See crbub.com/1369454 for details.
+    // in html.css. This avoids allocation overhead from copy-on-write when
+    // these properties are set only via UA styles. The overhead shows up on
+    // motionmark which stress tests this code. See crbub.com/1369454 for
+    // details.
     ComputedStyleBuilder builder(IsA<HTMLImageElement>(element)
                                      ? *initial_style_for_img_
                                      : *initial_style_);
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
index cf92209b..3f6b40f0 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver_test.cc
@@ -925,7 +925,7 @@
   CSSPropertyID property_id = CSSPropertyID::kColor;
   auto* set =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLStandardMode);
-  MutableCSSPropertyValueSet::SetResult result = set->SetProperty(
+  MutableCSSPropertyValueSet::SetResult result = set->ParseAndSetProperty(
       property_id, "var(--color)", false, SecureContextMode::kInsecureContext,
       /*context_style_sheet=*/nullptr);
   ASSERT_NE(MutableCSSPropertyValueSet::kParseError, result);
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc
index 6d789a734c..75c7bb27 100644
--- a/third_party/blink/renderer/core/dom/element.cc
+++ b/third_party/blink/renderer/core/dom/element.cc
@@ -7421,7 +7421,7 @@
   DCHECK_NE(property_id, CSSPropertyID::kVariable);
   DCHECK(IsStyledElement());
   bool did_change =
-      EnsureMutableInlineStyle().SetProperty(
+      EnsureMutableInlineStyle().ParseAndSetProperty(
           property_id, value, important,
           GetExecutionContext() ? GetExecutionContext()->GetSecureContextMode()
                                 : SecureContextMode::kInsecureContext,
@@ -7525,11 +7525,11 @@
     CSSPropertyID property_id,
     const String& value) {
   DCHECK(IsStyledElement());
-  style->SetProperty(property_id, value, false,
-                     GetExecutionContext()
-                         ? GetExecutionContext()->GetSecureContextMode()
-                         : SecureContextMode::kInsecureContext,
-                     GetDocument().ElementSheet().Contents());
+  style->ParseAndSetProperty(property_id, value, false,
+                             GetExecutionContext()
+                                 ? GetExecutionContext()->GetSecureContextMode()
+                                 : SecureContextMode::kInsecureContext,
+                             GetDocument().ElementSheet().Contents());
 }
 
 void Element::AddPropertyToPresentationAttributeStyle(
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
index c7c64fd..6e77506 100644
--- a/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/apply_style_command.cc
@@ -641,8 +641,8 @@
     } else {
       MutableCSSPropertyValueSet* inline_style =
           CopyStyleOrCreateEmpty(element->InlineStyle());
-      inline_style->SetProperty(CSSPropertyID::kUnicodeBidi,
-                                CSSValueID::kNormal);
+      inline_style->SetLonghandProperty(CSSPropertyID::kUnicodeBidi,
+                                        CSSValueID::kNormal);
       inline_style->RemoveProperty(CSSPropertyID::kDirection);
       SetNodeAttribute(element, html_names::kStyleAttr,
                        AtomicString(inline_style->AsText()));
diff --git a/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc b/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc
index c9febeae3..1e3cb434 100644
--- a/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc
+++ b/third_party/blink/renderer/core/editing/commands/apply_style_command_test.cc
@@ -48,8 +48,9 @@
 
   auto* style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(CSSPropertyID::kTextAlign, "center", /* important */ false,
-                     SecureContextMode::kInsecureContext);
+  style->ParseAndSetProperty(CSSPropertyID::kTextAlign, "center",
+                             /* important */ false,
+                             SecureContextMode::kInsecureContext);
   MakeGarbageCollected<ApplyStyleCommand>(
       GetDocument(), MakeGarbageCollected<EditingStyle>(style),
       InputEvent::InputType::kFormatJustifyCenter,
@@ -78,8 +79,9 @@
 
   auto* style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(CSSPropertyID::kTextAlign, "right", /* important */ false,
-                     SecureContextMode::kInsecureContext);
+  style->ParseAndSetProperty(CSSPropertyID::kTextAlign, "right",
+                             /* important */ false,
+                             SecureContextMode::kInsecureContext);
   MakeGarbageCollected<ApplyStyleCommand>(
       GetDocument(), MakeGarbageCollected<EditingStyle>(style),
       InputEvent::InputType::kFormatJustifyCenter,
@@ -96,9 +98,9 @@
       SetSelectionOptions());
 
   auto* style = MakeGarbageCollected<MutableCSSPropertyValueSet>(kUASheetMode);
-  style->SetProperty(CSSPropertyID::kInternalFontSizeDelta, "3px",
-                     /* important */ false,
-                     GetFrame().DomWindow()->GetSecureContextMode());
+  style->ParseAndSetProperty(CSSPropertyID::kInternalFontSizeDelta, "3px",
+                             /* important */ false,
+                             GetFrame().DomWindow()->GetSecureContextMode());
   MakeGarbageCollected<ApplyStyleCommand>(
       GetDocument(), MakeGarbageCollected<EditingStyle>(style),
       InputEvent::InputType::kNone)
@@ -118,9 +120,9 @@
       SetSelectionOptions());
 
   auto* style = MakeGarbageCollected<MutableCSSPropertyValueSet>(kUASheetMode);
-  style->SetProperty(CSSPropertyID::kTextAlign, "right",
-                     /* important */ false,
-                     GetFrame().DomWindow()->GetSecureContextMode());
+  style->ParseAndSetProperty(CSSPropertyID::kTextAlign, "right",
+                             /* important */ false,
+                             GetFrame().DomWindow()->GetSecureContextMode());
   MakeGarbageCollected<ApplyStyleCommand>(
       GetDocument(), MakeGarbageCollected<EditingStyle>(style),
       InputEvent::InputType::kFormatJustifyRight,
@@ -145,9 +147,9 @@
       SetSelectionOptions());
 
   auto* style = MakeGarbageCollected<MutableCSSPropertyValueSet>(kUASheetMode);
-  style->SetProperty(CSSPropertyID::kTextAlign, "center",
-                     /* important */ false,
-                     GetFrame().DomWindow()->GetSecureContextMode());
+  style->ParseAndSetProperty(CSSPropertyID::kTextAlign, "center",
+                             /* important */ false,
+                             GetFrame().DomWindow()->GetSecureContextMode());
   MakeGarbageCollected<ApplyStyleCommand>(
       GetDocument(), MakeGarbageCollected<EditingStyle>(style),
       InputEvent::InputType::kFormatJustifyCenter,
@@ -191,9 +193,9 @@
                            SetSelectionOptions());
 
   auto* style = MakeGarbageCollected<MutableCSSPropertyValueSet>(kUASheetMode);
-  style->SetProperty(CSSPropertyID::kFontStyle, "italic",
-                     /* important */ false,
-                     GetFrame().DomWindow()->GetSecureContextMode());
+  style->ParseAndSetProperty(CSSPropertyID::kFontStyle, "italic",
+                             /* important */ false,
+                             GetFrame().DomWindow()->GetSecureContextMode());
   MakeGarbageCollected<ApplyStyleCommand>(
       GetDocument(), MakeGarbageCollected<EditingStyle>(style),
       InputEvent::InputType::kFormatItalic)
diff --git a/third_party/blink/renderer/core/editing/commands/editor_command.cc b/third_party/blink/renderer/core/editing/commands/editor_command.cc
index 7c591134..680c02f 100644
--- a/third_party/blink/renderer/core/editing/commands/editor_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/editor_command.cc
@@ -261,8 +261,8 @@
                                        const String& property_value) {
   auto* style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(property_id, property_value, /* important */ false,
-                     frame.DomWindow()->GetSecureContextMode());
+  style->ParseAndSetProperty(property_id, property_value, /* important */ false,
+                             frame.DomWindow()->GetSecureContextMode());
   // FIXME: We don't call shouldApplyStyle when the source is DOM; is there a
   // good reason for that?
   switch (source) {
diff --git a/third_party/blink/renderer/core/editing/commands/remove_format_command.cc b/third_party/blink/renderer/core/editing/commands/remove_format_command.cc
index 49a2c80..3513d29d 100644
--- a/third_party/blink/renderer/core/editing/commands/remove_format_command.cc
+++ b/third_party/blink/renderer/core/editing/commands/remove_format_command.cc
@@ -78,8 +78,8 @@
 
   // We want to remove everything but transparent background.
   // FIXME: We shouldn't access style().
-  default_style->Style()->SetProperty(CSSPropertyID::kBackgroundColor,
-                                      CSSValueID::kTransparent);
+  default_style->Style()->SetLonghandProperty(CSSPropertyID::kBackgroundColor,
+                                              CSSValueID::kTransparent);
 
   ApplyCommandToComposite(MakeGarbageCollected<ApplyStyleCommand>(
                               GetDocument(), default_style,
diff --git a/third_party/blink/renderer/core/editing/commands/style_commands.cc b/third_party/blink/renderer/core/editing/commands/style_commands.cc
index efc7cdb..8aafbc16 100644
--- a/third_party/blink/renderer/core/editing/commands/style_commands.cc
+++ b/third_party/blink/renderer/core/editing/commands/style_commands.cc
@@ -108,8 +108,8 @@
   DCHECK(frame.GetDocument());
   auto* const style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(property_id, property_value, /* important */ false,
-                     frame.DomWindow()->GetSecureContextMode());
+  style->ParseAndSetProperty(property_id, property_value, /* important */ false,
+                             frame.DomWindow()->GetSecureContextMode());
   return ApplyCommandToFrame(frame, source, input_type, style);
 }
 
@@ -120,7 +120,7 @@
                                       CSSValueID property_value) {
   auto* const style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(property_id, property_value);
+  style->SetLonghandProperty(property_id, property_value);
   return ApplyCommandToFrame(frame, source, input_type, style);
 }
 
@@ -176,8 +176,8 @@
     const String&) {
   auto* const style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(CSSPropertyID::kUnicodeBidi, CSSValueID::kIsolate);
-  style->SetProperty(CSSPropertyID::kDirection, CSSValueID::kLtr);
+  style->SetLonghandProperty(CSSPropertyID::kUnicodeBidi, CSSValueID::kIsolate);
+  style->SetLonghandProperty(CSSPropertyID::kDirection, CSSValueID::kLtr);
   ApplyStyle(frame, style, InputEvent::InputType::kFormatSetBlockTextDirection);
   return true;
 }
@@ -188,7 +188,7 @@
                                                            const String&) {
   auto* const style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(CSSPropertyID::kUnicodeBidi, CSSValueID::kNormal);
+  style->SetLonghandProperty(CSSPropertyID::kUnicodeBidi, CSSValueID::kNormal);
   ApplyStyle(frame, style, InputEvent::InputType::kFormatSetBlockTextDirection);
   return true;
 }
@@ -200,8 +200,8 @@
     const String&) {
   auto* const style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(CSSPropertyID::kUnicodeBidi, CSSValueID::kIsolate);
-  style->SetProperty(CSSPropertyID::kDirection, CSSValueID::kRtl);
+  style->SetLonghandProperty(CSSPropertyID::kUnicodeBidi, CSSValueID::kIsolate);
+  style->SetLonghandProperty(CSSPropertyID::kDirection, CSSValueID::kRtl);
   ApplyStyle(frame, style, InputEvent::InputType::kFormatSetBlockTextDirection);
   return true;
 }
@@ -323,8 +323,9 @@
   // We should have setPropertyCSSValue.
   auto* const new_mutable_style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  new_mutable_style->SetProperty(property_id, new_style, /* important */ false,
-                                 frame.DomWindow()->GetSecureContextMode());
+  new_mutable_style->ParseAndSetProperty(
+      property_id, new_style, /* important */ false,
+      frame.DomWindow()->GetSecureContextMode());
   return ApplyCommandToFrame(frame, source, input_type, new_mutable_style);
 }
 
diff --git a/third_party/blink/renderer/core/editing/editing_style.cc b/third_party/blink/renderer/core/editing/editing_style.cc
index b0168b3..7e5704b 100644
--- a/third_party/blink/renderer/core/editing/editing_style.cc
+++ b/third_party/blink/renderer/core/editing/editing_style.cc
@@ -362,7 +362,7 @@
 
   auto* dummy_style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  dummy_style->SetProperty(
+  dummy_style->ParseAndSetProperty(
       property_id_, value, /* important */ false,
       element->GetExecutionContext()->GetSecureContextMode());
   return dummy_style->GetPropertyCSSValue(property_id_);
@@ -563,14 +563,14 @@
   if (properties_to_include == kEditingPropertiesInEffect) {
     if (const CSSValue* value =
             EditingStyleUtilities::BackgroundColorValueInEffect(node)) {
-      mutable_style_->SetProperty(
+      mutable_style_->ParseAndSetProperty(
           CSSPropertyID::kBackgroundColor, value->CssText(),
           /* important */ false,
           node->GetExecutionContext()->GetSecureContextMode());
     }
     if (const CSSValue* value = computed_style_at_position->GetPropertyCSSValue(
             CSSPropertyID::kWebkitTextDecorationsInEffect)) {
-      mutable_style_->SetProperty(
+      mutable_style_->ParseAndSetProperty(
           CSSPropertyID::kTextDecoration, value->CssText(),
           /* important */ false,
           node->GetExecutionContext()->GetSecureContextMode());
@@ -588,7 +588,7 @@
     if (computed_style->ComputedFontSize() !=
         computed_style->SpecifiedFontSize()) {
       // ReplaceSelectionCommandTest_TextAutosizingDoesntInflateText gets here.
-      mutable_style_->SetProperty(
+      mutable_style_->ParseAndSetProperty(
           CSSPropertyID::kFontSize,
           CSSNumericLiteralValue::Create(computed_style->SpecifiedFontSize(),
                                          CSSPrimitiveValue::UnitType::kPixels)
@@ -635,8 +635,8 @@
         MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
   }
 
-  mutable_style_->SetProperty(property_id, value, important,
-                              secure_context_mode);
+  mutable_style_->ParseAndSetProperty(property_id, value, important,
+                                      secure_context_mode);
 }
 
 void EditingStyle::ReplaceFontSizeByKeywordIfPossible(
@@ -645,7 +645,7 @@
     CSSComputedStyleDeclaration* css_computed_style) {
   DCHECK(computed_style);
   if (computed_style->GetFontDescription().KeywordSize()) {
-    mutable_style_->SetProperty(
+    mutable_style_->ParseAndSetProperty(
         CSSPropertyID::kFontSize,
         css_computed_style->GetFontSizeCSSValuePreferringKeyword()->CssText(),
         /* important */ false, secure_context_mode);
@@ -792,11 +792,11 @@
   EditingStyle* text_direction = MakeGarbageCollected<EditingStyle>();
   text_direction->mutable_style_ =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  text_direction->mutable_style_->SetProperty(
+  text_direction->mutable_style_->SetLonghandProperty(
       CSSPropertyID::kUnicodeBidi, CSSValueID::kIsolate,
       mutable_style_->PropertyIsImportant(CSSPropertyID::kUnicodeBidi));
 
-  text_direction->mutable_style_->SetProperty(
+  text_direction->mutable_style_->ParseAndSetProperty(
       CSSPropertyID::kDirection,
       mutable_style_->GetPropertyValue(CSSPropertyID::kDirection),
       mutable_style_->PropertyIsImportant(CSSPropertyID::kDirection),
@@ -864,7 +864,7 @@
     return;
 
   if (text_decorations_in_effect->IsValueList()) {
-    mutable_style_->SetProperty(
+    mutable_style_->ParseAndSetProperty(
         CSSPropertyID::kTextDecorationLine,
         text_decorations_in_effect->CssText(),
         mutable_style_->PropertyIsImportant(CSSPropertyID::kTextDecorationLine),
@@ -1318,12 +1318,13 @@
 
   if (auto* unicode_bidi_identifier_value =
           DynamicTo<CSSIdentifierValue>(unicode_bidi)) {
-    mutable_style_->SetProperty(CSSPropertyID::kUnicodeBidi,
-                                unicode_bidi_identifier_value->GetValueID());
+    mutable_style_->SetLonghandProperty(
+        CSSPropertyID::kUnicodeBidi,
+        unicode_bidi_identifier_value->GetValueID());
     if (auto* direction_identifier_value =
             DynamicTo<CSSIdentifierValue>(direction)) {
-      mutable_style_->SetProperty(CSSPropertyID::kDirection,
-                                  direction_identifier_value->GetValueID());
+      mutable_style_->SetLonghandProperty(
+          CSSPropertyID::kDirection, direction_identifier_value->GetValueID());
     }
   }
 }
@@ -1483,7 +1484,7 @@
     }
 
     if (mode == kOverrideValues || (mode == kDoNotOverrideValues && !value)) {
-      mutable_style_->SetProperty(
+      mutable_style_->SetLonghandProperty(
           CSSPropertyValue(property.PropertyMetadata(), property.Value()));
     }
   }
@@ -1598,7 +1599,7 @@
   if (computed_style->mutable_style_) {
     if (!computed_style->mutable_style_->GetPropertyCSSValue(
             CSSPropertyID::kBackgroundColor)) {
-      computed_style->mutable_style_->SetProperty(
+      computed_style->mutable_style_->SetLonghandProperty(
           CSSPropertyID::kBackgroundColor, CSSValueID::kTransparent);
     }
 
@@ -1641,8 +1642,8 @@
         MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
   }
   const bool kPropertyIsImportant = true;
-  mutable_style_->SetProperty(CSSPropertyID::kDisplay, CSSValueID::kInline,
-                              kPropertyIsImportant);
+  mutable_style_->SetLonghandProperty(
+      CSSPropertyID::kDisplay, CSSValueID::kInline, kPropertyIsImportant);
 }
 
 int EditingStyle::LegacyFontSize(Document* document) const {
@@ -1670,9 +1671,9 @@
   // "web_tests/editing/execCommand/insert-list-and-strikethrough.html" makes
   // both |textDecorationsInEffect| and |textDecoration| non-null.
   if (text_decorations_in_effect) {
-    style->SetProperty(CSSPropertyID::kTextDecorationLine,
-                       text_decorations_in_effect->CssText(),
-                       /* important */ false, secure_context_mode);
+    style->ParseAndSetProperty(CSSPropertyID::kTextDecorationLine,
+                               text_decorations_in_effect->CssText(),
+                               /* important */ false, secure_context_mode);
     style->RemoveProperty(CSSPropertyID::kWebkitTextDecorationsInEffect);
     text_decoration = text_decorations_in_effect;
   }
@@ -1724,7 +1725,7 @@
   // FIXME: Shouldn't this be done in getPropertiesNotIn?
   if (mutable_style->GetPropertyCSSValue(CSSPropertyID::kUnicodeBidi) &&
       !style->Style()->GetPropertyCSSValue(CSSPropertyID::kDirection)) {
-    mutable_style->SetProperty(
+    mutable_style->ParseAndSetProperty(
         CSSPropertyID::kDirection,
         style->Style()->GetPropertyValue(CSSPropertyID::kDirection),
         /* important */ false,
@@ -1740,9 +1741,9 @@
                                       CSSPropertyID property_id,
                                       SecureContextMode secure_context_mode) {
   if (new_text_decoration->length()) {
-    style->SetProperty(property_id, new_text_decoration->CssText(),
-                       style->PropertyIsImportant(property_id),
-                       secure_context_mode);
+    style->ParseAndSetProperty(property_id, new_text_decoration->CssText(),
+                               style->PropertyIsImportant(property_id),
+                               secure_context_mode);
   } else {
     // text-decoration: none is redundant since it does not remove any text
     // decorations.
diff --git a/third_party/blink/renderer/core/editing/editing_style_utilities.cc b/third_party/blink/renderer/core/editing/editing_style_utilities.cc
index f5b831c..56343e0 100644
--- a/third_party/blink/renderer/core/editing/editing_style_utilities.cc
+++ b/third_party/blink/renderer/core/editing/editing_style_utilities.cc
@@ -178,8 +178,10 @@
     // value of CSS vertical-align property.
     if (GetIdentifierValue(element_style, CSSPropertyID::kVerticalAlign) ==
             CSSValueID::kBaseline &&
-        HasAncestorVerticalAlignStyle(*element, value_id))
-      style->Style()->SetProperty(CSSPropertyID::kVerticalAlign, value_id);
+        HasAncestorVerticalAlignStyle(*element, value_id)) {
+      style->Style()->SetLonghandProperty(CSSPropertyID::kVerticalAlign,
+                                          value_id);
+    }
   }
 
   // If background color is transparent, traverse parent nodes until we hit a
diff --git a/third_party/blink/renderer/core/editing/editor.cc b/third_party/blink/renderer/core/editing/editor.cc
index 7c5f7db..09a0436 100644
--- a/third_party/blink/renderer/core/editing/editor.cc
+++ b/third_party/blink/renderer/core/editing/editor.cc
@@ -657,13 +657,12 @@
 
   auto* style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(
+  style->ParseAndSetProperty(
       CSSPropertyID::kDirection,
-      direction == mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT
-          ? "ltr"
-          : direction == mojo_base::mojom::blink::TextDirection::RIGHT_TO_LEFT
-                ? "rtl"
-                : "inherit",
+      direction == mojo_base::mojom::blink::TextDirection::LEFT_TO_RIGHT ? "ltr"
+      : direction == mojo_base::mojom::blink::TextDirection::RIGHT_TO_LEFT
+          ? "rtl"
+          : "inherit",
       /* important */ false, GetFrame().DomWindow()->GetSecureContextMode());
   ApplyParagraphStyleToSelection(
       style, InputEvent::InputType::kFormatSetBlockTextDirection);
diff --git a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
index c79befa9..708ec38 100644
--- a/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
+++ b/third_party/blink/renderer/core/editing/serializers/styled_markup_serializer.cc
@@ -248,7 +248,7 @@
                  CSSPropertyID::kBackgroundImage)) &&
             fully_selected_root->FastHasAttribute(
                 html_names::kBackgroundAttr)) {
-          fully_selected_root_style->Style()->SetProperty(
+          fully_selected_root_style->Style()->ParseAndSetProperty(
               CSSPropertyID::kBackgroundImage,
               "url('" +
                   fully_selected_root->getAttribute(
@@ -266,13 +266,13 @@
           // "inherit", and copy it.
           if (!PropertyMissingOrEqualToNone(fully_selected_root_style->Style(),
                                             CSSPropertyID::kTextDecoration)) {
-            fully_selected_root_style->Style()->SetProperty(
+            fully_selected_root_style->Style()->SetLonghandProperty(
                 CSSPropertyID::kTextDecoration, CSSValueID::kNone);
           }
           if (!PropertyMissingOrEqualToNone(
                   fully_selected_root_style->Style(),
                   CSSPropertyID::kWebkitTextDecorationsInEffect)) {
-            fully_selected_root_style->Style()->SetProperty(
+            fully_selected_root_style->Style()->SetLonghandProperty(
                 CSSPropertyID::kWebkitTextDecorationsInEffect,
                 CSSValueID::kNone);
           }
@@ -506,8 +506,8 @@
         // block }.
         inline_style->ForceInline();
         // FIXME: Should this be included in forceInline?
-        inline_style->Style()->SetProperty(CSSPropertyID::kFloat,
-                                           CSSValueID::kNone);
+        inline_style->Style()->SetLonghandProperty(CSSPropertyID::kFloat,
+                                                   CSSValueID::kNone);
 
         if (IsForMarkupSanitization()) {
           EditingStyleUtilities::StripUAStyleRulesForMarkupSanitization(
diff --git a/third_party/blink/renderer/core/html/html_body_element.cc b/third_party/blink/renderer/core/html/html_body_element.cc
index 5962729..ba62db3 100644
--- a/third_party/blink/renderer/core/html/html_body_element.cc
+++ b/third_party/blink/renderer/core/html/html_body_element.cc
@@ -73,7 +73,7 @@
                    GetExecutionContext()->GetReferrerPolicy()),
           OriginClean::kTrue, false /* is_ad_related */);
       image_value->SetInitiator(localName());
-      style->SetProperty(CSSPropertyValue(
+      style->SetLonghandProperty(CSSPropertyValue(
           CSSPropertyName(CSSPropertyID::kBackgroundImage), *image_value));
     }
   } else if (name == html_names::kMarginwidthAttr ||
diff --git a/third_party/blink/renderer/core/html/html_font_element.cc b/third_party/blink/renderer/core/html/html_font_element.cc
index 846f6ad..7531373 100644
--- a/third_party/blink/renderer/core/html/html_font_element.cc
+++ b/third_party/blink/renderer/core/html/html_font_element.cc
@@ -189,7 +189,7 @@
   } else if (name == html_names::kFaceAttr && !value.empty()) {
     if (const CSSValueList* font_face_value = CreateFontFaceValueWithPool(
             value, GetExecutionContext()->GetSecureContextMode())) {
-      style->SetProperty(CSSPropertyValue(
+      style->SetLonghandProperty(CSSPropertyValue(
           CSSPropertyName(CSSPropertyID::kFontFamily), *font_face_value));
     }
   } else {
diff --git a/third_party/blink/renderer/core/html/html_pre_element.cc b/third_party/blink/renderer/core/html/html_pre_element.cc
index 134d128..8644236 100644
--- a/third_party/blink/renderer/core/html/html_pre_element.cc
+++ b/third_party/blink/renderer/core/html/html_pre_element.cc
@@ -43,10 +43,12 @@
     const QualifiedName& name,
     const AtomicString& value,
     MutableCSSPropertyValueSet* style) {
-  if (name == html_names::kWrapAttr)
-    style->SetProperty(CSSPropertyID::kWhiteSpace, CSSValueID::kPreWrap);
-  else
+  if (name == html_names::kWrapAttr) {
+    style->SetLonghandProperty(CSSPropertyID::kWhiteSpace,
+                               CSSValueID::kPreWrap);
+  } else {
     HTMLElement::CollectStyleForPresentationAttribute(name, value, style);
+  }
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/html_table_element.cc b/third_party/blink/renderer/core/html/html_table_element.cc
index 68f4ce61..1149374e 100644
--- a/third_party/blink/renderer/core/html/html_table_element.cc
+++ b/third_party/blink/renderer/core/html/html_table_element.cc
@@ -331,7 +331,7 @@
           Referrer(GetExecutionContext()->OutgoingReferrer(),
                    GetExecutionContext()->GetReferrerPolicy()),
           OriginClean::kTrue, false /* is_ad_related */);
-      style->SetProperty(CSSPropertyValue(
+      style->SetLonghandProperty(CSSPropertyValue(
           CSSPropertyName(CSSPropertyID::kBackgroundImage), *image_value));
     }
   } else if (name == html_names::kValignAttr) {
@@ -457,10 +457,10 @@
 static CSSPropertyValueSet* CreateBorderStyle(CSSValueID value) {
   auto* style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
-  style->SetProperty(CSSPropertyID::kBorderTopStyle, value);
-  style->SetProperty(CSSPropertyID::kBorderBottomStyle, value);
-  style->SetProperty(CSSPropertyID::kBorderLeftStyle, value);
-  style->SetProperty(CSSPropertyID::kBorderRightStyle, value);
+  style->SetLonghandProperty(CSSPropertyID::kBorderTopStyle, value);
+  style->SetLonghandProperty(CSSPropertyID::kBorderBottomStyle, value);
+  style->SetLonghandProperty(CSSPropertyID::kBorderLeftStyle, value);
+  style->SetLonghandProperty(CSSPropertyID::kBorderRightStyle, value);
   return style;
 }
 
@@ -518,18 +518,26 @@
 
   switch (GetCellBorders()) {
     case kSolidBordersColsOnly:
-      style->SetProperty(CSSPropertyID::kBorderLeftWidth, CSSValueID::kThin);
-      style->SetProperty(CSSPropertyID::kBorderRightWidth, CSSValueID::kThin);
-      style->SetProperty(CSSPropertyID::kBorderLeftStyle, CSSValueID::kSolid);
-      style->SetProperty(CSSPropertyID::kBorderRightStyle, CSSValueID::kSolid);
+      style->SetLonghandProperty(CSSPropertyID::kBorderLeftWidth,
+                                 CSSValueID::kThin);
+      style->SetLonghandProperty(CSSPropertyID::kBorderRightWidth,
+                                 CSSValueID::kThin);
+      style->SetLonghandProperty(CSSPropertyID::kBorderLeftStyle,
+                                 CSSValueID::kSolid);
+      style->SetLonghandProperty(CSSPropertyID::kBorderRightStyle,
+                                 CSSValueID::kSolid);
       style->SetProperty(CSSPropertyID::kBorderColor,
                          *CSSInheritedValue::Create());
       break;
     case kSolidBordersRowsOnly:
-      style->SetProperty(CSSPropertyID::kBorderTopWidth, CSSValueID::kThin);
-      style->SetProperty(CSSPropertyID::kBorderBottomWidth, CSSValueID::kThin);
-      style->SetProperty(CSSPropertyID::kBorderTopStyle, CSSValueID::kSolid);
-      style->SetProperty(CSSPropertyID::kBorderBottomStyle, CSSValueID::kSolid);
+      style->SetLonghandProperty(CSSPropertyID::kBorderTopWidth,
+                                 CSSValueID::kThin);
+      style->SetLonghandProperty(CSSPropertyID::kBorderBottomWidth,
+                                 CSSValueID::kThin);
+      style->SetLonghandProperty(CSSPropertyID::kBorderTopStyle,
+                                 CSSValueID::kSolid);
+      style->SetLonghandProperty(CSSPropertyID::kBorderBottomStyle,
+                                 CSSValueID::kSolid);
       style->SetProperty(CSSPropertyID::kBorderColor,
                          *CSSInheritedValue::Create());
       break;
@@ -575,15 +583,23 @@
   auto* style =
       MakeGarbageCollected<MutableCSSPropertyValueSet>(kHTMLQuirksMode);
   if (rows) {
-    style->SetProperty(CSSPropertyID::kBorderTopWidth, CSSValueID::kThin);
-    style->SetProperty(CSSPropertyID::kBorderBottomWidth, CSSValueID::kThin);
-    style->SetProperty(CSSPropertyID::kBorderTopStyle, CSSValueID::kSolid);
-    style->SetProperty(CSSPropertyID::kBorderBottomStyle, CSSValueID::kSolid);
+    style->SetLonghandProperty(CSSPropertyID::kBorderTopWidth,
+                               CSSValueID::kThin);
+    style->SetLonghandProperty(CSSPropertyID::kBorderBottomWidth,
+                               CSSValueID::kThin);
+    style->SetLonghandProperty(CSSPropertyID::kBorderTopStyle,
+                               CSSValueID::kSolid);
+    style->SetLonghandProperty(CSSPropertyID::kBorderBottomStyle,
+                               CSSValueID::kSolid);
   } else {
-    style->SetProperty(CSSPropertyID::kBorderLeftWidth, CSSValueID::kThin);
-    style->SetProperty(CSSPropertyID::kBorderRightWidth, CSSValueID::kThin);
-    style->SetProperty(CSSPropertyID::kBorderLeftStyle, CSSValueID::kSolid);
-    style->SetProperty(CSSPropertyID::kBorderRightStyle, CSSValueID::kSolid);
+    style->SetLonghandProperty(CSSPropertyID::kBorderLeftWidth,
+                               CSSValueID::kThin);
+    style->SetLonghandProperty(CSSPropertyID::kBorderRightWidth,
+                               CSSValueID::kThin);
+    style->SetLonghandProperty(CSSPropertyID::kBorderLeftStyle,
+                               CSSValueID::kSolid);
+    style->SetLonghandProperty(CSSPropertyID::kBorderRightStyle,
+                               CSSValueID::kSolid);
   }
   return style;
 }
diff --git a/third_party/blink/renderer/core/html/html_table_part_element.cc b/third_party/blink/renderer/core/html/html_table_part_element.cc
index 6549795..b52d6c8 100644
--- a/third_party/blink/renderer/core/html/html_table_part_element.cc
+++ b/third_party/blink/renderer/core/html/html_table_part_element.cc
@@ -63,7 +63,7 @@
           Referrer(GetExecutionContext()->OutgoingReferrer(),
                    GetExecutionContext()->GetReferrerPolicy()),
           OriginClean::kTrue, false /* is_ad_related */);
-      style->SetProperty(CSSPropertyValue(
+      style->SetLonghandProperty(CSSPropertyValue(
           CSSPropertyName(CSSPropertyID::kBackgroundImage), *image_value));
     }
   } else if (name == html_names::kValignAttr) {
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc
index 5e852e3..7a7d250 100644
--- a/third_party/blink/renderer/core/layout/layout_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -838,19 +838,6 @@
   return nullptr;
 }
 
-bool LayoutObject::IsTextDecorationBoundary(NGStyleVariant variant) const {
-  const LayoutObject* parent = NonCulledParent();
-  if (!parent)
-    return true;
-  const ComputedStyle& style = EffectiveStyle(variant);
-  const ComputedStyle& parent_style = variant == NGStyleVariant::kEllipsis
-                                          ? parent->FirstLineStyleRef()
-                                          : parent->EffectiveStyle(variant);
-  if (!style.IsAppliedTextDecorationsSame(parent_style))
-    return true;
-  return false;
-}
-
 LayoutObject* LayoutObject::NextInPreOrderAfterChildren() const {
   NOT_DESTROYED();
   LayoutObject* o = NextSibling();
diff --git a/third_party/blink/renderer/core/layout/layout_object.h b/third_party/blink/renderer/core/layout/layout_object.h
index 9a766b5..c947d6d 100644
--- a/third_party/blink/renderer/core/layout/layout_object.h
+++ b/third_party/blink/renderer/core/layout/layout_object.h
@@ -1912,8 +1912,6 @@
   // Returns true if this object is a proper descendant of any list marker.
   bool IsInListMarker() const;
 
-  bool IsTextDecorationBoundary(NGStyleVariant) const;
-
   // The pseudo element style can be cached or uncached. Use the cached method
   // if the pseudo element doesn't respect any pseudo classes (and therefore
   // has no concept of changing state). The cached pseudo style always inherits
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
index 7770ba7..e2db104a 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.cc
@@ -1130,11 +1130,6 @@
   return inline_offset <= size.inline_size / 2 ? StartOffset() : EndOffset();
 }
 
-bool NGFragmentItem::IsTextDecorationBoundary() const {
-  const LayoutObject* object = GetLayoutObject();
-  return object->IsTextDecorationBoundary(StyleVariant());
-}
-
 void NGFragmentItem::Trace(Visitor* visitor) const {
   visitor->Trace(layout_object_);
   // Looking up |const_trace_type_| inside Trace() is safe since it is const.
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
index 4a84431..1f02f92 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_fragment_item.h
@@ -514,8 +514,6 @@
   // LayoutSVGInlineText.
   const Font& ScaledFont() const;
 
-  bool IsTextDecorationBoundary() const;
-
   // Get a description of |this| for the debug purposes.
   String ToString() const;
 
diff --git a/third_party/blink/renderer/core/layout/scroll_anchor.cc b/third_party/blink/renderer/core/layout/scroll_anchor.cc
index 63f5f5d..5f00563 100644
--- a/third_party/blink/renderer/core/layout/scroll_anchor.cc
+++ b/third_party/blink/renderer/core/layout/scroll_anchor.cc
@@ -258,8 +258,6 @@
   }
 
   TRACE_EVENT0("blink", "ScrollAnchor::SerializeAnchor");
-  SCOPED_BLINK_UMA_HISTOGRAM_TIMER(
-      "Layout.ScrollAnchor.TimeToComputeAnchorNodeSelector");
 
   Vector<String> selector_list;
   for (Element* element = ElementTraversal::FirstAncestorOrSelf(*anchor_node);
@@ -284,11 +282,6 @@
     builder.Append(*reverse_iterator);
   }
 
-  DEFINE_STATIC_LOCAL(CustomCountHistogram, selector_length_histogram,
-                      ("Layout.ScrollAnchor.SerializedAnchorSelectorLength", 1,
-                       kMaxSerializedSelectorLength, 50));
-  selector_length_histogram.Count(builder.length());
-
   if (builder.length() > kMaxSerializedSelectorLength) {
     return String();
   }
@@ -669,7 +662,6 @@
   if (scroll_anchor_disabling_style_changed_) {
     // Note that we only clear if the adjustment would have been non-zero.
     // This minimizes redundant calls to findAnchor.
-    // TODO(skobes): add UMA metric for this.
     ClearSelf();
     return;
   }
@@ -687,8 +679,6 @@
     return false;
   }
 
-  SCOPED_BLINK_UMA_HISTOGRAM_TIMER("Layout.ScrollAnchor.TimeToRestoreAnchor");
-
   if (anchor_object_ && serialized_anchor.selector == saved_selector_) {
     return true;
   }
diff --git a/third_party/blink/renderer/core/layout/scroll_anchor_test.cc b/third_party/blink/renderer/core/layout/scroll_anchor_test.cc
index 8da7ec4..52c8e70 100644
--- a/third_party/blink/renderer/core/layout/scroll_anchor_test.cc
+++ b/third_party/blink/renderer/core/layout/scroll_anchor_test.cc
@@ -4,7 +4,6 @@
 
 #include "third_party/blink/renderer/core/layout/scroll_anchor.h"
 
-#include "base/test/metrics/histogram_tester.h"
 #include "build/build_config.h"
 #include "third_party/blink/public/common/input/web_mouse_event.h"
 #include "third_party/blink/renderer/core/dom/shadow_root.h"
@@ -155,56 +154,6 @@
 
 INSTANTIATE_TEST_SUITE_P(All, MAYBE_ScrollAnchorTest, testing::Bool());
 
-// TODO(ymalik): Currently, this should be the first test in the file to avoid
-// failure when running with other tests. Dig into this more and fix.
-TEST_P(MAYBE_ScrollAnchorTest, UMAMetricUpdated) {
-  base::HistogramTester histogram_tester;
-  SetBodyInnerHTML(R"HTML(
-    <style> body { height: 1000px } div { height: 100px } </style>
-    <div id='block1'>abc</div>
-    <div id='block2'>def</div>
-    <script></script>
-  )HTML");
-
-  ScrollableArea* viewport = LayoutViewport();
-
-  // Scroll position not adjusted, metric not updated.
-  ScrollLayoutViewport(ScrollOffset(0, 150));
-  histogram_tester.ExpectTotalCount(
-      "Layout.ScrollAnchor.TimeToComputeAnchorNodeSelector", 0);
-
-  SetHeight(GetDocument().getElementById("block1"), 200);
-
-  EXPECT_EQ(250, viewport->ScrollOffsetInt().y());
-  EXPECT_EQ(GetDocument().getElementById("block2")->GetLayoutObject(),
-            GetScrollAnchor(viewport).AnchorObject());
-
-  GetScrollAnchor(viewport).GetSerializedAnchor();
-  histogram_tester.ExpectTotalCount(
-      "Layout.ScrollAnchor.TimeToComputeAnchorNodeSelector", 1);
-  // 7 == "#block2".length()
-  histogram_tester.ExpectUniqueSample(
-      "Layout.ScrollAnchor.SerializedAnchorSelectorLength", 7, 1);
-
-  // Clear the current anchor so that we can test restoration histograms.
-  // Restoration only proceeds if there isn't an existing anchor.
-  GetScrollAnchor(viewport).Clear();
-
-  SerializedAnchor bad_anchor("##foobar", LayoutPoint(0, 0));
-  EXPECT_FALSE(GetScrollAnchor(LayoutViewport()).RestoreAnchor(bad_anchor));
-  SerializedAnchor bad_anchor2("#bl", LayoutPoint(0, 0));
-  EXPECT_FALSE(GetScrollAnchor(LayoutViewport()).RestoreAnchor(bad_anchor2));
-  SerializedAnchor bad_anchor3("script", LayoutPoint(0, -1000));
-  EXPECT_FALSE(GetScrollAnchor(LayoutViewport()).RestoreAnchor(bad_anchor3));
-
-  SerializedAnchor serialized_anchor("#block1", LayoutPoint(0, 0));
-  EXPECT_TRUE(
-      GetScrollAnchor(LayoutViewport()).RestoreAnchor(serialized_anchor));
-
-  histogram_tester.ExpectTotalCount("Layout.ScrollAnchor.TimeToRestoreAnchor",
-                                    4);
-}
-
 // TODO(skobes): Convert this to web-platform-tests when visual viewport API is
 // launched (http://crbug.com/635031).
 TEST_P(MAYBE_ScrollAnchorTest, VisualViewportAnchors) {
diff --git a/third_party/blink/renderer/core/svg/svg_animate_element.cc b/third_party/blink/renderer/core/svg/svg_animate_element.cc
index 826f92f8..bd639e3 100644
--- a/third_party/blink/renderer/core/svg/svg_animate_element.cc
+++ b/third_party/blink/renderer/core/svg/svg_animate_element.cc
@@ -475,7 +475,7 @@
         target_element->EnsureAnimatedSMILStyleProperties();
     auto animated_value_string = animated_value->ValueAsString();
     auto& document = target_element->GetDocument();
-    auto set_result = properties->SetProperty(
+    auto set_result = properties->ParseAndSetProperty(
         css_property_id_, animated_value_string, false,
         document.GetExecutionContext()->GetSecureContextMode(),
         document.ElementSheet().Contents());
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
index 1059852..3a177a4 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
+++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.cc
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_gpu_canvas_configuration.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_union_canvasrenderingcontext2d_gpucanvascontext_imagebitmaprenderingcontext_webgl2renderingcontext_webglrenderingcontext.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_union_gpucanvascontext_imagebitmaprenderingcontext_offscreencanvasrenderingcontext2d_webgl2renderingcontext_webglrenderingcontext.h"
+#include "third_party/blink/renderer/core/html/canvas/predefined_color_space.h"
 #include "third_party/blink/renderer/core/imagebitmap/image_bitmap.h"
 #include "third_party/blink/renderer/core/offscreencanvas/offscreen_canvas.h"
 #include "third_party/blink/renderer/modules/webgpu/dawn_conversions.h"
@@ -19,6 +20,7 @@
 #include "third_party/blink/renderer/modules/webgpu/gpu_queue.h"
 #include "third_party/blink/renderer/modules/webgpu/gpu_texture.h"
 #include "third_party/blink/renderer/platform/graphics/accelerated_static_bitmap_image.h"
+#include "third_party/blink/renderer/platform/graphics/canvas_color_params.h"
 #include "third_party/blink/renderer/platform/graphics/canvas_resource_provider.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/shared_gpu_context.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_mailbox_texture.h"
@@ -79,7 +81,7 @@
                      alpha_mode_ == V8GPUCanvasAlphaMode::Enum::kOpaque
                          ? kOpaque_SkAlphaType
                          : kPremul_SkAlphaType,
-                     SkColorSpace::MakeSRGB());
+                     PredefinedColorSpaceToSkColorSpace(color_space_));
 }
 
 void GPUCanvasContext::Stop() {
@@ -365,20 +367,15 @@
     return;
   }
 
-  // TODO(crbug.com/1241375): Support additional color spaces for external
-  // textures.
-  if (descriptor->colorSpace().AsEnum() !=
-      V8PredefinedColorSpace::Enum::kSRGB) {
-    exception_state.ThrowDOMException(
-        DOMExceptionCode::kOperationError,
-        "colorSpace !== 'srgb' isn't supported yet.");
+  if (!ValidateAndConvertColorSpace(descriptor->colorSpace(), color_space_,
+                                    exception_state)) {
     return;
   }
 
   swap_buffers_ = base::AdoptRef(new WebGPUSwapBufferProvider(
       this, device_->GetDawnControlClient(), device_->GetHandle(),
       static_cast<WGPUTextureUsage>(texture_descriptor_.usage),
-      texture_descriptor_.format));
+      texture_descriptor_.format, color_space_));
   swap_buffers_->SetFilterQuality(filter_quality_);
 
   // Note: SetContentsOpaque is only an optimization hint. It doesn't
diff --git a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
index 225a39d4..2e8e8787 100644
--- a/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
+++ b/third_party/blink/renderer/modules/webgpu/gpu_canvas_context.h
@@ -11,6 +11,7 @@
 #include "third_party/blink/renderer/core/html/canvas/canvas_rendering_context_factory.h"
 #include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
 #include "third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h"
+#include "third_party/blink/renderer/platform/graphics/graphics_types.h"
 #include "third_party/blink/renderer/platform/graphics/static_bitmap_image.h"
 
 namespace blink {
@@ -137,6 +138,7 @@
       cc::PaintFlags::FilterQuality::kLow;
   Member<GPUDevice> device_;
   Member<GPUTexture> texture_;
+  PredefinedColorSpace color_space_ = PredefinedColorSpace::kSRGB;
   V8GPUCanvasAlphaMode::Enum alpha_mode_;
   scoped_refptr<WebGPUTextureAlphaClearer> alpha_clearer_;
   scoped_refptr<WebGPUSwapBufferProvider> swap_buffers_;
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
index 3adcfa0..0ab7036 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.cc
@@ -36,12 +36,14 @@
     scoped_refptr<DawnControlClientHolder> dawn_control_client,
     WGPUDevice device,
     WGPUTextureUsage usage,
-    WGPUTextureFormat format)
+    WGPUTextureFormat format,
+    PredefinedColorSpace color_space)
     : dawn_control_client_(dawn_control_client),
       client_(client),
       device_(device),
       format_(WGPUFormatToViz(format)),
-      usage_(usage) {
+      usage_(usage),
+      color_space_(color_space) {
   // Create a layer that will be used by the canvas and will ask for a
   // SharedImage each frame.
   layer_ = cc::TextureLayer::CreateForMailbox(this);
@@ -164,8 +166,8 @@
 
   if (unused_swap_buffers_.empty()) {
     gpu::Mailbox mailbox = sii->CreateSharedImage(
-        Format(), size, gfx::ColorSpace::CreateSRGB(), kTopLeft_GrSurfaceOrigin,
-        alpha_mode,
+        Format(), size, PredefinedColorSpaceToGfxColorSpace(color_space_),
+        kTopLeft_GrSurfaceOrigin, alpha_mode,
         gpu::SHARED_IMAGE_USAGE_WEBGPU |
             gpu::SHARED_IMAGE_USAGE_WEBGPU_SWAP_CHAIN_TEXTURE |
             gpu::SHARED_IMAGE_USAGE_DISPLAY_READ,
@@ -283,7 +285,7 @@
       current_swap_buffer_->mailbox, GL_LINEAR, GetTextureTarget(),
       current_swap_buffer_->access_finished_token, current_swap_buffer_->size,
       Format(), IsOverlayCandidate());
-  out_resource->color_space = gfx::ColorSpace::CreateSRGB();
+  out_resource->color_space = PredefinedColorSpaceToGfxColorSpace(color_space_);
 
   // This holds a ref on the SwapBuffers that will keep it alive until the
   // mailbox is released (and while the release callback is running).
@@ -323,7 +325,8 @@
                                     GetTextureTarget());
 
   auto success = frame_pool->CopyRGBATextureToVideoFrame(
-      Format(), current_swap_buffer_->size, gfx::ColorSpace::CreateSRGB(),
+      Format(), current_swap_buffer_->size,
+      PredefinedColorSpaceToGfxColorSpace(color_space_),
       kTopLeft_GrSurfaceOrigin, mailbox_holder, dst_color_space,
       std::move(callback));
 
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
index 64be91b..51150a42 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider.h
@@ -40,7 +40,8 @@
       scoped_refptr<DawnControlClientHolder> dawn_control_client,
       WGPUDevice device,
       WGPUTextureUsage usage,
-      WGPUTextureFormat format);
+      WGPUTextureFormat format,
+      PredefinedColorSpace color_space);
   ~WebGPUSwapBufferProvider() override;
 
   viz::ResourceFormat Format() const;
@@ -161,8 +162,9 @@
 
   WTF::Vector<scoped_refptr<SwapBuffer>> unused_swap_buffers_;
   scoped_refptr<SwapBuffer> last_swap_buffer_;
-  viz::ResourceFormat format_;
-  WGPUTextureUsage usage_;
+  const viz::ResourceFormat format_;
+  const WGPUTextureUsage usage_;
+  const PredefinedColorSpace color_space_;
 
   scoped_refptr<SwapBuffer> current_swap_buffer_;
 };
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
index f09f6f3..f1f10a0 100644
--- a/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
+++ b/third_party/blink/renderer/platform/graphics/gpu/webgpu_swap_buffer_provider_test.cc
@@ -100,12 +100,14 @@
       WGPUDevice device,
       scoped_refptr<DawnControlClientHolder> dawn_control_client,
       WGPUTextureUsage usage,
-      WGPUTextureFormat format)
+      WGPUTextureFormat format,
+      PredefinedColorSpace color_space)
       : WebGPUSwapBufferProvider(client,
                                  dawn_control_client,
                                  device,
                                  usage,
-                                 format),
+                                 format,
+                                 color_space),
         alive_(alive),
         client_(client) {
     texture_desc_.nextInChain = nullptr;
@@ -157,7 +159,7 @@
 
     provider_ = base::MakeRefCounted<WebGPUSwapBufferProviderForTests>(
         &provider_alive_, &client_, fake_device_, dawn_control_client_, kUsage,
-        kFormat);
+        kFormat, PredefinedColorSpace::kSRGB);
   }
 
   void TearDown() override { Platform::UnsetMainThreadTaskRunnerForTesting(); }
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
index 469093b..56c0d8f6 100644
--- a/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
+++ b/third_party/blink/renderer/platform/loader/fetch/resource_fetcher.cc
@@ -109,6 +109,9 @@
 // Timeout for link preloads to be used after window.onload
 static constexpr base::TimeDelta kUnusedPreloadTimeout = base::Seconds(3);
 
+static constexpr char kCrossDocumentCachedResource[] =
+    "Blink.MemoryCache.CrossDocumentCachedResource";
+
 #define RESOURCE_HISTOGRAM_PREFIX "Blink.MemoryCache.RevalidationPolicy."
 
 #define DEFINE_SINGLE_RESOURCE_HISTOGRAM(prefix, name)                         \
@@ -1156,6 +1159,13 @@
   DCHECK(resource);
   DCHECK_EQ(resource->GetType(), resource_type);
 
+  // in_cached_resources_map is checked to detect Resources shared across
+  // Documents, in the same way as features::kScopeMemoryCachePerContext.
+  if (policy == RevalidationPolicy::kUse && !in_cached_resources_map) {
+    base::UmaHistogramEnumeration(kCrossDocumentCachedResource,
+                                  resource->GetType());
+  }
+
   if (policy != RevalidationPolicy::kUse)
     resource->VirtualTimePauser() = std::move(pauser);
 
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index 301066d..5440072726 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1549,7 +1549,7 @@
       name: "LayoutMediaNGContainer",
       // This feature doesn't work in the legacy layout.
       depends_on: ["LayoutNGPrinting"],
-      status: "test",
+      status: "stable",
       base_feature: "LayoutMediaNGContainer",
     },
     {
@@ -2962,7 +2962,7 @@
     {
       name: "WebAppLaunchHandler",
       origin_trial_feature_name: "Launch Handler",
-      status: "experimental",
+      status: {"Android": "experimental", "default": "stable"},
       base_feature: "WebAppEnableLaunchHandler",
     },
     {
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index 4257a4a..a12d31459 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -3039,6 +3039,11 @@
 crbug.com/626703 [ Win ] virtual/partitioned-cookies/http/tests/inspector-protocol/network/disabled-cache-navigation.js [ Failure ]
 
 # ====== New tests from wpt-importer added here ======
+crbug.com/626703 external/wpt/css/css-grid/subgrid/grid-gap-010.html [ Failure ]
+crbug.com/626703 external/wpt/css/css-grid/subgrid/grid-gap-011.html [ Failure ]
+crbug.com/626703 [ Win ] external/wpt/html/semantics/disabled-elements/event-propagate-disabled.tentative.html [ Timeout Failure ]
+crbug.com/626703 [ Win11 ] external/wpt/screen-orientation/hidden_document.html [ Timeout Failure ]
+crbug.com/626703 [ Win10.20h2 ] external/wpt/speculation-rules/prerender/opt-out.html [ Timeout Failure ]
 crbug.com/626703 [ Mac12 ] virtual/pending-beacon/external/wpt/pending-beacon/pending_beacon-sendonhidden.tentative.https.window.html [ Timeout ]
 crbug.com/626703 [ Linux ] external/wpt/web-share/disabled-by-permissions-policy-cross-origin.https.sub.html [ Crash Failure ]
 crbug.com/626703 [ Mac11 ] external/wpt/web-share/disabled-by-permissions-policy-cross-origin.https.sub.html [ Crash Failure ]
@@ -6926,6 +6931,9 @@
 crbug.com/1383990 [ Mac ] external/wpt/html/dom/idlharness.worker.html [ Failure Skip ]
 crbug.com/1383989 [ Mac ] external/wpt/html/webappapis/scripting/events/event-handler-attributes-body-window.html [ Failure Skip ]
 
+# Temporarily disable tests to land background service changes.
+crbug.com/1382392 http/tests/inspector-protocol/background-services/background-services-events.js [ Failure Skip ]
+
 # Tests disabled for the memory measurement API.
 crbug.com/1085129 virtual/force-eager/external/wpt/measure-memory/detached.https.window.html [ Skip Timeout ]
 crbug.com/1085129 virtual/force-eager/external/wpt/measure-memory/window-open.mix.https.window.html [ Skip Timeout ]
diff --git a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
index b2716059..0de4efa 100644
--- a/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
+++ b/third_party/blink/web_tests/external/WPT_BASE_MANIFEST_8.json
@@ -2338,6 +2338,13 @@
         {}
        ]
       ],
+      "oof-in-additional-column-before-spanner.html": [
+       "e59df7039a20f69d7da69f2786d3fb6073963745",
+       [
+        null,
+        {}
+       ]
+      ],
       "oof-in-nested-line-float.html": [
        "d4d67763c875bd0a64b8069de73d6d95abb8a740",
        [
@@ -4749,6 +4756,13 @@
          null,
          {}
         ]
+       ],
+       "reportValidity-crash.html": [
+        "d6bab924adc9fb481235af10d706cbf4d4ef2df9",
+        [
+         null,
+         {}
+        ]
        ]
       },
       "the-datalist-element": {
@@ -96877,7 +96891,7 @@
       ]
      ],
      "contain-body-overflow-002.html": [
-      "bc432e3e0e1ffcde0773ae2a2c7e8da3511ee985",
+      "bf741491c62cbadaba021f01899c61daef7e6e5e",
       [
        null,
        [
@@ -130029,6 +130043,32 @@
         {}
        ]
       ],
+      "grid-gap-010.html": [
+       "23d67b95dd9a4e4cdb1ba8241b2ebd2e8ebb93a8",
+       [
+        null,
+        [
+         [
+          "/css/css-grid/subgrid/grid-gap-010-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
+      "grid-gap-011.html": [
+       "d40ad2640f183d5a881e6c85b5c30e2b54f40284",
+       [
+        null,
+        [
+         [
+          "/css/css-grid/subgrid/grid-gap-011-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "grid-gap-larger-001.html": [
        "85725d52925b898f562329256cf60ea24486f517",
        [
@@ -246130,7 +246170,7 @@
      },
      "popovers": {
       "popover-anchor-display.tentative.html": [
-       "03b486d745dd58605673bc58442c73dfb4f258a9",
+       "103bc9849fdbd60d140a991c35a3906e9c50b83d",
        [
         null,
         [
@@ -246207,19 +246247,6 @@
         {}
        ]
       ],
-      "popover-defaultopen-display.tentative.html": [
-       "d624289a27a4802ddb4863a79295e19841c1dad0",
-       [
-        null,
-        [
-         [
-          "/html/semantics/popovers/popover-defaultopen-display-ref.tentative.html",
-          "=="
-         ]
-        ],
-        {}
-       ]
-      ],
       "popover-dialog-appearance.tentative.html": [
        "9707ac0e9345dbe2fa513151ef5fa0e05bac508c",
        [
@@ -257385,6 +257412,16 @@
    }
   },
   "support": {
+   ".cache": {
+    "gitignore2.json": [
+     "464b9c93eed0495e70ff94d9868b04b37a348730",
+     []
+    ],
+    "mtime.json": [
+     "a52b35a00de1e750a3bb515d90621afa6a0943c1",
+     []
+    ]
+   },
    ".gitignore": [
     "d93e645d547894b50149d3726de2654957b6e06f",
     []
@@ -263849,15 +263886,15 @@
      ],
      "resources": {
       "partitioned-cookies-cross-site-embed.html": [
-       "f48268df7835b5a6298c6027dd8de54a1fd39573",
+       "05a99626dc4211c64b9e092366e0e3ed4933ab39",
        []
       ],
       "partitioned-cookies-cross-site-window.html": [
-       "e3419937fee6b72c00032ac74a1400b8f87e9c8e",
+       "ca1a27c8a04fbc4c88a264b0591f53dfed968a49",
        []
       ],
       "test-helpers.js": [
-       "6ba7f897e5056f4bf503c1c6b37e3d31fed9bb8d",
+       "0ecaa63c39ae9f955d6a920e2334a1f85c82d321",
        []
       ]
      }
@@ -264242,7 +264279,7 @@
       ]
      },
      "fedcm-helper.sub.js": [
-      "528072989253d39f50fa0ff29508a1fbe5d045fd",
+      "87a1337a06cbd63f7302fd4f93298d9ffcf072ab",
       []
      ],
      "fedcm-iframe-level2.html": [
@@ -264254,7 +264291,7 @@
       []
      ],
      "fedcm-mock.js": [
-      "ef4e94d6e957f698884fba73f6e368d956e0a23a",
+      "f52bd6e0e70d73782ea1618c3c694599536761e9",
       []
      ],
      "fedcm-mojojs-helper.js": [
@@ -291128,6 +291165,14 @@
        "7e301180a2be5bf12c97562e33feb5a741988731",
        []
       ],
+      "grid-gap-010-ref.html": [
+       "8e13f6e561757fbef35ebc7eef817a069d6e90a9",
+       []
+      ],
+      "grid-gap-011-ref.html": [
+       "23bcdfaa5ae3dd0b3a76d2b208b965a8ba4254ce",
+       []
+      ],
       "grid-gap-larger-001-ref.html": [
        "0d3050f568bd0c7ce6ee295335b17bd7e29a3c5d",
        []
@@ -291395,10 +291440,6 @@
      }
     },
     "css-highlight-api": {
-     "idlharness.window-expected.txt": [
-      "27d19d246468da345b6a500d7983b438a260eaf8",
-      []
-     ],
      "idlharness.window.js.ini": [
       "63108e58f25594b9dd864319a925a180053a92bd",
       []
@@ -308503,10 +308544,6 @@
      }
     },
     "css-toggle": {
-     "idlharness.tentative-expected.txt": [
-      "64237dac75226bea5cc88062f35bbc0d0b740a7a",
-      []
-     ],
      "idlharness.tentative.html.ini": [
       "e824603f64a53916ad80c2c0620126921800cdb6",
       []
@@ -310438,6 +310475,10 @@
       ]
      },
      "stylevalue-subclasses": {
+      "cssRGB-expected.txt": [
+       "1543463be5be954ab42c900628b7ef72901183df",
+       []
+      ],
       "numeric-objects": {
        "arithmetic.tentative-expected.txt": [
         "0331089df0cf2ee7455218a3de9801ab74101f63",
@@ -316587,6 +316628,10 @@
       "d39aade52a316bcd8f7f35b5363920d719f462d0",
       []
      ],
+     "font-variant-shorthand-serialization-expected.txt": [
+      "60543dd5671170b29619c7fd2cf3f2364ff51fad",
+      []
+     ],
      "getComputedStyle-detached-subtree-expected.txt": [
       "35c11f0d1aaa335d70b7519d42eb40ab52f82aba",
       []
@@ -319594,10 +319639,6 @@
      "ee34d8b900423cdc4de0876f4909c528b835dad6",
      []
     ],
-    "idlharness.window-expected.txt": [
-     "f5a0bf2ff29a847b97ac74a65da31866571f1bec",
-     []
-    ],
     "idlharness.window.js.ini": [
      "95d9e826672223c5dbf37d3dba9effb841b66eab",
      []
@@ -345024,10 +345065,6 @@
        "bf2b16c3f5de4777808d92e436a97609a9fbc16b",
        []
       ],
-      "popover-defaultopen-display-ref.tentative.html": [
-       "8973616308b8547a45118f79f840199b2a90574a",
-       []
-      ],
       "popover-dialog-appearance-ref.tentative.html": [
        "12efbb6b1e4934de6b32df60304cd40a44548301",
        []
@@ -345058,7 +345095,7 @@
         []
        ],
        "popover-utils.js": [
-        "be10017e5feb87525643df0090bac81a41343e0a",
+        "0df24ccd4fc936d0a2effb3d9b1e28d5a30955a5",
         []
        ]
       }
@@ -348435,7 +348472,7 @@
        []
       ],
       "consumption-crossorigin-child.sub.html": [
-       "3ab469fe611bfc2a964fdcb1b20a50cc0c2a55e9",
+       "518e000d0b9cd92f88552dc21072ee7793106638",
        []
       ],
       "consumption-sameorigin-child.html": [
@@ -348443,7 +348480,7 @@
        []
       ],
       "propagation-crossorigin-child.sub.html": [
-       "ec465bf4acbbca907a94d314eb2b1feaf9611c3c",
+       "e920566a21edcb3a15a5973d6bdb16d84ddcdfd1",
        []
       ],
       "propagation-sameorigin-child.html": [
@@ -352010,7 +352047,7 @@
     ]
    },
    "lint.ignore": [
-    "c3ab694b9fa6d0ea941abcf80b61cd6e7fc84f15",
+    "7ac79fc36ba68b7d02ae99fc482269a9e20f88e6",
     []
    ],
    "loading": {
@@ -358203,7 +358240,7 @@
      []
     ],
     "link-header-preload.html.headers": [
-     "338da6b5f856f243107a37eecb73336c4866d69c",
+     "83670cd86e34c3cbf3b465428b8ff6848d51f534",
      []
     ],
     "onerror-event-expected.txt": [
@@ -361139,7 +361176,7 @@
      []
     ],
     "idlharness.js": [
-     "e097ee7f7fead84912f797fd945b74eb37d3b3f9",
+     "bda4a31fb0ee617b53a668325a54bb50ce46e3ba",
      []
     ],
     "idlharness.js.headers": [
@@ -361369,7 +361406,7 @@
      []
     ],
     "hidden_document-expected.txt": [
-     "e1aa609fd0bc1762d52304ac7b3bfef10d406b5a",
+     "46575e6b01a54d370f99753cb7db2a1bb8ae70cf",
      []
     ],
     "lock-basic-expected.txt": [
@@ -366635,7 +366672,7 @@
       "656ecd1db88236fcaa6e9e6dc53599249fccd4d0",
       []
      ],
-     "web-database.html.ini": [
+     "web-database.https.html.ini": [
       "faec8efadd78f403b5c11dd9e4c4ce9a51dfee64",
       []
      ],
@@ -370498,7 +370535,7 @@
       []
      ],
      "urlpatterntestdata.json": [
-      "58a1ea31b4bfb0c533ffd21ed781850c8dc07a33",
+      "56b3a0c0f23dbc7ae15583c9e31f07bac251ffae",
       []
      ],
      "urlpatterntests.js": [
@@ -378786,7 +378823,7 @@
       []
      ],
      "idlharness.https.window-expected.txt": [
-      "ce8dc9018edcf0bbe05c65b1b4c4843594b2a7bd",
+      "d72c358765ca10a70104b7499f4b028e14ff1ad1",
       []
      ],
      "idlharness.https.window.js.ini": [
@@ -412249,7 +412286,7 @@
     },
     "partitioned-cookies": {
      "partitioned-cookies.tentative.https.html": [
-      "a2d92c5361f8f687dabb5400f03cf9b3892c7d4a",
+      "deab6691019ce119d17ad269c41802b55f0fe4c7",
       [
        null,
        {
@@ -412912,6 +412949,71 @@
       {}
      ]
     ],
+    "fedcm-multi-idp": {
+     "get-before-and-after-onload.https.html": [
+      "fa9ec7b52fca1faf6cdd29ce6deef31669417f7b",
+      [
+       null,
+       {}
+      ]
+     ],
+     "get-before-and-during-onload.https.html": [
+      "93ee2075fe54128d55c8d69262134bad36840505",
+      [
+       null,
+       {}
+      ]
+     ],
+     "get-before-onload-and-during-dom-content-loaded.https.html": [
+      "edc293daff8806efea54d86425d29828fdbdfd87",
+      [
+       null,
+       {}
+      ]
+     ],
+     "multiple-gets-after-onload.https.html": [
+      "1a806a2049d39990039b10e690a8505ad1e5856b",
+      [
+       null,
+       {}
+      ]
+     ],
+     "multiple-gets-before-onload.https.html": [
+      "69a70ce47de9dbe946d0451cda0f0a68aa45cbd8",
+      [
+       null,
+       {}
+      ]
+     ],
+     "multiple-gets-during-onload.https.html": [
+      "e98b63ff339f5948188d7422a80e2ba70cd886b1",
+      [
+       null,
+       {}
+      ]
+     ],
+     "single-get-after-onload.https.html": [
+      "a34ff84aabdf3e4297af4a126f670d6587fc9b5f",
+      [
+       null,
+       {}
+      ]
+     ],
+     "single-get-before-onload.https.html": [
+      "91195fc5a75f626796b73dbaf1d5dea386519c26",
+      [
+       null,
+       {}
+      ]
+     ],
+     "single-get-during-onload.https.html": [
+      "17939d2d9353fa255c746729f14a37c7383d1814",
+      [
+       null,
+       {}
+      ]
+     ]
+    },
     "fedcm-network-requests.https.html": [
      "ebcf61ba18edc008b58678339a6726fb84364e68",
      [
@@ -414621,6 +414723,13 @@
        {}
       ]
      ],
+     "at-position-fallback-invalidation.html": [
+      "68a0874931245741b7b35e2c517367f8733bc764",
+      [
+       null,
+       {}
+      ]
+     ],
      "position-fallback-001.html": [
       "85f1d1d65acbf177c7fd4c0eb48848876b3004de",
       [
@@ -418334,7 +418443,7 @@
        ]
       ],
       "content-visibility-auto-state-changed.html": [
-       "d1076459d4b4d52e423f2ed8722ead69451ca73e",
+       "a65db6a2f82675586cc1f87d09ee5694e16334a4",
        [
         null,
         {
@@ -437463,7 +437572,7 @@
        ]
       ],
       "cssRGB.html": [
-       "062ff7629f7e8fd4ee78497e71d9eec28072d07c",
+       "8ec193da4d1ced0169f4b04ec17e3fa55c06f983",
        [
         null,
         {}
@@ -442401,6 +442510,13 @@
        {}
       ]
      ],
+     "font-variant-shorthand-serialization.html": [
+      "0e4651cdc0db738b34d004b15556c89916a9a10f",
+      [
+       null,
+       {}
+      ]
+     ],
      "getComputedStyle-animations-replaced-into-ib-split.html": [
       "47198803a0d265f35dabb1084218434559badf64",
       [
@@ -516515,6 +516631,16 @@
         null,
         {}
        ]
+      ],
+      "event-propagate-disabled.tentative.html": [
+       "0c00cc8db078b027acca3eec4b70d4092c19df08",
+       [
+        null,
+        {
+         "testdriver": true,
+         "timeout": "long"
+        }
+       ]
       ]
      },
      "document-metadata": {
@@ -524768,20 +524894,6 @@
         }
        ]
       ],
-      "popover-defaultopen-2.tentative.html": [
-       "4ed78609f5c42b0cc70d33ce73d37859aacdf235",
-       [
-        null,
-        {}
-       ]
-      ],
-      "popover-defaultopen.tentative.html": [
-       "daf12f7ff5afc729fc8ba9b08154869533a590d0",
-       [
-        null,
-        {}
-       ]
-      ],
       "popover-document-open.tentative.html": [
        "429fd89d3ba68d9588b66e696095e5007eaccc9a",
        [
@@ -524887,7 +524999,7 @@
        ]
       ],
       "popover-top-layer-combinations.tentative.html": [
-       "66106ce17d9afedc89c00f9dccfb3aa377d7ddf6",
+       "d4529b9e39c87a42aa9f15cd44ab84516c653d25",
        [
         null,
         {
@@ -553146,7 +553258,7 @@
      ]
     ],
     "pointerevent_disabled_form_control.html": [
-     "83ad053a146a9fb7035ed47fc4fb910c37211621",
+     "d253111115f1efdde514f28f1026447179026c44",
      [
       "pointerevents/pointerevent_disabled_form_control.html?mouse",
       {
@@ -554555,7 +554667,7 @@
      ]
     ],
     "link-header-preload.html": [
-     "e70315e377d0acb04cac2339b0d473bbf4b7c732",
+     "5a477867fb9c9953a6f909a8dce3a84cc41ea707",
      [
       null,
       {}
@@ -570319,7 +570431,7 @@
      ]
     ],
     "hidden_document.html": [
-     "b78dbb62438b91f45e4298d5855735a10a71bd03",
+     "6097cc9d28d2baae076e4b9949b2bf11b9e25e02",
      [
       null,
       {
@@ -579527,7 +579639,7 @@
        }
       ]
      ],
-     "web-database.html": [
+     "web-database.https.html": [
       "3ef1141e2063e9eda6bbf5b7a4b62760b5c52c03",
       [
        null,
@@ -600605,7 +600717,7 @@
      ]
     ],
     "audio-encoder-config.https.any.js": [
-     "a847473fbb52ca1d8307c83d1032b12e76f444d1",
+     "52ff3dc16e6c093b9867a9498b85f41377cb901f",
      [
       "webcodecs/audio-encoder-config.https.any.html",
       {
@@ -600638,7 +600750,7 @@
      ]
     ],
     "audio-encoder.https.any.js": [
-     "d1ae55435a68f7fa744954eaf9a5776f04c6e4dd",
+     "7db9148ed58433c0686b6117097a01f6dfc55b2f",
      [
       "webcodecs/audio-encoder.https.any.html",
       {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-overflow-002.html b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-overflow-002.html
index bc432e3e..bf741491 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-overflow-002.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-contain/contain-body-overflow-002.html
@@ -1,13 +1,11 @@
 <!doctype html>
-<html lang=en>
-  <meta charset=utf-8>
-  <title>CSS-contain test: paint containment on body prevents overflow propagation</title>
-  <link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
-  <meta name=flags content="">
-  <meta name=assert content="paint containment on body prevents overflow propagation">
-  <link rel="match" href="reference/contain-body-overflow-001-ref.html">
-  <link rel=help href="https://drafts.csswg.org/css-contain-1/#contain-property">
-
+<html lang=en class="reftest-wait">
+<meta charset=utf-8>
+<title>CSS-contain test: paint containment on body prevents overflow propagation</title>
+<link rel="author" title="Florian Rivoal" href="https://florian.rivoal.net">
+<meta name="assert" content="paint containment on body prevents overflow propagation">
+<link rel="match" href="reference/contain-body-overflow-001-ref.html">
+<link rel="help" href="https://drafts.csswg.org/css-contain-1/#contain-property">
 <style>
 html, body, p, div {
     margin: 0;
@@ -28,6 +26,9 @@
 <p tabindex=1 id=target>Test passes if there is no red.
 <script>
 window.onload = function() {
-    document.getElementById("target").focus()
+    document.getElementById("target").focus();
+    setTimeout(() => {
+        document.documentElement.className = "";
+    }, 0);
 }
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-010-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-010-ref.html
new file mode 100644
index 0000000..8e13f6e5
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-010-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html><head>
+  <meta charset="utf-8">
+  <title>CSS Grid Test: Subgrids with empty tracks and column gap</title>
+  <link rel="author" title="Matt Woodrow" href="mailto:mattwoodrow@apple.com">
+  <link rel="help" href="https://drafts.csswg.org/css-grid-2">
+</head>
+<body>
+<div style="width:100px; height: 100px; background-color: blue; position:relative; left:50px;"></div>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-010.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-010.html
new file mode 100644
index 0000000..23d67b95
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-010.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html><head>
+  <meta charset="utf-8">
+  <title>CSS Grid Test: Subgrids with empty tracks and column gap</title>
+  <link rel="author" title="Matt Woodrow" href="mailto:mattwoodrow@apple.com">
+  <link rel="help" href="https://drafts.csswg.org/css-grid-2">
+  <link rel="match" href="grid-gap-010-ref.html">
+</head>
+<body>
+<div style="display:grid; grid-template-columns: auto 200px; width: 200px">
+    <div style="display:grid; grid-template-columns: subgrid; gap: 100px; grid-column: span 2">
+        <div style="width:100px; height: 100px; background-color: blue; grid-column: 2"></div>
+    </div>
+</div>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-011-ref.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-011-ref.html
new file mode 100644
index 0000000..23bcdfa
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-011-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE HTML>
+<html><head>
+  <meta charset="utf-8">
+  <title>CSS Grid Test: Subgrids with empty tracks and column gap</title>
+  <link rel="author" title="Matt Woodrow" href="mailto:mattwoodrow@apple.com">
+  <link rel="help" href="https://drafts.csswg.org/css-grid-2">
+</head>
+<body>
+<div style="width:200px; height: 100px; background-color: blue; position:relative; left:175px;"></div>
+</body>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-011.html b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-011.html
new file mode 100644
index 0000000..d40ad26
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-grid/subgrid/grid-gap-011.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html><head>
+  <meta charset="utf-8">
+  <title>CSS Grid Test: Subgrids with column gap larger than the track size</title>
+  <link rel="author" title="Matt Woodrow" href="mailto:mattwoodrow@apple.com">
+  <link rel="help" href="https://drafts.csswg.org/css-grid-2">
+  <link rel="match" href="grid-gap-011-ref.html">
+</head>
+<body>
+<div style="display:grid; grid-template-columns: 100px 100px 100px; width: 300px">
+    <div style="display:grid; grid-template-columns: subgrid; gap: 150px; grid-column: span 3">
+        <div style="width:100px; height: 100px; background-color: blue; grid-column: 2"></div>
+        <div style="width:100px; height: 100px; background-color: blue; grid-column: 3"></div>
+    </div>
+</div>
+
+</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssRGB-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssRGB-expected.txt
new file mode 100644
index 0000000..1543463
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssRGB-expected.txt
@@ -0,0 +1,57 @@
+This is a testharness.js-based test.
+Found 53 tests; 31 PASS, 22 FAIL, 0 TIMEOUT, 0 NOTRUN.
+FAIL Constructing a CSSRGB with an angle CSSUnitValue for the color channels throws a SyntaxError. assert_throws_dom: function "() => new CSSRGB(color, 0, 0)" threw object "TypeError: Failed to construct 'CSSRGB': Color channel must be interpretable as a number or a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Constructing a CSSRGB with a CSSMathValue that doesn"t match <number> for the color channels throws a SyntaxError. assert_throws_dom: function "() => new CSSRGB(color, 0, 0)" threw object "TypeError: Failed to construct 'CSSRGB': Color channel must be interpretable as a number or a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Constructing a CSSRGB with undefined for the color channels throws a SyntaxError. assert_throws_dom: function "() => new CSSRGB(color, 0, 0)" threw object "TypeError: Failed to construct 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Constructing a CSSRGB with a CSS math calculation for the color channels throws a SyntaxError. assert_throws_dom: function "() => new CSSRGB(color, 0, 0)" threw object "TypeError: Failed to construct 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Constructing a CSSRGB with a CSS number for the alpha channels throws a SyntaxError. assert_throws_dom: function "() => new CSSRGB(0, 0, 0, CSS.number(1))" threw object "TypeError: Failed to construct 'CSSRGB': Alpha must be interpretable as a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. r to an angle CSSUnitValue throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'r' property on 'CSSRGB': Color channel must be interpretable as a number or a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. r to a CSSMathValue that doesn"t match <number> throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'r' property on 'CSSRGB': Color channel must be interpretable as a number or a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. r to undefined throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'r' property on 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. r to a CSS math calculation throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'r' property on 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. g to an angle CSSUnitValue throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'g' property on 'CSSRGB': Color channel must be interpretable as a number or a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. g to a CSSMathValue that doesn"t match <number> throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'g' property on 'CSSRGB': Color channel must be interpretable as a number or a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. g to undefined throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'g' property on 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. g to a CSS math calculation throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'g' property on 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. b to an angle CSSUnitValue throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'b' property on 'CSSRGB': Color channel must be interpretable as a number or a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. b to a CSSMathValue that doesn"t match <number> throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'b' property on 'CSSRGB': Color channel must be interpretable as a number or a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. b to undefined throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'b' property on 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. b to a CSS math calculation throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'b' property on 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. alpha to an angle CSSUnitValue throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'alpha' property on 'CSSRGB': Alpha must be interpretable as a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. alpha to a CSSMathValue that doesn"t match <number> throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'alpha' property on 'CSSRGB': Alpha must be interpretable as a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. alpha to undefined throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'alpha' property on 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating CSSRGB. alpha to a CSS math calculation throws a SyntaxError. assert_throws_dom: function "() => result[attr] = color" threw object "TypeError: Failed to set the 'alpha' property on 'CSSRGB': The provided double value is non-finite." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+FAIL Updating the alpha channel to a CSS number throws a SyntaxError. assert_throws_dom: function "() => result.alpha = CSS.number(1)" threw object "TypeError: Failed to set the 'alpha' property on 'CSSRGB': Alpha must be interpretable as a percentage." that is not a DOMException SyntaxError: property "code" is equal to undefined, expected 12
+PASS CSSRGB can be constructed from three numbers and will get an alpha of 100%.
+PASS CSSRGB can be constructed from four numbers.
+PASS CSSRGB.r can be updated with a number with the resulting value being a percentage.
+PASS CSSRGB.r can be updated with a CSS number.
+PASS CSSRGB.r can be updated with CSS percent.
+PASS CSSRGB.r can be updated with CSS math sum.
+PASS CSSRGB.r can be updated with CSS math product.
+PASS CSSRGB.r can be updated with CSS math max.
+PASS CSSRGB.r can be updated with CSS math min.
+PASS CSSRGB.g can be updated with a number with the resulting value being a percentage.
+PASS CSSRGB.g can be updated with a CSS number.
+PASS CSSRGB.g can be updated with CSS percent.
+PASS CSSRGB.g can be updated with CSS math sum.
+PASS CSSRGB.g can be updated with CSS math product.
+PASS CSSRGB.g can be updated with CSS math max.
+PASS CSSRGB.g can be updated with CSS math min.
+PASS CSSRGB.b can be updated with a number with the resulting value being a percentage.
+PASS CSSRGB.b can be updated with a CSS number.
+PASS CSSRGB.b can be updated with CSS percent.
+PASS CSSRGB.b can be updated with CSS math sum.
+PASS CSSRGB.b can be updated with CSS math product.
+PASS CSSRGB.b can be updated with CSS math max.
+PASS CSSRGB.b can be updated with CSS math min.
+PASS CSSRGB.alpha can be updated with a number with the resulting value being a percentage.
+PASS CSSRGB.alpha can be updated with CSS percent.
+PASS CSSRGB.alpha can be updated with CSS math sum.
+PASS CSSRGB.alpha can be updated with CSS math product.
+PASS CSSRGB.alpha can be updated with CSS math max.
+PASS CSSRGB.alpha can be updated with CSS math min.
+PASS toRGB function evaluates sum, product and max objects.
+PASS toRGB() function works as expected and values can be updated.
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssRGB.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssRGB.html
index 062ff762..8ec193d 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssRGB.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/stylevalue-subclasses/cssRGB.html
@@ -28,34 +28,34 @@
 
 for (const {color, desc, skipAlpha} of gInvalidColorTestCases) {
   test(() => {
-    assert_throws_js(TypeError, () => new CSSRGB(color, 0, 0));
-    assert_throws_js(TypeError, () => new CSSRGB(0, color, 0));
-    assert_throws_js(TypeError, () => new CSSRGB(0, 0, color));
-    assert_throws_js(TypeError, () => new CSSRGB(color, 0, 0, 0));
-    assert_throws_js(TypeError, () => new CSSRGB(0, color, 0, 0));
-    assert_throws_js(TypeError, () => new CSSRGB(0, 0, color, 0));
-    if (!skipAlpha) assert_throws_js(TypeError, () => new CSSRGB(0, 0, 0, color));
-  }, `Constructing a CSSRGB with ${desc} for the color channels throws a TypeError.`);
+    assert_throws_dom("SyntaxError", () => new CSSRGB(color, 0, 0));
+    assert_throws_dom("SyntaxError", () => new CSSRGB(0, color, 0));
+    assert_throws_dom("SyntaxError", () => new CSSRGB(0, 0, color));
+    assert_throws_dom("SyntaxError", () => new CSSRGB(color, 0, 0, 0));
+    assert_throws_dom("SyntaxError", () => new CSSRGB(0, color, 0, 0));
+    assert_throws_dom("SyntaxError", () => new CSSRGB(0, 0, color, 0));
+    if (!skipAlpha) assert_throws_dom("SyntaxError", () => new CSSRGB(0, 0, 0, color));
+  }, `Constructing a CSSRGB with ${desc} for the color channels throws a SyntaxError.`);
 }
 
 test(() => {
-  assert_throws_js(TypeError, () => new CSSRGB(0, 0, 0, CSS.number(1)));
-}, `Constructing a CSSRGB with a CSS number for the alpha channels throws a TypeError.`);
+  assert_throws_dom("SyntaxError", () => new CSSRGB(0, 0, 0, CSS.number(1)));
+}, `Constructing a CSSRGB with a CSS number for the alpha channels throws a SyntaxError.`);
 
 for (const attr of ['r', 'g', 'b', 'alpha']) {
-  for (const {value, desc} of gInvalidColorTestCases) {
+  for (const {color, desc} of gInvalidColorTestCases) {
     test(() => {
       const result = new CSSRGB(0, 0, 0, 0);
-      assert_throws_js(TypeError, () => result[attr] = value);
+      assert_throws_dom("SyntaxError", () => result[attr] = color);
       assert_style_value_equals(result[attr], CSS.percent(0));
-    }, `Updating CSSRGB. ${attr} to ${desc} throws a TypeError.`);
+    }, `Updating CSSRGB. ${attr} to ${desc} throws a SyntaxError.`);
   }
 }
 
 test(() => {
   const result = new CSSRGB(0, 0, 0);
-  assert_throws_js(TypeError, () => result.alpha = CSS.number(1));
-}, "Updating the alpha channel to a CSS number throws a TypeError.");
+  assert_throws_dom("SyntaxError", () => result.alpha = CSS.number(1));
+}, "Updating the alpha channel to a CSS number throws a SyntaxError.");
 
 test(() => {
   const result = new CSSRGB(0.5, CSS.number(73), CSS.percent(91));
@@ -113,4 +113,4 @@
     assert_color_channel_approx_equals(result[attr], CSS.percent(70));
   }
 }, "toRGB() function works as expected and values can be updated.");
-</script>
\ No newline at end of file
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/font-variant-shorthand-serialization-expected.txt b/third_party/blink/web_tests/external/wpt/css/cssom/font-variant-shorthand-serialization-expected.txt
new file mode 100644
index 0000000..60543dd
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/font-variant-shorthand-serialization-expected.txt
@@ -0,0 +1,10 @@
+This is a testharness.js-based test.
+FAIL font-variant: normal serialization assert_equals: font-variant-position was set expected "normal" but got ""
+FAIL font-variant: none serialization assert_equals: font-variant-position was set expected "normal" but got ""
+FAIL font-variant-ligatures: none serialization with non-default value for another longhand assert_equals: font-variant-position was set expected "normal" but got ""
+FAIL font-variant: normal with non-default longhands assert_equals: font-variant-position was set expected "normal" but got ""
+FAIL CSS-wide keyword in one longhand assert_equals: font-variant-position was set expected "normal" but got ""
+FAIL CSS-wide keyword in shorthand assert_equals: font-variant-position was set expected "initial" but got ""
+FAIL font: menu serialization assert_equals: font-variant was set expected "" but got "normal"
+Harness: the test ran to completion.
+
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/font-variant-shorthand-serialization.html b/third_party/blink/web_tests/external/wpt/css/cssom/font-variant-shorthand-serialization.html
new file mode 100644
index 0000000..0e4651c
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/cssom/font-variant-shorthand-serialization.html
@@ -0,0 +1,131 @@
+<!doctype html>
+<html>
+<meta charset="utf-8">
+<title>Serialization of font-variant shorthand</title>
+<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m">
+<link rel="help" href="https://drafts.csswg.org/cssom-1/#serialize-a-css-declaration-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<div id="target"></div>
+<script>
+    const cssWideKeywords = ["initial", "inherit", "unset", "revert", "revert-layer"];
+    function test_serialization_set(expected) {
+        for (const [property, value] of Object.entries(expected)) {
+            if (!CSS.supports(`${property}: initial`))
+                continue;
+            assert_equals(target.style[property], value, `${property} was set`);
+        }
+    }
+    function setWithValue(value) {
+        return {
+            "font-variant-ligatures": value,
+            "font-variant-caps": value,
+            "font-variant-alternates": value,
+            "font-variant-numeric": value,
+            "font-variant-east-asian": value,
+            "font-variant-position": value,
+            "font-variant-emoji": value,
+            "font-variant": value
+        };
+    }
+    const emptySet = setWithValue("");
+    const normalSet = setWithValue("normal");
+    const nonDefaultValues = {
+        "font-variant-ligatures": "common-ligatures discretionary-ligatures",
+        "font-variant-caps": "small-caps",
+        "font-variant-alternates": "historical-forms",
+        "font-variant-numeric": "oldstyle-nums stacked-fractions",
+        "font-variant-east-asian": "ruby",
+        "font-variant-position": "sub",
+        "font-variant-emoji": "emoji",
+    };
+    test(function(t) {
+        target.style.fontVariant = "normal";
+        t.add_cleanup(() => target.removeAttribute("style"));
+
+        test_serialization_set(normalSet);
+    }, "font-variant: normal serialization");
+
+    test(function(t) {
+        target.style.fontVariant = "normal";
+        target.style.fontVariantLigatures = "none";
+        t.add_cleanup(() => target.removeAttribute("style"));
+
+        const expected = Object.assign({}, normalSet);
+        expected["font-variant-ligatures"] = "none";
+        expected["font-variant"] = "none";
+
+        test_serialization_set(expected);
+    }, "font-variant: none serialization");
+
+    test(function(t) {
+        t.add_cleanup(() => target.removeAttribute("style"));
+        for (const [property, value] of Object.entries(nonDefaultValues)) {
+            if (property == "font-variant-ligatures" || !CSS.supports(`${property}: initial`))
+                continue;
+            target.style.fontVariant = "normal";
+            target.style.fontVariantLigatures = "none";
+            target.style[property] = value;
+
+            const expected = Object.assign({}, normalSet);
+            expected["font-variant-ligatures"] = "none";
+            expected["font-variant"] = "";
+            expected[property] = value;
+
+            test_serialization_set(expected);
+            target.removeAttribute("style");
+        }
+    }, "font-variant-ligatures: none serialization with non-default value for another longhand");
+
+    test(function(t) {
+        t.add_cleanup(() => target.removeAttribute("style"));
+
+        for (const [property, value] of Object.entries(nonDefaultValues)) {
+            if (!CSS.supports(`${property}: initial`))
+                continue;
+            target.style.fontVariant = "normal";
+            target.style[property] = value;
+
+            const expected = Object.assign({}, normalSet);
+            expected[property] = value;
+            expected["font-variant"] = value;
+            test_serialization_set(expected);
+
+            target.removeAttribute("style");
+        }
+    }, "font-variant: normal with non-default longhands");
+
+    test(function(t) {
+        t.add_cleanup(() => target.removeAttribute("style"));
+        for (const keyword of cssWideKeywords) {
+            target.style.fontVariant = "normal";
+            target.style.fontVariantLigatures = keyword;
+
+            const expected = Object.assign({}, normalSet);
+            expected["font-variant-ligatures"] = keyword;
+            expected["font-variant"] = "";
+            test_serialization_set(expected);
+            target.removeAttribute("style");
+        }
+    }, "CSS-wide keyword in one longhand");
+
+    test(function(t) {
+        t.add_cleanup(() => target.removeAttribute("style"));
+
+        for (const keyword of cssWideKeywords) {
+            target.style.fontVariant = keyword;
+            test_serialization_set(setWithValue(keyword));
+            target.removeAttribute("style");
+        }
+    }, "CSS-wide keyword in shorthand");
+
+    test(function(t) {
+        target.style.fontVariant = "normal";
+        target.style.font = "menu";
+        t.add_cleanup(() => target.removeAttribute("style"));
+
+        test_serialization_set(emptySet);
+    }, "font: menu serialization");
+</script>
+</html>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/disabled-elements/event-propagate-disabled.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/disabled-elements/event-propagate-disabled.tentative.html
new file mode 100644
index 0000000..0c00cc8d
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/html/semantics/disabled-elements/event-propagate-disabled.tentative.html
@@ -0,0 +1,243 @@
+<!DOCTYPE html>
+<meta charset="utf8">
+<meta name="timeout" content="long">
+<title>Event propagation on disabled form elements</title>
+<link rel="author" href="mailto:krosylight@mozilla.com">
+<link rel="help" href="https://github.com/whatwg/html/issues/2368">
+<link rel="help" href="https://github.com/whatwg/html/issues/5886">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+
+<div id="cases">
+  <input> <!-- Sanity check with non-disabled control -->
+  <select disabled></select>
+  <select disabled>
+    <!-- <option> can't be clicked as it doesn't have its own painting area -->
+    <option>foo</option>
+  </select>
+  <fieldset disabled>Text</fieldset>
+  <fieldset disabled><span class="target">Span</span></fieldset>
+  <button disabled>Text</button>
+  <button disabled><span class="target">Span</span></button>
+  <textarea disabled></textarea>
+  <input disabled type="button">
+  <input disabled type="checkbox">
+  <input disabled type="color" value="#000000">
+  <input disabled type="date">
+  <input disabled type="datetime-local">
+  <input disabled type="email">
+  <input disabled type="file">
+  <input disabled type="image">
+  <input disabled type="month">
+  <input disabled type="number">
+  <input disabled type="password">
+  <input disabled type="radio">
+  <!-- Native click will click the bar -->
+  <input disabled type="range" value="0">
+  <!-- Native click will click the slider -->
+  <input disabled type="range" value="50">
+  <input disabled type="reset">
+  <input disabled type="search">
+  <input disabled type="submit">
+  <input disabled type="tel">
+  <input disabled type="text">
+  <input disabled type="time">
+  <input disabled type="url">
+  <input disabled type="week">
+</div>
+
+<script>
+  /**
+   * @param {Element} element
+   */
+  function getEventFiringTarget(element) {
+    return element.querySelector(".target") || element;
+  }
+
+  const allEvents = ["pointermove", "mousemove", "pointerdown", "mousedown", "pointerup", "mouseup", "click"];
+
+  /**
+   * @param {*} t
+   * @param {Element} element
+   * @param {Element} observingElement
+   */
+  function setupTest(t, element, observingElement) {
+    /** @type {{type: string, composedPath: Node[]}[]} */
+    const observedEvents = [];
+    const controller = new AbortController();
+    const { signal } = controller;
+    const listenerFn = t.step_func(event => {
+      observedEvents.push({
+        type: event.type,
+        target: event.target,
+        isTrusted: event.isTrusted,
+        composedPath: event.composedPath().map(n => n.constructor.name),
+      });
+    });
+    for (const event of allEvents) {
+      observingElement.addEventListener(event, listenerFn, { signal });
+    }
+    t.add_cleanup(() => controller.abort());
+
+    const target = getEventFiringTarget(element);
+    return { target, observedEvents };
+  }
+
+  /**
+   * @param {Element} target
+   * @param {*} observedEvent
+   */
+  function shouldNotBubble(target, observedEvent) {
+    return (
+      target.disabled &&
+      observedEvent.isTrusted &&
+      ["mousedown", "mouseup", "click"].includes(observedEvent.type)
+    );
+  }
+
+  /**
+   * @param {Event} event
+   */
+  function getExpectedComposedPath(event) {
+    let target = event.target;
+    const result = [];
+    while (target) {
+      if (shouldNotBubble(target, event)) {
+        return result;
+      }
+      result.push(target.constructor.name);
+      target = target.parentNode;
+    }
+    result.push("Window");
+    return result;
+  }
+
+  /**
+  * @param {object} options
+  * @param {Element & { disabled: boolean }} options.element
+  * @param {Element} options.observingElement
+  * @param {string[]} options.expectedEvents
+  * @param {(target: Element) => (Promise<void> | void)} options.clickerFn
+  * @param {string} options.title
+  */
+  function promise_event_test({ element, observingElement, expectedEvents, nonDisabledExpectedEvents, clickerFn, title }) {
+    promise_test(async t => {
+      const { target, observedEvents } = setupTest(t, element, observingElement);
+
+      await t.step_func(clickerFn)(target);
+      await new Promise(resolve => t.step_timeout(resolve, 0));
+
+      const expected = element.disabled ? expectedEvents : nonDisabledExpectedEvents;
+      assert_array_equals(observedEvents.map(e => e.type), expected, "Observed events");
+
+      for (const observed of observedEvents) {
+        assert_equals(observed.target, target, `${observed.type}.target`)
+        assert_array_equals(
+          observed.composedPath,
+          getExpectedComposedPath(observed),
+          `${observed.type}.composedPath`
+        );
+      }
+
+    }, `${title} on ${element.outerHTML}, observed from <${observingElement.localName}>`);
+  }
+
+  /**
+   * @param {object} options
+   * @param {Element & { disabled: boolean }} options.element
+   * @param {string[]} options.expectedEvents
+   * @param {(target: Element) => (Promise<void> | void)} options.clickerFn
+   * @param {string} options.title
+   */
+  function promise_event_test_hierarchy({ element, expectedEvents, nonDisabledExpectedEvents, clickerFn, title }) {
+    const targets = [element, document.body];
+    if (element.querySelector(".target")) {
+      targets.unshift(element.querySelector(".target"));
+    }
+    for (const observingElement of targets) {
+      promise_event_test({ element, observingElement, expectedEvents, nonDisabledExpectedEvents, clickerFn, title });
+    }
+  }
+
+  function trusted_click(target) {
+    // To workaround type=file clicking issue
+    // https://github.com/w3c/webdriver/issues/1666
+    return new test_driver.Actions()
+      .pointerMove(0, 0, { origin: target })
+      .pointerDown()
+      .pointerUp()
+      .send();
+  }
+
+  const mouseEvents = ["mousemove", "mousedown", "mouseup", "click"];
+  const pointerEvents = ["pointermove", "pointerdown", "pointerup"];
+
+  // Events except mousedown/up/click
+  const allowedEvents = ["pointermove", "mousemove", "pointerdown", "pointerup"];
+
+  const elements = document.getElementById("cases").children;
+  for (const element of elements) {
+    // Observe on a child element of the control, if exists
+    const target = element.querySelector(".target");
+    if (target) {
+      promise_event_test({
+        element,
+        observingElement: target,
+        expectedEvents: allEvents,
+        nonDisabledExpectedEvents: allEvents,
+        clickerFn: trusted_click,
+        title: "Trusted click"
+      });
+    }
+
+    // Observe on the control itself
+    promise_event_test({
+      element,
+      observingElement: element,
+      expectedEvents: allowedEvents,
+      nonDisabledExpectedEvents: allEvents,
+      clickerFn: trusted_click,
+      title: "Trusted click"
+    });
+
+    // Observe on document.body
+    promise_event_test({
+      element,
+      observingElement: document.body,
+      expectedEvents: allowedEvents,
+      nonDisabledExpectedEvents: allEvents,
+      clickerFn: trusted_click,
+      title: "Trusted click"
+    });
+
+    const eventFirePair = [
+      [MouseEvent, mouseEvents],
+      [PointerEvent, pointerEvents]
+    ];
+
+    for (const [eventInterface, events] of eventFirePair) {
+      promise_event_test_hierarchy({
+        element,
+        expectedEvents: events,
+        nonDisabledExpectedEvents: events,
+        clickerFn: target => {
+          for (const event of events) {
+            target.dispatchEvent(new eventInterface(event, { bubbles: true }))
+          }
+        },
+        title: `Dispatch new ${eventInterface.name}()`
+      })
+    }
+
+    promise_event_test_hierarchy({
+      element,
+      expectedEvents: getEventFiringTarget(element) === element ? [] : ["click"],
+      nonDisabledExpectedEvents: ["click"],
+      clickerFn: target => target.click(),
+      title: `click()`
+    })
+  }
+</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/resources/consumption-crossorigin-child.sub.html b/third_party/blink/web_tests/external/wpt/html/user-activation/resources/consumption-crossorigin-child.sub.html
index 3ab469f..518e000 100644
--- a/third_party/blink/web_tests/external/wpt/html/user-activation/resources/consumption-crossorigin-child.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/user-activation/resources/consumption-crossorigin-child.sub.html
@@ -23,7 +23,7 @@
   <!-- The midpoint of this frame should be outside the grandchild frame. -->
   <div style="height: 75px;">Cross-origin child frame</div>
   <iframe id="child2" width="270px" height="30px"
-          src="http://{{hosts[alt][]}}:{{ports[http][0]}}/html/user-activation/resources/child-two.html">
+          src="http://{{hosts[][]}}:{{ports[http][1]}}/html/user-activation/resources/child-two.html">
   </iframe>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/html/user-activation/resources/propagation-crossorigin-child.sub.html b/third_party/blink/web_tests/external/wpt/html/user-activation/resources/propagation-crossorigin-child.sub.html
index ec465bf..e920566a 100644
--- a/third_party/blink/web_tests/external/wpt/html/user-activation/resources/propagation-crossorigin-child.sub.html
+++ b/third_party/blink/web_tests/external/wpt/html/user-activation/resources/propagation-crossorigin-child.sub.html
@@ -21,7 +21,7 @@
   <!-- The midpoint of this frame should be outside the grandchild frame. -->
   <div style="height: 75px;">Cross-origin child frame</div>
   <iframe id="child2" width="270px" height="30px"
-          src="http://{{hosts[alt][]}}:{{ports[http][0]}}/html/user-activation/resources/child-two.html">
+          src="http://{{hosts[][]}}:{{ports[http][1]}}/html/user-activation/resources/child-two.html">
   </iframe>
 </body>
 </html>
diff --git a/third_party/blink/web_tests/external/wpt/lint.ignore b/third_party/blink/web_tests/external/wpt/lint.ignore
index c3ab694..7ac79fc 100644
--- a/third_party/blink/web_tests/external/wpt/lint.ignore
+++ b/third_party/blink/web_tests/external/wpt/lint.ignore
@@ -146,6 +146,7 @@
 SET TIMEOUT: conformance-checkers/*
 SET TIMEOUT: content-security-policy/*
 SET TIMEOUT: css/compositing/opacity-and-transform-animation-crash.html
+SET TIMEOUT: css/css-contain/contain-body-overflow-002.html
 SET TIMEOUT: css/css-display/display-contents-shadow-dom-1.html
 SET TIMEOUT: css/CSS2/normal-flow/crashtests/block-in-inline-ax-crash.html
 SET TIMEOUT: css/selectors/selector-placeholder-shown-type-change-001.html
diff --git a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_disabled_form_control.html b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_disabled_form_control.html
index 83ad053a..d2531111 100644
--- a/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_disabled_form_control.html
+++ b/third_party/blink/web_tests/external/wpt/pointerevents/pointerevent_disabled_form_control.html
@@ -18,7 +18,7 @@
             var inputSource = location.search.substring(1);
             var detected_pointertypes = {};
             var detected_eventTypes = {};
-            var eventList = ['pointerout', 'pointerover', 'pointerenter', 'pointermove', 'pointerdown', 'pointerup', 'pointerleave'];
+            var eventList = ['pointerout', 'pointerover', 'pointerenter', 'pointermove', 'pointerdown', 'gotpointercapture', 'pointerup', 'lostpointercapture', 'pointerleave'];
 
             function resetTestState() {
                 detected_eventTypes = {};
@@ -29,10 +29,14 @@
                 var actions_promise;
 
                 eventList.forEach(function(eventName) {
-                on_event(target, eventName, function (event) {
+                    on_event(target, eventName, function (event) {
                         detected_eventTypes[event.type] = true;
                         detected_pointertypes[event.pointerType] = true;
 
+                        if (event.type === "pointerdown") {
+                            target.setPointerCapture(event.pointerId);
+                        }
+
                         if (Object.keys(detected_eventTypes).length == eventList.length) {
                             // Make sure the test finishes after all the input actions are completed.
                             actions_promise.then( () => {
@@ -55,6 +59,7 @@
                         actions_promise = clickInTarget(inputSource, target).then(function() {
                             return new test_driver.Actions()
                                 .addPointer(inputSource + "Pointer1", inputSource)
+                                .pointerMove(0, 0, {origin: target})
                                 .pointerMove(0, 0)
                                 .send();
                         });
diff --git a/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html b/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html
index e70315e..5a477867f 100644
--- a/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html
+++ b/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html
@@ -7,8 +7,16 @@
   fail.
 -->
 <link rel="preload" as="style" crossorigin href="resources/dummy.css?link-header-crossorigin-preload2">
+<link rel="preload" as="font" crossorigin="anonymous" href="resources/font.ttf?link-header-crossorigin-preload2">
 <link rel="stylesheet" crossorigin href="resources/dummy.css?link-header-crossorigin-preload2">
 <script src="resources/dummy.js?link-header-preload2"></script>
+<style>
+    @font-face {
+        font-family: myFont;
+        src: url(resources/font.ttf?link-header-crossorigin-preload2);
+    }
+    .custom-font { font-family: myFont, sans-serif; }
+</style>
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <script src="/preload/resources/preload_helper.js"></script>
@@ -24,7 +32,9 @@
             numberOfResourceTimingEntries("resources/dummy.js?link-header-preload2") == 1 &&
             numberOfResourceTimingEntries("resources/dummy.css?link-header-preload") == 1 &&
             numberOfResourceTimingEntries("resources/dummy.css?link-header-crossorigin-preload1") == 1 &&
-            numberOfResourceTimingEntries("resources/dummy.css?link-header-crossorigin-preload2") == 1) {
+            numberOfResourceTimingEntries("resources/dummy.css?link-header-crossorigin-preload1") == 1 &&
+            numberOfResourceTimingEntries("resources/font.ttf?link-header-crossorigin-preload1") == 1 &&
+            numberOfResourceTimingEntries("resources/font.ttf?link-header-crossorigin-preload2") == 1) {
             done();
         }
         iterations++;
@@ -36,6 +46,8 @@
             verifyNumberOfResourceTimingEntries("resources/dummy.css?link-header-preload", 1);
             verifyNumberOfResourceTimingEntries("resources/dummy.css?link-header-crossorigin-preload1", 1);
             verifyNumberOfResourceTimingEntries("resources/dummy.css?link-header-crossorigin-preload2", 1);
+            verifyNumberOfResourceTimingEntries("resources/font.ttf?link-header-crossorigin-preload1", 1);
+            verifyNumberOfResourceTimingEntries("resources/font.ttf?link-header-crossorigin-preload2", 1);
             done();
         } else {
             step_timeout(check_finished, 500);
@@ -47,4 +59,5 @@
         step_timeout(check_finished, 500);
     });
 </script>
+<span class="custom-font">PASS - this text is here just so that the browser will download the font.</span>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html.headers b/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html.headers
index 338da6b..83670cd 100644
--- a/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html.headers
+++ b/third_party/blink/web_tests/external/wpt/preload/link-header-preload.html.headers
@@ -6,3 +6,5 @@
 Link: </preload/resources/square.png?link-header-preload>;rel=preload;as=image
 Link: </preload/resources/dummy.css?link-header-crossorigin-preload1>;rel=preload;as=style;crossorigin
 Link: </preload/resources/dummy.css?link-header-crossorigin-preload2>;rel=preload;as=style;crossorigin
+Link: </preload/resources/font.ttf?link-header-crossorigin-preload1>;rel=preload;as=font;crossorigin="anonymous"
+Link: </preload/resources/font.ttf?link-header-crossorigin-preload2>;rel=preload;as=font;crossorigin="anonymous"
diff --git a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt
index 651b377..5fc0b68 100644
--- a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https-expected.txt
@@ -1,8 +1,8 @@
 This is a testharness.js-based test.
-Found 60 tests; 58 PASS, 2 FAIL, 0 TIMEOUT, 0 NOTRUN.
+Found 60 tests; 59 PASS, 1 FAIL, 0 TIMEOUT, 0 NOTRUN.
 PASS getDisplayMedia in navigator.mediaDevices
 FAIL getDisplayMedia() must require user activation assert_unreached: Should have rejected: getDisplayMedia should have returned an already-rejected promise. Reached unreachable code
-FAIL getDisplayMedia() must adhere to frameRate if set assert_greater_than_equal: expected a number greater than or equal to 2.5 but got NaN
+PASS getDisplayMedia() must adhere to frameRate if set
 PASS getDisplayMedia({"video":true}) must succeed with video
 PASS getDisplayMedia({"video":true,"audio":false}) must succeed with video
 PASS getDisplayMedia({"video":{}}) must succeed with video
diff --git a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html
index d2229e11..989835af 100644
--- a/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html
+++ b/third_party/blink/web_tests/external/wpt/screen-capture/getdisplaymedia.https.html
@@ -40,7 +40,7 @@
   const v = document.getElementById('display');
   v.autoplay = true;
   // work around firefox bug 1586505, orthogonal to what's being tested
-  const frames = () => v.getVideoPlaybackQuality()?.totalVideoFrames || v.mozPaintedFrames;
+  const frames = () => v.getVideoPlaybackQuality()?.totalVideoFrames ?? v.mozPaintedFrames;
   const target_rate = 5;
   const stream = await getDisplayMedia({video: {width:160, frameRate: target_rate}});
   t.add_cleanup(() => stopTracks(stream));
diff --git a/third_party/blink/web_tests/external/wpt/screen-orientation/hidden_document-expected.txt b/third_party/blink/web_tests/external/wpt/screen-orientation/hidden_document-expected.txt
index e1aa609..46575e6 100644
--- a/third_party/blink/web_tests/external/wpt/screen-orientation/hidden_document-expected.txt
+++ b/third_party/blink/web_tests/external/wpt/screen-orientation/hidden_document-expected.txt
@@ -1,7 +1,7 @@
 This is a testharness.js-based test.
-FAIL hidden documents must reject went trying to call lock or unlock promise_test: Unhandled rejection with value: object "ReferenceError: window_state_context is not defined"
-FAIL hidden documents must reject went trying to call unlock promise_test: Unhandled rejection with value: object "ReferenceError: window_state_context is not defined"
-FAIL hidden documents must not unlock the screen orientation promise_test: Unhandled rejection with value: object "ReferenceError: window_state_context is not defined"
-FAIL Once maximized, a minimized window can lock or unlock the screen orientation again promise_test: Unhandled rejection with value: object "ReferenceError: window_state_context is not defined"
+FAIL hidden documents must reject went trying to call lock or unlock assert_unreached: Should have rejected: undefined Reached unreachable code
+FAIL hidden documents must reject went trying to call unlock promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'then')"
+FAIL hidden documents must not unlock the screen orientation promise_test: Unhandled rejection with value: object "ReferenceError: make_cleanup is not defined"
+FAIL Once maximized, a minimized window can lock or unlock the screen orientation again promise_test: Unhandled rejection with value: object "ReferenceError: make_cleanup is not defined"
 Harness: the test ran to completion.
 
diff --git a/third_party/blink/web_tests/external/wpt/screen-orientation/hidden_document.html b/third_party/blink/web_tests/external/wpt/screen-orientation/hidden_document.html
index b78dbb62..6097cc9 100644
--- a/third_party/blink/web_tests/external/wpt/screen-orientation/hidden_document.html
+++ b/third_party/blink/web_tests/external/wpt/screen-orientation/hidden_document.html
@@ -8,7 +8,7 @@
 <script src="/resources/testharnessreport.js"></script>
 <script src="/resources/testdriver.js"></script>
 <script src="/resources/testdriver-vendor.js"></script>
-<script src="/screen-visibility/resources/window_state_context.js"></script>
+<script src="/page-visibility/resources/window_state_context.js"></script>
 <script src="/screen-orientation/resources/orientation_.js"></script>
 <script>
   promise_test(async (t) => {
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/big-image.png b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/big-image.png
new file mode 100644
index 0000000..6dcc7fa5
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/big-image.png
Binary files differ
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/tracing-test.js b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/tracing-test.js
index 8bd9a296..692d7d79 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/tracing-test.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/tracing-test.js
@@ -119,7 +119,7 @@
     return JSON.stringify(formattedEvents, null, 2);
   }
 
-  logEventShape(evt) {
+  logEventShape(evt, excludedProperties) {
     const logArray = (prefix, name, array) => {
       let start = name ? `${name}: ` : '';
       start = prefix + start;
@@ -150,6 +150,9 @@
           logObject(`${prefix}\t`, key, value)
           continue;
         }
+        if (excludedProperties && excludedProperties.includes(key)) {
+          continue;
+        }
         this._testRunner.log(`${prefix}\t${key}: ${typeof value}`);
       }
       this._testRunner.log(`${prefix}}`);
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/resources/web-vitals.html b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/web-vitals.html
new file mode 100644
index 0000000..195d845
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/resources/web-vitals.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<html>
+  <body>
+    <script>
+      (new PerformanceObserver(console.log)).observe({ entryTypes: ["layout-shift"] });
+      window.setTimeout(() => {
+        const img = document.querySelector('img');
+        img.setAttribute('src', './big-image.png');
+      }, 500);
+
+    </script>
+    <div>
+      <img>
+    </div>
+    <div>
+      text
+    </div>
+  </body>
+</html>
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/tracing/page-load-metrics-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/tracing/page-load-metrics-expected.txt
new file mode 100644
index 0000000..a82f75b
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/tracing/page-load-metrics-expected.txt
@@ -0,0 +1,191 @@
+Tests the data of page load and web vitals trace events
+Recording started
+Tracing complete
+
+Got FCP event:
+Object: {
+	args: {
+		data: {
+			navigationId: string
+		}
+		frame: string
+	}
+	cat: string
+	name: string
+	ph: string
+	pid: number
+	s: string
+	tid: number
+	ts: number
+}
+
+Got LCP candidate events:
+Array: [
+	{
+		args: {
+			data: {
+				candidateIndex: number
+				isMainFrame: boolean
+				isOutermostMainFrame: boolean
+				navigationId: string
+				nodeId: number
+				size: number
+				type: string
+			}
+			frame: string
+		}
+		cat: string
+		name: string
+		ph: string
+		pid: number
+		s: string
+		tid: number
+		ts: number
+	}
+	{
+		args: {
+			data: {
+				candidateIndex: number
+				isMainFrame: boolean
+				isOutermostMainFrame: boolean
+				navigationId: string
+				nodeId: number
+				size: number
+				type: string
+			}
+			frame: string
+		}
+		cat: string
+		name: string
+		ph: string
+		pid: number
+		s: string
+		tid: number
+		ts: number
+	}
+]
+
+Got LayoutShift event:
+Object: {
+	args: {
+		data: {
+			cumulative_score: number
+			frame_max_distance: number
+			had_recent_input: boolean
+			impacted_nodes: [
+				{
+					new_rect: [
+						number,
+						number,
+						number,
+						number,
+					]
+					node_id: number
+					old_rect: [
+						number,
+						number,
+						number,
+						number,
+					]
+				}
+			]
+			is_main_frame: boolean
+			last_input_timestamp: number
+			overall_max_distance: number
+			region_rects: [
+				[
+					number,
+					number,
+					number,
+					number,
+				]
+			]
+			score: number
+			weighted_score_delta: number
+		}
+		frame: string
+	}
+	cat: string
+	name: string
+	ph: string
+	pid: number
+	s: string
+	tid: number
+	ts: number
+	tts: number
+}
+
+Got firstPaint event:
+Object: {
+	args: {
+		data: {
+			navigationId: string
+		}
+		frame: string
+	}
+	cat: string
+	name: string
+	ph: string
+	pid: number
+	s: string
+	tid: number
+	ts: number
+}
+
+Got MarkDOMContent event:
+Object: {
+	args: {
+		data: {
+			frame: string
+			isMainFrame: boolean
+			isOutermostMainFrame: boolean
+			page: string
+		}
+	}
+	cat: string
+	name: string
+	ph: string
+	pid: number
+	s: string
+	tid: number
+	ts: number
+	tts: number
+}
+
+Got MarkLoad event:
+Object: {
+	args: {
+		data: {
+			frame: string
+			isMainFrame: boolean
+			isOutermostMainFrame: boolean
+			page: string
+		}
+	}
+	cat: string
+	name: string
+	ph: string
+	pid: number
+	s: string
+	tid: number
+	ts: number
+	tts: number
+}
+
+Got RunTask event:
+Object: {
+	args: {
+	}
+	cat: string
+	dur: number
+	name: string
+	ph: string
+	pid: number
+	tdur: number
+	tid: number
+	ts: number
+	tts: number
+}
+
+Page load events belong to the same navigation.
+
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/tracing/page-load-metrics.js b/third_party/blink/web_tests/http/tests/inspector-protocol/tracing/page-load-metrics.js
new file mode 100644
index 0000000..b435ace
--- /dev/null
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/tracing/page-load-metrics.js
@@ -0,0 +1,76 @@
+(async function(testRunner) {
+  const {session, dp} = await testRunner.startBlank(
+      'Tests the data of page load and web vitals trace events');
+
+  const TracingHelper =
+      await testRunner.loadScript('../resources/tracing-test.js');
+  const tracingHelper = new TracingHelper(testRunner, session);
+  await tracingHelper.startTracing(
+      'disabled-by-default-devtools.timeline,devtools.timeline,loading');
+  await dp.Page.navigate({
+    url: 'http://127.0.0.1:8000/inspector-protocol/resources/web-vitals.html'
+  });
+
+  // Wait for trace events.
+  await session.evaluateAsync(`
+    new Promise((res) => {
+      (new PerformanceObserver(res)).observe({entryTypes: ['layout-shift']});
+    })`);
+
+  await tracingHelper.stopTracing(
+      /loading|(disabled-by-default)?devtools.timeline/);
+
+  // Web vitals
+  const firstContentfulPaint =
+      tracingHelper.findEvent('firstContentfulPaint', 'R');
+  const largestContentfulPaintCandidates =
+      tracingHelper.findEvents('largestContentfulPaint::Candidate', 'R');
+  const layoutShift = tracingHelper.findEvent('LayoutShift', 'I');
+
+  testRunner.log('\nGot FCP event:');
+  tracingHelper.logEventShape(firstContentfulPaint);
+
+  testRunner.log('\nGot LCP candidate events:');
+  tracingHelper.logEventShape(largestContentfulPaintCandidates);
+
+  testRunner.log('\nGot LayoutShift event:');
+  tracingHelper.logEventShape(layoutShift);
+
+  // "Marker" events
+  const firstPaint = tracingHelper.findEvent('firstPaint', 'R');
+  const markDOMContent = tracingHelper.findEvent('MarkDOMContent', 'I');
+  const markLoad = tracingHelper.findEvent('MarkLoad', 'I');
+
+  testRunner.log('\nGot firstPaint event:');
+  tracingHelper.logEventShape(firstPaint);
+
+  testRunner.log('\nGot MarkDOMContent event:');
+  tracingHelper.logEventShape(markDOMContent);
+
+  testRunner.log('\nGot MarkLoad event:');
+  tracingHelper.logEventShape(markLoad)
+
+  // Long tasks
+  const runTask = tracingHelper.findEvent('RunTask', 'X');
+
+  testRunner.log('\nGot RunTask event:');
+  tracingHelper.logEventShape(runTask)
+
+  const networkRequest = tracingHelper.findEvent('ResourceSendRequest', 'I');
+  const navigationId = networkRequest.args.data.requestId;
+
+  const allRequestIds = [
+    ...largestContentfulPaintCandidates,
+    firstContentfulPaint,
+    firstPaint,
+  ].map(event => event.args.data.navigationId);
+
+
+  const allIdsAreEqual = allRequestIds.every(id => id === navigationId);
+
+  if (allIdsAreEqual) {
+    testRunner.log('\nPage load events belong to the same navigation.');
+  }
+
+  testRunner.completeTest();
+})
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
index a0a403f..fa9f7ae 100644
--- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
+++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -4478,6 +4478,7 @@
 interface LaunchParams
     attribute @@toStringTag
     getter files
+    getter targetURL
     method constructor
 interface LaunchQueue
     attribute @@toStringTag
diff --git a/third_party/closure_compiler/externs/terminal_private.js b/third_party/closure_compiler/externs/terminal_private.js
index b0a0627f6..930b797 100644
--- a/third_party/closure_compiler/externs/terminal_private.js
+++ b/third_party/closure_compiler/externs/terminal_private.js
@@ -117,7 +117,6 @@
  *   alternative_emulator: boolean,
  *   multi_profile: boolean,
  *   sftp: boolean,
- *   tast: boolean,
  *   tmux_integration: boolean
  * }): void} callback Callback that will be called with the info object.
  */
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium
index 8583a7c..fafe59f 100644
--- a/third_party/freetype/README.chromium
+++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@
 Name: FreeType
 URL: http://www.freetype.org/
-Version: VER-2-12-1-135-g47e61d02e
-Revision: 47e61d02e6efb00d9e3c2b38d7fc3211a7514c7f
+Version: VER-2-12-1-136-g0f43a0e7e
+Revision: 0f43a0e7ebfbda303f0b2e8b6d5db63c362233a3
 CPEPrefix: cpe:/a:freetype:freetype:2.12.1
 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent
          JPEG Group) licenses"
diff --git a/third_party/ipcz/src/ipcz/parcel.cc b/third_party/ipcz/src/ipcz/parcel.cc
index e85578f..474cc0a 100644
--- a/third_party/ipcz/src/ipcz/parcel.cc
+++ b/third_party/ipcz/src/ipcz/parcel.cc
@@ -44,8 +44,8 @@
 
 void Parcel::SetDataFromMessage(Message::ReceivedDataBuffer buffer,
                                 absl::Span<uint8_t> data_view) {
-  ABSL_ASSERT(data_view.begin() >= buffer.bytes().begin());
-  ABSL_ASSERT(data_view.end() <= buffer.bytes().end());
+  ABSL_ASSERT(data_view.empty() || data_view.begin() >= buffer.bytes().begin());
+  ABSL_ASSERT(data_view.empty() || data_view.end() <= buffer.bytes().end());
   data_.storage = std::move(buffer);
   data_.view = data_view;
 }
diff --git a/tools/bisect-builds.py b/tools/bisect-builds.py
index 4968d15..5886809c4 100755
--- a/tools/bisect-builds.py
+++ b/tools/bisect-builds.py
@@ -591,9 +591,9 @@
                     displayed.
   """
   def ReportHook(blocknum, blocksize, totalsize):
-    if quit_event and quit_event.isSet():
+    if quit_event and quit_event.is_set():
       raise RuntimeError('Aborting download of revision %s' % str(rev))
-    if progress_event and progress_event.isSet():
+    if progress_event and progress_event.is_set():
       size = blocknum * blocksize
       if totalsize == -1:  # Total size not known.
         progress = 'Received %d bytes' % size
@@ -607,7 +607,7 @@
   download_url = context.GetDownloadURL(rev)
   try:
     urllib.urlretrieve(download_url, filename, ReportHook)
-    if progress_event and progress_event.isSet():
+    if progress_event and progress_event.is_set():
       print()
 
   except RuntimeError:
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index f61ff91..0641b25 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -3596,19 +3596,19 @@
     ],
 
     'release_trybot_backuprefptr_arm64_reclient': [
-      'release_trybot_minimal_symbols_reclient', 'backuprefptr', 'android', 'arm64', 'enable_dangling_raw_ptr_checks',
+      'release_trybot_blink', 'no_goma', 'reclient', 'backuprefptr', 'android', 'arm64', 'enable_dangling_raw_ptr_checks',
     ],
 
     'release_trybot_backuprefptr_arm_reclient': [
-      'release_trybot_minimal_symbols_reclient', 'backuprefptr', 'android', 'arm', 'enable_dangling_raw_ptr_checks',
+      'release_trybot_blink', 'no_goma', 'reclient', 'backuprefptr', 'android', 'arm', 'enable_dangling_raw_ptr_checks',
     ],
 
     'release_trybot_backuprefptr_x64_reclient': [
-      'release_trybot_minimal_symbols_reclient', 'backuprefptr', 'x64', 'enable_dangling_raw_ptr_checks',
+      'release_trybot_blink', 'no_goma', 'reclient', 'backuprefptr', 'x64', 'enable_dangling_raw_ptr_checks',
     ],
 
     'release_trybot_backuprefptr_x86_reclient': [
-      'release_trybot_minimal_symbols_reclient', 'backuprefptr', 'x86', 'enable_dangling_raw_ptr_checks',
+      'release_trybot_blink', 'no_goma', 'reclient', 'backuprefptr', 'x86', 'enable_dangling_raw_ptr_checks',
     ],
 
     'release_trybot_blink': [
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json
index 00f0584..d5e63ea 100644
--- a/tools/mb/mb_config_expectations/chromium.fyi.json
+++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -606,6 +606,7 @@
       "symbol_level": 1,
       "target_cpu": "arm",
       "target_os": "android",
+      "use_goma": false,
       "use_partition_alloc_as_malloc": true,
       "use_remoteexec": true
     }
@@ -625,6 +626,7 @@
       "symbol_level": 1,
       "target_cpu": "arm64",
       "target_os": "android",
+      "use_goma": false,
       "use_partition_alloc_as_malloc": true,
       "use_remoteexec": true
     }
@@ -1074,11 +1076,14 @@
       "enable_backup_ref_ptr_slow_checks": true,
       "enable_backup_ref_ptr_support": true,
       "enable_dangling_raw_ptr_checks": true,
+      "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
+      "proprietary_codecs": true,
       "put_ref_count_in_previous_slot": true,
       "symbol_level": 1,
       "target_cpu": "x64",
+      "use_goma": false,
       "use_partition_alloc_as_malloc": true,
       "use_remoteexec": true
     }
@@ -1385,11 +1390,14 @@
       "enable_backup_ref_ptr_slow_checks": true,
       "enable_backup_ref_ptr_support": true,
       "enable_dangling_raw_ptr_checks": true,
+      "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
+      "proprietary_codecs": true,
       "put_ref_count_in_previous_slot": true,
       "symbol_level": 1,
       "target_cpu": "x64",
+      "use_goma": false,
       "use_partition_alloc_as_malloc": true,
       "use_remoteexec": true
     }
@@ -1447,11 +1455,14 @@
       "enable_backup_ref_ptr_slow_checks": true,
       "enable_backup_ref_ptr_support": true,
       "enable_dangling_raw_ptr_checks": true,
+      "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
+      "proprietary_codecs": true,
       "put_ref_count_in_previous_slot": true,
       "symbol_level": 1,
       "target_cpu": "x64",
+      "use_goma": false,
       "use_partition_alloc_as_malloc": true,
       "use_remoteexec": true
     }
@@ -1462,11 +1473,14 @@
       "enable_backup_ref_ptr_slow_checks": true,
       "enable_backup_ref_ptr_support": true,
       "enable_dangling_raw_ptr_checks": true,
+      "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
+      "proprietary_codecs": true,
       "put_ref_count_in_previous_slot": true,
       "symbol_level": 1,
       "target_cpu": "x86",
+      "use_goma": false,
       "use_partition_alloc_as_malloc": true,
       "use_remoteexec": true
     }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 633869a..7c628d49 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -1227,6 +1227,9 @@
   <int value="3" label="Network error"/>
   <int value="4" label="Unexpected response"/>
   <int value="5" label="Blocked by policy"/>
+  <int value="6" label="Mojo remote disconnected"/>
+  <int value="7"
+      label="Incompatible Mojo versions between remote and receiver"/>
 </enum>
 
 <enum name="AccountManagerAccountAdditionSource">
@@ -36609,6 +36612,8 @@
   <int value="1730" label="PASSWORDSPRIVATE_REQUESTCREDENTIALSDETAILS"/>
   <int value="1731" label="PASSWORDSPRIVATE_GETCREDENTIALGROUPS"/>
   <int value="1732" label="AUTOTESTPRIVATE_GETLAUNCHERSSEARCHBOXSTATE"/>
+  <int value="1733" label="OS_DIAGNOSTICS_RUNSENSITIVESENSORROUTINE"/>
+  <int value="1734" label="OS_DIAGNOSTICS_RUNNVMESELFTESTROUTINE"/>
 </enum>
 
 <enum name="ExtensionIconState">
@@ -54128,6 +54133,14 @@
   <int value="2" label="Subresource"/>
 </enum>
 
+<enum name="IsolatedWebAppResponseReaderCacheState">
+  <int value="0" label="Not cached"/>
+  <int value="1" label="Cached and ready"/>
+  <int value="2"
+      label="Cached but still processing integrity block, signatures, or
+             metadata"/>
+</enum>
+
 <enum name="IsPinnedToTaskbarResult">
   <int value="0" label="Not pinned"/>
   <int value="1" label="Pinned"/>
@@ -63235,6 +63248,7 @@
   <int value="1075637651" label="disable-tablet-splitview"/>
   <int value="1075862390" label="LauncherItemSuggest:enabled"/>
   <int value="1076335895" label="CrosPrivacyHubV0:enabled"/>
+  <int value="1079017005" label="LayoutExtraction:disabled"/>
   <int value="1079032226" label="ParallelDownloading:enabled"/>
   <int value="1079302639" label="ArcEnableWebAppShare:disabled"/>
   <int value="1080108820" label="OneGroupPerRenderer:enabled"/>
@@ -63700,6 +63714,7 @@
   <int value="1344833841" label="ImeThread:enabled"/>
   <int value="1345192233" label="VaapiVideoDecoder:enabled"/>
   <int value="1346994602" label="SyncPseudoUSSDictionary:enabled"/>
+  <int value="1348575062" label="LayoutExtraction:enabled"/>
   <int value="1349100152"
       label="AutofillEnablePasswordInfoBarAccountIndicationFooter:disabled"/>
   <int value="1349313561" label="RestrictedApiOrigins:enabled"/>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml
index f5730c07..76104f9 100644
--- a/tools/metrics/histograms/metadata/blink/histograms.xml
+++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -2043,6 +2043,20 @@
   </summary>
 </histogram>
 
+<histogram name="Blink.MemoryCache.CrossDocumentCachedResource"
+    enum="ResourceType" expires_after="2023-04-01">
+  <owner>gjc@chromium.org</owner>
+  <owner>blink-network-dev@chromium.org</owner>
+  <summary>
+    Type of cached resources reused across Documents when loading a new document
+    in the same renderer. Recorded by the ResourceFetcher when a resource is
+    requested for a new document. If the resource is available from the memory
+    cache and previously loaded by a different document, the resource will be
+    considered as reused. Repetitive requests to the same url in a document will
+    be counted only once.
+  </summary>
+</histogram>
+
 <histogram name="Blink.MemoryCache.RevalidationPolicy"
     enum="RevalidationPolicy" expires_after="2021-04-21">
   <owner>hiroshige@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/content/histograms.xml b/tools/metrics/histograms/metadata/content/histograms.xml
index b05e510e..5806bb5 100644
--- a/tools/metrics/histograms/metadata/content/histograms.xml
+++ b/tools/metrics/histograms/metadata/content/histograms.xml
@@ -395,6 +395,16 @@
   </summary>
 </histogram>
 
+<histogram name="ContentSettings.RegularProfile.DefaultBackgroundSyncSetting"
+    enum="ContentSetting" expires_after="2023-04-16">
+  <owner>tungnh@chromium.org</owner>
+  <owner>src/components/permissions/PERMISSIONS_OWNERS</owner>
+  <summary>
+    The default permission setting for Background Sync at profile open. This
+    histogram is only recorded for regular profiles.
+  </summary>
+</histogram>
+
 <histogram
     name="ContentSettings.{RegularProfileFiltered}DefaultAutoDarkWebContentSetting"
     enum="ContentSetting" expires_after="2023-02-19">
diff --git a/tools/metrics/histograms/metadata/network/histograms.xml b/tools/metrics/histograms/metadata/network/histograms.xml
index 631db88..920dd25 100644
--- a/tools/metrics/histograms/metadata/network/histograms.xml
+++ b/tools/metrics/histograms/metadata/network/histograms.xml
@@ -1315,7 +1315,7 @@
 </histogram>
 
 <histogram name="Network.EarlyHints.Preload.RequestDestination"
-    enum="RequestDestination" expires_after="2022-12-25">
+    enum="RequestDestination" expires_after="2023-04-15">
   <owner>bashi@chromium.org</owner>
   <owner>blink-network-stack@google.com</owner>
   <summary>
diff --git a/tools/metrics/histograms/metadata/webapps/histograms.xml b/tools/metrics/histograms/metadata/webapps/histograms.xml
index 9fcf6b2..eee1437 100644
--- a/tools/metrics/histograms/metadata/webapps/histograms.xml
+++ b/tools/metrics/histograms/metadata/webapps/histograms.xml
@@ -746,6 +746,23 @@
   <summary>Records the result code of Web App installs.</summary>
 </histogram>
 
+<histogram name="WebApp.Isolated.ResponseReaderCacheState"
+    enum="IsolatedWebAppResponseReaderCacheState" expires_after="2023-11-08">
+  <owner>cmfcmf@chromium.org</owner>
+  <owner>peletskyi@chromium.org</owner>
+  <summary>
+    This histogram is logged whenever an HTTP request to read a response from a
+    Signed Web Bundle used for Isolated Web Apps is made through the
+    isolated-app: scheme and handled by the corresponding URLLoader. This
+    happens both during installation of an Isolated Web App, and when users
+    browse an installed Isolated Web App. The histogram records whether a cached
+    reader was used to read the response. A cached reader is able to directly
+    read a response from the Signed Web Bundle, whereas an uncached reader first
+    needs to parse the Signed Web Bundle's Integrity Block and metadata, and
+    possibly verify signatures.
+  </summary>
+</histogram>
+
 <histogram name="WebApp.Isolated.SignatureVerificationDuration" units="ms"
     expires_after="2023-11-08">
   <owner>cmfcmf@chromium.org</owner>
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc
index c63b031..4e40dc6cb 100644
--- a/ui/accessibility/accessibility_features.cc
+++ b/ui/accessibility/accessibility_features.cc
@@ -305,14 +305,8 @@
   return base::FeatureList::IsEnabled(::features::kReadAnythingWithScreen2x);
 }
 
-BASE_FEATURE(kScreenAI, "ScreenAI", base::FEATURE_DISABLED_BY_DEFAULT);
-
-bool IsScreenAIVisualAnnotationsEnabled() {
-  return base::FeatureList::IsEnabled(::features::kScreenAI);
-}
-
 bool IsScreenAIServiceNeeded() {
-  return IsPdfOcrEnabled() || IsScreenAIVisualAnnotationsEnabled() ||
+  return IsPdfOcrEnabled() || IsLayoutExtractionEnabled() ||
          IsReadAnythingWithScreen2xEnabled();
 }
 
@@ -326,20 +320,20 @@
   return base::FeatureList::IsEnabled(::features::kScreenAIDebugMode);
 }
 
-BASE_FEATURE(kScreenAIUseLayoutExtraction,
-             "ScreenAIUseLayoutExtraction",
-             base::FEATURE_DISABLED_BY_DEFAULT);
-
-bool IsScreenAIUseLayoutExtractionEnabled() {
-  return base::FeatureList::IsEnabled(::features::kScreenAIUseLayoutExtraction);
-}
-
 BASE_FEATURE(kPdfOcr, "PdfOcr", base::FEATURE_DISABLED_BY_DEFAULT);
 
 bool IsPdfOcrEnabled() {
   return base::FeatureList::IsEnabled(::features::kPdfOcr);
 }
 
+BASE_FEATURE(kLayoutExtraction,
+             "LayoutExtraction",
+             base::FEATURE_DISABLED_BY_DEFAULT);
+
+bool IsLayoutExtractionEnabled() {
+  return base::FeatureList::IsEnabled(::features::kLayoutExtraction);
+}
+
 BASE_FEATURE(kAccessibilityService,
              "AccessibilityService",
              base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/ui/accessibility/accessibility_features.h b/ui/accessibility/accessibility_features.h
index 5663c11..05a78c69 100644
--- a/ui/accessibility/accessibility_features.h
+++ b/ui/accessibility/accessibility_features.h
@@ -99,7 +99,8 @@
     kExperimentalAccessibilityDictationWithPumpkin);
 
 // Returns true if Dictation with context checking is enabled.
-AX_BASE_EXPORT bool IsExperimentalAccessibilityDictationContextCheckingEnabled();
+AX_BASE_EXPORT bool
+IsExperimentalAccessibilityDictationContextCheckingEnabled();
 
 // Enables Context Checking with the accessibility Dictation feature.
 AX_BASE_EXPORT BASE_DECLARE_FEATURE(
@@ -239,14 +240,6 @@
 // distills web pages using an ML model.
 AX_BASE_EXPORT bool IsReadAnythingWithScreen2xEnabled();
 
-// Enables using Screen AI library to add metadata for accessibility tools.
-AX_BASE_EXPORT BASE_DECLARE_FEATURE(kScreenAI);
-
-// Returns true if Screen AI Visual Annotations feature is enabled. This feature
-// uses a local machine intelligence library to process browser screenshots and
-// add metadata to the accessibility tree.
-AX_BASE_EXPORT bool IsScreenAIVisualAnnotationsEnabled();
-
 // Returns true if Screen AI Service is needed as either
 // ScreenAIVisualAnnotations or ReadAnythingWithScreen2x are enabled.
 AX_BASE_EXPORT bool IsScreenAIServiceNeeded();
@@ -254,14 +247,6 @@
 // If enabled, ScreenAI library writes some debug data in /tmp.
 AX_BASE_EXPORT bool IsScreenAIDebugModeEnabled();
 
-// If enabled, ScreenAI library uses Layout Extraction output, and if disabled,
-// uses OCR output.
-// TODO(https://crbug.com/1278249): Remove this flag after the two outputs are
-// merged in the library.
-AX_BASE_EXPORT BASE_DECLARE_FEATURE(kScreenAIUseLayoutExtraction);
-
-AX_BASE_EXPORT bool IsScreenAIUseLayoutExtractionEnabled();
-
 // Enables a feature whereby inaccessible (i.e. untagged) PDFs are made
 // accessible using an optical character recognition service. Due to the size of
 // the OCR component, this feature targets desktop versions of Chrome for now.
@@ -272,6 +257,15 @@
 // to the accessibility tree.
 AX_BASE_EXPORT bool IsPdfOcrEnabled();
 
+// Enables a feature whereby inaccessible surfaces such as canvases are made
+// accessible using a local machine intelligence service.
+AX_BASE_EXPORT BASE_DECLARE_FEATURE(kLayoutExtraction);
+
+// Returns true if Layout Extraction feature is enabled. This feature uses a
+// local machine intelligence library to process screenshots and adds metadata
+// to the accessibility tree.
+AX_BASE_EXPORT bool IsLayoutExtractionEnabled();
+
 // Enables the experimental Accessibility Service.
 AX_BASE_EXPORT BASE_DECLARE_FEATURE(kAccessibilityService);
 
diff --git a/ui/base/dragdrop/drop_target_event.h b/ui/base/dragdrop/drop_target_event.h
index 49c5908..caae18f 100644
--- a/ui/base/dragdrop/drop_target_event.h
+++ b/ui/base/dragdrop/drop_target_event.h
@@ -30,7 +30,7 @@
 
  private:
   // Data associated with the drag/drop session.
-  const raw_ref<const OSExchangeData> data_;
+  const raw_ref<const OSExchangeData, DanglingUntriaged> data_;
 
   // Bitmask of supported DragDropTypes::DragOperation by the source.
   int source_operations_;
diff --git a/ui/file_manager/file_manager/background/js/BUILD.gn b/ui/file_manager/file_manager/background/js/BUILD.gn
index fb561d5..d5001064 100644
--- a/ui/file_manager/file_manager/background/js/BUILD.gn
+++ b/ui/file_manager/file_manager/background/js/BUILD.gn
@@ -28,7 +28,6 @@
     ":metrics_start",
     ":progress_center",
     ":test_util",
-    ":trash",
   ]
 }
 
@@ -51,7 +50,6 @@
     ":progress_center",
     ":runtime_loaded_test_util",
     ":test_util_base",
-    ":trash",
     ":volume_info_impl",
     ":volume_info_list_impl",
     ":volume_manager_factory",
@@ -239,7 +237,6 @@
 js_library("file_operation_manager") {
   deps = [
     ":file_operation_util",
-    ":trash",
     "//ui/file_manager/file_manager/common/js:util",
     "//ui/file_manager/file_manager/externs:entry_location",
     "//ui/file_manager/file_manager/externs:files_app_entry_interfaces",
@@ -372,30 +369,6 @@
   ]
 }
 
-js_library("trash") {
-  deps = [
-    ":file_operation_util",
-    "//ui/file_manager/file_manager/common/js:trash",
-    "//ui/file_manager/file_manager/common/js:util",
-    "//ui/file_manager/file_manager/externs:volume_manager",
-    "//ui/webui/resources/js:assert",
-  ]
-}
-
-js_unittest("trash_unittest") {
-  deps = [
-    ":mock_volume_manager",
-    ":trash",
-    "//chrome/test/data/webui/chromeos:chai_assert",
-    "//ui/file_manager/file_manager/common/js:mock_entry",
-    "//ui/file_manager/file_manager/common/js:trash",
-    "//ui/file_manager/file_manager/common/js:util",
-    "//ui/file_manager/file_manager/common/js:volume_manager_types",
-    "//ui/webui/resources/js:assert",
-    "//ui/webui/resources/js:load_time_data.m",
-  ]
-}
-
 js_library("volume_info_list_impl") {
   deps = [
     "//ui/file_manager/file_manager/common/js:array_data_model",
@@ -457,7 +430,6 @@
     ":drive_sync_handler_unittest",
     ":file_operation_handler_unittest",
     ":file_operation_manager_unittest",
-    ":trash_unittest",
     ":volume_manager_unittest",
   ]
 
diff --git a/ui/file_manager/file_manager/background/js/file_operation_manager.js b/ui/file_manager/file_manager/background/js/file_operation_manager.js
index c402c026..10486e20 100644
--- a/ui/file_manager/file_manager/background/js/file_operation_manager.js
+++ b/ui/file_manager/file_manager/background/js/file_operation_manager.js
@@ -8,7 +8,6 @@
 import {VolumeManager} from '../../externs/volume_manager.js';
 
 import {fileOperationUtil} from './file_operation_util.js';
-import {Trash} from './trash.js';
 
 /**
  * FileOperationManagerImpl: implementation of {FileOperationManager}.
@@ -26,12 +25,6 @@
      * @private {number}
      */
     this.taskIdCounter_ = 0;
-
-    /**
-     * @private {!Trash}
-     * @const
-     */
-    this.trash_ = new Trash();
   }
 
   /**
@@ -76,18 +69,6 @@
   }
 
   /**
-   * Returns true if all entries will use trash for delete.
-   *
-   * @param {!VolumeManager} volumeManager
-   * @param {!Array<!Entry>} entries The entries.
-   * @return {boolean}
-   */
-  willUseTrash(volumeManager, entries) {
-    return entries.every(
-        entry => this.trash_.shouldMoveToTrash(volumeManager, entry));
-  }
-
-  /**
    * Writes file to destination dir. This function is called when an image is
    * dragged from a web page. In this case there is no FileSystem Entry to copy
    * or move, just the JS File object with attached Blob. This operation does
diff --git a/ui/file_manager/file_manager/background/js/test_util.js b/ui/file_manager/file_manager/background/js/test_util.js
index 3cffe54..25f0ede 100644
--- a/ui/file_manager/file_manager/background/js/test_util.js
+++ b/ui/file_manager/file_manager/background/js/test_util.js
@@ -13,6 +13,14 @@
 export {test};
 
 /**
+ * Sanitizes the formatted date. Replaces unusual space with normal space.
+ * @param {string} strDate the date already in the string format.
+ * @return {string}
+ */
+export function sanitizeDate(strDate) {
+  return strDate.replace('\u202f', ' ');
+}
+/**
  * Opens the main Files app's window and waits until it is ready.
  *
  * @param {!FilesAppState} appState App state.
@@ -64,7 +72,7 @@
       row.querySelector('.filename-label').textContent,
       row.querySelector('.size').textContent,
       row.querySelector('.type').textContent,
-      row.querySelector('.date').textContent,
+      sanitizeDate(row.querySelector('.date').textContent || ''),
     ]);
   }
   return fileList;
diff --git a/ui/file_manager/file_manager/background/js/trash.js b/ui/file_manager/file_manager/background/js/trash.js
deleted file mode 100644
index 27d176d..0000000
--- a/ui/file_manager/file_manager/background/js/trash.js
+++ /dev/null
@@ -1,403 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-/**
- * @fileoverview  Files App trash implementation based on
- * https://specifications.freedesktop.org/trash-spec/trashspec-1.0.html
- */
-
-import {assert} from 'chrome://resources/js/assert.js';
-
-import {AUTO_DELETE_INTERVAL_MS, TrashConfig, TrashDirs, TrashEntry} from '../../common/js/trash.js';
-import {util} from '../../common/js/util.js';
-import {VolumeManager} from '../../externs/volume_manager.js';
-
-import {fileOperationUtil} from './file_operation_util.js';
-
-/**
- * Implementation of trash.
- */
-export class Trash {
-  constructor() {
-    /**
-     * Store TrashDirs to avoid repeated lookup, keyed by TrashConfig.id.
-     * @private {!Object<string, !TrashDirs>}
-     * @const
-     */
-    this.trashDirs_ = {};
-
-    /**
-     * Set of in-progress deletes, keyed by TrashConfig.id with Set containing
-     * *.trashinfo filename. Items in this list are ignored by
-     * removeOldItems_(). Each Set entry is removed once removeOldItems_() runs
-     * for the related TrashConfig.
-     *
-     * @private {!Map<string, Set<string>>}
-     * @const
-     */
-    this.inProgress_ = new Map(TrashConfig.CONFIG.map(c => [c.id, new Set()]));
-  }
-
-  /**
-   * Get the TrashConfig for the trash that this entry would be placed in, if
-   * any. Initializes TrashConfig with pathPrefix if required.
-   *
-   * @param {!VolumeManager} volumeManager
-   * @param {!Entry} entry The entry to find a matching TrashConfig for.
-   * @return {?TrashConfig} TrashConfig for entry or null.
-   * @private
-   */
-  getConfig_(volumeManager, entry) {
-    const info = volumeManager.getLocationInfo(entry);
-    if (!util.isTrashEnabled() || !info) {
-      return null;
-    }
-    const fullPathSlash = entry.fullPath + '/';
-    for (const config of TrashConfig.CONFIG) {
-      const entryInVolume = fullPathSlash.startsWith(config.topDir);
-      if (config.volumeType === info.volumeInfo.volumeType && entryInVolume) {
-        if (config.prefixPathWithRemoteMount &&
-            info.volumeInfo.remoteMountPath) {
-          config.pathPrefix = info.volumeInfo.remoteMountPath;
-        }
-        return config;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Only move to trash if feature is on, and entry is in one of the supported
-   * volumes, but not already in the trash.
-   *
-   * @param {!VolumeManager} volumeManager
-   * @param {!Entry} entry The entry to remove.
-   * @return {?TrashConfig} Valid TrashConfig if item should be moved to trash,
-   *     else null if item should be permanently deleted.
-   */
-  shouldMoveToTrash(volumeManager, entry) {
-    const config = this.getConfig_(volumeManager, entry);
-    if (config) {
-      const fullPathSlash = entry.fullPath + '/';
-      const entryInTrash = fullPathSlash.startsWith(config.trashDir);
-      if (!entryInTrash) {
-        return config;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Remove a file or a directory, either deleting it permanently, or moving it
-   * to the trash.
-   *
-   * @param {!VolumeManager} volumeManager
-   * @param {!Entry} entry The entry to remove.
-   * @param {boolean} permanentlyDelete If true, entry is deleted, else it is
-   *     moved to trash.
-   * @return {!Promise<!TrashEntry|undefined>} Promise which resolves when entry
-   *     is removed, rejects with Error.
-   */
-  removeFileOrDirectory(volumeManager, entry, permanentlyDelete) {
-    if (!permanentlyDelete) {
-      const config = this.shouldMoveToTrash(volumeManager, entry);
-      if (config) {
-        return this.trashFileOrDirectory_(entry, config).catch(error => {
-          console.log(
-              ('Error deleting ' + entry.toURL() +
-               ', will refresh trashdir and try again'),
-              error);
-          delete this.trashDirs_[config.id];
-          return this.trashFileOrDirectory_(entry, config);
-        });
-      }
-    }
-    return this.permanentlyDeleteFileOrDirectory_(entry);
-  }
-
-  /**
-   * Delete a file or a directory permanently.
-   *
-   * @param {!Entry} entry The entry to remove.
-   * @return {!Promise<void>} Promise which resolves when entry is removed.
-   * @private
-   */
-  permanentlyDeleteFileOrDirectory_(entry) {
-    return new Promise((resolve, reject) => {
-      if (entry.isDirectory) {
-        entry.removeRecursively(resolve, reject);
-      } else {
-        entry.remove(resolve, reject);
-      }
-    });
-  }
-
-  /**
-   * Get trash files and info directories.
-   *
-   * @param {!Entry} entry The entry to remove.
-   * @param {!TrashConfig} config
-   * @return {!Promise<!TrashDirs>} Promise which resolves with trash dirs.
-   * @private
-   */
-  async getTrashDirs_(entry, config) {
-    let trashDirs = this.trashDirs_[config.id];
-    if (trashDirs) {
-      return trashDirs;
-    }
-
-    trashDirs = assert(await TrashDirs.getTrashDirs(
-        entry.filesystem, config, /*create=*/ true));
-
-    // Check and remove old items max once per session.
-    if (this.inProgress_.has(config.id)) {
-      this.removeOldItems_(trashDirs, config, Date.now()).then(() => {
-        // In-progress set is not required after removeOldItems_() runs.
-        this.inProgress_.delete(config.id);
-      });
-    }
-    this.trashDirs_[config.id] = trashDirs;
-    return trashDirs;
-  }
-
-  /**
-   * Write /.Trash/info/<name>.trashinfo file.
-   * Since creating and writing the file requires multiple async operations, we
-   * keep a record of which writes are in progress to be ignored by
-   * removeOldItems_() if it is running concurrently.
-   *
-   * @param {!DirectoryEntry} trashInfoDir /.Trash/info directory.
-   * @param {string} trashInfoName name of the *.trashinfo file.
-   * @param {string} path path to use in *.trashinfo file.
-   * @param {!Date} deletionDate deletion date to use in *.trashinfo file.
-   * @return {!Promise<!FileEntry>}
-   * @private
-   */
-  async writeTrashInfoFile_(trashInfoDir, trashInfoName, path, deletionDate) {
-    return new Promise((resolve, reject) => {
-      trashInfoDir.getFile(trashInfoName, {create: true}, infoFile => {
-        infoFile.createWriter(writer => {
-          writer.onwriteend = () => {
-            resolve(infoFile);
-          };
-          writer.onerror = reject;
-          const info = `[Trash Info]\nPath=${path}\nDeletionDate=${
-              deletionDate.toISOString()}`;
-          writer.write(new Blob([info], {type: 'text/plain'}));
-        }, reject);
-      }, reject);
-    });
-  }
-
-  /**
-   * Promise wrapper for FileSystemEntry.moveTo().
-   *
-   * @param {!T} srcEntry source entry to move.
-   * @param {!DirectoryEntry} dstDirEntry destination directory.
-   * @param {string} name name of entry in destination directory.
-   * @return {!Promise<!T>} Promise which resolves with moved entry.
-   * @template T
-   * @private
-   */
-  moveTo_(srcEntry, dstDirEntry, name) {
-    return new Promise((resolve, reject) => {
-      srcEntry.moveTo(dstDirEntry, name, resolve, reject);
-    });
-  }
-
-  /**
-   * Move a file or a directory to the trash.
-   *
-   * @param {!Entry} entry The entry to remove.
-   * @param {!TrashConfig} config trash config for entry.
-   * @return {!Promise<!TrashEntry>}
-   * @private
-   */
-  async trashFileOrDirectory_(entry, config) {
-    const trashDirs = await this.getTrashDirs_(entry, config);
-    const name =
-        await fileOperationUtil.deduplicatePath(trashDirs.files, entry.name);
-    const trashInfoName = `${name}.trashinfo`;
-
-    // Write trashinfo first, then only move file if info write succeeds.
-    // If any step fails, the file will be unchanged, and any partial trashinfo
-    // file created will be cleaned up when we remove old items.
-    const inProgress = this.inProgress_.get(config.id);
-    if (inProgress) {
-      inProgress.add(trashInfoName);
-    }
-    const path = config.pathPrefix + entry.fullPath;
-    const deletionDate = new Date();
-    const infoEntry = await this.writeTrashInfoFile_(
-        trashDirs.info, trashInfoName, path, deletionDate);
-    const filesEntry = await this.moveTo_(entry, trashDirs.files, name);
-    return new TrashEntry(
-        entry.name, deletionDate, filesEntry, infoEntry, entry);
-  }
-
-  /**
-   * Restores the specified trash item.
-   *
-   * @param {!VolumeManager} volumeManager
-   * @param {!TrashEntry} trashEntry entry in trash.
-   * @return {Promise<void>} Promise which resolves when file is restored.
-   */
-  async restore(volumeManager, trashEntry) {
-    const infoEntry = trashEntry.infoEntry;
-    const config = this.getConfig_(volumeManager, infoEntry);
-    if (!config) {
-      throw new Error(`No TrashConfig for ${infoEntry.toURL()}`);
-    }
-
-    // Read Path from info entry.
-    const file =
-        await new Promise((resolve, reject) => infoEntry.file(resolve, reject));
-    const text = await file.text();
-    const path = TrashEntry.parsePath(text);
-    if (!path) {
-      throw new Error(
-          `No Path found to restore in ${infoEntry.fullPath}, text=${text}`);
-    } else if (!path.startsWith(config.pathPrefix)) {
-      throw new Error(`Path does not match expected prefix in ${
-          infoEntry.fullPath}, prefix=${config.pathPrefix}, text=${text}`);
-    }
-    const pathNoLeadingSlash = path.substring(config.pathPrefix.length + 1);
-    const parts = pathNoLeadingSlash.split('/');
-
-    // Move to last directory in path, making sure dirs are created if needed.
-    let dir = trashEntry.filesEntry.filesystem.root;
-    for (let i = 0; i < parts.length - 1; i++) {
-      dir =
-          assert(await TrashDirs.getDirectory(dir, parts[i], /*create=*/ true));
-    }
-
-    // Restore filesEntry first, then remove its trash infoEntry.
-    // If any step fails, then either we still have the file in trash with a
-    // valid trashinfo, or file is restored and trashinfo will be cleaned up
-    // when we remove old items.
-    const name =
-        await fileOperationUtil.deduplicatePath(dir, parts[parts.length - 1]);
-    await this.moveTo_(trashEntry.filesEntry, dir, name);
-    // Ignore any error deleting *.trashinfo since DriveFS auto deletes this
-    // file when filesEntry is moved.
-    await this.permanentlyDeleteFileOrDirectory_(infoEntry).catch(
-        e => console.warn(`Error deleting ${infoEntry.toURL()}`, e));
-  }
-
-  /**
-   * Remove any items from trash older than 30d.
-   * @param {!TrashDirs} trashDirs
-   * @param {!TrashConfig} config trash config for entry.
-   * @param {number} now Current time in milliseconds from epoch.
-   */
-  async removeOldItems_(trashDirs, config, now) {
-    const ls = (reader) => {
-      return new Promise((resolve, reject) => {
-        reader.readEntries(results => resolve(results), error => reject(error));
-      });
-    };
-    const rm = (entry, log, desc) => {
-      if (entry) {
-        log(`Deleting ${entry.toURL()}: ${desc}`);
-        return this.permanentlyDeleteFileOrDirectory_(entry).catch(
-            e => console.warn(`Error deleting ${entry.toURL()}: ${desc}`, e));
-      }
-    };
-
-    // Get all entries in trash/files. Read files first before info in case
-    // trash or restore operations happen during this.
-    const filesEntries = {};
-    const filesReader = trashDirs.files.createReader();
-    try {
-      while (true) {
-        const entries = await ls(filesReader);
-        if (!entries.length) {
-          break;
-        }
-        entries.forEach(entry => filesEntries[entry.name] = entry);
-      }
-    } catch (e) {
-      console.warn('Error reading old files entries', e);
-      return;
-    }
-
-    // Check entries in trash/info and delete items older than 30d.
-    const infoReader = trashDirs.info.createReader();
-    try {
-      while (true) {
-        const entries = await ls(infoReader);
-        if (!entries.length) {
-          break;
-        }
-        for (const entry of entries) {
-          // Delete any directories.
-          if (!entry.isFile) {
-            rm(entry, console.warn, 'Unexpected trash info directory');
-            continue;
-          }
-
-          // Delete any files not *.trashinfo.
-          if (!entry.name.endsWith('.trashinfo')) {
-            rm(entry, console.warn, 'Unexpected trash info file');
-            continue;
-          }
-
-          // Ignore any in-progress files.
-          const inProgress = this.inProgress_.get(config.id);
-          if (inProgress && inProgress.has(entry.name)) {
-            console.log(`Ignoring write in progress ${entry.toURL()}`);
-            continue;
-          }
-
-          const name = entry.name.substring(0, entry.name.length - 10);
-          const filesEntry = filesEntries[name];
-          delete filesEntries[name];
-
-          // Delete any .trashinfo file with no matching file entry (unless it
-          // was write-in-progress).
-          if (!filesEntry) {
-            rm(entry, console.warn, 'No matching files entry');
-            continue;
-          }
-
-          // Delete any entries with no DeletionDate.
-          const file = await new Promise(
-              (resolve, reject) => entry.file(resolve, reject));
-          const text = await file.text();
-          const found = text.match(/^DeletionDate=(.*)/m);
-          if (!found) {
-            rm(entry, console.warn, 'Could not find DeletionDate in ' + text);
-            rm(filesEntry, console.warn, 'Invalid matching trashinfo');
-            continue;
-          }
-
-          // Delete any entries with invalid DeletionDate.
-          const d = Date.parse(found[1]);
-          if (!d) {
-            rm(entry, console.warn, 'Could not parse DeletionDate in ' + text);
-            rm(filesEntry, console.warn, 'Invalid matching trashinfo');
-            continue;
-          }
-
-          // Delete entries older than 30d.
-          const ago30d = now - AUTO_DELETE_INTERVAL_MS;
-          const ago30dStr = new Date(ago30d).toISOString();
-          if (d < ago30d) {
-            const msg = `Older than ${ago30dStr}, DeletionDate=${found[1]}`;
-            rm(entry, console.log, msg);
-            rm(filesEntry, console.log, msg);
-          }
-        }
-      }
-    } catch (e) {
-      console.warn('Error reading old info entries', e);
-      return;
-    }
-
-    // Any entries left in filesEntries have no matching *.trashinfo file.
-    for (const entry of Object.values(filesEntries)) {
-      rm(entry, console.warn, 'No matching *.trashinfo file');
-    }
-  }
-}
diff --git a/ui/file_manager/file_manager/background/js/trash_unittest.js b/ui/file_manager/file_manager/background/js/trash_unittest.js
deleted file mode 100644
index d2dfd84..0000000
--- a/ui/file_manager/file_manager/background/js/trash_unittest.js
+++ /dev/null
@@ -1,364 +0,0 @@
-// Copyright 2020 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import {assert} from 'chrome://resources/js/assert.js';
-import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chromeos/chai_assert.js';
-
-import {MockDirectoryEntry, MockFileEntry, MockFileSystem} from '../../common/js/mock_entry.js';
-import {TrashDirs} from '../../common/js/trash.js';
-import {util} from '../../common/js/util.js';
-import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
-
-import {MockVolumeManager} from './mock_volume_manager.js';
-import {Trash} from './trash.js';
-
-/** @type {!MockVolumeManager} */
-let volumeManager;
-
-/**
- * Boolean indicating whether Trash is enabled.
- * @type {boolean}
- * */
-let trashEnabled = true;
-
-// Set up the test components.
-export function setUp() {
-  util.isTrashEnabled = () => trashEnabled;
-
-  volumeManager = new MockVolumeManager();
-}
-
-/**
- * Call removeFileOrDirectory with the supplied settings and validate that
- * we correctly either permanently delete, or move to trash.
- *
- * @suppress {accessControls} Access private functions
- * permanentlyDeleteFileOrDirectory_() and trashFileOrDirectory_().
- */
-function checkRemoveFileOrDirectory(
-    filesTrashEnabled, rootType, path, deletePermanently,
-    expectPermanentlyDelete) {
-  trashEnabled = filesTrashEnabled;
-  const volumeInfo =
-      volumeManager.createVolumeInfo(rootType, 'volumeId', 'label');
-  const f = MockFileEntry.create(volumeInfo.fileSystem, path);
-
-  const trash = new Trash();
-  // Detect whether permanentlyDelete..., or trash... is called.
-  let permanentlyDeleteCalled = false;
-  let trashCalled = false;
-  trash.permanentlyDeleteFileOrDirectory_ = () => {
-    permanentlyDeleteCalled = true;
-    return Promise.resolve();
-  };
-  trash.trashFileOrDirectory_ = (volumeManager, entry) => {
-    trashCalled = true;
-    return Promise.resolve();
-  };
-
-  trash.removeFileOrDirectory(volumeManager, f, deletePermanently);
-  assertEquals(expectPermanentlyDelete, permanentlyDeleteCalled);
-  assertEquals(!expectPermanentlyDelete, trashCalled);
-}
-
-/**
- * Test that removeFileOrDirectory() correctly moves to trash, or permanently
- * deletes.
- */
-export function testRemoveFileOrDirectory() {
-  // Only use trash if flag is enabled, entry is in 'downloads' volume, but not
-  // in /.Trash.
-
-  // enabled, rootType, path, deletePermanently, expectPermanentlyDelete.
-  checkRemoveFileOrDirectory(false, 'removable', '/f', false, true);
-  checkRemoveFileOrDirectory(false, 'removable', '/f', true, true);
-  checkRemoveFileOrDirectory(false, 'downloads', '/f', false, true);
-  checkRemoveFileOrDirectory(false, 'downloads', '/f', true, true);
-  checkRemoveFileOrDirectory(true, 'removable', '/f', false, true);
-  checkRemoveFileOrDirectory(true, 'removable', '/f', true, true);
-  checkRemoveFileOrDirectory(true, 'downloads', '/f', false, false);
-  checkRemoveFileOrDirectory(true, 'downloads', '/.Trash/f', false, true);
-  checkRemoveFileOrDirectory(true, 'downloads', '/f', true, true);
-}
-
-/**
- * Test permanentlyDeleteFileOrDirectory_().
- *
- * @suppress {accessControls} Access permanentlyDeleteFileOrDirectory_().
- */
-export async function testPermanentlyDeleteFileOrDirectory(done) {
-  const trash = new Trash();
-  const fs = new MockFileSystem('volumeId');
-  const dir = MockDirectoryEntry.create(fs, '/dir');
-  const file1 = MockFileEntry.create(fs, '/dir/file1');
-  MockFileEntry.create(fs, '/dir/file2');
-  MockFileEntry.create(fs, '/dir/file3');
-
-  // Deleted file should be removed and no new files in FileSystem.
-  assertEquals(5, Object.keys(fs.entries).length);
-  assertTrue(!!fs.entries['/dir/file1']);
-  await trash.permanentlyDeleteFileOrDirectory_(file1);
-  assertFalse(!!fs.entries['/dir/file1']);
-  assertEquals(4, Object.keys(fs.entries).length);
-
-  // Deleted dir should also delete all children.
-  assertTrue(!!fs.entries['/dir']);
-  await trash.permanentlyDeleteFileOrDirectory_(dir);
-  assertFalse(!!fs.entries['/dir']);
-  assertFalse(!!fs.entries['/dir/file2']);
-  assertFalse(!!fs.entries['/dir/file3']);
-  assertEquals(1, Object.keys(fs.entries).length);
-
-  done();
-}
-
-/**
- * Test trash in MyFiles.
- */
-export async function testMyFilesTrash(done) {
-  const trash = new Trash();
-  const deletePermanently = false;
-  const downloads = volumeManager.getCurrentProfileVolumeInfo(
-      VolumeManagerCommon.VolumeType.DOWNLOADS);
-  const fs = downloads.fileSystem;
-
-  const dir = MockDirectoryEntry.create(fs, '/dir');
-  const file1 = MockFileEntry.create(fs, '/dir/file1', null, new Blob(['f1']));
-  const file2 = MockFileEntry.create(fs, '/dir/file2', null, new Blob(['f2']));
-  const file3 = MockFileEntry.create(fs, '/dir/file3', null, new Blob(['f3']));
-
-  // Trashed file should be moved to /.Trash/files and new file added in
-  // /.Trash/info.
-  assertEquals(5, Object.keys(fs.entries).length);
-  assertTrue(!!fs.entries['/dir/file1']);
-  await trash.removeFileOrDirectory(volumeManager, file1, deletePermanently);
-  assertFalse(!!fs.entries['/dir/file1']);
-  assertTrue(fs.entries['/.Trash/files'].isDirectory);
-  assertTrue(fs.entries['/.Trash/info'].isDirectory);
-  assertTrue(fs.entries['/.Trash/files/file1'].isFile);
-  assertTrue(fs.entries['/.Trash/info/file1.trashinfo'].isFile);
-  let text = await fs.entries['/.Trash/files/file1'].content.text();
-  assertEquals('f1', text);
-  text = await fs.entries['/.Trash/info/file1.trashinfo'].content.text();
-  assertTrue(text.startsWith('[Trash Info]\nPath=/dir/file1\nDeletionDate='));
-  assertEquals(9, Object.keys(fs.entries).length);
-
-  // Trashed dir should also move children files into /.Trash/files.
-  assertTrue(!!fs.entries['/dir']);
-  await trash.removeFileOrDirectory(volumeManager, dir, deletePermanently);
-  assertFalse(!!fs.entries['/dir']);
-  assertFalse(!!fs.entries['/dir/file2']);
-  assertFalse(!!fs.entries['/dir/file3']);
-  assertTrue(fs.entries['/.Trash/files'].isDirectory);
-  assertTrue(fs.entries['/.Trash/info'].isDirectory);
-  assertTrue(fs.entries['/.Trash/files/dir'].isDirectory);
-  assertTrue(fs.entries['/.Trash/files/dir/file2'].isFile);
-  assertTrue(fs.entries['/.Trash/files/dir/file3'].isFile);
-  text = await fs.entries['/.Trash/files/dir/file2'].content.text();
-  assertEquals('f2', text);
-  text = await fs.entries['/.Trash/files/dir/file3'].content.text();
-  assertEquals('f3', text);
-  assertTrue(fs.entries['/.Trash/info/dir.trashinfo'].isFile);
-  text = await fs.entries['/.Trash/info/dir.trashinfo'].content.text();
-  assertTrue(text.startsWith('[Trash Info]\nPath=/dir\nDeletionDate='));
-  assertEquals(10, Object.keys(fs.entries).length);
-
-  done();
-}
-
-/**
- * Test that Downloads has its own /Downloads/.Trash since it is a separate
- * mount on a device and we don't want move to trash to be a copy operation.
- */
-export async function testDownloadsHasOwnTrash(done) {
-  const trash = new Trash();
-  const deletePermanently = false;
-  const downloads = volumeManager.getCurrentProfileVolumeInfo(
-      VolumeManagerCommon.VolumeType.DOWNLOADS);
-  const fs = downloads.fileSystem;
-  const file1 = MockFileEntry.create(fs, '/file1', null, new Blob(['f1']));
-  const dir2 = MockDirectoryEntry.create(fs, '/Downloads');
-  const file2 =
-      MockFileEntry.create(fs, '/Downloads/file2', null, new Blob(['f2']));
-  const file3 =
-      MockFileEntry.create(fs, '/Downloads/file3', null, new Blob(['f3']));
-  assertEquals(5, Object.keys(fs.entries).length);
-
-  // Move /file1 to trash.
-  await trash.removeFileOrDirectory(volumeManager, file1, deletePermanently);
-  assertTrue(fs.entries['/.Trash'].isDirectory);
-  assertTrue(fs.entries['/.Trash/files'].isDirectory);
-  assertTrue(fs.entries['/.Trash/info'].isDirectory);
-  assertTrue(fs.entries['/.Trash/files/file1'].isFile);
-  assertTrue(fs.entries['/.Trash/info/file1.trashinfo'].isFile);
-  assertEquals(9, Object.keys(fs.entries).length);
-
-  // Move /Downloads/file2 to trash.
-  await trash.removeFileOrDirectory(volumeManager, file2, deletePermanently);
-  assertTrue(fs.entries['/Downloads/.Trash'].isDirectory);
-  assertTrue(fs.entries['/Downloads/.Trash/files'].isDirectory);
-  assertTrue(fs.entries['/Downloads/.Trash/info'].isDirectory);
-  assertTrue(fs.entries['/Downloads/.Trash/files/file2'].isFile);
-  assertTrue(fs.entries['/Downloads/.Trash/info/file2.trashinfo'].isFile);
-  assertEquals(13, Object.keys(fs.entries).length);
-
-  // Delete /Downloads/.Trash/files/file2.
-  const file2Trashed = fs.entries['/Downloads/.Trash/files/file2'];
-  assertFalse(!!trash.shouldMoveToTrash(volumeManager, file2Trashed));
-  await trash.removeFileOrDirectory(
-      volumeManager, file2Trashed, deletePermanently);
-  assertEquals(12, Object.keys(fs.entries).length);
-
-  // Delete /Downloads/.Trash.
-  const downloadsTrash = fs.entries['/Downloads/.Trash'];
-  assertFalse(!!trash.shouldMoveToTrash(volumeManager, downloadsTrash));
-  await trash.removeFileOrDirectory(
-      volumeManager, downloadsTrash, deletePermanently);
-  assertFalse(!!fs.entries['/Downloads/.Trash']);
-  assertEquals(8, Object.keys(fs.entries).length);
-
-  // Move /Downloads/file3 to trash, should recreate /Downloads/.Trash.
-  await trash.removeFileOrDirectory(volumeManager, file3, deletePermanently);
-  assertTrue(fs.entries['/Downloads/.Trash'].isDirectory);
-  assertTrue(fs.entries['/Downloads/.Trash/files'].isDirectory);
-  assertTrue(fs.entries['/Downloads/.Trash/info'].isDirectory);
-  assertTrue(fs.entries['/Downloads/.Trash/files/file3'].isFile);
-  assertTrue(fs.entries['/Downloads/.Trash/info/file3.trashinfo'].isFile);
-  assertEquals(12, Object.keys(fs.entries).length);
-  done();
-}
-
-/**
- * Test restore().
- */
-export async function testRestore(done) {
-  const trash = new Trash();
-  const deletePermanently = false;
-  const downloads = volumeManager.getCurrentProfileVolumeInfo(
-      VolumeManagerCommon.VolumeType.DOWNLOADS);
-  const fs = downloads.fileSystem;
-
-  const dir = MockDirectoryEntry.create(fs, '/dir');
-  const file1 = MockFileEntry.create(fs, '/dir/file1', null, new Blob(['f1']));
-  const file2 = MockFileEntry.create(fs, '/dir/file2', null, new Blob(['f2']));
-  const file3 = MockFileEntry.create(fs, '/dir/file3', null, new Blob(['f3']));
-
-  // Move /dir/file1 to trash.
-  const file1TrashEntry = await trash.removeFileOrDirectory(
-      volumeManager, file1, deletePermanently);
-  assertEquals(9, Object.keys(fs.entries).length);
-  assertFalse(!!fs.entries['/dir/file1']);
-  assertEquals('file1', file1TrashEntry.name);
-  assertEquals(fs.entries['/.Trash/files/file1'], file1TrashEntry.filesEntry);
-  assertEquals(
-      fs.entries['/.Trash/info/file1.trashinfo'], file1TrashEntry.infoEntry);
-
-  // Restore it.
-  await trash.restore(volumeManager, assert(file1TrashEntry));
-  assertEquals(8, Object.keys(fs.entries).length);
-  assertTrue(!!fs.entries['/dir/file1']);
-
-  // Move /dir/file2 to trash, recreate a new /dir/file2,
-  // original should restore to '/dir/file2 (1)'.
-  const file2TrashEntry = await trash.removeFileOrDirectory(
-      volumeManager, file2, deletePermanently);
-  assertFalse(!!fs.entries['/dir/file2']);
-  assertEquals(9, Object.keys(fs.entries).length);
-  MockFileEntry.create(fs, '/dir/file2', null, new Blob(['f2v2']));
-  assertEquals(10, Object.keys(fs.entries).length);
-  await trash.restore(volumeManager, assert(file2TrashEntry));
-  assertEquals(9, Object.keys(fs.entries).length);
-  assertTrue(!!fs.entries['/dir/file2 (1)']);
-  let text = await fs.entries['/dir/file2'].content.text();
-  assertEquals('f2v2', text);
-  text = await fs.entries['/dir/file2 (1)'].content.text();
-  assertEquals('f2', text);
-
-  done();
-}
-
-/**
- * Test removeOldEntries_().
- *
- * @suppress {accessControls} Access removeOldItems_() and inProgress_.
- */
-export async function testRemoveOldItems_(done) {
-  const trash = new Trash();
-  const deletePermanently = false;
-  const downloads = volumeManager.getCurrentProfileVolumeInfo(
-      VolumeManagerCommon.VolumeType.DOWNLOADS);
-  const fs = downloads.fileSystem;
-
-  const dir = MockDirectoryEntry.create(fs, '/dir');
-  const file1 = MockFileEntry.create(fs, '/dir/file1', null, new Blob(['f1']));
-  const file2 = MockFileEntry.create(fs, '/dir/file2', null, new Blob(['f2']));
-  const file3 = MockFileEntry.create(fs, '/dir/file3', null, new Blob(['f3']));
-  const file4 = MockFileEntry.create(fs, '/dir/file4', null, new Blob(['f4']));
-  const file5 = MockFileEntry.create(fs, '/dir/file5', null, new Blob(['f5']));
-  const file6 = MockFileEntry.create(fs, '/dir/file6', null, new Blob(['f6']));
-
-  // Get TrashConfig.
-  const config = trash.shouldMoveToTrash(volumeManager, fs.root);
-  assert(config);
-
-  // Move files to trash.
-  for (const f of [file1, file2, file3, file4, file5, file6]) {
-    await trash.removeFileOrDirectory(volumeManager, f, deletePermanently);
-  }
-  assertEquals(17, Object.keys(fs.entries).length);
-  const now = Date.now();
-
-  // Directories inside info should be deleted.
-  MockDirectoryEntry.create(fs, '/.Trash/info/baddir.trashinfo');
-  // Files that do not end with .trashinfo should be deleted.
-  MockFileEntry.create(fs, '/.Trash/info/f', null, new Blob(['f']));
-  // Files that are write-in-progress with no DeletionDate should be ignored.
-  fs.entries['/.Trash/info/file1.trashinfo'].content =
-      new Blob(['no-deletion-date']);
-  trash.inProgress_.set('downloads-/', new Set(['file1.trashinfo']));
-  delete fs.entries['/.Trash/files/file1'];
-  // Files without a matching file in .Trash/files should be deleted.
-  delete fs.entries['/.Trash/files/file2'];
-  // Files with no DeletionDate should be deleted.
-  fs.entries['/.Trash/info/file3.trashinfo'].content =
-      new Blob(['no-deletion-date']);
-  // Files with DeletionDate which cannot be parsed should be deleted.
-  fs.entries['/.Trash/info/file4.trashinfo'].content =
-      new Blob(['DeletionDate=abc']);
-  // Files with no matching trashinfo should be deleted.
-  delete fs.entries['/.Trash/info/file5.trashinfo'];
-
-  const trashDirs =
-      new TrashDirs(fs.entries['/.Trash/files'], fs.entries['/.Trash/info']);
-  await trash.removeOldItems_(trashDirs, config, now);
-  assertTrue(!!fs.entries['/']);
-  assertTrue(!!fs.entries['/.Trash']);
-  assertTrue(!!fs.entries['/.Trash/files']);
-  assertTrue(!!fs.entries['/.Trash/files/file6']);
-  assertTrue(!!fs.entries['/.Trash/info']);
-  assertTrue(!!fs.entries['/.Trash/info/file1.trashinfo']);
-  assertTrue(!!fs.entries['/.Trash/info/file6.trashinfo']);
-  assertTrue(!!fs.entries['/dir']);
-  assertEquals(8, Object.keys(fs.entries).length);
-
-  // Items older than 30d should be deleted.
-  const daysAgo29 = now + (29 * 24 * 60 * 60 * 1000);
-  const daysAgo31 = now + (31 * 24 * 60 * 60 * 1000);
-  await trash.removeOldItems_(trashDirs, config, daysAgo29);
-  assertEquals(8, Object.keys(fs.entries).length);
-
-  await trash.removeOldItems_(trashDirs, config, daysAgo31);
-  assertTrue(!!fs.entries['/.Trash/info/file1.trashinfo']);
-  assertFalse(!!fs.entries['/.Trash/info/file5.trashinfo']);
-  assertFalse(!!fs.entries['/.Trash/files/file5']);
-  assertEquals(6, Object.keys(fs.entries).length);
-
-  // trashinfo with no matching file, and not in-progress should be deleted.
-  trash.inProgress_.get('downloads-/').delete('file1.trashinfo');
-  await trash.removeOldItems_(trashDirs, config, daysAgo31);
-  assertFalse(!!fs.entries['/.Trash/info/file1.trashinfo']);
-  assertEquals(5, Object.keys(fs.entries).length);
-
-  done();
-}
diff --git a/ui/file_manager/file_manager/common/js/trash.js b/ui/file_manager/file_manager/common/js/trash.js
index 150bdb6..65ae594 100644
--- a/ui/file_manager/file_manager/common/js/trash.js
+++ b/ui/file_manager/file_manager/common/js/trash.js
@@ -25,6 +25,7 @@
 import {parseTrashInfoFiles, startIOTask} from './api.js';
 import {FakeEntryImpl} from './files_app_entry_types.js';
 import {metrics} from './metrics.js';
+import {util} from './util.js';
 import {VolumeManagerCommon} from './volume_manager_types.js';
 
 /**
@@ -133,6 +134,51 @@
 }
 
 /**
+ * Returns true if all entries are on a trashable volume and they aren't already
+ * trashed.
+ * @param {!Array<!Entry>} entries List of entries to verify.
+ * @param {!VolumeManager} volumeManager Volume manager used to get trash
+ *     location URLs.
+ * @returns {boolean} True if all entries can be sent to trash.
+ */
+export function shouldMoveToTrash(entries, volumeManager) {
+  if (!util.isTrashEnabled()) {
+    return false;
+  }
+  const urls = [];
+  for (let i = 0; i < volumeManager.volumeInfoList.length; i++) {
+    const volumeInfo = volumeManager.volumeInfoList.item(i);
+    for (const config of TrashConfig.CONFIG) {
+      if (volumeInfo.volumeType === config.volumeType) {
+        let fileSystemRootURL = volumeInfo.fileSystem.root.toURL();
+        if (fileSystemRootURL.endsWith('/')) {
+          fileSystemRootURL =
+              fileSystemRootURL.substring(0, fileSystemRootURL.length - 1);
+        }
+        const trashURLs = {
+          volume: volumeInfo.fileSystem.root.toURL(),
+          volumeAndTrashPath: fileSystemRootURL + config.trashDir,
+        };
+        urls.push(trashURLs);
+      }
+    }
+  }
+  return entries.every(e => {
+    for (const {volume, volumeAndTrashPath} of urls) {
+      const entryURL = e.toURL();
+      if (!entryURL.startsWith(volume)) {
+        continue;
+      }
+      if (entryURL.startsWith(volumeAndTrashPath)) {
+        return false;
+      }
+      return true;
+    }
+    return false;
+  });
+}
+
+/**
  * Wrapper for /.Trash/files and /.Trash/info directories.
  */
 export class TrashDirs {
@@ -331,32 +377,6 @@
   getNativeEntry() {
     return this.filesEntry;
   }
-
-  /**
-   * Parse Path from info entry text, or null if parse fails.
-   * @param {string} text text of info entry.
-   * @return {?string} path or null if parse fails.
-   */
-  static parsePath(text) {
-    const found = text.match(/^Path=(.*)/m);
-    return found ? found[1] : null;
-  }
-
-  /**
-   * Parse DeletionDate from info entry text, or null if parse fails.
-   * @param {string} text text of info entry.
-   * @return {?Date} deletion date or null if parse fails.
-   */
-  static parseDeletionDate(text) {
-    const found = text.match(/^DeletionDate=(.*)/m);
-    if (found) {
-      const n = Date.parse(found[1]);
-      if (!Number.isNaN(n)) {
-        return new Date(n);
-      }
-    }
-    return null;
-  }
 }
 
 /**
diff --git a/ui/file_manager/file_manager/externs/background/file_operation_manager.js b/ui/file_manager/file_manager/externs/background/file_operation_manager.js
index fe41c9c..23af593 100644
--- a/ui/file_manager/file_manager/externs/background/file_operation_manager.js
+++ b/ui/file_manager/file_manager/externs/background/file_operation_manager.js
@@ -24,15 +24,6 @@
   filterSameDirectoryEntry(sourceEntries, targetEntry, isMove) {}
 
   /**
-   * Returns true if all entries will use trash for delete.
-   *
-   * @param {!VolumeManager} volumeManager
-   * @param {!Array<!Entry>} entries The entries.
-   * @return {boolean}
-   */
-  willUseTrash(volumeManager, entries) {}
-
-  /**
    * Writes file to destination dir.
    *
    * @param {!File} file The file entry to be written.
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
index 9c9fd7f7e..f3ded1d 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager_commands.js
@@ -13,7 +13,7 @@
 import {FileType} from '../../common/js/file_type.js';
 import {EntryList} from '../../common/js/files_app_entry_types.js';
 import {metrics} from '../../common/js/metrics.js';
-import {RestoreFailedType, RestoreFailedTypesUMA, RestoreFailedUMA, TrashEntry} from '../../common/js/trash.js';
+import {RestoreFailedType, RestoreFailedTypesUMA, RestoreFailedUMA, shouldMoveToTrash, TrashEntry} from '../../common/js/trash.js';
 import {str, strf, util} from '../../common/js/util.js';
 import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js';
 import {xfm} from '../../common/js/xfm.js';
@@ -1157,8 +1157,7 @@
 
     // Hide 'move-to-trash' if trash will not be used. E.g. drive or removable.
     if (event.command.id === 'move-to-trash' &&
-        (!fileManager.fileOperationManager.willUseTrash(
-             fileManager.volumeManager, entries) ||
+        (!shouldMoveToTrash(entries, fileManager.volumeManager) ||
          !fileManager.trashEnabled)) {
       event.canExecute = false;
       event.command.setHidden(true);
@@ -1184,10 +1183,10 @@
       return;
     }
 
-    // We show undo toast rather than dialog for entries which will use trash.
+    // Trashing an item shows an "Undo" visual signal instead of a confirmation
+    // dialog.
     if (!permanentlyDelete &&
-        fileManager.fileOperationManager.willUseTrash(
-            fileManager.volumeManager, entries) &&
+        shouldMoveToTrash(entries, fileManager.volumeManager) &&
         fileManager.trashEnabled) {
       fileManager.ui.nudgeContainer.showNudge(NudgeType['TRASH_NUDGE']);
 
diff --git a/ui/file_manager/file_names.gni b/ui/file_manager/file_names.gni
index abab961..8f0413dd 100644
--- a/ui/file_manager/file_names.gni
+++ b/ui/file_manager/file_names.gni
@@ -35,7 +35,6 @@
   "file_manager/background/js/runtime_loaded_test_util.js",
   "file_manager/background/js/test_util.js",
   "file_manager/background/js/test_util_base.js",
-  "file_manager/background/js/trash.js",
   "file_manager/background/js/volume_info_impl.js",
   "file_manager/background/js/volume_info_list_impl.js",
   "file_manager/background/js/volume_manager_factory.js",
@@ -401,7 +400,6 @@
   "file_manager/background/js/drive_sync_handler_unittest.js",
   "file_manager/background/js/file_operation_handler_unittest.js",
   "file_manager/background/js/file_operation_manager_unittest.js",
-  "file_manager/background/js/trash_unittest.js",
   "file_manager/background/js/volume_manager_unittest.js",
   "file_manager/background/js/crostini_unittest.js",
 
diff --git a/ui/file_manager/integration_tests/file_manager/guest_os.js b/ui/file_manager/integration_tests/file_manager/guest_os.js
index b3e7128..b76249e 100644
--- a/ui/file_manager/integration_tests/file_manager/guest_os.js
+++ b/ui/file_manager/integration_tests/file_manager/guest_os.js
@@ -8,26 +8,6 @@
 import {IGNORE_APP_ERRORS, remoteCall, setupAndWaitUntilReady} from './background.js';
 
 /**
- * Tests that Guest OS entries don't show up if the flag controlling guest os +
- * files app integration is disabled.
- */
-testcase.notListedWithoutFlag = async () => {
-  // Prepopulate the list with a bunch of guests.
-  const names = ['Electra', 'Etcetera', 'Jemima'];
-  for (const name of names) {
-    await sendTestMessage({name: 'registerMountableGuest', displayName: name});
-  }
-
-  // Open the files app.
-  const appId =
-      await setupAndWaitUntilReady(RootPath.DOWNLOADS, [ENTRIES.hello], []);
-
-  // Check that we have no Guest OS entries.
-  const query = '#directory-tree [root-type-icon=bruschetta]';
-  await remoteCall.waitForElementsCount(appId, [query], 0);
-};
-
-/**
  * Tests that Guest OS entries show up in the sidebar at files app launch.
  */
 testcase.fakesListed = async () => {
diff --git a/ui/file_manager/integration_tests/file_manager/quick_view.js b/ui/file_manager/integration_tests/file_manager/quick_view.js
index 55275aa..b96e084a 100644
--- a/ui/file_manager/integration_tests/file_manager/quick_view.js
+++ b/ui/file_manager/integration_tests/file_manager/quick_view.js
@@ -6,7 +6,7 @@
 
 import {DialogType} from '../dialog_type.js';
 import {ExecuteScriptError} from '../remote_call.js';
-import {addEntries, ENTRIES, EntryType, getCaller, getHistogramCount, pending, repeatUntil, RootPath, sendTestMessage, TestEntryInfo, wait} from '../test_util.js';
+import {addEntries, ENTRIES, EntryType, getCaller, getHistogramCount, pending, repeatUntil, RootPath, sanitizeDate, sendTestMessage, TestEntryInfo, wait} from '../test_util.js';
 import {testcase} from '../testcase.js';
 
 import {mountCrostini, mountGuestOs, navigateWithDirectoryTree, openNewWindow, remoteCall, setupAndWaitUntilReady} from './background.js';
@@ -339,7 +339,11 @@
   }
 
   const element = await remoteCall.waitForElement(appId, quickViewQuery);
-  return element.text;
+  if (name === 'Date modified') {
+    return sanitizeDate(element.text || '');
+  } else {
+    return element.text;
+  }
 }
 
 /**
diff --git a/ui/file_manager/integration_tests/file_manager/recents.js b/ui/file_manager/integration_tests/file_manager/recents.js
index d1b7d17..e1b5b41 100644
--- a/ui/file_manager/integration_tests/file_manager/recents.js
+++ b/ui/file_manager/integration_tests/file_manager/recents.js
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-import {addEntries, ENTRIES, getCaller, getDateWithDayDiff, pending, repeatUntil, RootPath, sendTestMessage, TestEntryInfo} from '../test_util.js';
+import {addEntries, ENTRIES, formatDate, getCaller, getDateWithDayDiff, pending, repeatUntil, RootPath, sanitizeDate, sendTestMessage, TestEntryInfo} from '../test_util.js';
 import {testcase} from '../testcase.js';
 
 import {mountCrostini, navigateWithDirectoryTree, openNewWindow, remoteCall, setupAndWaitUntilReady} from './background.js';
@@ -1077,7 +1077,7 @@
   const nowDate = new Date();
   nowDate.setHours(1, 0, 0, 0);
   // Format: "May 2, 2021, 11:25 AM GMT+1000"
-  const modifiedDate = nowDate.toLocaleString('default', {
+  const modifiedDate = sanitizeDate(nowDate.toLocaleString('default', {
     month: 'short',
     day: 'numeric',
     year: 'numeric',
@@ -1086,7 +1086,7 @@
     minute: 'numeric',
     timeZone: timezone,
     timeZoneName: 'longOffset',
-  });
+  }));
   return ENTRIES.beautiful.cloneWithModifiedDate(modifiedDate);
 }
 
diff --git a/ui/file_manager/integration_tests/test_util.js b/ui/file_manager/integration_tests/test_util.js
index 96810044..a0002c1 100644
--- a/ui/file_manager/integration_tests/test_util.js
+++ b/ui/file_manager/integration_tests/test_util.js
@@ -1689,12 +1689,28 @@
   const nowDate = new Date();
   nowDate.setDate(nowDate.getDate() - diffDays);
   // Format: "May 2, 2021, 11:25 AM"
-  return nowDate.toLocaleString('default', {
+  return formatDate(nowDate);
+}
+
+/**
+ * Formats the date to be able to compare to Files app date.
+ */
+export function formatDate(date) {
+  return sanitizeDate(date.toLocaleString('default', {
     month: 'short',
     day: 'numeric',
     year: 'numeric',
     hour12: true,
     hour: 'numeric',
     minute: 'numeric',
-  });
+  }));
+}
+
+/**
+ * Sanitizes the formatted date. Replaces unusual space with normal space.
+ * @param {string} strDate the date already in the string format.
+ * @return {string}
+ */
+export function sanitizeDate(strDate) {
+  return strDate.replace('\u202f', ' ');
 }
diff --git a/ui/ozone/platform/wayland/host/wayland_event_source.cc b/ui/ozone/platform/wayland/host/wayland_event_source.cc
index d7016431..eb443177 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_source.cc
+++ b/ui/ozone/platform/wayland/host/wayland_event_source.cc
@@ -99,7 +99,7 @@
   TouchPoint(gfx::PointF location, WaylandWindow* current_window);
   ~TouchPoint() = default;
 
-  raw_ptr<WaylandWindow> window;
+  raw_ptr<WaylandWindow, DanglingUntriaged> window;
   gfx::PointF last_known_location;
 };
 
diff --git a/ui/ozone/platform/wayland/host/wayland_event_watcher_unittest.cc b/ui/ozone/platform/wayland/host/wayland_event_watcher_unittest.cc
index 4091977..60065836 100644
--- a/ui/ozone/platform/wayland/host/wayland_event_watcher_unittest.cc
+++ b/ui/ozone/platform/wayland/host/wayland_event_watcher_unittest.cc
@@ -10,6 +10,7 @@
 #include "base/nix/xdg_util.h"
 #include "base/strings/strcat.h"
 #include "base/strings/utf_string_conversions.h"
+#include "base/test/bind.h"
 #include "components/crash/core/common/crash_key.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/ozone/platform/wayland/test/mock_surface.h"
@@ -28,48 +29,77 @@
 
 }  // namespace
 
+// Tests that various types of critical errors result in correct crash keys.
+//
+// Posting the error terminates the client-server connection.  Further attempts
+// to sync will hang.  That is why we run "bare" lambdas in all tests of this
+// suite instead of using `PostToServerAndWait()`: that helper syncs the
+// connection after running the server task.  Due to the same reason we disable
+// the sync on the test tear down.
 class WaylandEventWatcherTest : public WaylandTest {
  public:
-  WaylandEventWatcherTest() = default;
+  WaylandEventWatcherTest() : WaylandTest(TestServerMode::kAsync) {}
+  WaylandEventWatcherTest(const WaylandEventWatcherTest&) = delete;
+  WaylandEventWatcherTest& operator=(const WaylandEventWatcherTest&) = delete;
+  ~WaylandEventWatcherTest() override = default;
+
+ protected:
+  void TearDown() override {
+    // All tests in this suite terminate the client-server connection by posting
+    // various errors.  We cannot sync the connection on tear down.
+    DisableSyncOnTearDown();
+
+    WaylandTest::TearDown();
+  }
 };
 
 TEST_P(WaylandEventWatcherTest, CrashKeyResourceError) {
   const std::string kTestErrorString = "This is a nice error.";
-  auto* mock_surface = server_.GetObject<wl::MockSurface>(
-      window_->root_surface()->get_surface_id());
-  auto* xdg_surface = mock_surface->xdg_surface();
 
-  // Prepare the expectation error string.
-  const std::string expected_error_code =
-      base::StrCat({wl_resource_get_class(xdg_surface->resource()), ": error ",
-                    NumberToString(static_cast<uint32_t>(
-                        XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER)),
-                    ": ", kTestErrorString});
+  std::string text;
+  auto callback = base::BindLambdaForTesting(
+      [&text](const std::string& data) { text = data; });
 
-  wl_resource_post_error(xdg_surface->resource(),
-                         XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER, "%s",
-                         kTestErrorString.c_str());
+  server_.RunAndWait(base::BindLambdaForTesting(
+      [&kTestErrorString, callback,
+       surface_id = window_->root_surface()->get_surface_id()](
+          wl::TestWaylandServerThread* server) {
+        auto* const xdg_surface = server->GetObject<wl::MockSurface>(surface_id)
+                                      ->xdg_surface()
+                                      ->resource();
 
-  Sync();
+        // Prepare the expectation error string.
+        const std::string expected_error_code =
+            base::StrCat({wl_resource_get_class(xdg_surface), ": error ",
+                          NumberToString(static_cast<uint32_t>(
+                              XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER)),
+                          ": ", kTestErrorString});
 
-  EXPECT_EQ(expected_error_code,
-            crash_reporter::GetCrashKeyValue("wayland_error"));
+        callback.Run(expected_error_code);
+        wl_resource_post_error(xdg_surface,
+                               XDG_SURFACE_ERROR_UNCONFIGURED_BUFFER, "%s",
+                               kTestErrorString.c_str());
+      }));
+
+  EXPECT_EQ(text, crash_reporter::GetCrashKeyValue("wayland_error"));
 }
 
 TEST_P(WaylandEventWatcherTest, CrashKeyResourceNoMemory) {
-  auto* mock_surface = server_.GetObject<wl::MockSurface>(
-      window_->root_surface()->get_surface_id());
-  auto* xdg_surface = mock_surface->xdg_surface();
-
   // Prepare the expectation error string.
   const std::string expected_error_code = base::StrCat(
       {"wl_display: error ",
        NumberToString(static_cast<uint32_t>(WL_DISPLAY_ERROR_NO_MEMORY)),
        ": no memory"});
 
-  wl_resource_post_no_memory(xdg_surface->resource());
+  server_.RunAndWait(base::BindLambdaForTesting(
+      [surface_id = window_->root_surface()->get_surface_id()](
+          wl::TestWaylandServerThread* server) {
+        auto* const xdg_surface = server->GetObject<wl::MockSurface>(surface_id)
+                                      ->xdg_surface()
+                                      ->resource();
 
-  Sync();
+        wl_resource_post_no_memory(xdg_surface);
+      }));
 
   EXPECT_EQ(expected_error_code,
             crash_reporter::GetCrashKeyValue("wayland_error"));
@@ -81,9 +111,10 @@
        NumberToString(static_cast<uint32_t>(WL_DISPLAY_ERROR_NO_MEMORY)),
        ": no memory"});
 
-  wl_client_post_no_memory(server_.client());
-
-  Sync();
+  server_.RunAndWait(
+      base::BindLambdaForTesting([](wl::TestWaylandServerThread* server) {
+        wl_client_post_no_memory(server->client());
+      }));
 
   EXPECT_EQ(expected_error_code,
             crash_reporter::GetCrashKeyValue("wayland_error"));
@@ -96,9 +127,11 @@
        NumberToString(static_cast<uint32_t>(WL_DISPLAY_ERROR_IMPLEMENTATION)),
        ": ", kError});
 
-  wl_client_post_implementation_error(server_.client(), "%s", kError.c_str());
-
-  Sync();
+  server_.RunAndWait(base::BindLambdaForTesting(
+      [&kError](wl::TestWaylandServerThread* server) {
+        wl_client_post_implementation_error(server->client(), "%s",
+                                            kError.c_str());
+      }));
 
   EXPECT_EQ(expected_error_code,
             crash_reporter::GetCrashKeyValue("wayland_error"));
@@ -109,8 +142,11 @@
   base::Environment::Create()->SetVar(base::nix::kXdgCurrentDesktopEnvVar,
                                       kTestWaylandCompositor);
 
-  wl_client_post_implementation_error(server_.client(), "%s", "stub error");
-  Sync();
+  server_.RunAndWait(
+      base::BindLambdaForTesting([](wl::TestWaylandServerThread* server) {
+        wl_client_post_implementation_error(server->client(), "%s",
+                                            "stub error");
+      }));
 
   EXPECT_EQ(kTestWaylandCompositor,
             crash_reporter::GetCrashKeyValue("wayland_compositor"));
@@ -119,8 +155,11 @@
 TEST_P(WaylandEventWatcherTest, CrashKeyCompositorNameUnset) {
   base::Environment::Create()->UnSetVar(base::nix::kXdgCurrentDesktopEnvVar);
 
-  wl_client_post_implementation_error(server_.client(), "%s", "stub error");
-  Sync();
+  server_.RunAndWait(
+      base::BindLambdaForTesting([](wl::TestWaylandServerThread* server) {
+        wl_client_post_implementation_error(server->client(), "%s",
+                                            "stub error");
+      }));
 
   EXPECT_EQ("Unknown", crash_reporter::GetCrashKeyValue("wayland_compositor"));
 }
diff --git a/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc b/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc
index 09860209..96c044df 100644
--- a/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc
+++ b/ui/ozone/platform/wayland/host/wayland_window_manager_unittests.cc
@@ -5,6 +5,7 @@
 #include "base/memory/raw_ptr.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/ozone/platform/wayland/host/wayland_output.h"
+#include "ui/ozone/platform/wayland/host/wayland_seat.h"
 #include "ui/ozone/platform/wayland/test/mock_pointer.h"
 #include "ui/ozone/platform/wayland/test/mock_surface.h"
 #include "ui/ozone/platform/wayland/test/test_keyboard.h"
@@ -23,9 +24,10 @@
 
 class WaylandWindowManagerTest : public WaylandTest {
  public:
-  WaylandWindowManagerTest() {}
+  WaylandWindowManagerTest() : WaylandTest(TestServerMode::kAsync) {}
   WaylandWindowManagerTest(const WaylandWindowManagerTest&) = delete;
   WaylandWindowManagerTest& operator=(const WaylandWindowManagerTest&) = delete;
+  ~WaylandWindowManagerTest() override = default;
 
   void SetUp() override {
     WaylandTest::SetUp();
@@ -86,42 +88,48 @@
 TEST_P(WaylandWindowManagerTest, GetCurrentFocusedWindow) {
   MockPlatformWindowDelegate delegate;
 
-  wl_seat_send_capabilities(server_.seat()->resource(),
-                            WL_SEAT_CAPABILITY_POINTER);
-
-  Sync();
+  PostToServerAndWait([](wl::TestWaylandServerThread* server) {
+    wl_seat_send_capabilities(server->seat()->resource(),
+                              WL_SEAT_CAPABILITY_POINTER);
+  });
+  ASSERT_TRUE(connection_->seat()->pointer());
 
   auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
                                                kDefaultBounds, &delegate);
   // When window is shown, it automatically gets keyboard focus. Reset it.
   connection_->wayland_window_manager()->SetKeyboardFocusedWindow(nullptr);
 
-  Sync();
+  SyncDisplay();
 
   EXPECT_FALSE(manager_->GetCurrentFocusedWindow());
+  EXPECT_FALSE(manager_->GetCurrentKeyboardFocusedWindow());
   EXPECT_FALSE(manager_->GetCurrentPointerOrTouchFocusedWindow());
   EXPECT_FALSE(manager_->GetCurrentPointerFocusedWindow());
 
-  auto* pointer = server_.seat()->pointer();
-  ASSERT_TRUE(pointer);
+  PostToServerAndWait([surface_id = window1->root_surface()->get_surface_id()](
+                          wl::TestWaylandServerThread* server) {
+    auto* const pointer = server->seat()->pointer()->resource();
+    auto* const surface =
+        server->GetObject<wl::MockSurface>(surface_id)->resource();
 
-  wl::MockSurface* surface = server_.GetObject<wl::MockSurface>(
-      window1->root_surface()->get_surface_id());
-  wl_pointer_send_enter(pointer->resource(), 1, surface->resource(), 0, 0);
-  wl_pointer_send_frame(pointer->resource());
-
-  Sync();
+    wl_pointer_send_enter(pointer, server->GetNextSerial(), surface, 0, 0);
+    wl_pointer_send_frame(pointer);
+  });
 
   EXPECT_FALSE(manager_->GetCurrentKeyboardFocusedWindow());
-  EXPECT_TRUE(window1.get() == manager_->GetCurrentFocusedWindow());
-  EXPECT_TRUE(window1.get() ==
-              manager_->GetCurrentPointerOrTouchFocusedWindow());
-  EXPECT_TRUE(window1.get() == manager_->GetCurrentPointerFocusedWindow());
+  EXPECT_EQ(window1.get(), manager_->GetCurrentFocusedWindow());
+  EXPECT_EQ(window1.get(), manager_->GetCurrentPointerOrTouchFocusedWindow());
+  EXPECT_EQ(window1.get(), manager_->GetCurrentPointerFocusedWindow());
 
-  wl_pointer_send_leave(pointer->resource(), 2, surface->resource());
-  wl_pointer_send_frame(pointer->resource());
+  PostToServerAndWait([surface_id = window1->root_surface()->get_surface_id()](
+                          wl::TestWaylandServerThread* server) {
+    auto* const pointer = server->seat()->pointer()->resource();
+    auto* const surface =
+        server->GetObject<wl::MockSurface>(surface_id)->resource();
 
-  Sync();
+    wl_pointer_send_leave(pointer, server->GetNextSerial(), surface);
+    wl_pointer_send_frame(pointer);
+  });
 
   EXPECT_FALSE(manager_->GetCurrentFocusedWindow());
   EXPECT_FALSE(manager_->GetCurrentPointerOrTouchFocusedWindow());
@@ -131,39 +139,44 @@
 TEST_P(WaylandWindowManagerTest, GetCurrentKeyboardFocusedWindow) {
   MockPlatformWindowDelegate delegate;
 
-  wl_seat_send_capabilities(server_.seat()->resource(),
-                            WL_SEAT_CAPABILITY_KEYBOARD);
-
-  Sync();
+  PostToServerAndWait([](wl::TestWaylandServerThread* server) {
+    wl_seat_send_capabilities(server->seat()->resource(),
+                              WL_SEAT_CAPABILITY_KEYBOARD);
+  });
+  ASSERT_TRUE(connection_->seat()->keyboard());
 
   auto window1 = CreateWaylandWindowWithParams(PlatformWindowType::kWindow,
                                                kDefaultBounds, &delegate);
   // When window is shown, it automatically gets keyboard focus. Reset it.
   connection_->wayland_window_manager()->SetKeyboardFocusedWindow(nullptr);
 
-  Sync();
+  SyncDisplay();
 
   EXPECT_FALSE(manager_->GetCurrentKeyboardFocusedWindow());
 
-  auto* keyboard = server_.seat()->keyboard();
-  ASSERT_TRUE(keyboard);
+  PostToServerAndWait([surface_id = window1->root_surface()->get_surface_id()](
+                          wl::TestWaylandServerThread* server) {
+    auto* const keyboard = server->seat()->keyboard()->resource();
+    auto* const surface =
+        server->GetObject<wl::MockSurface>(surface_id)->resource();
 
-  wl::MockSurface* surface = server_.GetObject<wl::MockSurface>(
-      window1->root_surface()->get_surface_id());
-
-  struct wl_array empty;
-  wl_array_init(&empty);
-  wl_keyboard_send_enter(keyboard->resource(), 1, surface->resource(), &empty);
-
-  Sync();
+    wl::ScopedWlArray empty({});
+    wl_keyboard_send_enter(keyboard, server->GetNextSerial(), surface,
+                           empty.get());
+  });
 
   EXPECT_FALSE(manager_->GetCurrentPointerOrTouchFocusedWindow());
-  EXPECT_TRUE(window1.get() == manager_->GetCurrentFocusedWindow());
-  EXPECT_TRUE(window1.get() == manager_->GetCurrentKeyboardFocusedWindow());
+  EXPECT_EQ(window1.get(), manager_->GetCurrentFocusedWindow());
+  EXPECT_EQ(window1.get(), manager_->GetCurrentKeyboardFocusedWindow());
 
-  wl_keyboard_send_leave(keyboard->resource(), 2, surface->resource());
+  PostToServerAndWait([surface_id = window1->root_surface()->get_surface_id()](
+                          wl::TestWaylandServerThread* server) {
+    auto* const keyboard = server->seat()->keyboard()->resource();
+    auto* const surface =
+        server->GetObject<wl::MockSurface>(surface_id)->resource();
 
-  Sync();
+    wl_keyboard_send_leave(keyboard, server->GetNextSerial(), surface);
+  });
 
   EXPECT_FALSE(manager_->GetCurrentKeyboardFocusedWindow());
 }
diff --git a/ui/ozone/platform/wayland/test/wayland_test.cc b/ui/ozone/platform/wayland/test/wayland_test.cc
index 6d893c7..8d8c324 100644
--- a/ui/ozone/platform/wayland/test/wayland_test.cc
+++ b/ui/ozone/platform/wayland/test/wayland_test.cc
@@ -151,6 +151,10 @@
   SyncDisplay();
 }
 
+void WaylandTest::DisableSyncOnTearDown() {
+  initialized_ = false;
+}
+
 void WaylandTest::SetPointerFocusedWindow(WaylandWindow* window) {
   connection_->wayland_window_manager()->SetPointerFocusedWindow(window);
 }
diff --git a/ui/ozone/platform/wayland/test/wayland_test.h b/ui/ozone/platform/wayland/test/wayland_test.h
index f41bd95..dd0134b 100644
--- a/ui/ozone/platform/wayland/test/wayland_test.h
+++ b/ui/ozone/platform/wayland/test/wayland_test.h
@@ -83,6 +83,10 @@
   }
 
  protected:
+  // Disables client-server sync during the teardown.  Used by tests that
+  // intentionally spoil the client-server communication.
+  void DisableSyncOnTearDown();
+
   void SetPointerFocusedWindow(WaylandWindow* window);
   void SetKeyboardFocusedWindow(WaylandWindow* window);