diff --git a/.vpython3 b/.vpython3
index cf8d313..afdb00e 100644
--- a/.vpython3
+++ b/.vpython3
@@ -343,7 +343,7 @@
 >
 wheel: <
   name: "infra/python/wheels/aioquic/${vpython_platform}"
-  version: "version:0.9.15"
+  version: "version:0.9.20.chromium.1"
 >
 wheel: <
   name: "infra/python/wheels/pylsqpack/${vpython_platform}"
@@ -573,7 +573,7 @@
 >
 wheel: <
   name: "infra/python/wheels/pyopenssl-py2_py3"
-  version: "version:19.0.0"
+  version: "version:20.0.0"
 >
 
 # Used by //tools/md_browser to render Markdown.
diff --git a/DEPS b/DEPS
index d5aae1f..5abe717 100644
--- a/DEPS
+++ b/DEPS
@@ -304,11 +304,11 @@
   # 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': '4d02e783654f2d8dda1b1d62e24a63bf6747f782',
+  'skia_revision': '4ca827754bc1df03a5845f11e9aecce57470a44e',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling V8
   # and whatever else without interference from each other.
-  'v8_revision': '5f3e79483b2aa400469f4562321d00c874e300e8',
+  'v8_revision': '99f2989b243a99f961b0de891b51f74542aaecbc',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling ANGLE
   # and whatever else without interference from each other.
@@ -391,7 +391,7 @@
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling devtools-frontend
   # and whatever else without interference from each other.
-  'devtools_frontend_revision': 'e24710d614f3f16412444484e1f64b4439b965d8',
+  'devtools_frontend_revision': '22507bc198a16eb9509bce5c5e381ed69ca79912',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling libprotobuf-mutator
   # and whatever else without interference from each other.
@@ -467,7 +467,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.
-  'cros_components_revision': '89fbccea0f10557c413a6b738b080d949558f98c',
+  'cros_components_revision': 'e8f7d0cc3350e2554e86edd7bebc6313f018e25c',
   # Three lines of non-changing comments so that
   # the commit queue can handle CLs rolling feed
   # and whatever else without interference from each other.
@@ -504,6 +504,10 @@
   # https://chrome-infra-packages.appspot.com/p/infra/3pp/tools/ninja
   # This has to stay in sync with the version in src/third_party/ninja/README.chromium.
   'ninja_version': 'version:2@1.11.1.chromium.6',
+
+  # Used for src-internal deps into src migration.
+  # TODO(1409738): Remove this post migration.
+  'checkout_chromeos_assistant': False,
 }
 
 # Only these hosts are allowed for dependencies in this DEPS file.
@@ -790,7 +794,7 @@
 
   'src/clank': {
     'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' +
-    '42af8144c4d7e1a21248b51ff91ba232487a5598',
+    'd1a26064079efd7b4bc90871eed5b35a19a19423',
     'condition': 'checkout_android and checkout_src_internal',
   },
 
@@ -979,7 +983,7 @@
     'packages': [
       {
           'package': 'chromium/third_party/androidx',
-          'version': 'QPqCY3deY_Lq8R2HBZPqbHd4iApiVuEsI2VBdGzi3VUC',
+          'version': '1j00hDfcV8VMhu7wcLzPRN_BjaAn5940aefYoIPYUYgC',
       },
     ],
     'condition': 'checkout_android',
@@ -1236,7 +1240,7 @@
     Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'),
 
   'src/third_party/devtools-frontend-internal': {
-      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '658a36d0b36f3594824ab614126937dfe82c1cb0',
+      'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'b9c635e3e4cbb50994c4ec21677f8850b9e7f26e',
     'condition': 'checkout_src_internal',
   },
 
@@ -1702,7 +1706,7 @@
   },
 
   'src/third_party/perfetto':
-    Var('android_git') + '/platform/external/perfetto.git' + '@' + '1c8b4fe31582532ffa4967f46d708e971a662c43',
+    Var('android_git') + '/platform/external/perfetto.git' + '@' + '01c4b0e3e49fb99f7c00ff96bf9c5a244be52562',
 
   'src/third_party/perl': {
       'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3',
@@ -1742,7 +1746,7 @@
       'packages': [
           {
               'package': 'chromium/third_party/r8',
-              'version': 'uKXfzLPZnqaH-VIthzomHhqKZXkBEDRnpDLViS2yXSkC',
+              'version': 'BTs9W6pUBDK8YTePjjF3Q0-ZQo1snO7GBCT6frWMIj8C',
           },
       ],
       'condition': 'checkout_android',
@@ -1887,7 +1891,7 @@
     Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '904c74af6fee0530ce33434974aa0df6316fdef1',
 
   'src/third_party/webrtc':
-    Var('webrtc_git') + '/src.git' + '@' + '1063e30df88649f321c7072c27db189e81a6d58c',
+    Var('webrtc_git') + '/src.git' + '@' + '7bb9322e9ea2ae90fb11101a58cda6aebaedbd51',
 
   # 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.
@@ -1964,7 +1968,7 @@
     Var('chromium_git') + '/v8/v8.git' + '@' +  Var('v8_revision'),
 
   'src-internal': {
-    'url': Var('chrome_git') + '/chrome/src-internal.git@33e704f835fab296771a93bff24f224cbbad9688',
+    'url': Var('chrome_git') + '/chrome/src-internal.git@a01ce548b397143dd01f0e64e5efaf89587fc9f2',
     'condition': 'checkout_src_internal',
   },
 
@@ -2016,7 +2020,7 @@
     'packages': [
       {
         'package': 'chromeos_internal/apps/projector_app/app',
-        'version': 'FRWLTfoJNsRlr_d-rX0Ef2sMf9AvB3rTpNPb-mfOts0C',
+        'version': 'iur9WcgDC2QZq2awVp1NybKu9W449sGwfG332Bz2ER8C',
       },
     ],
     'condition': 'checkout_chromeos and checkout_src_internal',
@@ -3918,6 +3922,23 @@
     'dep_type': 'cipd',
     'condition': 'checkout_win and checkout_bazel',
   },
+
+  # Dependencies from src_internal
+  'src/chromeos/assistant/internal': {
+      'url': Var('chrome_git') + '/chrome/assistant.git' + '@' +
+        '89ad232d3c9b60b50348c4a2ff383b72e478fc17',
+      'condition': 'checkout_src_internal and checkout_chromeos',
+    },
+
+  'src/chromeos/assistant/libassistant/src': {
+      'url': Var('chrome_git') + '/external/gob/libassistant-internal/standalone/src.git' + '@' + '7e8a91342977bbcac4536afdee7af96ab45e51f3',
+      'condition': 'checkout_src_internal and checkout_chromeos',
+  },
+
+  'src/libassistant': {
+      'url': Var('chrome_git') + '/chrome/libassistant.git' + '@' + 'fe0ef57f250510e890fc01e1b6c7da7b59117603',
+      'condition': 'checkout_src_internal and checkout_chromeos',
+  },
 }
 
 
@@ -5101,4 +5122,7 @@
   # clank has its own DEPS file, does not need to be in trybot_analyze_config
   # since the roller does not run tests.
   'src/clank',
+  'src/chromeos/assistant/internal',
+  'src/chromeos/assistant/libassistant/src',
+  'src/libassistant',
 ]
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc
index 8aa5bcfe..c31a628 100644
--- a/ash/login/login_screen_controller.cc
+++ b/ash/login/login_screen_controller.cc
@@ -480,13 +480,6 @@
   client_->FocusOobeDialog();
 }
 
-void LoginScreenController::NotifyUserActivity() {
-  if (!client_) {
-    return;
-  }
-  client_->OnUserActivity();
-}
-
 void LoginScreenController::OnAuthenticateComplete(
     OnAuthenticateCallback callback,
     bool success) {
diff --git a/ash/login/login_screen_controller.h b/ash/login/login_screen_controller.h
index 5d3a832..3215a2f8 100644
--- a/ash/login/login_screen_controller.h
+++ b/ash/login/login_screen_controller.h
@@ -100,7 +100,6 @@
   void ShowParentAccessHelpApp();
   void ShowLockScreenNotificationSettings();
   void FocusOobeDialog();
-  void NotifyUserActivity();
 
   // Enable or disable authentication for the debug overlay.
   enum class ForceFailAuth { kOff, kImmediate, kDelayed };
diff --git a/ash/login/mock_login_screen_client.h b/ash/login/mock_login_screen_client.h
index f1f402a..8ebd79c 100644
--- a/ash/login/mock_login_screen_client.h
+++ b/ash/login/mock_login_screen_client.h
@@ -113,7 +113,6 @@
   MOCK_METHOD(void, ShowLockScreenNotificationSettings, (), (override));
   MOCK_METHOD(void, FocusOobeDialog, (), (override));
   MOCK_METHOD(void, OnFocusLeavingSystemTray, (bool reverse), (override));
-  MOCK_METHOD(void, OnUserActivity, (), (override));
   MOCK_METHOD(void, OnLoginScreenShown, (), (override));
   MOCK_METHOD(void, OnSystemTrayBubbleShown, (), (override));
   MOCK_METHOD(views::Widget*, GetLoginWindowWidget, (), (override));
diff --git a/ash/login/ui/lock_contents_view.cc b/ash/login/ui/lock_contents_view.cc
index 6a0533d1..91d6961b 100644
--- a/ash/login/ui/lock_contents_view.cc
+++ b/ash/login/ui/lock_contents_view.cc
@@ -304,30 +304,6 @@
 
 }  // namespace
 
-class LockContentsView::AutoLoginUserActivityHandler
-    : public ui::UserActivityObserver {
- public:
-  AutoLoginUserActivityHandler() {
-    observation_.Observe(ui::UserActivityDetector::Get());
-  }
-
-  AutoLoginUserActivityHandler(const AutoLoginUserActivityHandler&) = delete;
-  AutoLoginUserActivityHandler& operator=(const AutoLoginUserActivityHandler&) =
-      delete;
-
-  ~AutoLoginUserActivityHandler() override = default;
-
-  void OnUserActivity(const ui::Event* event) override {
-    if (Shell::Get()->login_screen_controller()) {
-      Shell::Get()->login_screen_controller()->NotifyUserActivity();
-    }
-  }
-
- private:
-  base::ScopedObservation<ui::UserActivityDetector, ui::UserActivityObserver>
-      observation_{this};
-};
-
 // static
 const int LockContentsView::kLoginAttemptsBeforeGaiaDialog = 4;
 
@@ -340,11 +316,6 @@
       screen_type_(screen_type),
       data_dispatcher_(data_dispatcher),
       detachable_base_model_(std::move(detachable_base_model)) {
-  if (screen_type == LockScreen::ScreenType::kLogin) {
-    auto_login_user_activity_handler_ =
-        std::make_unique<AutoLoginUserActivityHandler>();
-  }
-
   data_dispatcher_->AddObserver(this);
   Shell::Get()->system_tray_notifier()->AddSystemTrayObserver(this);
   keyboard::KeyboardUIController::Get()->AddObserver(this);
diff --git a/ash/login/ui/lock_contents_view.h b/ash/login/ui/lock_contents_view.h
index 4ed71308..b5be7fba 100644
--- a/ash/login/ui/lock_contents_view.h
+++ b/ash/login/ui/lock_contents_view.h
@@ -236,8 +236,6 @@
   bool AreMediaControlsEnabled() const;
 
  private:
-  class AutoLoginUserActivityHandler;
-
   using DisplayLayoutAction = base::RepeatingCallback<void(bool landscape)>;
 
   // Focus the next/previous widget.
@@ -536,11 +534,6 @@
   // Accelerators handled by login screen.
   std::map<ui::Accelerator, LoginAcceleratorAction> accel_map_;
 
-  // Notifies Chrome when user activity is detected on the login screen so that
-  // the auto-login timer can be reset.
-  std::unique_ptr<AutoLoginUserActivityHandler>
-      auto_login_user_activity_handler_;
-
   BottomIndicatorState bottom_status_indicator_state_ =
       BottomIndicatorState::kNone;
 
diff --git a/ash/public/cpp/login_screen_client.h b/ash/public/cpp/login_screen_client.h
index a90d27e..83196a4 100644
--- a/ash/public/cpp/login_screen_client.h
+++ b/ash/public/cpp/login_screen_client.h
@@ -162,9 +162,6 @@
   // Called when the lock screen is shown.
   virtual void OnLoginScreenShown() = 0;
 
-  // Used by Ash to signal that user activity occurred on the login screen.
-  virtual void OnUserActivity() = 0;
-
   // Get login screen widget. Currently used to set proper accessibility
   // navigation.
   virtual views::Widget* GetLoginWindowWidget() = 0;
diff --git a/ash/style/dark_light_mode_controller_impl.cc b/ash/style/dark_light_mode_controller_impl.cc
index c254a0f..cb75246 100644
--- a/ash/style/dark_light_mode_controller_impl.cc
+++ b/ash/style/dark_light_mode_controller_impl.cc
@@ -52,14 +52,10 @@
   native_theme->NotifyOnNativeThemeUpdated();
 
   auto* native_theme_web = ui::NativeTheme::GetInstanceForWeb();
-  if (!native_theme_web->IsForcedDarkMode()) {
-    // If we're in forced dark mode, leave the value alone to allow the tests to
-    // work.
-    native_theme_web->set_use_dark_colors(is_dark_mode_enabled);
-    native_theme_web->set_preferred_color_scheme(
-        is_dark_mode_enabled ? ui::NativeTheme::PreferredColorScheme::kDark
-                             : ui::NativeTheme::PreferredColorScheme::kLight);
-  }
+  native_theme_web->set_use_dark_colors(is_dark_mode_enabled);
+  native_theme_web->set_preferred_color_scheme(
+      is_dark_mode_enabled ? ui::NativeTheme::PreferredColorScheme::kDark
+                           : ui::NativeTheme::PreferredColorScheme::kLight);
   native_theme_web->set_user_color(themed_color);
   native_theme_web->NotifyOnNativeThemeUpdated();
 }
diff --git a/ash/system/accessibility/accessibility_feature_pod_controller.cc b/ash/system/accessibility/accessibility_feature_pod_controller.cc
index b99983b16..009bbab 100644
--- a/ash/system/accessibility/accessibility_feature_pod_controller.cc
+++ b/ash/system/accessibility/accessibility_feature_pod_controller.cc
@@ -43,8 +43,9 @@
                        login_status == LoginStatus::LOCKED ||
                        delegate->ShouldShowAccessibilityMenu();
   button->SetVisible(visible);
-  if (visible)
+  if (visible) {
     TrackVisibilityUMA();
+  }
 
   return button;
 }
@@ -68,6 +69,17 @@
       base::BindRepeating(&FeaturePodControllerBase::OnLabelPressed,
                           weak_ptr_factory_.GetWeakPtr()),
       tooltip_text);
+
+  AccessibilityDelegate* delegate = Shell::Get()->accessibility_delegate();
+  LoginStatus login_status = Shell::Get()->session_controller()->login_status();
+  const bool visible = login_status == LoginStatus::NOT_LOGGED_IN ||
+                       login_status == LoginStatus::LOCKED ||
+                       delegate->ShouldShowAccessibilityMenu();
+  feature_tile->SetVisible(visible);
+  if (visible) {
+    TrackVisibilityUMA();
+  }
+
   return feature_tile;
 }
 
diff --git a/ash/system/accessibility/accessibility_feature_pod_controller_unittest.cc b/ash/system/accessibility/accessibility_feature_pod_controller_unittest.cc
index 9a44a41..cd8362e 100644
--- a/ash/system/accessibility/accessibility_feature_pod_controller_unittest.cc
+++ b/ash/system/accessibility/accessibility_feature_pod_controller_unittest.cc
@@ -4,20 +4,32 @@
 
 #include "ash/system/accessibility/accessibility_feature_pod_controller.h"
 
+#include "ash/constants/ash_features.h"
 #include "ash/constants/quick_settings_catalogs.h"
 #include "ash/system/unified/feature_pod_button.h"
+#include "ash/system/unified/feature_tile.h"
 #include "ash/system/unified/unified_system_tray.h"
 #include "ash/system/unified/unified_system_tray_bubble.h"
 #include "ash/system/unified/unified_system_tray_controller.h"
 #include "ash/test/ash_test_base.h"
 #include "base/test/metrics/histogram_tester.h"
+#include "base/test/scoped_feature_list.h"
+#include "ui/views/view.h"
 
 namespace ash {
 
 // Tests manually control their session state.
-class AccessibilityFeaturePodControllerTest : public NoSessionAshTestBase {
+class AccessibilityFeaturePodControllerTest
+    : public NoSessionAshTestBase,
+      public testing::WithParamInterface<bool> {
  public:
-  AccessibilityFeaturePodControllerTest() = default;
+  AccessibilityFeaturePodControllerTest() {
+    if (IsQsRevampEnabled()) {
+      feature_list_.InitAndEnableFeature(features::kQsRevamp);
+    } else {
+      feature_list_.InitAndDisableFeature(features::kQsRevamp);
+    }
+  }
 
   AccessibilityFeaturePodControllerTest(
       const AccessibilityFeaturePodControllerTest&) = delete;
@@ -26,6 +38,8 @@
 
   ~AccessibilityFeaturePodControllerTest() override = default;
 
+  bool IsQsRevampEnabled() const { return GetParam(); }
+
   void SetUp() override {
     NoSessionAshTestBase::SetUp();
     GetPrimaryUnifiedSystemTray()->ShowBubble();
@@ -41,7 +55,11 @@
   void SetUpButton() {
     controller_ =
         std::make_unique<AccessibilityFeaturePodController>(tray_controller());
-    button_.reset(controller_->CreateButton());
+    if (IsQsRevampEnabled()) {
+      tile_ = controller_->CreateTile();
+    } else {
+      button_.reset(controller_->CreateButton());
+    }
   }
 
   UnifiedSystemTrayController* tray_controller() {
@@ -50,84 +68,98 @@
         ->unified_system_tray_controller();
   }
 
-  FeaturePodButton* button() { return button_.get(); }
-
+  bool IsButtonVisible() {
+    return IsQsRevampEnabled() ? tile_->GetVisible() : button_->GetVisible();
+  }
   void PressIcon() { controller_->OnIconPressed(); }
 
   void PressLabel() { controller_->OnLabelPressed(); }
 
+  const char* GetToggledOnHistogramName() {
+    return IsQsRevampEnabled() ? "Ash.QuickSettings.FeaturePod.ToggledOn"
+                               : "Ash.UnifiedSystemView.FeaturePod.ToggledOn";
+  }
+
+  const char* GetToggledOffHistogramName() {
+    return IsQsRevampEnabled() ? "Ash.QuickSettings.FeaturePod.ToggledOff"
+                               : "Ash.UnifiedSystemView.FeaturePod.ToggledOff";
+  }
+
+  const char* GetDiveInHistogramName() {
+    return IsQsRevampEnabled() ? "Ash.QuickSettings.FeaturePod.DiveIn"
+                               : "Ash.UnifiedSystemView.FeaturePod.DiveIn";
+  }
+
  private:
+  base::test::ScopedFeatureList feature_list_;
   std::unique_ptr<AccessibilityFeaturePodController> controller_;
   std::unique_ptr<FeaturePodButton> button_;
+  std::unique_ptr<FeatureTile> tile_;
 };
 
-TEST_F(AccessibilityFeaturePodControllerTest, ButtonVisibilityNotLoggedIn) {
+INSTANTIATE_TEST_SUITE_P(QsRevamp,
+                         AccessibilityFeaturePodControllerTest,
+                         testing::Bool());
+
+TEST_P(AccessibilityFeaturePodControllerTest, ButtonVisibilityNotLoggedIn) {
   SetUpButton();
   // If not logged in, it should be always visible.
-  EXPECT_TRUE(button()->GetVisible());
+  EXPECT_TRUE(IsButtonVisible());
 }
 
-TEST_F(AccessibilityFeaturePodControllerTest, ButtonVisibilityLoggedIn) {
+TEST_P(AccessibilityFeaturePodControllerTest, ButtonVisibilityLoggedIn) {
   CreateUserSessions(1);
   SetUpButton();
   // If logged in, it's not visible by default.
-  EXPECT_FALSE(button()->GetVisible());
+  EXPECT_FALSE(IsButtonVisible());
 }
 
-TEST_F(AccessibilityFeaturePodControllerTest, IconUMATracking) {
+TEST_P(AccessibilityFeaturePodControllerTest, IconUMATracking) {
   SetUpButton();
 
   // No metrics logged before clicking on any views.
   auto histogram_tester = std::make_unique<base::HistogramTester>();
-  histogram_tester->ExpectTotalCount(
-      "Ash.UnifiedSystemView.FeaturePod.ToggledOn",
-      /*count=*/0);
-  histogram_tester->ExpectTotalCount(
-      "Ash.UnifiedSystemView.FeaturePod.ToggledOff",
-      /*count=*/0);
-  histogram_tester->ExpectTotalCount("Ash.UnifiedSystemView.FeaturePod.DiveIn",
+  histogram_tester->ExpectTotalCount(GetToggledOnHistogramName(),
+                                     /*count=*/0);
+  histogram_tester->ExpectTotalCount(GetToggledOffHistogramName(),
+                                     /*count=*/0);
+  histogram_tester->ExpectTotalCount(GetDiveInHistogramName(),
                                      /*count=*/0);
 
   // Show a11y detailed view when pressing on the icon.
   PressIcon();
-  histogram_tester->ExpectTotalCount(
-      "Ash.UnifiedSystemView.FeaturePod.ToggledOn",
-      /*count=*/0);
-  histogram_tester->ExpectTotalCount(
-      "Ash.UnifiedSystemView.FeaturePod.ToggledOff",
-      /*count=*/0);
-  histogram_tester->ExpectTotalCount("Ash.UnifiedSystemView.FeaturePod.DiveIn",
+  histogram_tester->ExpectTotalCount(GetToggledOnHistogramName(),
+                                     /*count=*/0);
+  histogram_tester->ExpectTotalCount(GetToggledOffHistogramName(),
+                                     /*count=*/0);
+  histogram_tester->ExpectTotalCount(GetDiveInHistogramName(),
                                      /*count=*/1);
-  histogram_tester->ExpectBucketCount("Ash.UnifiedSystemView.FeaturePod.DiveIn",
+  histogram_tester->ExpectBucketCount(GetDiveInHistogramName(),
                                       QsFeatureCatalogName::kAccessibility,
                                       /*expected_count=*/1);
 }
 
-TEST_F(AccessibilityFeaturePodControllerTest, LabelUMATracking) {
+TEST_P(AccessibilityFeaturePodControllerTest, LabelUMATracking) {
   SetUpButton();
 
   // No metrics logged before clicking on any views.
   auto histogram_tester = std::make_unique<base::HistogramTester>();
-  histogram_tester->ExpectTotalCount(
-      "Ash.UnifiedSystemView.FeaturePod.ToggledOn",
-      /*count=*/0);
-  histogram_tester->ExpectTotalCount(
-      "Ash.UnifiedSystemView.FeaturePod.ToggledOff",
-      /*count=*/0);
-  histogram_tester->ExpectTotalCount("Ash.UnifiedSystemView.FeaturePod.DiveIn",
+  histogram_tester->ExpectTotalCount(GetToggledOnHistogramName(),
+                                     /*count=*/0);
+  histogram_tester->ExpectTotalCount(GetToggledOffHistogramName(),
+                                     /*count=*/0);
+  histogram_tester->ExpectTotalCount(GetDiveInHistogramName(),
                                      /*count=*/0);
 
   // Show a11y detailed view when pressing on the label.
   PressLabel();
-  histogram_tester->ExpectTotalCount(
-      "Ash.UnifiedSystemView.FeaturePod.ToggledOn",
-      /*count=*/0);
-  histogram_tester->ExpectTotalCount(
-      "Ash.UnifiedSystemView.FeaturePod.ToggledOff",
-      /*count=*/0);
-  histogram_tester->ExpectTotalCount("Ash.UnifiedSystemView.FeaturePod.DiveIn",
+  histogram_tester->ExpectTotalCount(GetToggledOnHistogramName(),
+                                     /*count=*/0);
+  histogram_tester->ExpectTotalCount(GetToggledOffHistogramName(),
+                                     /*count=*/0);
+  histogram_tester->ExpectTotalCount(GetDiveInHistogramName(),
                                      /*count=*/1);
-  histogram_tester->ExpectBucketCount("Ash.UnifiedSystemView.FeaturePod.DiveIn",
+  histogram_tester->ExpectBucketCount(GetDiveInHistogramName(),
                                       QsFeatureCatalogName::kAccessibility,
                                       /*expected_count=*/1);
 }
diff --git a/ash/webui/camera_app_ui/resources/js/test/cca_type.ts b/ash/webui/camera_app_ui/resources/js/test/cca_type.ts
index fe6efec..cb6090c 100644
--- a/ash/webui/camera_app_ui/resources/js/test/cca_type.ts
+++ b/ash/webui/camera_app_ui/resources/js/test/cca_type.ts
@@ -34,10 +34,10 @@
   documentFixModeImage: '.document-fix-mode .image',
   documentPreviewModeImage: '.document-preview-mode .image',
   documentReview: '#view-document-review',
-  documentSaveAsPhotoButton:
-      '.document-preview-mode button[i18n-text=label_save_photo_document]',
   documentSaveAsPdfButton:
       '.document-preview-mode button[i18n-text=label_save_pdf_document]',
+  documentSaveAsPhotoButton:
+      '.document-preview-mode button[i18n-text=label_save_photo_document]',
   expertCustomVideoParametersOption: '#custom-video-parameters',
   expertModeButton: '#settings-expert',
   expertModeOption: '#expert-enable-expert-mode',
@@ -51,8 +51,8 @@
       '#view-photo-resolution-settings .menu-item>input[data-facing="user"]',
   frontVideoResolutionOptions:
       '#view-video-resolution-settings .menu-item>input[data-facing="user"]',
+  galleryButton: '#gallery-enter',
   galleryButtonCover: '#gallery-enter>img',
-  galleryEnter: '#gallery-enter',
   gifRecordingOption: 'input[type=radio][data-state=record-type-gif]',
   gifReviewRetakeButton: '#review-retake',
   gifReviewSaveButton: '#view-review button[i18n-text=label_save]',
@@ -79,12 +79,14 @@
   reviewView: '#view-review',
   scanBarcodeOption: '#scan-barcode',
   scanDocumentModeOption: '#scan-document',
-  scanModeButton: '.mode-item>input[data-mode="scan"]',
   settingsButton: '#open-settings',
+  settingsButtonContainer: 'div:has(> #open-settings)',
   shutter: '.shutter',
   switchDeviceButton: '#switch-device',
   tiltDownButton: '#tilt-down',
   tiltUpButton: '#tilt-up',
+  timeLapseRecordingOption:
+      'input[type=radio][data-state=record-type-time-lapse]',
   videoPauseResumeButton: '#pause-recordvideo',
   videoProfileSelect: '#video-profile',
   videoResolutionSettingButton: '#settings-video-resolution',
diff --git a/base/allocator/partition_allocator/pointers/raw_ptr.h b/base/allocator/partition_allocator/pointers/raw_ptr.h
index 7119730..fc165ec 100644
--- a/base/allocator/partition_allocator/pointers/raw_ptr.h
+++ b/base/allocator/partition_allocator/pointers/raw_ptr.h
@@ -157,6 +157,21 @@
 
 }  // namespace raw_ptr_traits
 
+template <typename T, RawPtrTraits Traits = RawPtrTraits::kEmpty>
+class raw_ptr;
+
+}  // namespace base
+
+// This type is to be used internally, or in callbacks arguments when it is
+// known that they might receive dangling pointers. In any other cases, please
+// use one of:
+// - raw_ptr<T, DanglingUntriaged>
+// - raw_ptr<T, DisableDanglingPtrDetection>
+template <typename T, base::RawPtrTraits Traits = base::RawPtrTraits::kEmpty>
+using MayBeDangling = base::raw_ptr<T, Traits | base::RawPtrTraits::kMayDangle>;
+
+namespace base {
+
 namespace internal {
 // These classes/structures are part of the raw_ptr implementation.
 // DO NOT USE THESE CLASSES DIRECTLY YOURSELF.
@@ -503,12 +518,8 @@
 // non-default move constructor/assignment. Thus, it's possible to get an error
 // where the pointer is not actually dangling, and have to work around the
 // compiler. We have not managed to construct such an example in Chromium yet.
-template <typename T, RawPtrTraits Traits = RawPtrTraits::kEmpty>
+template <typename T, RawPtrTraits Traits>
 class PA_TRIVIAL_ABI PA_GSL_POINTER raw_ptr {
-  // Type to return from ExtractAsDangling(), which is identical except
-  // kMayDangle trait is added (if one isn't there already).
-  using DanglingRawPtrType = raw_ptr<T, Traits | RawPtrTraits::kMayDangle>;
-
  public:
   using Impl = typename raw_ptr_traits::TraitsToImpl<Traits>::Impl;
 
@@ -847,21 +858,15 @@
   // variable (or worse, a field)! It's meant to be used as a temporary, to be
   // passed into a cleanup & freeing function, and destructed at the end of the
   // statement.
-  PA_ALWAYS_INLINE constexpr DanglingRawPtrType ExtractAsDangling() noexcept {
-    if constexpr (std::is_same_v<
-                      typename std::remove_reference<decltype(*this)>::type,
-                      DanglingRawPtrType>) {
-      DanglingRawPtrType res(std::move(*this));
-      // Not all implementation clear the source pointer on move, so do it
-      // here just in case. Should be cheap.
-      operator=(nullptr);
-      return res;
-    } else {
-      T* ptr = GetForExtraction();
-      DanglingRawPtrType res(ptr);
-      operator=(nullptr);
-      return res;
-    }
+  PA_ALWAYS_INLINE constexpr MayBeDangling<T, Traits>
+  ExtractAsDangling() noexcept {
+    MayBeDangling<T, Traits> res(std::move(*this));
+    // Not all implementation clear the source pointer on move. Furthermore,
+    // even for implemtantions that do, cross-kind conversions (that add
+    // kMayDangle) fall back to a copy, instead of move. So do it here just in
+    // case. Should be cheap.
+    operator=(nullptr);
+    return res;
   }
 
   // Comparison operators between raw_ptr and raw_ptr<U>/U*/std::nullptr_t.
@@ -1104,13 +1109,6 @@
 // occurrences are meant to be removed. See https://crbug.com/1291138.
 constexpr auto DanglingUntriaged = base::RawPtrTraits::kMayDangle;
 
-// This type is to be used in callbacks arguments when it is known that they
-// might receive dangling pointers. In any other cases, please use one of:
-// - raw_ptr<T, DanglingUntriaged>
-// - raw_ptr<T, DisableDanglingPtrDetection>
-template <typename T, base::RawPtrTraits Traits = base::RawPtrTraits::kEmpty>
-using MayBeDangling = base::raw_ptr<T, Traits | base::RawPtrTraits::kMayDangle>;
-
 // The use of pointer arithmetic with raw_ptr is strongly discouraged and
 // disabled by default. Usually a container like span<> should be used
 // instead of the raw_ptr.
diff --git a/base/allocator/partition_allocator/pointers/raw_ptr_unittest.cc b/base/allocator/partition_allocator/pointers/raw_ptr_unittest.cc
index 177541c..082c8f4 100644
--- a/base/allocator/partition_allocator/pointers/raw_ptr_unittest.cc
+++ b/base/allocator/partition_allocator/pointers/raw_ptr_unittest.cc
@@ -355,11 +355,22 @@
 TEST_F(RawPtrTest, Delete) {
   CountingRawPtr<int> ptr = new int(42);
   delete ptr.ExtractAsDangling();
-  // The pointer was extracted using implicit cast before passing to |delete|.
+  // The pointer is first internally converted to MayDangle kind, then extracted
+  // using implicit cast before passing to |delete|.
   EXPECT_THAT((CountingRawPtrExpectations<RawPtrCountingImpl>{
                   .get_for_dereference_cnt = 0,
+                  .get_for_extraction_cnt = 0,
+                  .get_for_comparison_cnt = 0,
+                  .wrap_raw_ptr_for_dup_cnt = 0,
+                  .get_for_duplication_cnt = 1,
+              }),
+              CountersMatch());
+  EXPECT_THAT((CountingRawPtrExpectations<RawPtrCountingMayDangleImpl>{
+                  .get_for_dereference_cnt = 0,
                   .get_for_extraction_cnt = 1,
                   .get_for_comparison_cnt = 0,
+                  .wrap_raw_ptr_for_dup_cnt = 1,
+                  .get_for_duplication_cnt = 0,
               }),
               CountersMatch());
 }
@@ -412,6 +423,8 @@
                   .release_wrapped_ptr_cnt = 0,
                   .get_for_dereference_cnt = 0,
                   .wrapped_ptr_swap_cnt = 0,
+                  .wrap_raw_ptr_for_dup_cnt = 0,
+                  .get_for_duplication_cnt = 0,
               }),
               CountersMatch());
   EXPECT_THAT((CountingRawPtrExpectations<RawPtrCountingMayDangleImpl>{
@@ -419,6 +432,8 @@
                   .release_wrapped_ptr_cnt = 0,
                   .get_for_dereference_cnt = 0,
                   .wrapped_ptr_swap_cnt = 0,
+                  .wrap_raw_ptr_for_dup_cnt = 0,
+                  .get_for_duplication_cnt = 0,
               }),
               CountersMatch());
 
@@ -431,13 +446,17 @@
                   .release_wrapped_ptr_cnt = 1,
                   .get_for_dereference_cnt = 0,
                   .wrapped_ptr_swap_cnt = 0,
+                  .wrap_raw_ptr_for_dup_cnt = 0,
+                  .get_for_duplication_cnt = 1,
               }),
               CountersMatch());
   EXPECT_THAT((CountingRawPtrExpectations<RawPtrCountingMayDangleImpl>{
-                  .wrap_raw_ptr_cnt = 1,
+                  .wrap_raw_ptr_cnt = 0,
                   .release_wrapped_ptr_cnt = 0,
                   .get_for_dereference_cnt = 0,
                   .wrapped_ptr_swap_cnt = 0,
+                  .wrap_raw_ptr_for_dup_cnt = 1,
+                  .get_for_duplication_cnt = 0,
               }),
               CountersMatch());
 
@@ -455,6 +474,8 @@
                   .release_wrapped_ptr_cnt = 0,
                   .get_for_dereference_cnt = 0,
                   .wrapped_ptr_swap_cnt = 0,
+                  .wrap_raw_ptr_for_dup_cnt = 0,
+                  .get_for_duplication_cnt = 0,
               }),
               CountersMatch());
 
@@ -467,6 +488,8 @@
                   .release_wrapped_ptr_cnt = 1,
                   .get_for_dereference_cnt = 0,
                   .wrapped_ptr_swap_cnt = 0,
+                  .wrap_raw_ptr_for_dup_cnt = 0,
+                  .get_for_duplication_cnt = 0,
               }),
               CountersMatch());
 
diff --git a/build/fuchsia/linux_internal.sdk.sha1 b/build/fuchsia/linux_internal.sdk.sha1
index ece2cbe..fc35fdb 100644
--- a/build/fuchsia/linux_internal.sdk.sha1
+++ b/build/fuchsia/linux_internal.sdk.sha1
@@ -1 +1 @@
-12.20230326.3.1
+12.20230327.0.1
diff --git a/build/sanitizers/tsan_suppressions.cc b/build/sanitizers/tsan_suppressions.cc
index c1deaf5..d90546e 100644
--- a/build/sanitizers/tsan_suppressions.cc
+++ b/build/sanitizers/tsan_suppressions.cc
@@ -83,7 +83,7 @@
     // https://crbug.com/1405439
     "race:*::perfetto_track_event::internal::g_category_state_storage\n"
     "race:perfetto::DataSource*::static_state_\n"
-    "race:perfetto::Tracing::ResetForTesting\n"
+    "race:perfetto::*::ResetForTesting\n"
 
     // In V8 each global safepoint might lock isolate mutexes in a different
     // order. This is allowed in this context as it is always guarded by a
diff --git a/build_overrides/build.gni b/build_overrides/build.gni
index 5b7bc4d..c5bcad1a 100644
--- a/build_overrides/build.gni
+++ b/build_overrides/build.gni
@@ -2,6 +2,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import("//build/config/chromecast_build.gni")
 import("//build/config/gclient_args.gni")
 
 # Uncomment these to specify a different NDK location and version in
@@ -34,10 +35,9 @@
   enable_base_tracing = true
 
   # Switches the TRACE_EVENT instrumentation from base's TraceLog implementation
-  # to //third_party/perfetto's client library. Not implemented yet, currently a
-  # no-op to set up trybot infrastructure.
-  # TODO(crbug/1006769): Switch to perfetto's client library.
-  use_perfetto_client_library = false
+  # to //third_party/perfetto's client library.
+  # TODO(crbug/1006541): Switch to perfetto's client library on all platforms.
+  use_perfetto_client_library = is_linux && !is_castos
 
   # Limits the defined //third_party/android_deps targets to only "buildCompile"
   # and "buildCompileNoDeps" targets. This is useful for third-party
diff --git a/cc/layers/picture_layer_impl.cc b/cc/layers/picture_layer_impl.cc
index fc1223c..64e1a14c 100644
--- a/cc/layers/picture_layer_impl.cc
+++ b/cc/layers/picture_layer_impl.cc
@@ -336,7 +336,7 @@
     auto* quad = render_pass->CreateAndAppendDrawQuad<viz::PictureDrawQuad>();
     quad->SetNew(shared_quad_state, geometry_rect, visible_geometry_rect,
                  needs_blending, texture_rect, texture_size, nearest_neighbor_,
-                 viz::RGBA_8888, quad_content_rect, max_contents_scale,
+                 quad_content_rect, max_contents_scale,
                  std::move(image_animation_map),
                  raster_source_->GetDisplayItemList());
     ValidateQuadResources(quad);
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni
index 01cac95..5d5abd5e 100644
--- a/chrome/android/chrome_java_sources.gni
+++ b/chrome/android/chrome_java_sources.gni
@@ -446,6 +446,7 @@
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabIncognitoManager.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabIntentDataProvider.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabLaunchCauseMetrics.java",
+  "java/src/org/chromium/chrome/browser/customtabs/CustomTabLocator.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabNavigationEventObserver.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabNightModeStateController.java",
   "java/src/org/chromium/chrome/browser/customtabs/CustomTabObserver.java",
@@ -1199,7 +1200,6 @@
   "java/src/org/chromium/chrome/browser/webapps/WebappIntentDataProviderFactory.java",
   "java/src/org/chromium/chrome/browser/webapps/WebappLaunchCauseMetrics.java",
   "java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java",
-  "java/src/org/chromium/chrome/browser/webapps/WebappLocator.java",
   "java/src/org/chromium/chrome/browser/webapps/WebappRegistry.java",
   "java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorActivity.java",
   "java/src/org/chromium/chrome/browser/webauth/authenticator/CableAuthenticatorUSBActivity.java",
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java
index fc24112..c7dafce 100644
--- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java
+++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java
@@ -897,11 +897,6 @@
         return super.canHostBeFocusable();
     }
 
-    @Override
-    public boolean isRunningAnimations() {
-        return mDeferredAnimationRunnable != null || mTabToSwitcherAnimation != null;
-    }
-
     /**
      * Shrink/Expand animation is disabled for Tablet TabSwitcher launch polish.
      * @return Whether shrink/expand animation is enabled.
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java
index 5eff80bf..dd15d7d 100644
--- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java
+++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherLayout.java
@@ -728,11 +728,6 @@
         return super.canHostBeFocusable();
     }
 
-    @Override
-    public boolean isRunningAnimations() {
-        return mDeferredAnimationRunnable != null || mTabToSwitcherAnimation != null;
-    }
-
     /**
      * Shrink/Expand animation is disabled for Tablet TabSwitcher launch polish.
      * @return Whether shrink/expand animation is enabled.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
index 42a95d63..2809004c 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/Layout.java
@@ -793,9 +793,4 @@
      */
     @LayoutType
     public abstract int getLayoutType();
-
-    /** Returns whether the layout is currently running animations. */
-    public boolean isRunningAnimations() {
-        return false;
-    }
 }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
index 3a22616..f05ff8b 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerImpl.java
@@ -59,7 +59,6 @@
 import org.chromium.chrome.browser.theme.ThemeUtils;
 import org.chromium.chrome.browser.theme.TopUiThemeColorProvider;
 import org.chromium.chrome.browser.toolbar.ControlContainer;
-import org.chromium.chrome.browser.toolbar.ToolbarFeatures;
 import org.chromium.chrome.browser.toolbar.bottom.ScrollingBottomViewSceneLayer;
 import org.chromium.chrome.browser.toolbar.top.TopToolbarOverlayCoordinator;
 import org.chromium.chrome.browser.ui.native_page.NativePage;
@@ -474,16 +473,13 @@
         }
         mUpdateRequested = false;
 
-        // TODO(crbug.com/1070281): Remove after the FrameRequestSupplier migrates to the animation
-        //  system.
-        final Layout layout = getActiveLayout();
-
         // TODO(mdjones): Remove the time related params from this method. The new animation system
         // has its own timer.
         boolean areAnimatorsComplete = mAnimationHandler.pushUpdate();
-        if (layout != null && ToolbarFeatures.shouldDelayTransitionsForAnimation()) {
-            areAnimatorsComplete &= !layout.isRunningAnimations();
-        }
+
+        // TODO(crbug.com/1070281): Remove after the FrameRequestSupplier migrates to the animation
+        //  system.
+        final Layout layout = getActiveLayout();
 
         // TODO(crbug.com/1070281): Layout itself should decide when it's done hiding and done
         //  showing.
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLocator.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabLocator.java
similarity index 62%
rename from chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLocator.java
rename to chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabLocator.java
index dc7595d..0f1cf68 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLocator.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabLocator.java
@@ -2,28 +2,35 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-package org.chromium.chrome.browser.webapps;
+package org.chromium.chrome.browser.customtabs;
 
 import android.app.Activity;
 import android.text.TextUtils;
 
 import org.chromium.base.ApplicationStatus;
 import org.chromium.chrome.browser.browserservices.intents.WebappExtras;
-import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity;
 import org.chromium.chrome.browser.tab.Tab;
+import org.chromium.chrome.browser.webapps.WebappActivity;
 
 import java.lang.ref.WeakReference;
 
 /**
- * Utility class for locating running {@link WebappActivity}.
+ * Utility class for locating running {@link BaseCustomTabActivity} and {@link WebappActivity} as
+ * well.
  */
-public class WebappLocator {
-    /** Returns the running WebappActivity with the given tab id. Returns null if there is none. */
-    public static WeakReference<BaseCustomTabActivity> findWebappActivityWithTabId(int tabId) {
+public class CustomTabLocator {
+    /**
+     * Returns the running BaseCustomTabActivity with the given tab id. Returns null if there is
+     * none.
+     *
+     * @param tabId the tabId to search with.
+     * @return The matched BaseCustomTabActivity if there's any, otherwise returns null.
+     */
+    public static WeakReference<BaseCustomTabActivity> findCustomTabActivityWithTabId(int tabId) {
         if (tabId == Tab.INVALID_TAB_ID) return null;
 
         for (Activity activity : ApplicationStatus.getRunningActivities()) {
-            if (!(activity instanceof WebappActivity)) continue;
+            if (!(activity instanceof BaseCustomTabActivity)) continue;
 
             BaseCustomTabActivity customTabActivity = (BaseCustomTabActivity) activity;
             Tab tab = customTabActivity.getActivityTab();
@@ -34,7 +41,12 @@
         return null;
     }
 
-    /** Returns the WebappActivity with the given {@link webappId}. */
+    /**
+     * Returns the BaseCustomTabActivity represents the running WebAppActivity with the given id.
+     *
+     * @param webappId The webapp id to search with.
+     * @return The matched WepappActivity if there's any, otherwise returns null.
+     */
     public static WeakReference<BaseCustomTabActivity> findRunningWebappActivityWithId(
             String webappId) {
         for (Activity activity : ApplicationStatus.getRunningActivities()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
index a023668..b7064c0 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -933,9 +933,6 @@
                 if (layoutType == LayoutType.TAB_SWITCHER) {
                     mToolbar.onTabSwitcherTransitionFinished();
                 }
-                if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) {
-                    mToolbar.onTransitionEnd();
-                }
             }
 
             @Override
@@ -950,9 +947,6 @@
                         mControlContainer.invalidateBitmap();
                     }
                 }
-                if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) {
-                    mToolbar.onTransitionStart();
-                }
             }
 
             @Override
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateTask.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateTask.java
index 1912930..37f1500 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateTask.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebApkUpdateTask.java
@@ -8,6 +8,7 @@
 
 import org.chromium.base.StrictModeContext;
 import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity;
+import org.chromium.chrome.browser.customtabs.CustomTabLocator;
 import org.chromium.components.background_task_scheduler.NativeBackgroundTask;
 import org.chromium.components.background_task_scheduler.TaskIds;
 import org.chromium.components.background_task_scheduler.TaskParameters;
@@ -40,7 +41,7 @@
         for (String id : ids) {
             WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(id);
             WeakReference<BaseCustomTabActivity> activity =
-                    WebappLocator.findRunningWebappActivityWithId(storage.getId());
+                    CustomTabLocator.findRunningWebappActivityWithId(storage.getId());
             if (activity == null || activity.get() == null) {
                 mStorageToUpdate = storage;
                 mMoreToUpdate = ids.size() > 1;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java
index f274e32f..61390cc 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappActionsNotificationManager.java
@@ -21,6 +21,7 @@
 import org.chromium.chrome.browser.browserservices.intents.BrowserServicesIntentDataProvider;
 import org.chromium.chrome.browser.browserservices.intents.WebappExtras;
 import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity;
+import org.chromium.chrome.browser.customtabs.CustomTabLocator;
 import org.chromium.chrome.browser.customtabs.content.CustomTabActivityTabProvider;
 import org.chromium.chrome.browser.dependency_injection.ActivityScope;
 import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher;
@@ -159,7 +160,7 @@
 
         int tabId = IntentHandler.getTabId(intent);
         WeakReference<BaseCustomTabActivity> customTabActivityRef =
-                WebappLocator.findWebappActivityWithTabId(tabId);
+                CustomTabLocator.findCustomTabActivityWithTabId(tabId);
         if (customTabActivityRef == null) return false;
 
         BaseCustomTabActivity customTabActivity = customTabActivityRef.get();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java
index b8bbe88a..7e6b0bf 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/webapps/WebappLauncherActivity.java
@@ -34,6 +34,7 @@
 import org.chromium.chrome.browser.browserservices.intents.WebappConstants;
 import org.chromium.chrome.browser.browserservices.intents.WebappIntentUtils;
 import org.chromium.chrome.browser.customtabs.BaseCustomTabActivity;
+import org.chromium.chrome.browser.customtabs.CustomTabLocator;
 import org.chromium.chrome.browser.document.ChromeLauncherActivity;
 import org.chromium.chrome.browser.firstrun.FirstRunFlowSequencer;
 import org.chromium.components.webapk.lib.client.WebApkValidator;
@@ -108,7 +109,7 @@
      */
     public static boolean bringWebappToFront(int tabId) {
         WeakReference<BaseCustomTabActivity> customTabActivity =
-                WebappLocator.findWebappActivityWithTabId(tabId);
+                CustomTabLocator.findCustomTabActivityWithTabId(tabId);
         if (customTabActivity == null || customTabActivity.get() == null) return false;
         customTabActivity.get().getWebContentsDelegate().activateContents();
         return true;
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index 749e2a9..d07091d 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -4995,6 +4995,9 @@
           <message name="IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_DIAGNOSTICS" desc="Permission string for chrome.os.diagnostcs API.">
             Run ChromeOS Flex diagnostic tests
           </message>
+          <message name="IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_EVENTS" desc="Permission string for chrome.os.events API.">
+            Subscribe to ChromeOS Flex system events
+          </message>
           <message name="IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_TELEMETRY" desc="Permission string for chrome.os.telemetry API.">
             Read ChromeOS Flex device information and device data
           </message>
@@ -5009,6 +5012,9 @@
           <message name="IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_DIAGNOSTICS" desc="Permission string for chrome.os.diagnostcs API.">
             Run ChromeOS diagnostic tests
           </message>
+          <message name="IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_EVENTS" desc="Permission string for chrome.os.events API.">
+            Subscribe to ChromeOS system events
+          </message>
           <message name="IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_TELEMETRY" desc="Permission string for chrome.os.telemetry API.">
             Read ChromeOS device information and device data
           </message>
diff --git a/chrome/app/generated_resources_grd/IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_EVENTS.png.sha1 b/chrome/app/generated_resources_grd/IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_EVENTS.png.sha1
new file mode 100644
index 0000000..0e9777d
--- /dev/null
+++ b/chrome/app/generated_resources_grd/IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_EVENTS.png.sha1
@@ -0,0 +1 @@
+7706f72572eebdfe50162fd7ece9392e835e7eed
\ No newline at end of file
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc
index e5386e4..c7a0f6c 100644
--- a/chrome/browser/apps/guest_view/web_view_browsertest.cc
+++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -5540,9 +5540,9 @@
   ASSERT_TRUE(loaded_listener.WaitUntilSatisfied());
 
   const std::string script =
-      "window.domAutomationController.send("
+      "chrome.test.sendScriptResult("
       "    window.testPassed ? 'PASSED' : 'FAILED');";
-  const std::string test_passed =
+  const base::Value test_passed =
       ExecuteScriptInBackgroundPage(extension->id(), script);
   EXPECT_EQ("PASSED", test_passed);
 }
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn
index 5e8f39ac..f6eced84 100644
--- a/chrome/browser/ash/BUILD.gn
+++ b/chrome/browser/ash/BUILD.gn
@@ -594,6 +594,8 @@
     "arc/video/gpu_arc_video_service_host.h",
     "arc/vmm/arc_system_state_bridge.cc",
     "arc/vmm/arc_system_state_bridge.h",
+    "arc/vmm/arc_system_state_observation.cc",
+    "arc/vmm/arc_system_state_observation.h",
     "arc/vmm/arc_vmm_manager.cc",
     "arc/vmm/arc_vmm_manager.h",
     "arc/vmm/arc_vmm_swap_scheduler.cc",
@@ -1535,8 +1537,6 @@
     "login/app_mode/force_install_observer.h",
     "login/app_mode/kiosk_launch_controller.cc",
     "login/app_mode/kiosk_launch_controller.h",
-    "login/app_mode/network_ui_controller.cc",
-    "login/app_mode/network_ui_controller.h",
     "login/auth/chrome_login_performer.cc",
     "login/auth/chrome_login_performer.h",
     "login/auth/chrome_safe_mode_delegate.cc",
@@ -4355,6 +4355,8 @@
     "input_method/stub_input_method_engine_observer.h",
     "lock_screen_apps/fake_lock_screen_profile_creator.cc",
     "lock_screen_apps/fake_lock_screen_profile_creator.h",
+    "login/app_mode/test/kiosk_test_helpers.cc",
+    "login/app_mode/test/kiosk_test_helpers.h",
     "login/demo_mode/demo_mode_test_helper.cc",
     "login/demo_mode/demo_mode_test_helper.h",
     "login/demo_mode/demo_setup_test_utils.cc",
@@ -4393,8 +4395,6 @@
     "login/test/embedded_test_server_setup_mixin.h",
     "login/test/js_checker.cc",
     "login/test/js_checker.h",
-    "login/test/kiosk_test_helpers.cc",
-    "login/test/kiosk_test_helpers.h",
     "login/test/local_state_mixin.cc",
     "login/test/local_state_mixin.h",
     "login/test/logged_in_user_mixin.cc",
@@ -4966,6 +4966,7 @@
     "arc/tts/arc_tts_service_unittest.cc",
     "arc/user_session/arc_user_session_service_unittest.cc",
     "arc/vmm/arc_system_state_bridge_unittest.cc",
+    "arc/vmm/arc_system_state_observation_unittest.cc",
     "arc/vmm/arc_vmm_manager_unittest.cc",
     "arc/vmm/arc_vmm_swap_scheduler_unittest.cc",
     "arc/wallpaper/arc_wallpaper_service_unittest.cc",
diff --git a/chrome/browser/ash/accessibility/autoclick_browsertest.cc b/chrome/browser/ash/accessibility/autoclick_browsertest.cc
index db20cf1..64cbd85 100644
--- a/chrome/browser/ash/accessibility/autoclick_browsertest.cc
+++ b/chrome/browser/ash/accessibility/autoclick_browsertest.cc
@@ -106,11 +106,11 @@
       (async function() {
         window.accessibilityCommon.setFeatureLoadCallbackForTest('autoclick',
             () => {
-              window.domAutomationController.send('ready');
+              chrome.test.sendScriptResult('ready');
             });
       })();
     )JS");
-    std::string result =
+    base::Value result =
         extensions::browsertest_util::ExecuteScriptInBackgroundPage(
             browser()->profile(),
             extension_misc::kAccessibilityCommonExtensionId, script);
diff --git a/chrome/browser/ash/accessibility/dictation_browsertest.cc b/chrome/browser/ash/accessibility/dictation_browsertest.cc
index 60bad619..a267651 100644
--- a/chrome/browser/ash/accessibility/dictation_browsertest.cc
+++ b/chrome/browser/ash/accessibility/dictation_browsertest.cc
@@ -545,10 +545,11 @@
   }
 
   std::string ExecuteAccessibilityCommonScript(const std::string& script) {
-    return extensions::browsertest_util::ExecuteScriptInBackgroundPage(
-        /*context=*/browser()->profile(),
-        /*extension_id=*/extension_misc::kAccessibilityCommonExtensionId,
-        /*script=*/script);
+    return extensions::browsertest_util::
+        ExecuteScriptInBackgroundPageDeprecated(
+            /*context=*/browser()->profile(),
+            /*extension_id=*/extension_misc::kAccessibilityCommonExtensionId,
+            /*script=*/script);
   }
 
   std::string GetClipboardText() {
diff --git a/chrome/browser/ash/accessibility/magnification_controller_browsertest.cc b/chrome/browser/ash/accessibility/magnification_controller_browsertest.cc
index 053e5a6c..af069d0 100644
--- a/chrome/browser/ash/accessibility/magnification_controller_browsertest.cc
+++ b/chrome/browser/ash/accessibility/magnification_controller_browsertest.cc
@@ -124,11 +124,11 @@
             () => {
               window.accessibilityCommon.magnifier_.setIsInitializingForTest(
                   false);
-              window.domAutomationController.send('ready');
+              chrome.test.sendScriptResult('ready');
             });
       })();
     )JS");
-    std::string result =
+    base::Value result =
         extensions::browsertest_util::ExecuteScriptInBackgroundPage(
             browser()->profile(),
             extension_misc::kAccessibilityCommonExtensionId, script);
diff --git a/chrome/browser/ash/accessibility/select_to_speak_browsertest.cc b/chrome/browser/ash/accessibility/select_to_speak_browsertest.cc
index 40d85de..56e76df 100644
--- a/chrome/browser/ash/accessibility/select_to_speak_browsertest.cc
+++ b/chrome/browser/ash/accessibility/select_to_speak_browsertest.cc
@@ -196,13 +196,6 @@
     return weak_ptr_factory_.GetWeakPtr();
   }
 
-  void RunJavaScriptInSelectToSpeakBackgroundPage(const std::string& script) {
-    extensions::browsertest_util::ExecuteScriptInBackgroundPage(
-        /*context=*/browser()->profile(),
-        /*extension_id=*/extension_misc::kSelectToSpeakExtensionId,
-        /*script=*/script);
-  }
-
   content::WebContents* GetWebContents() {
     return browser()->tab_strip_model()->GetActiveWebContents();
   }
@@ -218,21 +211,20 @@
       (async function() {
         let module = await import('./select_to_speak_main.js');
         module.selectToSpeak.setOnLoadDesktopCallbackForTest(() => {
-            window.domAutomationController.send('ready');
+            chrome.test.sendScriptResult('ready');
           });
         // Set enhanced network voices dialog as shown, because the pref
         // change takes some time to propagate.
         module.selectToSpeak.prefsManager_.enhancedVoicesDialogShown_ = true;
       })();
     )JS");
-    std::string result =
+    base::Value result =
         extensions::browsertest_util::ExecuteScriptInBackgroundPage(
             browser()->profile(), extension_misc::kSelectToSpeakExtensionId,
             script);
     ASSERT_EQ("ready", result);
   }
 
-  base::test::ScopedFeatureList scoped_feature_list_;
   std::unique_ptr<base::RunLoop> loop_runner_;
   std::unique_ptr<base::RunLoop> highlights_runner_;
   std::unique_ptr<base::RunLoop> tray_loop_runner_;
diff --git a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
index 5f1b52b..a19e72e8 100644
--- a/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
+++ b/chrome/browser/ash/accessibility/spoken_feedback_browsertest.cc
@@ -180,7 +180,7 @@
 
 void LoggedInSpokenFeedbackTest::ImportJSModuleForChromeVox(std::string name,
                                                             std::string path) {
-  extensions::browsertest_util::ExecuteScriptInBackgroundPage(
+  extensions::browsertest_util::ExecuteScriptInBackgroundPageDeprecated(
       browser()->profile(), extension_misc::kChromeVoxExtensionId,
       "import('" + path +
           "').then(mod => {"
diff --git a/chrome/browser/ash/accessibility/switch_access_browsertest.cc b/chrome/browser/ash/accessibility/switch_access_browsertest.cc
index 4ffdc01..143d60e 100644
--- a/chrome/browser/ash/accessibility/switch_access_browsertest.cc
+++ b/chrome/browser/ash/accessibility/switch_access_browsertest.cc
@@ -94,7 +94,7 @@
         << test_support_path;
 
     std::string result =
-        extensions::browsertest_util::ExecuteScriptInBackgroundPage(
+        extensions::browsertest_util::ExecuteScriptInBackgroundPageDeprecated(
             browser()->profile(), extension_misc::kSwitchAccessExtensionId,
             script);
     ASSERT_EQ("ready", result);
@@ -103,7 +103,7 @@
   // Run js snippet and wait for it to finish.
   void WaitForJS(const std::string& js_to_eval) {
     std::string result =
-        extensions::browsertest_util::ExecuteScriptInBackgroundPage(
+        extensions::browsertest_util::ExecuteScriptInBackgroundPageDeprecated(
             browser()->profile(), extension_misc::kSwitchAccessExtensionId,
             js_to_eval,
             extensions::browsertest_util::ScriptUserActivation::kDontActivate);
diff --git a/chrome/browser/ash/app_list/search/local_images/sql_database.cc b/chrome/browser/ash/app_list/search/local_images/sql_database.cc
index 66bd34b..e1426ba 100644
--- a/chrome/browser/ash/app_list/search/local_images/sql_database.cc
+++ b/chrome/browser/ash/app_list/search/local_images/sql_database.cc
@@ -142,7 +142,7 @@
   DVLOG(1) << "Razing db.";
   if (db_ && db_->is_open()) {
     // Sometimes it fails to do it due to locks or open handles.
-    if (!db_->Raze() && !base::DeleteFile(path_to_db_)) {
+    if (!db_->Raze() && !sql::Database::Delete(path_to_db_)) {
       return false;
     }
     db_.reset();
diff --git a/chrome/browser/ash/app_mode/kiosk_crash_restore_browsertest.cc b/chrome/browser/ash/app_mode/kiosk_crash_restore_browsertest.cc
index 800d5d45..772b66c1 100644
--- a/chrome/browser/ash/app_mode/kiosk_crash_restore_browsertest.cc
+++ b/chrome/browser/ash/app_mode/kiosk_crash_restore_browsertest.cc
@@ -12,9 +12,9 @@
 #include "base/values.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_launch_error.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_manager.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/embedded_test_server_setup_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/local_state_mixin.h"
 #include "chrome/browser/ash/ownership/owner_settings_service_ash_factory.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
diff --git a/chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.cc b/chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.cc
index 4ff870ab..e4072bc 100644
--- a/chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.cc
+++ b/chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.cc
@@ -9,7 +9,7 @@
 namespace arc {
 
 ArcActiveWindowThrottleObserver::ArcActiveWindowThrottleObserver()
-    : WindowThrottleObserverBase("ArcWindowIsActiveWindow") {}
+    : WindowThrottleObserverBase(kArcActiveWindowThrottleObserverName) {}
 
 bool ArcActiveWindowThrottleObserver::ProcessWindowActivation(
     ActivationReason reason,
diff --git a/chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.h b/chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.h
index 885445c..5d26d0f 100644
--- a/chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.h
+++ b/chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.h
@@ -9,6 +9,11 @@
 
 namespace arc {
 
+namespace {
+constexpr char kArcActiveWindowThrottleObserverName[] =
+    "ArcWindowIsActiveWindow";
+}  // namespace
+
 // This class observes window activations and sets the state to active if the
 // currently active window is an ARC window.
 class ArcActiveWindowThrottleObserver : public ash::WindowThrottleObserverBase {
diff --git a/chrome/browser/ash/arc/vmm/arc_system_state_observation.cc b/chrome/browser/ash/arc/vmm/arc_system_state_observation.cc
new file mode 100644
index 0000000..09f9cc2
--- /dev/null
+++ b/chrome/browser/ash/arc/vmm/arc_system_state_observation.cc
@@ -0,0 +1,42 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/arc/vmm/arc_system_state_observation.h"
+
+#include "chrome/browser/ash/arc/idle_manager/arc_background_service_observer.h"
+#include "chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.h"
+
+namespace arc {
+
+ArcSystemStateObservation::ArcSystemStateObservation(
+    content::BrowserContext* context)
+    : ThrottleService(context) {
+  // TODO(sstan): Use ARC window observer after it's landed.
+  AddObserver(std::make_unique<ArcActiveWindowThrottleObserver>());
+
+  // Observe background service in ARC side.
+  AddObserver(std::make_unique<ArcBackgroundServiceObserver>());
+}
+
+ArcSystemStateObservation::~ArcSystemStateObservation() = default;
+
+void ArcSystemStateObservation::ThrottleInstance(bool should_throttle) {
+  // ARC system or app is active.
+  if (!should_throttle) {
+    last_peace_timestamp_.reset();
+    return;
+  }
+
+  // ARC system and app is not active.
+  last_peace_timestamp_ = base::Time::Now();
+}
+
+absl::optional<base::TimeDelta> ArcSystemStateObservation::GetPeaceDuration() {
+  if (last_peace_timestamp_->is_null()) {
+    return absl::nullopt;
+  }
+  return base::Time::Now() - *last_peace_timestamp_;
+}
+
+}  // namespace arc
diff --git a/chrome/browser/ash/arc/vmm/arc_system_state_observation.h b/chrome/browser/ash/arc/vmm/arc_system_state_observation.h
new file mode 100644
index 0000000..25272c91
--- /dev/null
+++ b/chrome/browser/ash/arc/vmm/arc_system_state_observation.h
@@ -0,0 +1,38 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_ASH_ARC_VMM_ARC_SYSTEM_STATE_OBSERVATION_H_
+#define CHROME_BROWSER_ASH_ARC_VMM_ARC_SYSTEM_STATE_OBSERVATION_H_
+
+#include "chrome/browser/ash/throttle_service.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
+
+namespace content {
+class BrowserContext;
+}
+
+namespace arc {
+
+class ArcSystemStateObservation : public ash::ThrottleService {
+ public:
+  explicit ArcSystemStateObservation(content::BrowserContext* context);
+
+  ArcSystemStateObservation(const ArcSystemStateObservation&) = delete;
+  ArcSystemStateObservation& operator=(const ArcSystemStateObservation&) =
+      delete;
+
+  ~ArcSystemStateObservation() override;
+
+  absl::optional<base::TimeDelta> GetPeaceDuration();
+
+  // ash::ThrottleService override:
+  void ThrottleInstance(bool should_throttle) override;
+
+ private:
+  absl::optional<base::Time> last_peace_timestamp_;
+};
+
+}  // namespace arc
+
+#endif  // CHROME_BROWSER_ASH_ARC_VMM_ARC_SYSTEM_STATE_OBSERVATION_H_
diff --git a/chrome/browser/ash/arc/vmm/arc_system_state_observation_unittest.cc b/chrome/browser/ash/arc/vmm/arc_system_state_observation_unittest.cc
new file mode 100644
index 0000000..c43414b
--- /dev/null
+++ b/chrome/browser/ash/arc/vmm/arc_system_state_observation_unittest.cc
@@ -0,0 +1,55 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ash/arc/vmm/arc_system_state_observation.h"
+
+#include "chrome/browser/ash/arc/idle_manager/arc_background_service_observer.h"
+#include "chrome/browser/ash/arc/instance_throttle/arc_active_window_throttle_observer.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/public/test/browser_task_environment.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace arc {
+
+class ArcSystemStateObservationTest : public testing::Test {
+ public:
+  ArcSystemStateObservationTest() = default;
+
+  ArcSystemStateObservationTest(const ArcSystemStateObservationTest&) = delete;
+  ArcSystemStateObservationTest& operator=(
+      const ArcSystemStateObservationTest&) = delete;
+
+  ~ArcSystemStateObservationTest() override = default;
+
+  void SetUp() override {
+    // Order matters: TestingProfile must be after ArcServiceManager.
+    testing_profile_ = std::make_unique<TestingProfile>();
+
+    observation_ =
+        std::make_unique<ArcSystemStateObservation>(testing_profile_.get());
+
+    active_window_observer_ =
+        observation_->GetObserverByName(kArcActiveWindowThrottleObserverName);
+    background_service_observer_ =
+        observation_->GetObserverByName(kArcBackgroundServiceObserverName);
+  }
+
+  void TearDown() override { testing_profile_.reset(); }
+
+ private:
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+  std::unique_ptr<TestingProfile> testing_profile_;
+
+  std::unique_ptr<ArcSystemStateObservation> observation_;
+
+  ash::ThrottleObserver* active_window_observer_;
+  ash::ThrottleObserver* background_service_observer_;
+};
+
+TEST_F(ArcSystemStateObservationTest, TestConstructDestruct) {}
+
+// TODO(sstan): Test the ARC system running state update from mojo.
+
+}  // namespace arc
diff --git a/chrome/browser/ash/input_method/ui/undo_window.cc b/chrome/browser/ash/input_method/ui/undo_window.cc
index 1e2aee9..332de6d 100644
--- a/chrome/browser/ash/input_method/ui/undo_window.cc
+++ b/chrome/browser/ash/input_method/ui/undo_window.cc
@@ -104,15 +104,15 @@
   const auto* const color_provider = GetColorProvider();
   learn_more_button_->SetBorder(views::CreatePaddedBorder(
       views::CreateSolidSidedBorder(
-          gfx::Insets::TLBR(1, 0, 0, 0),
-          color_provider->GetColor(ui::kColorBubbleFooterBorder)),
+          gfx::Insets::TLBR(4, 0, 4, 4),
+          color_provider->GetColor(ui::kColorButtonBackground)),
       views::LayoutProvider::Get()->GetInsetsMetric(
           views::INSETS_VECTOR_IMAGE_BUTTON)));
 
   // TODO(crbug.com/1099044): Update and use cros colors.
   learn_more_button_->SetImageModel(
       views::Button::ButtonState::STATE_NORMAL,
-      ui::ImageModel::FromVectorIcon(vector_icons::kHelpOutlineIcon,
+      ui::ImageModel::FromVectorIcon(vector_icons::kSettingsOutlineIcon,
                                      ui::kColorIconSecondary));
 
   BubbleDialogDelegateView::OnThemeChanged();
diff --git a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc
index e7826b2..d1a11d3 100644
--- a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc
+++ b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.cc
@@ -9,17 +9,14 @@
 #include "ash/constants/ash_switches.h"
 #include "ash/public/cpp/login_accelerators.h"
 #include "base/check_is_test.h"
-#include "base/debug/stack_trace.h"
 #include "base/feature_list.h"
 #include "base/functional/bind.h"
 #include "base/functional/callback.h"
 #include "base/functional/callback_helpers.h"
-#include "base/location.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/metrics/histogram_macros.h"
 #include "base/notreached.h"
 #include "base/syslog_logging.h"
-#include "base/task/sequenced_task_runner.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/app_mode/app_launch_utils.h"
 #include "chrome/browser/ash/app_mode/arc/arc_kiosk_app_manager.h"
@@ -35,7 +32,6 @@
 #include "chrome/browser/ash/crosapi/browser_data_migrator.h"
 #include "chrome/browser/ash/crosapi/browser_util.h"
 #include "chrome/browser/ash/login/app_mode/force_install_observer.h"
-#include "chrome/browser/ash/login/app_mode/network_ui_controller.h"
 #include "chrome/browser/ash/login/enterprise_user_session_metrics.h"
 #include "chrome/browser/ash/login/screens/encryption_migration_screen.h"
 #include "chrome/browser/ash/login/ui/login_display_host.h"
@@ -69,6 +65,12 @@
 // tests.
 bool g_disable_login_operations = false;
 
+base::OnceClosure* network_timeout_callback = nullptr;
+KioskLaunchController::ReturnBoolCallback* can_configure_network_callback =
+    nullptr;
+KioskLaunchController::ReturnBoolCallback*
+    need_owner_auth_to_configure_network_callback = nullptr;
+
 // Enum types for Kiosk.LaunchType UMA so don't change its values.
 // KioskLaunchType in histogram.xml must be updated when making changes here.
 enum KioskLaunchType {
@@ -203,16 +205,8 @@
   return base::Seconds(min_time_in_seconds);
 }
 
-template <class T>
-void DeleteSoon(std::unique_ptr<T> pointer) {
-  base::SequencedTaskRunner::GetCurrentDefault()->DeleteSoon(
-      FROM_HERE, std::move(pointer));
-}
-
 }  // namespace
 
-using NetworkUIState = NetworkUiController::NetworkUIState;
-
 const char kKioskLaunchStateCrashKey[] = "kiosk-launch-state";
 const base::TimeDelta kDefaultKioskSplashScreenMinTime = base::Seconds(10);
 
@@ -248,9 +242,7 @@
     KioskAppLauncherFactory app_launcher_factory)
     : host_(host),
       splash_screen_view_(splash_screen),
-      app_launcher_factory_(std::move(app_launcher_factory)),
-      network_ui_controller_(
-          std::make_unique<NetworkUiController>(*this, host, splash_screen)) {}
+      app_launcher_factory_(std::move(app_launcher_factory)) {}
 
 KioskLaunchController::~KioskLaunchController() {
   if (splash_screen_view_) {
@@ -283,7 +275,7 @@
     }
   }
 
-  splash_screen_view_->SetDelegate(network_ui_controller_.get());
+  splash_screen_view_->SetDelegate(this);
   splash_screen_view_->Show(GetAppData());
 
   splash_wait_timer_.Start(FROM_HERE, GetSplashScreenMinTime(),
@@ -357,12 +349,15 @@
 
   // This is needed to trigger input method extensions being loaded.
   profile->InitChromeOSPreferences();
-  network_ui_controller_->SetProfile(profile);
 
   InitializeKeyboard();
 
-  if (network_ui_controller_->ShouldShowNetworkConfig()) {
-    network_ui_controller_->UserRequestedNetworkConfig();
+  // We have loaded the profile, so we can create and start the
+  // `KioskAppLauncher`. However, if the user has requested to configure the
+  // network beforehand, we will show the dialog instead and create the launcher
+  // when that's done.
+  if (network_ui_state_ == NetworkUIState::kNeedToShow) {
+    ShowNetworkConfigureUI();
   } else {
     InitializeLauncher();
   }
@@ -382,12 +377,31 @@
   DCHECK(!app_launcher_);
 
   app_state_ = kInitLauncher;
-  app_launcher_ = app_launcher_factory_.Run(profile_, kiosk_app_id_,
-                                            network_ui_controller_.get());
+  app_launcher_ = app_launcher_factory_.Run(profile_, kiosk_app_id_, this);
   app_launcher_observation_.Observe(app_launcher_.get());
   app_launcher_->Initialize();
 }
 
+void KioskLaunchController::OnConfigureNetwork() {
+  DCHECK(profile_);
+  if (network_ui_state_ == NetworkUIState::kShowing) {
+    return;
+  }
+
+  network_ui_state_ = NetworkUIState::kShowing;
+  if (CanConfigureNetwork() && NeedOwnerAuthToConfigureNetwork()) {
+    host_->VerifyOwnerForKiosk(
+        base::BindOnce(&KioskLaunchController::ShowNetworkConfigureUI,
+                       weak_ptr_factory_.GetWeakPtr()));
+  } else {
+    // If kiosk mode was configured through enterprise policy, we may
+    // not have an owner user.
+    // TODO(tengs): We need to figure out the appropriate security meausres
+    // for this case.
+    NOTREACHED();
+  }
+}
+
 void KioskLaunchController::OnCancelAppLaunch() {
   if (cleaned_up_) {
     return;
@@ -448,15 +462,9 @@
   splash_wait_timer_.Stop();
 
   splash_screen_view_ = nullptr;
+  force_install_observer_.reset();
 
-  app_launcher_observation_.Reset();
-
-  // Deleting the local objects later so they
-  DeleteSoon(std::move(kiosk_profile_loader_));
-  DeleteSoon(std::move(force_install_observer_));
-  DeleteSoon(std::move(app_launcher_));
-  DeleteSoon(std::move(network_ui_controller_));
-
+  kiosk_profile_loader_.reset();
   // Can be null in tests.
   if (host_) {
     host_->Finalize(base::OnceClosure());
@@ -507,7 +515,7 @@
     return;
   }
 
-  if (network_ui_controller_->IsShowingNetworkConfigScreen()) {
+  if (network_ui_state_ != NetworkUIState::kNotShowing) {
     return;
   }
 
@@ -530,6 +538,55 @@
                      weak_ptr_factory_.GetWeakPtr()));
 }
 
+void KioskLaunchController::InitializeNetwork() {
+  if (!splash_screen_view_) {
+    return;
+  }
+
+  network_ui_state_ = NetworkUIState::kWaitingForNetwork;
+  network_wait_timer_.Start(FROM_HERE, g_network_wait_time, this,
+                            &KioskLaunchController::OnNetworkWaitTimedOut);
+
+  // When we are asked to initialize network, we should remember that this app
+  // requires network.
+  network_required_ = true;
+  splash_screen_view_->SetNetworkRequired();
+
+  splash_screen_view_->UpdateAppLaunchState(
+      AppLaunchSplashScreenView::AppLaunchState::kPreparingNetwork);
+
+  if (splash_screen_view_->IsNetworkReady()) {
+    OnNetworkStateChanged(true);
+  }
+}
+
+void KioskLaunchController::OnNetworkWaitTimedOut() {
+  DCHECK(network_ui_state_ == NetworkUIState::kNotShowing ||
+         network_ui_state_ == NetworkUIState::kWaitingForNetwork);
+
+  auto connection_type = network::mojom::ConnectionType::CONNECTION_UNKNOWN;
+  content::GetNetworkConnectionTracker()->GetConnectionType(&connection_type,
+                                                            base::DoNothing());
+  SYSLOG(WARNING) << "OnNetworkWaitTimedout... connection = "
+                  << connection_type;
+  network_wait_timedout_ = true;
+
+  MaybeShowNetworkConfigureUI();
+
+  if (network_timeout_callback) {
+    std::move(*network_timeout_callback).Run();
+    network_timeout_callback = nullptr;
+  }
+}
+
+bool KioskLaunchController::IsNetworkReady() const {
+  return splash_screen_view_ && splash_screen_view_->IsNetworkReady();
+}
+
+bool KioskLaunchController::IsShowingNetworkConfigScreen() const {
+  return network_ui_state_ == NetworkUIState::kShowing;
+}
+
 void KioskLaunchController::OnLaunchFailed(KioskAppLaunchError::Error error) {
   if (cleaned_up_) {
     return;
@@ -680,27 +737,104 @@
   migration_screen->SetupInitialView();
 }
 
+bool KioskLaunchController::CanConfigureNetwork() {
+  if (can_configure_network_callback) {
+    return can_configure_network_callback->Run();
+  }
+
+  if (IsDeviceEnterpriseManaged()) {
+    bool should_prompt;
+    if (CrosSettings::Get()->GetBoolean(
+            kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
+            &should_prompt)) {
+      return should_prompt;
+    }
+    // Default to true to allow network configuration if the policy is
+    // missing.
+    return true;
+  }
+
+  return user_manager::UserManager::Get()->GetOwnerAccountId().is_valid();
+}
+
+bool KioskLaunchController::NeedOwnerAuthToConfigureNetwork() {
+  if (need_owner_auth_to_configure_network_callback) {
+    return need_owner_auth_to_configure_network_callback->Run();
+  }
+
+  return !IsDeviceEnterpriseManaged();
+}
+
+void KioskLaunchController::MaybeShowNetworkConfigureUI() {
+  SYSLOG(INFO) << "Network configure UI was requested to be shown.";
+  if (!splash_screen_view_) {
+    return;
+  }
+
+  if (!profile_) {
+    SYSLOG(INFO)
+        << "Postponing configure network dialog till profile is loaded.";
+    splash_screen_view_->UpdateAppLaunchState(
+        AppLaunchSplashScreenView::AppLaunchState::kShowingNetworkConfigureUI);
+    network_ui_state_ = kNeedToShow;
+    return;
+  }
+
+  if (CanConfigureNetwork()) {
+    if (NeedOwnerAuthToConfigureNetwork()) {
+      if (!network_wait_timedout_) {
+        OnConfigureNetwork();
+      } else {
+        splash_screen_view_->ToggleNetworkConfig(true);
+      }
+    } else {
+      ShowNetworkConfigureUI();
+    }
+  } else {
+    splash_screen_view_->UpdateAppLaunchState(
+        AppLaunchSplashScreenView::AppLaunchState::kNetworkWaitTimeout);
+  }
+}
+
+void KioskLaunchController::ShowNetworkConfigureUI() {
+  DCHECK(profile_);
+
+  // We're about to show the network configure UI, so we destroy the
+  // app_launcher_ and effectively reset the installation state. A new launcher
+  // will be created in `OnNetworkConfigFinished`.
+  app_launcher_observation_.Reset();
+  app_launcher_.reset();
+  // We should stop timers since they may fire during network
+  // configure UI.
+  splash_wait_timer_.Stop();
+  network_wait_timer_.Stop();
+  launch_on_install_ = true;
+  app_state_ = kInitNetwork;
+  network_ui_state_ = NetworkUIState::kShowing;
+  splash_screen_view_->ShowNetworkConfigureUI();
+}
+
+void KioskLaunchController::CloseNetworkConfigureScreenIfOnline() {
+  if (network_ui_state_ == NetworkUIState::kShowing && network_wait_timedout_) {
+    SYSLOG(INFO) << "We are back online, closing network configure screen.";
+    splash_screen_view_->ToggleNetworkConfig(false);
+    splash_screen_view_->ContinueAppLaunch();
+    network_ui_state_ = NetworkUIState::kNotShowing;
+  }
+}
+
 void KioskLaunchController::OnNetworkConfigRequested() {
-  if (app_state_ == AppState::kLaunched) {
+  if (app_state_ == kLaunched) {
     // We do nothing since the splash screen is soon to be destroyed.
     return;
   }
 
-  network_ui_controller_->UserRequestedNetworkConfig();
+  MaybeShowNetworkConfigureUI();
 }
 
-void KioskLaunchController::OnNetworkConfigureUiShowing() {
-  LOG(WARNING) << "bfranz: OnNetworkConfigureUiShowing ";
-  splash_wait_timer_.Stop();
-  app_state_ = kInitNetwork;
-  launch_on_install_ = true;
-  app_launcher_observation_.Reset();
-  app_launcher_.reset();
-}
+void KioskLaunchController::OnNetworkConfigFinished() {
+  network_ui_state_ = NetworkUIState::kNotShowing;
 
-void KioskLaunchController::OnNetworkConfigureUiFinished() {
-  LOG(WARNING) << "bfranz: OnNetworkConfigureUiFinished ";
-  LOG(WARNING) << "bfranz: " << base::debug::StackTrace();
   if (splash_screen_view_) {
     splash_screen_view_->UpdateAppLaunchState(
         AppLaunchSplashScreenView::AppLaunchState::kPreparingProfile);
@@ -710,13 +844,40 @@
   InitializeLauncher();
 }
 
-void KioskLaunchController::OnNetworkReady() {
-  app_launcher_->ContinueWithNetworkReady();
+void KioskLaunchController::OnNetworkStateChanged(bool online) {
+  if (online) {
+    OnNetworkOnline();
+  } else {
+    OnNetworkOffline();
+  }
 }
 
-void KioskLaunchController::OnNetworkLost() {
-  if (app_state_ == kInstallingApp || app_state_ == kInstallingExtensions) {
-    network_ui_controller_->OnNetworkLostDuringInstallation();
+void KioskLaunchController::OnNetworkOnline() {
+  bool network_showing_after_timeout =
+      network_wait_timedout_ && network_ui_state_ == NetworkUIState::kShowing;
+
+  if (!network_showing_after_timeout &&
+      network_ui_state_ != NetworkUIState::kWaitingForNetwork) {
+    // The UI is not showing at all, or was requested by the user so we do
+    // nothing
+    return;
+  }
+
+  // Close the network UI and continue the app launch
+  network_wait_timer_.Stop();
+  CloseNetworkConfigureScreenIfOnline();
+  network_ui_state_ = kNotShowing;
+  if (app_launcher_) {
+    app_launcher_->ContinueWithNetworkReady();
+  }
+}
+
+void KioskLaunchController::OnNetworkOffline() {
+  if (network_required_ && (app_state_ == AppState::kInstallingApp ||
+                            app_state_ == AppState::kInstallingExtensions)) {
+    SYSLOG(WARNING)
+        << "Connection lost during installation, restarting launcher.";
+    OnNetworkWaitTimedOut();
   }
 }
 
@@ -734,10 +895,6 @@
   app_launcher_->LaunchApp();
 }
 
-NetworkUiController* KioskLaunchController::GetNetworkUiControllerForTesting() {
-  return network_ui_controller_.get();
-}
-
 // static
 std::unique_ptr<base::AutoReset<bool>>
 KioskLaunchController::DisableLoginOperationsForTesting() {
@@ -771,4 +928,23 @@
   return base::AutoReset<bool>(&g_block_exit_on_failure_for_testing, true);
 }
 
+// static
+void KioskLaunchController::SetNetworkTimeoutCallbackForTesting(
+    base::OnceClosure* callback) {
+  network_timeout_callback = callback;
+}
+
+// static
+void KioskLaunchController::SetCanConfigureNetworkCallbackForTesting(
+    ReturnBoolCallback* callback) {
+  can_configure_network_callback = callback;
+}
+
+// static
+void KioskLaunchController::
+    SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
+        ReturnBoolCallback* callback) {
+  need_owner_auth_to_configure_network_callback = callback;
+}
+
 }  // namespace ash
diff --git a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h
index 65eb553..58655c8f 100644
--- a/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h
+++ b/chrome/browser/ash/login/app_mode/kiosk_launch_controller.h
@@ -17,7 +17,6 @@
 #include "chrome/browser/ash/app_mode/kiosk_app_types.h"
 #include "chrome/browser/ash/app_mode/kiosk_profile_loader.h"
 #include "chrome/browser/ash/login/app_mode/force_install_observer.h"
-#include "chrome/browser/ash/login/app_mode/network_ui_controller.h"
 #include "chrome/browser/ui/webui/ash/login/app_launch_splash_screen_handler.h"
 
 namespace app_mode {
@@ -83,8 +82,9 @@
 // It is all encompassed within the combination of two states -- AppState and
 // NetworkUI state.
 class KioskLaunchController : public KioskProfileLoader::Delegate,
-                              public KioskAppLauncher::Observer,
-                              public NetworkUiController::Observer {
+                              public AppLaunchSplashScreenView::Delegate,
+                              public KioskAppLauncher::NetworkDelegate,
+                              public KioskAppLauncher::Observer {
  public:
   class KioskProfileLoadFailedObserver : public base::CheckedObserver {
    public:
@@ -120,12 +120,18 @@
   [[nodiscard]] static std::unique_ptr<base::AutoReset<bool>>
   BlockAppLaunchForTesting();
   [[nodiscard]] static base::AutoReset<bool> BlockExitOnFailureForTesting();
+  static void SetNetworkTimeoutCallbackForTesting(base::OnceClosure* callback);
+  static void SetCanConfigureNetworkCallbackForTesting(
+      ReturnBoolCallback* callback);
+  static void SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
+      ReturnBoolCallback* callback);
 
   bool waiting_for_network() const {
     return app_state_ == AppState::kInitNetwork;
   }
+  bool network_wait_timedout() const { return network_wait_timedout_; }
   bool showing_network_dialog() const {
-    return network_ui_controller_->IsShowingNetworkConfigScreen();
+    return network_ui_state_ == NetworkUIState::kShowing;
   }
 
   void Start(const KioskAppId& kiosk_app_id, bool auto_launch);
@@ -138,18 +144,6 @@
 
   bool HandleAccelerator(LoginAcceleratorAction action);
 
-  // `NetworkUiController::Observer`:
-  void OnNetworkConfigureUiShowing() override;
-  void OnNetworkConfigureUiFinished() override;
-  void OnNetworkReady() override;
-  void OnNetworkLost() override;
-
-  // Currently required for testing
-  NetworkUiController::NetworkUIState GetNetworkUiStateForTesting() const {
-    return network_ui_controller_->GetNetworkUiStateForTesting();
-  }
-  NetworkUiController* GetNetworkUiControllerForTesting();
-
  private:
   friend class KioskLaunchControllerTest;
 
@@ -164,11 +158,31 @@
     kInitNetwork,  // Waiting for the network to initialize.
   };
 
+  enum NetworkUIState {
+    kNotShowing = 0,     // Network configure UI is not being shown.
+    kNeedToShow,         // We need to show the UI as soon as we can.
+    kShowing,            // Network configure UI is being shown.
+    kWaitingForNetwork,  // App requested network. In this case we first wait
+                         // for 10s to see if network appears. If it does, we
+                         // continue the app launch, otherwise we show the
+                         // config network UI
+  };
+
   void OnCancelAppLaunch();
   void OnNetworkConfigRequested();
   void InitializeKeyboard();
   void InitializeLauncher();
 
+  // `AppLaunchSplashScreenView::Delegate`
+  void OnConfigureNetwork() override;
+  void OnNetworkConfigFinished() override;
+  void OnNetworkStateChanged(bool online) override;
+
+  // `KioskAppLauncher::NetworkDelegate`
+  void InitializeNetwork() override;
+  bool IsNetworkReady() const override;
+  bool IsShowingNetworkConfigScreen() const override;
+
   // `KioskAppLauncher::Observer`
   void OnLaunchFailed(KioskAppLaunchError::Error error) override;
   void OnAppInstalling() override;
@@ -187,6 +201,14 @@
 
   // Whether the network could be configured during launching.
   bool CanConfigureNetwork();
+  // Whether the owner password is needed to configure network.
+  bool NeedOwnerAuthToConfigureNetwork();
+  // Shows network configuration dialog if kiosk profile was already created or
+  // postpones the display upon creation.
+  void MaybeShowNetworkConfigureUI();
+  // Shows the network configuration dialog.
+  void ShowNetworkConfigureUI();
+  void CloseNetworkConfigureScreenIfOnline();
 
   void HandleWebAppInstallFailed();
 
@@ -195,6 +217,7 @@
   void FinishForcedExtensionsInstall(
       app_mode::ForceInstallObserver::Result result);
 
+  void OnNetworkWaitTimedOut();
   void OnNetworkOnline();
   void OnNetworkOffline();
   void OnTimerFire();
@@ -206,6 +229,8 @@
 
   // Current state of the controller.
   AppState app_state_ = AppState::kCreatingProfile;
+  // Current state of network configure dialog.
+  NetworkUIState network_ui_state_ = NetworkUIState::kNotShowing;
 
   // Not owned, destructed upon shutdown.
   raw_ptr<LoginDisplayHost> const host_;
@@ -216,10 +241,12 @@
   // Not owned.
   raw_ptr<Profile> profile_ = nullptr;
   const KioskAppLauncherFactory app_launcher_factory_;
-  std::unique_ptr<NetworkUiController> network_ui_controller_;
 
   // Whether app should be launched as soon as it is ready.
   bool launch_on_install_ = false;
+  bool network_wait_timedout_ = false;
+  // Whether the network is required for the installation.
+  bool network_required_ = false;
 
   // Whether the controller has already been cleaned-up.
   bool cleaned_up_ = false;
diff --git a/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc b/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc
index 244920ce..c0f993952 100644
--- a/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc
+++ b/chrome/browser/ash/login/app_mode/kiosk_launch_controller_unittest.cc
@@ -18,7 +18,7 @@
 #include "chrome/browser/ash/app_mode/kiosk_app_launcher.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_types.h"
 #include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/browser_process_platform_part.h"
@@ -87,7 +87,7 @@
 class KioskLaunchControllerTest : public extensions::ExtensionServiceTestBase {
  public:
   using AppState = KioskLaunchController::AppState;
-  using NetworkUIState = NetworkUiController::NetworkUIState;
+  using NetworkUIState = KioskLaunchController::NetworkUIState;
 
   KioskLaunchControllerTest()
       : extensions::ExtensionServiceTestBase(
@@ -136,12 +136,12 @@
 
   KioskLaunchController& controller() { return *controller_; }
 
-  KioskAppLauncher::NetworkDelegate& network_delegate() {
-    return *controller_->GetNetworkUiControllerForTesting();
-  }
+  KioskAppLauncher::NetworkDelegate& network_delegate() { return *controller_; }
 
   KioskProfileLoader::Delegate& profile_controls() { return *controller_; }
 
+  AppLaunchSplashScreenView::Delegate& view_controls() { return *controller_; }
+
   FakeKioskAppLauncher& launcher() { return *app_launcher_; }
 
   int num_launchers_created() { return app_launchers_created_; }
@@ -150,9 +150,9 @@
     return testing::AllOf(
         testing::Field("app_state", &KioskLaunchController::app_state_,
                        Eq(app_state)),
-        testing::Property("network_ui_state",
-                          &KioskLaunchController::GetNetworkUiStateForTesting,
-                          Eq(network_state)));
+        testing::Field("network_ui_state",
+                       &KioskLaunchController::network_ui_state_,
+                       Eq(network_state)));
   }
 
   auto HasViewState(AppLaunchSplashScreenView::AppLaunchState launch_state) {
diff --git a/chrome/browser/ash/login/app_mode/network_ui_controller.cc b/chrome/browser/ash/login/app_mode/network_ui_controller.cc
deleted file mode 100644
index 191f753..0000000
--- a/chrome/browser/ash/login/app_mode/network_ui_controller.cc
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ash/login/app_mode/network_ui_controller.h"
-
-#include "base/syslog_logging.h"
-#include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
-#include "chrome/browser/ash/login/ui/login_display_host.h"
-#include "chrome/browser/ash/policy/core/browser_policy_connector_ash.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/browser_process_platform_part_ash.h"
-#include "chromeos/ash/components/settings/cros_settings_names.h"
-#include "components/user_manager/user_manager.h"
-#include "content/public/browser/network_service_instance.h"
-
-namespace {
-
-// Time of waiting for the network to be ready to start installation. Can be
-// changed in tests.
-constexpr base::TimeDelta kKioskNetworkWaitTime = base::Seconds(10);
-base::TimeDelta g_network_wait_time = kKioskNetworkWaitTime;
-
-base::RepeatingCallback<bool()>* g_can_configure_network_callback = nullptr;
-base::RepeatingCallback<bool()>*
-    g_need_owner_auth_to_configure_network_callback = nullptr;
-base::OnceClosure* g_network_timeout_callback = nullptr;
-
-bool IsDeviceEnterpriseManaged() {
-  return g_browser_process->platform_part()
-      ->browser_policy_connector_ash()
-      ->IsDeviceEnterpriseManaged();
-}
-
-bool IsConsumerKiosk() {
-  if (g_need_owner_auth_to_configure_network_callback) {
-    return g_need_owner_auth_to_configure_network_callback->Run();
-  }
-
-  return !IsDeviceEnterpriseManaged();
-}
-
-bool CanConfigureNetworkForConsumerKiosk() {
-  return user_manager::UserManager::Get()->GetOwnerAccountId().is_valid();
-}
-
-bool CanConfigureNetworkForEnterpriseKiosk() {
-  bool should_prompt;
-  if (ash::CrosSettings::Get()->GetBoolean(
-          ash::kAccountsPrefDeviceLocalAccountPromptForNetworkWhenOffline,
-          &should_prompt)) {
-    return should_prompt;
-  }
-  // Default to true to allow network configuration if the policy is
-  // missing.
-  return true;
-}
-
-network::mojom::ConnectionType GetCurrentConnectionType() {
-  auto connection_type = network::mojom::ConnectionType::CONNECTION_UNKNOWN;
-  content::GetNetworkConnectionTracker()->GetConnectionType(&connection_type,
-                                                            base::DoNothing());
-  return connection_type;
-}
-
-}  // namespace
-
-namespace ash {
-
-NetworkUiController::NetworkUiController(
-    Observer& observer,
-    LoginDisplayHost* host,
-    AppLaunchSplashScreenView* splash_screen)
-    : observer_(observer), host_(host), splash_screen_view_(splash_screen) {}
-
-NetworkUiController::~NetworkUiController() = default;
-
-void NetworkUiController::SetProfile(Profile* profile) {
-  profile_ = profile;
-}
-
-void NetworkUiController::UserRequestedNetworkConfig() {
-  if (!profile_) {
-    SYSLOG(INFO) << "Postponing network dialog till profile is loaded.";
-    network_ui_state_ = NetworkUIState::kNeedToShow;
-    splash_screen_view_->UpdateAppLaunchState(
-        AppLaunchSplashScreenView::AppLaunchState::kShowingNetworkConfigureUI);
-    return;
-  }
-
-  MaybeShowNetworkConfigureUI();
-}
-
-bool NetworkUiController::ShouldShowNetworkConfig() {
-  return network_ui_state_ == kNeedToShow;
-}
-
-void NetworkUiController::OnNetworkLostDuringInstallation() {
-  if (network_required_) {
-    SYSLOG(WARNING) << "Connection lost during installation.";
-    OnNetworkWaitTimeout();
-  }
-}
-
-void NetworkUiController::InitializeNetwork() {
-  if (!splash_screen_view_) {
-    return;
-  }
-
-  network_ui_state_ = NetworkUIState::kWaitingForNetwork;
-
-  network_wait_timer_.Start(FROM_HERE, g_network_wait_time, this,
-                            &NetworkUiController::OnNetworkWaitTimeout);
-
-  // When we are asked to initialize network, we should remember that this app
-  // requires network.
-  network_required_ = true;
-  splash_screen_view_->SetNetworkRequired();
-
-  splash_screen_view_->UpdateAppLaunchState(
-      AppLaunchSplashScreenView::AppLaunchState::kPreparingNetwork);
-
-  if (splash_screen_view_->IsNetworkReady()) {
-    OnNetworkOnline();
-  }
-}
-
-void NetworkUiController::OnConfigureNetwork() {
-  CHECK(IsConsumerKiosk());
-  CHECK(profile_);
-
-  if (network_ui_state_ == NetworkUIState::kShowing) {
-    return;
-  }
-
-  if (CanConfigureNetworkForConsumerKiosk()) {
-    host_->VerifyOwnerForKiosk(
-        base::BindOnce(&NetworkUiController::ShowNetworkConfigureUI,
-                       weak_ptr_factory_.GetWeakPtr()));
-  }
-}
-
-void NetworkUiController::OnNetworkConfigFinished() {
-  network_ui_state_ = NetworkUIState::kNotShowing;
-
-  observer_->OnNetworkConfigureUiFinished();
-}
-
-void NetworkUiController::OnNetworkStateChanged(bool online) {
-  if (online) {
-    OnNetworkOnline();
-  } else {
-    OnNetworkOffline();
-  }
-}
-
-void NetworkUiController::OnNetworkOnline() {
-  bool network_showing_after_timeout =
-      network_wait_timeout_ && network_ui_state_ == kShowing;
-  bool is_waiting_for_network = network_ui_state_ == kWaitingForNetwork;
-
-  if (!is_waiting_for_network && !network_showing_after_timeout) {
-    // The UI is not showing at all, or was requested by the user so we do
-    // nothing
-    return;
-  }
-
-  network_wait_timer_.Stop();
-  network_ui_state_ = kNotShowing;
-
-  if (network_showing_after_timeout) {
-    SYSLOG(INFO) << "We are back online, closing network configure screen.";
-    CloseNetworkConfigureUI();
-  } else {
-    observer_->OnNetworkReady();
-  }
-}
-
-void NetworkUiController::OnNetworkOffline() {
-  observer_->OnNetworkLost();
-}
-
-void NetworkUiController::CloseNetworkConfigureUI() {
-  splash_screen_view_->ToggleNetworkConfig(false);
-  splash_screen_view_->ContinueAppLaunch();
-}
-
-bool NetworkUiController::IsNetworkReady() const {
-  return splash_screen_view_ && splash_screen_view_->IsNetworkReady();
-}
-
-bool NetworkUiController::IsShowingNetworkConfigScreen() const {
-  return network_ui_state_ == NetworkUIState::kShowing;
-}
-
-void NetworkUiController::MaybeShowNetworkConfigureUI() {
-  SYSLOG(INFO) << "Network configure UI was requested to be shown.";
-  if (!splash_screen_view_) {
-    return;
-  }
-
-  if (!CanConfigureNetwork()) {
-    splash_screen_view_->UpdateAppLaunchState(
-        AppLaunchSplashScreenView::AppLaunchState::kNetworkWaitTimeout);
-    return;
-  }
-
-  if (IsConsumerKiosk()) {
-    MaybeShowNetworkConfigureUIForConsumerKiosk();
-  } else {
-    ShowNetworkConfigureUI();
-  }
-}
-
-void NetworkUiController::ShowNetworkConfigureUI() {
-  // We should stop timers since they may fire during network
-  // configure UI.
-  network_wait_timer_.Stop();
-  network_ui_state_ = NetworkUIState::kShowing;
-  splash_screen_view_->ShowNetworkConfigureUI();
-
-  observer_->OnNetworkConfigureUiShowing();
-}
-
-void NetworkUiController::OnNetworkWaitTimeout() {
-  DCHECK(network_ui_state_ == NetworkUIState::kNotShowing ||
-         network_ui_state_ == NetworkUIState::kWaitingForNetwork);
-
-  network::mojom::ConnectionType connection_type = GetCurrentConnectionType();
-  SYSLOG(WARNING) << __FUNCTION__ << " connection = " << connection_type;
-  network_wait_timeout_ = true;
-
-  MaybeShowNetworkConfigureUI();
-
-  if (g_network_timeout_callback) {
-    std::move(*g_network_timeout_callback).Run();
-    g_network_timeout_callback = nullptr;
-  }
-}
-
-bool NetworkUiController::CanConfigureNetwork() {
-  if (g_can_configure_network_callback) {
-    return g_can_configure_network_callback->Run();
-  }
-
-  if (IsDeviceEnterpriseManaged()) {
-    return CanConfigureNetworkForEnterpriseKiosk();
-  }
-
-  return CanConfigureNetworkForConsumerKiosk();
-}
-
-void NetworkUiController::MaybeShowNetworkConfigureUIForConsumerKiosk() {
-  if (!network_wait_timeout_) {
-    OnConfigureNetwork();
-  } else {
-    splash_screen_view_->ToggleNetworkConfig(true);
-  }
-}
-
-// static
-void NetworkUiController::SetCanConfigureNetworkCallbackForTesting(
-    base::RepeatingCallback<bool()>* callback) {
-  g_can_configure_network_callback = callback;
-}
-
-// static
-void NetworkUiController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
-    base::RepeatingCallback<bool()>* callback) {
-  g_need_owner_auth_to_configure_network_callback = callback;
-}
-
-// static
-void NetworkUiController::SetNetworkTimeoutCallbackForTesting(
-    base::OnceClosure* callback) {
-  g_network_timeout_callback = callback;
-}
-
-}  // namespace ash
diff --git a/chrome/browser/ash/login/app_mode/network_ui_controller.h b/chrome/browser/ash/login/app_mode/network_ui_controller.h
deleted file mode 100644
index 61bdb05f1..0000000
--- a/chrome/browser/ash/login/app_mode/network_ui_controller.h
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ASH_LOGIN_APP_MODE_NETWORK_UI_CONTROLLER_H_
-#define CHROME_BROWSER_ASH_LOGIN_APP_MODE_NETWORK_UI_CONTROLLER_H_
-
-#include "base/timer/timer.h"
-#include "chrome/browser/ash/app_mode/kiosk_app_launcher.h"
-#include "chrome/browser/ui/webui/ash/login/app_launch_splash_screen_handler.h"
-
-class Profile;
-
-namespace ash {
-
-class LoginDisplayHost;
-
-class NetworkUiController : public AppLaunchSplashScreenView::Delegate,
-                            public KioskAppLauncher::NetworkDelegate {
- public:
-  enum NetworkUIState {
-    kNotShowing = 0,     // Network configure UI is not being shown.
-    kNeedToShow,         // We need to show the UI as soon as we can.
-    kShowing,            // Network configure UI is being shown.
-    kWaitingForNetwork,  // App requested network and we're waiting for it
-  };
-
-  class Observer {
-   public:
-    Observer() = default;
-    Observer(const Observer&) = delete;
-    Observer& operator=(const Observer&) = delete;
-    ~Observer() = default;
-
-    virtual void OnNetworkConfigureUiShowing() = 0;
-    virtual void OnNetworkConfigureUiFinished() = 0;
-    virtual void OnNetworkReady() = 0;
-    virtual void OnNetworkLost() = 0;
-  };
-
-  NetworkUiController(Observer& observer,
-                      LoginDisplayHost* host,
-                      AppLaunchSplashScreenView* splash_screen);
-  NetworkUiController(const NetworkUiController&) = delete;
-  NetworkUiController& operator=(const NetworkUiController&) = delete;
-  ~NetworkUiController() override;
-
-  void SetProfile(Profile* profile);
-  void UserRequestedNetworkConfig();
-  bool ShouldShowNetworkConfig();
-  void OnNetworkLostDuringInstallation();
-
-  // `AppLaunchSplashScreenView::Delegate`
-  void OnConfigureNetwork() override;
-  void OnNetworkConfigFinished() override;
-  void OnNetworkStateChanged(bool online) override;
-
-  // `KioskAppLauncher::NetworkDelegate`
-  void InitializeNetwork() override;
-  bool IsNetworkReady() const override;
-  bool IsShowingNetworkConfigScreen() const override;
-
-  NetworkUIState GetNetworkUiStateForTesting() const {
-    return network_ui_state_;
-  }
-
-  static void SetCanConfigureNetworkCallbackForTesting(
-      base::RepeatingCallback<bool()>* callback);
-  static void SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
-      base::RepeatingCallback<bool()>* callback);
-  static void SetNetworkTimeoutCallbackForTesting(base::OnceClosure* callback);
-
- private:
-  void MaybeShowNetworkConfigureUI();
-  void MaybeShowNetworkConfigureUIForConsumerKiosk();
-  void ShowNetworkConfigureUI();
-  void CloseNetworkConfigureUI();
-
-  void OnNetworkWaitTimeout();
-  bool CanConfigureNetwork();
-
-  void OnNetworkOnline();
-  void OnNetworkOffline();
-
-  const raw_ref<Observer> observer_;
-  const raw_ptr<LoginDisplayHost> host_;
-  const raw_ptr<AppLaunchSplashScreenView> splash_screen_view_;
-  raw_ptr<Profile> profile_ = nullptr;
-
-  NetworkUIState network_ui_state_ = kNotShowing;
-  bool network_required_ = false;
-
-  // A timer that fires when the network was not prepared and we require user
-  // network configuration to continue.
-  base::OneShotTimer network_wait_timer_;
-  bool network_wait_timeout_ = false;
-
-  base::WeakPtrFactory<NetworkUiController> weak_ptr_factory_{this};
-};
-
-}  // namespace ash
-
-#endif  // CHROME_BROWSER_ASH_LOGIN_APP_MODE_NETWORK_UI_CONTROLLER_H_
diff --git a/chrome/browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc
index eff07d4..6178574 100644
--- a/chrome/browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc
@@ -17,8 +17,8 @@
 #include "chrome/browser/ash/app_mode/kiosk_app_launch_error.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/test/local_state_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_base_test.h"
diff --git a/chrome/browser/ash/login/test/kiosk_apps_mixin.cc b/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.cc
similarity index 97%
rename from chrome/browser/ash/login/test/kiosk_apps_mixin.cc
rename to chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.cc
index 33b1ae1..a88b606 100644
--- a/chrome/browser/ash/login/test/kiosk_apps_mixin.cc
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
 
 #include "ash/public/cpp/login_screen_test_api.h"
 #include "base/strings/strcat.h"
diff --git a/chrome/browser/ash/login/test/kiosk_apps_mixin.h b/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h
similarity index 87%
rename from chrome/browser/ash/login/test/kiosk_apps_mixin.h
rename to chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h
index 2ce62bf3..113107a 100644
--- a/chrome/browser/ash/login/test/kiosk_apps_mixin.h
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ASH_LOGIN_TEST_KIOSK_APPS_MIXIN_H_
-#define CHROME_BROWSER_ASH_LOGIN_TEST_KIOSK_APPS_MIXIN_H_
+#ifndef CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_APPS_MIXIN_H_
+#define CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_APPS_MIXIN_H_
 
 #include "chrome/browser/ash/app_mode/fake_cws.h"
 #include "chrome/test/base/mixin_based_in_process_browser_test.h"
@@ -42,4 +42,4 @@
 
 }  // namespace ash
 
-#endif  // CHROME_BROWSER_ASH_LOGIN_TEST_KIOSK_APPS_MIXIN_H_
+#endif  // CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_APPS_MIXIN_H_
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_base_test.cc b/chrome/browser/ash/login/app_mode/test/kiosk_base_test.cc
index cb816f0..d0d1fe16 100644
--- a/chrome/browser/ash/login/app_mode/test/kiosk_base_test.cc
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_base_test.cc
@@ -16,15 +16,13 @@
 #include "base/logging.h"
 #include "base/run_loop.h"
 #include "base/test/bind.h"
-#include "base/test/test_future.h"
 #include "base/values.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
-#include "chrome/browser/ash/login/app_mode/network_ui_controller.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/startup_utils.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/ash/login/test/oobe_window_visibility_waiter.h"
 #include "chrome/browser/ash/login/test/test_condition_waiter.h"
@@ -187,7 +185,7 @@
 void KioskBaseTest::TearDownOnMainThread() {
   owner_settings_service_.reset();
   settings_helper_.RestoreRealDeviceSettingsProvider();
-  NetworkUiController::SetNetworkTimeoutCallbackForTesting(nullptr);
+  KioskLaunchController::SetNetworkTimeoutCallbackForTesting(nullptr);
 
   OobeBaseTest::TearDownOnMainThread();
 }
@@ -325,11 +323,16 @@
 }
 
 void KioskBaseTest::WaitForAppLaunchNetworkTimeout() {
-  base::test::TestFuture<void> network_timeout_future;
-  base::OnceClosure callback = base::BindOnce(
-      &OnNetworkWaitTimedOut, network_timeout_future.GetCallback());
-  NetworkUiController::SetNetworkTimeoutCallbackForTesting(&callback);
-  ASSERT_TRUE(network_timeout_future.Wait());
+  if (GetKioskLaunchController()->network_wait_timedout()) {
+    return;
+  }
+
+  base::RunLoop loop;
+  base::OnceClosure callback =
+      base::BindOnce(&OnNetworkWaitTimedOut, loop.QuitClosure());
+  KioskLaunchController::SetNetworkTimeoutCallbackForTesting(&callback);
+  loop.Run();
+  ASSERT_TRUE(GetKioskLaunchController()->network_wait_timedout());
 }
 
 void KioskBaseTest::RunAppLaunchNetworkDownTest() {
@@ -347,8 +350,7 @@
   test::OobeJS().ExpectVisiblePath(kConfigNetwork);
 
   // Configure network should bring up lock screen for owner.
-  GetKioskLaunchController()
-      ->GetNetworkUiControllerForTesting()
+  static_cast<AppLaunchSplashScreenView::Delegate*>(GetKioskLaunchController())
       ->OnConfigureNetwork();
   EXPECT_FALSE(LoginScreenTestApi::IsOobeDialogVisible());
   // There should be only one owner pod on this screen.
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_device_owned_browsertest.cc b/chrome/browser/ash/login/app_mode/test/kiosk_device_owned_browsertest.cc
index 33560bb..64d80d5 100644
--- a/chrome/browser/ash/login/app_mode/test/kiosk_device_owned_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_device_owned_browsertest.cc
@@ -18,10 +18,10 @@
 #include "chrome/browser/ash/accessibility/speech_monitor.h"
 #include "chrome/browser/ash/app_mode/app_session_ash.h"
 #include "chrome/browser/ash/login/app_mode/test/kiosk_base_test.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/app_mode/test/test_browser_closed_waiter.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/ash/login/ui/login_display_host.h"
@@ -690,19 +690,19 @@
   // Extension should be loaded only once.
   EXPECT_EQ(ready_observer.fired_times(), 1);
 
-  constexpr char kSetInStorageAPI[] =
+  static constexpr char kSetInStorageAPI[] =
       R"(chrome.storage.local.set(
              {test: 'testValue'},
-             () => { domAutomationController.send('') });)";
+             () => { chrome.test.sendScriptResult('') });)";
   // Store some data using Storage API for the extension.
   extensions::browsertest_util::ExecuteScriptInBackgroundPage(
       app_profile, extension_misc::kChromeVoxExtensionId, kSetInStorageAPI);
 
   // Expect the data to be saved.
-  constexpr char kGetFromStorageAPI[] =
+  static constexpr char kGetFromStorageAPI[] =
       R"(chrome.storage.local.get(
              'test',
-             (value) => domAutomationController.send(value.test));)";
+             (value) => chrome.test.sendScriptResult(value.test));)";
   EXPECT_EQ("testValue",
             extensions::browsertest_util::ExecuteScriptInBackgroundPage(
                 app_profile, extension_misc::kChromeVoxExtensionId,
@@ -746,12 +746,12 @@
   EXPECT_EQ(ready_observer.fired_times(), 1);
 
   // Expect the data to be cleared.
-  constexpr char kGetFromStorageAPI[] =
+  static constexpr char kGetFromStorageAPI[] =
       R"(
       chrome.storage.local.get(
           "test",
           function(value) {
-              domAutomationController.send(value.test == undefined ?
+              chrome.test.sendScriptResult(value.test == undefined ?
                   "<none>" : value.test);
           }
       );
@@ -761,9 +761,9 @@
                 app_profile, extension_misc::kChromeVoxExtensionId,
                 kGetFromStorageAPI));
 
-  constexpr char kGetFromLocalStorage[] =
+  static constexpr char kGetFromLocalStorage[] =
       R"(
-      domAutomationController.send(
+      chrome.test.sendScriptResult(
           localStorage.getItem('test2') == undefined ?
               "<none>" : localStorage.getItem('test2'));
       )";
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_browsertest.cc b/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_browsertest.cc
index 1d46705..3904f1a 100644
--- a/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_browsertest.cc
@@ -13,9 +13,9 @@
 #include "chrome/browser/ash/app_mode/kiosk_app_launch_error.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/ash/login/app_mode/test/kiosk_base_test.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/app_mode/test/test_app_data_load_waiter.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
 #include "chrome/browser/device_identity/device_oauth2_token_service.h"
 #include "chrome/browser/device_identity/device_oauth2_token_service_factory.h"
diff --git a/chrome/browser/ash/login/test/kiosk_test_helpers.cc b/chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.cc
similarity index 82%
rename from chrome/browser/ash/login/test/kiosk_test_helpers.cc
rename to chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.cc
index 8a68358..a584802 100644
--- a/chrome/browser/ash/login/test/kiosk_test_helpers.cc
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.cc
@@ -2,11 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 
 #include "chrome/browser/ash/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
-#include "chrome/browser/ash/login/app_mode/network_ui_controller.h"
 #include "chrome/browser/ash/ownership/fake_owner_settings_service.h"
 #include "chrome/browser/profiles/profile_manager.h"
 
@@ -50,14 +49,14 @@
       needs_owner_auth_callback_(base::BindRepeating(
           &ScopedCanConfigureNetwork::NeedsOwnerAuthToConfigureNetwork,
           base::Unretained(this))) {
-  NetworkUiController::SetCanConfigureNetworkCallbackForTesting(
+  KioskLaunchController::SetCanConfigureNetworkCallbackForTesting(
       &can_configure_network_callback_);
-  NetworkUiController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
+  KioskLaunchController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
       &needs_owner_auth_callback_);
 }
 ScopedCanConfigureNetwork::~ScopedCanConfigureNetwork() {
-  NetworkUiController::SetCanConfigureNetworkCallbackForTesting(nullptr);
-  NetworkUiController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
+  KioskLaunchController::SetCanConfigureNetworkCallbackForTesting(nullptr);
+  KioskLaunchController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
       nullptr);
 }
 
diff --git a/chrome/browser/ash/login/test/kiosk_test_helpers.h b/chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h
similarity index 91%
rename from chrome/browser/ash/login/test/kiosk_test_helpers.h
rename to chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h
index fe826db..1cb7774a 100644
--- a/chrome/browser/ash/login/test/kiosk_test_helpers.h
+++ b/chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h
@@ -2,8 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#ifndef CHROME_BROWSER_ASH_LOGIN_TEST_KIOSK_TEST_HELPERS_H_
-#define CHROME_BROWSER_ASH_LOGIN_TEST_KIOSK_TEST_HELPERS_H_
+#ifndef CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_TEST_HELPERS_H_
+#define CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_TEST_HELPERS_H_
 
 #include "base/run_loop.h"
 #include "base/scoped_multi_source_observation.h"
@@ -73,4 +73,4 @@
 
 }  // namespace ash
 
-#endif  // CHROME_BROWSER_ASH_LOGIN_TEST_KIOSK_TEST_HELPERS_H_
+#endif  // CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_KIOSK_TEST_HELPERS_H_
diff --git a/chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.cc b/chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.cc
index f77826e..e4cc479 100644
--- a/chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.cc
+++ b/chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.cc
@@ -8,7 +8,7 @@
 #include "base/time/time.h"
 #include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/oobe_base_test.h"
 #include "chrome/browser/ash/ownership/fake_owner_settings_service.h"
 #include "chrome/browser/ash/policy/core/device_local_account.h"
diff --git a/chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.h b/chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.h
index 4d0c0820..64109d76 100644
--- a/chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.h
+++ b/chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.h
@@ -6,8 +6,8 @@
 #define CHROME_BROWSER_ASH_LOGIN_APP_MODE_TEST_WEB_KIOSK_BASE_TEST_H_
 
 #include "base/time/time.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/network_portal_detector_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_base_test.h"
 #include "components/account_id/account_id.h"
diff --git a/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc b/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc
index 90987e9..49b3638b 100644
--- a/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc
+++ b/chrome/browser/ash/login/app_mode/test/web_kiosk_browsertest.cc
@@ -19,10 +19,10 @@
 #include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
 #include "chrome/browser/ash/login/app_mode/test/kiosk_base_test.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/app_mode/test/test_browser_closed_waiter.h"
 #include "chrome/browser/ash/login/app_mode/test/web_kiosk_base_test.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/ash/login/ui/login_display_host.h"
 #include "chrome/browser/ash/ownership/fake_owner_settings_service.h"
diff --git a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
index 469258c5..40fc720 100644
--- a/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
+++ b/chrome/browser/ash/login/enrollment/enrollment_embedded_policy_server_browsertest.cc
@@ -14,6 +14,8 @@
 #include "build/build_config.h"
 #include "chrome/browser/ash/app_mode/kiosk_app_manager.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/enrollment/auto_enrollment_check_screen.h"
 #include "chrome/browser/ash/login/enrollment/enrollment_screen.h"
 #include "chrome/browser/ash/login/enrollment/enrollment_screen_view.h"
@@ -22,8 +24,6 @@
 #include "chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h"
 #include "chrome/browser/ash/login/test/enrollment_ui_mixin.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/login_or_lock_screen_visible_waiter.h"
 #include "chrome/browser/ash/login/test/network_portal_detector_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_base_test.h"
diff --git a/chrome/browser/ash/login/error_screen_browsertest.cc b/chrome/browser/ash/login/error_screen_browsertest.cc
index f66688bc..cf36c8c 100644
--- a/chrome/browser/ash/login/error_screen_browsertest.cc
+++ b/chrome/browser/ash/login/error_screen_browsertest.cc
@@ -9,13 +9,13 @@
 #include "base/test/bind.h"
 #include "base/time/time.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/login_wizard.h"
 #include "chrome/browser/ash/login/screens/error_screen.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
 #include "chrome/browser/ash/login/test/dialog_window_waiter.h"
 #include "chrome/browser/ash/login/test/embedded_test_server_setup_mixin.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/ash/login/test/oobe_screens_utils.h"
diff --git a/chrome/browser/ash/login/existing_user_controller.cc b/chrome/browser/ash/login/existing_user_controller.cc
index 557db121..5fe915c 100644
--- a/chrome/browser/ash/login/existing_user_controller.cc
+++ b/chrome/browser/ash/login/existing_user_controller.cc
@@ -17,6 +17,7 @@
 #include "ash/public/cpp/login_screen.h"
 #include "ash/public/cpp/notification_utils.h"
 #include "base/barrier_closure.h"
+#include "base/check_is_test.h"
 #include "base/command_line.h"
 #include "base/compiler_specific.h"
 #include "base/functional/bind.h"
@@ -127,6 +128,8 @@
 #include "services/network/public/mojom/network_context.mojom.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/base/l10n/l10n_util.h"
+#include "ui/base/user_activity/user_activity_detector.h"
+#include "ui/base/user_activity/user_activity_observer.h"
 #include "ui/message_center/public/cpp/notification.h"
 #include "ui/message_center/public/cpp/notification_delegate.h"
 #include "ui/views/widget/widget.h"
@@ -383,6 +386,12 @@
                           base::Unretained(this)));
 
   observed_user_manager_.Observe(user_manager::UserManager::Get());
+
+  if (ui::UserActivityDetector::Get()) {
+    ui::UserActivityDetector::Get()->AddObserver(this);
+  } else {
+    CHECK_IS_TEST();
+  }
 }
 
 void ExistingUserController::Init(const user_manager::UserList& users) {
@@ -495,7 +504,12 @@
 ////////////////////////////////////////////////////////////////////////////////
 // ExistingUserController, private:
 
-ExistingUserController::~ExistingUserController() = default;
+ExistingUserController::~ExistingUserController() {
+  ui::UserActivityDetector* activity_detector = ui::UserActivityDetector::Get();
+  if (activity_detector) {
+    activity_detector->RemoveObserver(this);
+  }
+}
 
 ////////////////////////////////////////////////////////////////////////////////
 // ExistingUserController, LoginDisplay::Delegate implementation:
@@ -1352,7 +1366,7 @@
   }
 }
 
-void ExistingUserController::ResetAutoLoginTimer() {
+void ExistingUserController::OnUserActivity(const ui::Event* event) {
   // Only restart the auto-login timer if it's already running.
   if (auto_login_timer_ && auto_login_timer_->IsRunning()) {
     StopAutoLoginTimer();
diff --git a/chrome/browser/ash/login/existing_user_controller.h b/chrome/browser/ash/login/existing_user_controller.h
index ef95c758..586e6863 100644
--- a/chrome/browser/ash/login/existing_user_controller.h
+++ b/chrome/browser/ash/login/existing_user_controller.h
@@ -31,6 +31,7 @@
 #include "content/public/browser/notification_registrar.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "third_party/cros_system_api/dbus/cryptohome/dbus-constants.h"
+#include "ui/base/user_activity/user_activity_observer.h"
 #include "url/gurl.h"
 
 namespace base {
@@ -58,7 +59,8 @@
                                public content::NotificationObserver,
                                public LoginPerformer::Delegate,
                                public UserSessionManagerDelegate,
-                               public user_manager::UserManager::Observer {
+                               public user_manager::UserManager::Observer,
+                               public ui::UserActivityObserver {
  public:
   // Returns the current existing user controller fetched from the current
   // LoginDisplayHost instance.
@@ -99,7 +101,9 @@
   void Login(const UserContext& user_context,
              const SigninSpecifics& specifics) override;
   void OnStartKioskEnableScreen() override;
-  void ResetAutoLoginTimer() override;
+
+  // ui::UserActivityObserver:
+  void OnUserActivity(const ui::Event* event) override;
 
   void CompleteLogin(const UserContext& user_context);
   void OnGaiaScreenReady();
diff --git a/chrome/browser/ash/login/existing_user_controller_auto_login_unittest.cc b/chrome/browser/ash/login/existing_user_controller_auto_login_unittest.cc
index 8151595..7206535f 100644
--- a/chrome/browser/ash/login/existing_user_controller_auto_login_unittest.cc
+++ b/chrome/browser/ash/login/existing_user_controller_auto_login_unittest.cc
@@ -202,7 +202,7 @@
   EXPECT_FALSE(auto_login_timer());
 
   // When the timer isn't running, nothing should happen.
-  existing_user_controller()->ResetAutoLoginTimer();
+  existing_user_controller()->OnUserActivity(/*event=*/nullptr);
   EXPECT_FALSE(auto_login_timer());
 
   // Start the timer.
@@ -216,7 +216,7 @@
   // User activity should restart the timer, so check to see that the
   // timer delay was modified.
   set_auto_login_delay(kAutoLoginDelay1);
-  existing_user_controller()->ResetAutoLoginTimer();
+  existing_user_controller()->OnUserActivity(/*event=*/nullptr);
   ASSERT_TRUE(auto_login_timer());
   EXPECT_TRUE(auto_login_timer()->IsRunning());
   EXPECT_EQ(auto_login_timer()->GetCurrentDelay().InMilliseconds(),
diff --git a/chrome/browser/ash/login/login_ui_browsertest.cc b/chrome/browser/ash/login/login_ui_browsertest.cc
index def0d1d..3347721ae 100644
--- a/chrome/browser/ash/login/login_ui_browsertest.cc
+++ b/chrome/browser/ash/login/login_ui_browsertest.cc
@@ -11,13 +11,13 @@
 #include "ash/shell.h"
 #include "base/command_line.h"
 #include "base/test/scoped_feature_list.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/lock/screen_locker_tester.h"
 #include "chrome/browser/ash/login/login_manager_test.h"
 #include "chrome/browser/ash/login/screens/user_selection_screen.h"
 #include "chrome/browser/ash/login/startup_utils.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
 #include "chrome/browser/ash/login/test/js_checker.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/test/local_state_mixin.h"
 #include "chrome/browser/ash/login/test/logged_in_user_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
@@ -328,8 +328,9 @@
 
   void LoginAndLock(const LoginManagerMixin::TestUserInfo& test_user,
                     UserPolicyMixin* user_policy_mixin) {
-    if (user_policy_mixin)
+    if (user_policy_mixin) {
       user_policy_mixin->RequestPolicyUpdate();
+    }
 
     login_manager_mixin_.SkipPostLoginScreens();
 
diff --git a/chrome/browser/ash/login/login_ui_shelf_visibility_browsertest.cc b/chrome/browser/ash/login/login_ui_shelf_visibility_browsertest.cc
index 97d202b..fb313d7 100644
--- a/chrome/browser/ash/login/login_ui_shelf_visibility_browsertest.cc
+++ b/chrome/browser/ash/login/login_ui_shelf_visibility_browsertest.cc
@@ -5,10 +5,10 @@
 #include "ash/constants/ash_features.h"
 #include "ash/constants/ash_switches.h"
 #include "ash/public/cpp/login_screen_test_api.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/login_manager_test.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
 #include "chrome/browser/ash/login/test/embedded_test_server_setup_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_auth_page_waiter.h"
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
@@ -66,10 +66,11 @@
 
     // Sync consent is the first post-login screen shown when a new user signs
     // in.
-    if (features::IsOobeConsolidatedConsentEnabled())
+    if (features::IsOobeConsolidatedConsentEnabled()) {
       OobeScreenWaiter(ConsolidatedConsentScreenView::kScreenId).Wait();
-    else
+    } else {
       OobeScreenWaiter(SyncConsentScreenView::kScreenId).Wait();
+    }
   }
 
  private:
diff --git a/chrome/browser/ash/login/reporting/login_logout_reporter_browsertest.cc b/chrome/browser/ash/login/reporting/login_logout_reporter_browsertest.cc
index cb3a0fc..f33f1d07 100644
--- a/chrome/browser/ash/login/reporting/login_logout_reporter_browsertest.cc
+++ b/chrome/browser/ash/login/reporting/login_logout_reporter_browsertest.cc
@@ -16,9 +16,9 @@
 #include "base/run_loop.h"
 #include "chrome/browser/ash/app_mode/fake_cws.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/session/user_session_manager_test_api.h"
 #include "chrome/browser/ash/login/test/embedded_test_server_setup_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_screens_utils.h"
 #include "chrome/browser/ash/login/test/session_manager_state_waiter.h"
diff --git a/chrome/browser/ash/login/ui/login_display.h b/chrome/browser/ash/login/ui/login_display.h
index 03516c3..4ef5e48 100644
--- a/chrome/browser/ash/login/ui/login_display.h
+++ b/chrome/browser/ash/login/ui/login_display.h
@@ -26,9 +26,6 @@
     // Called when the user requests kiosk enable screen.
     virtual void OnStartKioskEnableScreen() = 0;
 
-    // Restarts the auto-login timer if it is running.
-    virtual void ResetAutoLoginTimer() = 0;
-
    protected:
     virtual ~Delegate();
   };
diff --git a/chrome/browser/ash/login/ui/login_display_webui.cc b/chrome/browser/ash/login/ui/login_display_webui.cc
index d51c730..86e40ac 100644
--- a/chrome/browser/ash/login/ui/login_display_webui.cc
+++ b/chrome/browser/ash/login/ui/login_display_webui.cc
@@ -12,28 +12,14 @@
 
 // LoginDisplayWebUI, public: --------------------------------------------------
 
-LoginDisplayWebUI::~LoginDisplayWebUI() {
-  ui::UserActivityDetector* activity_detector = ui::UserActivityDetector::Get();
-  if (activity_detector && activity_detector->HasObserver(this))
-    activity_detector->RemoveObserver(this);
-}
+LoginDisplayWebUI::~LoginDisplayWebUI() = default;
 
 // LoginDisplay implementation: ------------------------------------------------
 
 LoginDisplayWebUI::LoginDisplayWebUI() = default;
 
 void LoginDisplayWebUI::Init(const user_manager::UserList& users,
-                             bool show_guest) {
-  ui::UserActivityDetector* activity_detector = ui::UserActivityDetector::Get();
-  if (activity_detector && !activity_detector->HasObserver(this))
-    activity_detector->AddObserver(this);
-}
-
-// ---- Common methods
-
-// ---- Gaia screen methods
-
-// ---- Not yet classified methods
+                             bool show_guest) {}
 
 void LoginDisplayWebUI::SetUIEnabled(bool is_enabled) {
   LoginDisplayHost* host = LoginDisplayHost::default_host();
@@ -41,9 +27,4 @@
     host->GetWebUILoginView()->SetUIEnabled(is_enabled);
 }
 
-void LoginDisplayWebUI::OnUserActivity(const ui::Event* event) {
-  if (delegate_)
-    delegate_->ResetAutoLoginTimer();
-}
-
 }  // namespace ash
diff --git a/chrome/browser/ash/login/ui/login_display_webui.h b/chrome/browser/ash/login/ui/login_display_webui.h
index adda4dd..99099e6 100644
--- a/chrome/browser/ash/login/ui/login_display_webui.h
+++ b/chrome/browser/ash/login/ui/login_display_webui.h
@@ -7,12 +7,11 @@
 
 #include "chrome/browser/ash/login/ui/login_display.h"
 #include "components/user_manager/user.h"
-#include "ui/base/user_activity/user_activity_observer.h"
 
 namespace ash {
 
 // WebUI-based login UI implementation.
-class LoginDisplayWebUI : public LoginDisplay, public ui::UserActivityObserver {
+class LoginDisplayWebUI : public LoginDisplay {
  public:
   LoginDisplayWebUI();
 
@@ -24,9 +23,6 @@
   // LoginDisplay implementation:
   void Init(const user_manager::UserList& users, bool show_guest) override;
   void SetUIEnabled(bool is_enabled) override;
-
-  // ui::UserActivityDetector implementation:
-  void OnUserActivity(const ui::Event* event) override;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc
index 155832e..dcf00f4 100644
--- a/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc
+++ b/chrome/browser/ash/policy/handlers/minimum_version_policy_handler_browsertest.cc
@@ -19,11 +19,11 @@
 #include "base/time/time.h"
 #include "base/values.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/existing_user_controller.h"
 #include "chrome/browser/ash/login/login_manager_test.h"
 #include "chrome/browser/ash/login/login_wizard.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_base_test.h"
 #include "chrome/browser/ash/login/test/oobe_screen_exit_waiter.h"
@@ -169,8 +169,9 @@
     update_engine::Operation operation) {
   update_engine::StatusResult status;
   status.set_current_operation(operation);
-  if (operation == update_engine::Operation::UPDATED_NEED_REBOOT)
+  if (operation == update_engine::Operation::UPDATED_NEED_REBOOT) {
     status.set_new_version(kUpdatedVersion);
+  }
   fake_update_engine_client_->NotifyObserversThatStatusChanged(status);
 }
 
@@ -757,8 +758,9 @@
 
   bool SetUpUserDataDirectory() override {
     // LoginManagerMixin sets up command line in the SetUpUserDataDirectory.
-    if (!MinimumVersionPolicyTestBase::SetUpUserDataDirectory())
+    if (!MinimumVersionPolicyTestBase::SetUpUserDataDirectory()) {
       return false;
+    }
     // Postpone login host creation.
     base::CommandLine::ForCurrentProcess()->RemoveSwitch(
         ash::switches::kForceLoginManagerInTests);
diff --git a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter_browsertest.cc b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter_browsertest.cc
index 8310c6b..e0ac40b 100644
--- a/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter_browsertest.cc
+++ b/chrome/browser/ash/policy/reporting/user_added_removed/user_added_removed_reporter_browsertest.cc
@@ -12,9 +12,9 @@
 #include "base/auto_reset.h"
 #include "base/run_loop.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/test/device_state_mixin.h"
 #include "chrome/browser/ash/login/test/embedded_test_server_setup_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_apps_mixin.h"
 #include "chrome/browser/ash/login/test/login_manager_mixin.h"
 #include "chrome/browser/ash/login/test/oobe_screen_waiter.h"
 #include "chrome/browser/ash/login/test/oobe_screens_utils.h"
diff --git a/chrome/browser/ash/system_web_apps/system_web_app_manager_browsertest.cc b/chrome/browser/ash/system_web_apps/system_web_app_manager_browsertest.cc
index 7348405..ee6a7c456 100644
--- a/chrome/browser/ash/system_web_apps/system_web_app_manager_browsertest.cc
+++ b/chrome/browser/ash/system_web_apps/system_web_app_manager_browsertest.cc
@@ -1839,7 +1839,7 @@
   AccessibilityManager::Get()->EnableSpokenFeedback(true);
   speech_monitor_.ExpectSpeechPattern("*");
   speech_monitor_.Call([this]() {
-    extensions::browsertest_util::ExecuteScriptInBackgroundPage(
+    extensions::browsertest_util::ExecuteScriptInBackgroundPageDeprecated(
         browser()->profile(), extension_misc::kChromeVoxExtensionId, R"JS(
         import('/chromevox/background/chromevox_state.js').then(
             module => module.ChromeVoxState.ready().then(() =>
diff --git a/chrome/browser/autofill/autofill_across_iframes_browsertest.cc b/chrome/browser/autofill/autofill_across_iframes_browsertest.cc
index 70051d74..70550415 100644
--- a/chrome/browser/autofill/autofill_across_iframes_browsertest.cc
+++ b/chrome/browser/autofill/autofill_across_iframes_browsertest.cc
@@ -125,7 +125,8 @@
   test::SetCreditCardInfo(&card, kNameFull, kNumber, kExpMonth, kExpYear, "");
   auto* manager = TestAutofillManager::GetForRenderFrameHost(rfh);
   manager->FillCreditCardFormImpl(form, triggered_field, card,
-                                  base::ASCIIToUTF16(base::StringPiece(kCvc)));
+                                  base::ASCIIToUTF16(base::StringPiece(kCvc)),
+                                  AutofillTriggerSource::kPopup);
 }
 
 // Clicks the first input, textarea, or select in `rfh`.
diff --git a/chrome/browser/autofill/personal_data_manager_factory.cc b/chrome/browser/autofill/personal_data_manager_factory.cc
index b54b5c3..1a2b903 100644
--- a/chrome/browser/autofill/personal_data_manager_factory.cc
+++ b/chrome/browser/autofill/personal_data_manager_factory.cc
@@ -11,6 +11,7 @@
 #include "chrome/browser/history/history_service_factory.h"
 #include "chrome/browser/profiles/profile.h"
 #include "chrome/browser/signin/identity_manager_factory.h"
+#include "chrome/browser/sync/sync_service_factory.h"
 #include "chrome/browser/web_data_service_factory.h"
 #include "components/autofill/core/browser/personal_data_manager.h"
 #include "components/autofill/core/browser/strike_databases/strike_database.h"
@@ -63,6 +64,7 @@
   DependsOn(WebDataServiceFactory::GetInstance());
   DependsOn(StrikeDatabaseFactory::GetInstance());
   DependsOn(AutofillImageFetcherFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 PersonalDataManagerFactory::~PersonalDataManagerFactory() = default;
@@ -93,14 +95,13 @@
   // This is null for OTR profiles.
   auto* identity_manager = IdentityManagerFactory::GetForProfile(profile);
 
+  auto* sync_service = SyncServiceFactory::GetForProfile(profile);
+
   service->Init(local_storage, account_storage, profile->GetPrefs(),
                 g_browser_process->local_state(), identity_manager,
-                history_service, strike_database, image_fetcher,
+                history_service, sync_service, strike_database, image_fetcher,
                 profile->IsOffTheRecord());
 
-  if (!syncer::IsSyncAllowedByFlag())
-    service->OnSyncServiceInitialized(nullptr);
-
   return service;
 }
 
diff --git a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.cc b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.cc
index 98657b17..12347024 100644
--- a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.cc
+++ b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.cc
@@ -488,6 +488,20 @@
   std::move(pending->callback).Run(std::move(status_change_result));
 }
 
+void SmartCardProviderPrivateAPI::ReportCancelResult(
+    RequestId request_id,
+    SmartCardResultPtr result) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  std::unique_ptr<PendingResult<CancelCallback>> pending =
+      Extract(pending_cancel_, request_id);
+  if (!pending) {
+    return;
+  }
+
+  std::move(pending->callback).Run(std::move(result));
+}
+
 device::mojom::SmartCardConnectResultPtr
 SmartCardProviderPrivateAPI::CreateSmartCardConnection(
     Handle handle,
@@ -672,6 +686,21 @@
       std::move(event_args), std::max(base::Milliseconds(500), time_delta * 2));
 }
 
+void SmartCardProviderPrivateAPI::Cancel(CancelCallback callback) {
+  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+
+  const ContextId scard_context = context_receivers_.current_context();
+  CHECK(!scard_context.is_null());
+
+  DispatchEventWithTimeout(
+      scard_api::OnCancelRequested::kEventName,
+      extensions::events::SMART_CARD_PROVIDER_PRIVATE_ON_CANCEL_REQUESTED,
+      std::move(callback), pending_cancel_,
+      &SmartCardProviderPrivateAPI::OnCancelTimeout,
+      /*event_arguments=*/
+      base::Value::List().Append(scard_context.GetUnsafeValue()));
+}
+
 void SmartCardProviderPrivateAPI::Connect(
     const std::string& reader,
     device::mojom::SmartCardShareMode share_mode,
@@ -730,6 +759,8 @@
                 std::vector<device::mojom::SmartCardReaderStateOutPtr>(),
                 SmartCardResult::NewError(SmartCardError::kNoService))
 
+ON_TIMEOUT_IMPL(Cancel, SmartCardResult::NewError(SmartCardError::kNoService))
+
 ON_TIMEOUT_IMPL(Connect,
                 Handle(),
                 device::mojom::SmartCardProtocol::kUndefined,
@@ -781,6 +812,10 @@
     ProviderResultCodeToSmartCardResult(params->result_code))
 
 REPORT_RESULT_FUNCTION_IMPL(
+    Cancel,
+    ProviderResultCodeToSmartCardResult(params->result_code))
+
+REPORT_RESULT_FUNCTION_IMPL(
     Connect,
     SmartCardProviderPrivateAPI::Handle(params->scard_handle),
     ToDeviceMojomSmartCardProtocol(params->active_protocol),
diff --git a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.h b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.h
index d1610bd..e6d0c1f 100644
--- a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.h
+++ b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_api.h
@@ -58,6 +58,7 @@
       base::TimeDelta timeout,
       std::vector<device::mojom::SmartCardReaderStateInPtr> reader_states,
       GetStatusChangeCallback callback) override;
+  void Cancel(CancelCallback callback) override;
   void Connect(const std::string& reader,
                device::mojom::SmartCardShareMode share_mode,
                device::mojom::SmartCardProtocolsPtr preferred_protocols,
@@ -78,6 +79,8 @@
       RequestId request_id,
       std::vector<device::mojom::SmartCardReaderStateOutPtr> reader_states,
       device::mojom::SmartCardResultPtr result);
+  void ReportCancelResult(RequestId request_id,
+                          device::mojom::SmartCardResultPtr result);
   void ReportConnectResult(RequestId request_id,
                            Handle scard_handle,
                            device::mojom::SmartCardProtocol active_protocol,
@@ -129,6 +132,8 @@
                             RequestId request_id);
   void OnGetStatusChangeTimeout(const std::string& provider_extension_id,
                                 RequestId request_id);
+  void OnCancelTimeout(const std::string& provider_extension_id,
+                       RequestId request_id);
   void OnConnectTimeout(const std::string& provider_extension_id,
                         RequestId request_id);
   void OnDisconnectTimeout(const std::string& provider_extension_id,
@@ -161,6 +166,7 @@
 
   PendingResultMap<ListReadersCallback> pending_list_readers_;
   PendingResultMap<GetStatusChangeCallback> pending_get_status_change_;
+  PendingResultMap<CancelCallback> pending_cancel_;
   PendingResultMap<ConnectCallback> pending_connect_;
   PendingResultMap<DisconnectCallback> pending_disconnect_;
 
@@ -224,6 +230,17 @@
       SMARTCARDPROVIDERPRIVATE_REPORTGETSTATUSCHANGERESULT)
 };
 
+class SmartCardProviderPrivateReportCancelResultFunction
+    : public ExtensionFunction {
+ private:
+  // ExtensionFunction:
+  ~SmartCardProviderPrivateReportCancelResultFunction() override;
+  ResponseAction Run() override;
+
+  DECLARE_EXTENSION_FUNCTION("smartCardProviderPrivate.reportCancelResult",
+                             SMARTCARDPROVIDERPRIVATE_REPORTCANCELRESULT)
+};
+
 class SmartCardProviderPrivateReportConnectResultFunction
     : public ExtensionFunction {
  private:
diff --git a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_apitest.cc b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_apitest.cc
index 188c65e..daf9e6f 100644
--- a/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_apitest.cc
+++ b/chrome/browser/chromeos/extensions/smart_card_provider_private/smart_card_provider_private_apitest.cc
@@ -753,4 +753,81 @@
   ASSERT_TRUE(result_catcher.GetNextResult()) << result_catcher.message();
 }
 
+IN_PROC_BROWSER_TEST_F(SmartCardProviderPrivateApiTest, Cancel) {
+  std::string background_js(kEstablishContextJs);
+  background_js.append(
+      R"(
+      chrome.smartCardProviderPrivate.onCancelRequested.addListener(
+          cancel);
+
+      function cancel(requestId, scardContext) {
+        if (scardContext != 123) {
+          chrome.smartCardProviderPrivate.reportCancelResult(requestId,
+              readerStates, "INVALID_PARAMETER");
+          return;
+        }
+
+        chrome.smartCardProviderPrivate.reportCancelResult(requestId,
+            "SUCCESS");
+      }
+    )");
+  LoadFakeProviderExtension(background_js);
+
+  auto context_result = CreateContext();
+  ASSERT_TRUE(context_result->is_context());
+  mojo::Remote<device::mojom::SmartCardContext> context(
+      std::move(context_result->get_context()));
+
+  base::test::TestFuture<device::mojom::SmartCardResultPtr> result_future;
+
+  context->Cancel(result_future.GetCallback());
+
+  SmartCardResultPtr result = result_future.Take();
+  ASSERT_TRUE(result->is_success());
+}
+
+IN_PROC_BROWSER_TEST_F(SmartCardProviderPrivateApiTest, CancelNoProvider) {
+  LoadFakeProviderExtension(kEstablishContextJs);
+
+  auto context_result = CreateContext();
+  ASSERT_TRUE(context_result->is_context());
+  mojo::Remote<device::mojom::SmartCardContext> context(
+      std::move(context_result->get_context()));
+
+  base::test::TestFuture<device::mojom::SmartCardResultPtr> result_future;
+
+  context->Cancel(result_future.GetCallback());
+
+  device::mojom::SmartCardResultPtr result = result_future.Take();
+  ASSERT_TRUE(result->is_error());
+  EXPECT_EQ(result->get_error(), SmartCardError::kNoService);
+}
+
+IN_PROC_BROWSER_TEST_F(SmartCardProviderPrivateApiTest, CancelResponseTimeout) {
+  SmartCardProviderPrivateAPI& scard_provider_api =
+      SmartCardProviderPrivateAPI::Get(*profile());
+  scard_provider_api.SetResponseTimeLimitForTesting(base::Seconds(1));
+
+  std::string background_js(kEstablishContextJs);
+  background_js.append(
+      R"(
+      chrome.smartCardProviderPrivate.onCancelRequested.addListener(
+          function(requestId, scardContext){});
+    )");
+  LoadFakeProviderExtension(background_js);
+
+  auto context_result = CreateContext();
+  ASSERT_TRUE(context_result->is_context());
+  mojo::Remote<device::mojom::SmartCardContext> context(
+      std::move(context_result->get_context()));
+
+  base::test::TestFuture<device::mojom::SmartCardResultPtr> result_future;
+
+  context->Cancel(result_future.GetCallback());
+
+  device::mojom::SmartCardResultPtr result = result_future.Take();
+  ASSERT_TRUE(result->is_error());
+  EXPECT_EQ(result->get_error(), SmartCardError::kNoService);
+}
+
 }  // namespace extensions
diff --git a/chrome/browser/chromeos/extensions/telemetry/chromeos_permission_messages_unittest.cc b/chrome/browser/chromeos/extensions/telemetry/chromeos_permission_messages_unittest.cc
index e8ebc63..f4a7444 100644
--- a/chrome/browser/chromeos/extensions/telemetry/chromeos_permission_messages_unittest.cc
+++ b/chrome/browser/chromeos/extensions/telemetry/chromeos_permission_messages_unittest.cc
@@ -35,6 +35,8 @@
     "gogonhoemckpdpadfnjnpgbjpbjnodgc";
 const std::u16string kDiagnosticsPermissionMessage =
     u"Run ChromeOS diagnostic tests";
+const std::u16string kTelemetryEventsPermissionMessage =
+    u"Subscribe to ChromeOS system events";
 const std::u16string kTelemetryPermissionMessage =
     u"Read ChromeOS device information and device data";
 const std::u16string kTelemetrySerialNumberPermissionMessage =
@@ -199,4 +201,24 @@
             active_permissions()[0]);
 }
 
+TEST_F(ChromeOSPermissionMessageUnittest, OsTelemetryEventsMessage) {
+  CreateAndInstallExtensionWithPermissions(
+      base::Value::List(),
+      extensions::ListBuilder().Append("os.events").Build());
+
+  ASSERT_EQ(1U, optional_permissions().size());
+  EXPECT_EQ(kTelemetryEventsPermissionMessage, optional_permissions()[0]);
+  ASSERT_EQ(1U, GetInactiveOptionalPermissionMessages().size());
+  EXPECT_EQ(kTelemetryEventsPermissionMessage,
+            GetInactiveOptionalPermissionMessages()[0]);
+  EXPECT_EQ(0U, required_permissions().size());
+  EXPECT_EQ(0U, active_permissions().size());
+
+  GrantOptionalPermissions();
+
+  EXPECT_EQ(0U, GetInactiveOptionalPermissionMessages().size());
+  ASSERT_EQ(1U, active_permissions().size());
+  EXPECT_EQ(kTelemetryEventsPermissionMessage, active_permissions()[0]);
+}
+
 }  // namespace chromeos
diff --git a/chrome/browser/extensions/active_tab_apitest.cc b/chrome/browser/extensions/active_tab_apitest.cc
index 8d47ee7..96df839 100644
--- a/chrome/browser/extensions/active_tab_apitest.cc
+++ b/chrome/browser/extensions/active_tab_apitest.cc
@@ -164,13 +164,13 @@
   EXPECT_TRUE(background_page_ready.WaitUntilSatisfied());
 
   auto can_xhr_file_urls = [this, &extension_id]() {
-    constexpr char script[] = R"(
+    static constexpr char script[] = R"(
       var req = new XMLHttpRequest();
       var url = '%s';
       req.open('GET', url, true);
       req.onload = function() {
         if (req.responseText === 'Hello!')
-          window.domAutomationController.send('true');
+          chrome.test.sendScriptResult('true');
 
         // Even for a successful request, the status code might be 0. Ensure
         // that onloadend is not subsequently called if the request is
@@ -183,20 +183,20 @@
       // 'error' event).
       req.onloadend = function() {
         if (req.status === 0)
-          window.domAutomationController.send('false');
+          chrome.test.sendScriptResult('false');
       };
       req.send();
     )";
 
     base::FilePath test_file =
         test_data_dir_.DirName().AppendASCII("test_file.txt");
-    std::string result = ExecuteScriptInBackgroundPage(
+    base::Value result = ExecuteScriptInBackgroundPage(
         extension_id,
         base::StringPrintf(script,
                            net::FilePathToFileURL(test_file).spec().c_str()));
 
-    EXPECT_TRUE(result == "true" || result == "false");
-    return result == "true";
+    EXPECT_TRUE(result.is_string() && (result == "true" || result == "false"));
+    return result.is_string() && result == "true";
   };
 
   auto can_load_file_iframe = [this, &extension_id]() {
@@ -230,7 +230,7 @@
   };
 
   auto can_script_tab = [this, &extension_id](int tab_id) {
-    constexpr char script[] = R"(
+    static constexpr char script[] = R"(
       var tabID = %d;
       chrome.tabs.executeScript(
           tabID, {code: 'console.log("injected");'}, function() {
@@ -240,19 +240,20 @@
 
             if (chrome.runtime.lastError &&
                 expectedError != chrome.runtime.lastError.message) {
-              window.domAutomationController.send(
+              chrome.test.sendScriptResult(
                   'unexpected error: ' + chrome.runtime.lastError.message);
             } else {
-              window.domAutomationController.send(
+              chrome.test.sendScriptResult(
                   chrome.runtime.lastError ? 'false' : 'true');
             }
           });
     )";
 
-    std::string result = ExecuteScriptInBackgroundPage(
+    base::Value result = ExecuteScriptInBackgroundPage(
         extension_id, base::StringPrintf(script, tab_id));
-    EXPECT_TRUE(result == "true" || result == "false") << result;
-    return result == "true";
+    EXPECT_TRUE(result.is_string());
+    EXPECT_TRUE(result == "true" || result == "false");
+    return result.is_string() && result == "true";
   };
 
   auto get_active_tab_id = [this]() {
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.cc
index 4b8c6e1..4d19e03 100644
--- a/chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.cc
+++ b/chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.cc
@@ -4,6 +4,7 @@
 
 #include "chrome/browser/extensions/api/autofill_private/autofill_private_event_router_factory.h"
 
+#include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/extensions/api/autofill_private/autofill_private_event_router.h"
 #include "content/public/browser/browser_context.h"
 #include "extensions/browser/extension_system_provider.h"
@@ -30,10 +31,12 @@
           "AutofillPrivateEventRouter",
           ProfileSelections::BuildRedirectedInIncognito()) {
   DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory());
+  DependsOn(autofill::PersonalDataManagerFactory::GetInstance());
 }
 
 KeyedService* AutofillPrivateEventRouterFactory::BuildServiceInstanceFor(
     content::BrowserContext* context) const {
+  // TODO(1426498): pass router's dependencies directly instead of context.
   return AutofillPrivateEventRouter::Create(context);
 }
 
diff --git a/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc b/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
index 0e9bf22..6227cc1f 100644
--- a/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
+++ b/chrome/browser/extensions/api/crash_report_private/crash_report_private_apitest.cc
@@ -51,12 +51,12 @@
   void SetUpOnMainThread() override {
     ExtensionApiTest::SetUpOnMainThread();
 
-    constexpr char kKey[] =
+    static constexpr char kKey[] =
         "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+uU63MD6T82Ldq5wjrDFn5mGmPnnnj"
         "WZBWxYXfpG4kVf0s+p24VkXwTXsxeI12bRm8/ft9sOq0XiLfgQEh5JrVUZqvFlaZYoS+g"
         "iZfUqzKFGMLa4uiSMDnvv+byxrqAepKz5G8XX/q5Wm5cvpdjwgiu9z9iM768xJy+Ca/G5"
         "qQwIDAQAB";
-    constexpr char kManifestTemplate[] =
+    static constexpr char kManifestTemplate[] =
         R"({
       "key": "%s",
       "name": "chrome.crashReportPrivate basic extension tests",
@@ -97,12 +97,12 @@
 };
 
 IN_PROC_BROWSER_TEST_F(CrashReportPrivateApiTest, Basic) {
-  constexpr char kTestScript[] = R"(
+  static constexpr char kTestScript[] = R"(
     chrome.crashReportPrivate.reportError({
         message: "hi",
         url: "http://www.test.com",
       },
-      () => window.domAutomationController.send(""));
+      () => chrome.test.sendScriptResult(""));
   )";
   ExecuteScriptInBackgroundPage(extension_->id(), kTestScript);
 
@@ -126,7 +126,7 @@
 }
 
 IN_PROC_BROWSER_TEST_F(CrashReportPrivateApiTest, ExtraParamsAndStackTrace) {
-  constexpr char kTestScript[] = R"-(
+  static constexpr char kTestScript[] = R"-(
     chrome.crashReportPrivate.reportError({
         message: "hi",
         url: "http://www.test.com/foo",
@@ -137,7 +137,7 @@
         debugId: "2751679EE:233977D75E03BAC9DA/255DD0",
         stackTrace: "   at <anonymous>:1:1",
       },
-      () => window.domAutomationController.send(""));
+      () => chrome.test.sendScriptResult(""));
   )-";
   ExecuteScriptInBackgroundPage(extension_->id(), kTestScript);
 
@@ -165,7 +165,7 @@
 }
 
 IN_PROC_BROWSER_TEST_F(CrashReportPrivateApiTest, StackTraceWithErrorMessage) {
-  constexpr char kTestScript[] = R"(
+  static constexpr char kTestScript[] = R"(
     chrome.crashReportPrivate.reportError({
         message: "hi",
         url: "http://www.test.com/foo",
@@ -175,7 +175,7 @@
         columnNumber: 456,
         stackTrace: 'hi'
       },
-      () => window.domAutomationController.send(""));
+      () => chrome.test.sendScriptResult(""));
   )";
   ExecuteScriptInBackgroundPage(extension_->id(), kTestScript);
 
@@ -201,7 +201,7 @@
 IN_PROC_BROWSER_TEST_F(CrashReportPrivateApiTest, RedactMessage) {
   // We use the feedback APIs redaction tool, which scrubs many different types
   // of PII. As a sanity check, test if MAC addresses are redacted.
-  constexpr char kTestScript[] = R"(
+  static constexpr char kTestScript[] = R"(
     chrome.crashReportPrivate.reportError({
         message: "06-00-00-00-00-00",
         url: "http://www.test.com/foo",
@@ -210,7 +210,7 @@
         lineNumber: 123,
         columnNumber: 456,
       },
-      () => window.domAutomationController.send(""));
+      () => chrome.test.sendScriptResult(""));
   )";
   ExecuteScriptInBackgroundPage(extension_->id(), kTestScript);
 
@@ -244,13 +244,13 @@
   DevToolsWindow* devtools_window =
       DevToolsWindowTesting::OpenDevToolsWindowSync(
           web_contents, false /** is devtools docked. */);
-  constexpr char kTestScript[] = R"(
+  static constexpr char kTestScript[] = R"(
     chrome.crashReportPrivate.reportError({
         message: "hi",
         url: "http://www.test.com",
       },
       () => {
-        window.domAutomationController.send(chrome.runtime.lastError ?
+        chrome.test.sendScriptResult(chrome.runtime.lastError ?
             chrome.runtime.lastError.message : "")
       });
   )";
@@ -278,7 +278,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
   EXPECT_TRUE(NavigateToURL(web_content, extension_context_url));
 
-  constexpr char kTestScript[] = R"(
+  static constexpr char kTestScript[] = R"(
     chrome.crashReportPrivate.reportError({
         message: "hi",
         url: "http://www.test.com",
@@ -339,7 +339,7 @@
   const GURL extension_context_url("chrome://media-app");
   EXPECT_TRUE(NavigateToURL(web_content, extension_context_url));
 
-  constexpr char kTestScript[] = R"(
+  static constexpr char kTestScript[] = R"(
     chrome.crashReportPrivate.reportError({
         message: "hi",
         url: "http://www.test.com",
@@ -376,7 +376,7 @@
   MockCrashEndpoint endpoint(embedded_test_server());
   ScopedMockChromeJsErrorReportProcessor processor(endpoint);
 
-  constexpr char kTestScript[] = R"(
+  static constexpr char kTestScript[] = R"(
     chrome.crashReportPrivate.reportError({
         message: "hi",
         url: "http://www.test.com",
diff --git a/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc b/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc
index 45c54bc..04f5641 100644
--- a/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc
+++ b/chrome/browser/extensions/api/declarative_content/declarative_content_apitest.cc
@@ -81,17 +81,28 @@
     R"(var PageStateMatcher = chrome.declarativeContent.PageStateMatcher;
        var ShowAction = chrome.declarativeContent.ShowAction;
        var onPageChanged = chrome.declarativeContent.onPageChanged;
-       var reply = window.domAutomationController.send.bind(
-           window.domAutomationController);
+
+       function setRulesInPageEnvironment(rules, responseString) {
+         onPageChanged.removeRules(undefined, function() {
+           onPageChanged.addRules(rules, function() {
+             if (chrome.runtime.lastError) {
+               window.domAutomationController.send(
+                   chrome.runtime.lastError.message);
+               return;
+             }
+             window.domAutomationController.send(responseString);
+           });
+         });
+       };
 
        function setRules(rules, responseString) {
          onPageChanged.removeRules(undefined, function() {
            onPageChanged.addRules(rules, function() {
              if (chrome.runtime.lastError) {
-               reply(chrome.runtime.lastError.message);
+               chrome.test.sendScriptResult(chrome.runtime.lastError.message);
                return;
              }
-             reply(responseString);
+             chrome.test.sendScriptResult(responseString);
            });
          });
        };
@@ -99,20 +110,20 @@
        function addRules(rules, responseString) {
          onPageChanged.addRules(rules, function() {
            if (chrome.runtime.lastError) {
-             reply(chrome.runtime.lastError.message);
+             chrome.test.sendScriptResult(chrome.runtime.lastError.message);
              return;
            }
-           reply(responseString);
+           chrome.test.sendScriptResult(responseString);
          });
        };
 
        function removeRule(id, responseString) {
          onPageChanged.removeRules([id], function() {
            if (chrome.runtime.lastError) {
-             reply(chrome.runtime.lastError.message);
+             chrome.test.sendScriptResult(chrome.runtime.lastError.message);
              return;
            }
-           reply(responseString);
+           chrome.test.sendScriptResult(responseString);
          });
        };)";
 
@@ -235,10 +246,11 @@
            actions: [new ShowAction()]
          }], 'test_rule');)";
 
-  EXPECT_EQ("test_rule", ExecuteScriptInBackgroundPage(
-      extension->id(),
-      base::StringPrintf(kSetIsBookmarkedRule,
-                         match_is_bookmarked ? "true" : "false")));
+  EXPECT_EQ("test_rule",
+            ExecuteScriptInBackgroundPage(
+                extension->id(),
+                base::StringPrintf(kSetIsBookmarkedRule,
+                                   match_is_bookmarked ? "true" : "false")));
   EXPECT_EQ(!match_is_bookmarked, action->GetIsVisible(tab_id));
 
   // Check rule evaluation on add/remove bookmark.
@@ -504,7 +516,7 @@
       browser()->tab_strip_model()->GetActiveWebContents();
 
   static constexpr char kScript[] =
-      R"(setRules([{
+      R"(setRulesInPageEnvironment([{
            conditions: [new PageStateMatcher({pageUrl: {hostPrefix: 'test'}})],
            actions: [new chrome.declarativeContent.%s()]
          }], 'test_rule');)";
@@ -851,7 +863,7 @@
 
   static constexpr char kRemoveScript[] =
       R"(onPageChanged.removeRules(undefined, function() {
-           window.domAutomationController.send('removed');
+           chrome.test.sendScriptResult('removed');
          });)";
   EXPECT_EQ("removed",
             ExecuteScriptInBackgroundPage(extension->id(), kRemoveScript));
@@ -866,7 +878,7 @@
       FILE_PATH_LITERAL("background.js"),
       R"(var PageStateMatcher = chrome.declarativeContent.PageStateMatcher;
          function Return(obj) {
-           window.domAutomationController.send('' + obj);
+            chrome.test.sendScriptResult('' + obj);
          })");
   const Extension* extension = LoadExtension(ext_dir_.UnpackedPath());
   ASSERT_TRUE(extension);
@@ -885,9 +897,11 @@
          } catch (e) {
            Return(e.message);
          })";
-  EXPECT_THAT(
-      ExecuteScriptInBackgroundPage(extension->id(), kSelectorNotAnArrayScript),
-      testing::ContainsRegex("css.*xpected '?array'?"));
+  base::Value result =
+      ExecuteScriptInBackgroundPage(extension->id(), kSelectorNotAnArrayScript);
+  ASSERT_TRUE(result.is_string());
+  EXPECT_THAT(result.GetString(),
+              testing::ContainsRegex("css.*xpected '?array'?"));
 
   // CSS selector is not a string.
   static constexpr char kSelectorNotStringScript[] =
@@ -897,9 +911,11 @@
          } catch (e) {
            Return(e.message);
          })";
-  EXPECT_THAT(
-      ExecuteScriptInBackgroundPage(extension->id(), kSelectorNotStringScript),
-      testing::ContainsRegex("css.*0.*xpected '?string'?"));
+  result =
+      ExecuteScriptInBackgroundPage(extension->id(), kSelectorNotStringScript);
+  ASSERT_TRUE(result.is_string());
+  EXPECT_THAT(result.GetString(),
+              testing::ContainsRegex("css.*0.*xpected '?string'?"));
 
   // Invalid CSS selector.
   static constexpr char kInvalidSelectorScript[] =
@@ -909,9 +925,10 @@
          } catch (e) {
            Return(e.message);
          })";
-  EXPECT_THAT(
-      ExecuteScriptInBackgroundPage(extension->id(), kInvalidSelectorScript),
-      testing::ContainsRegex("valid.*: input''$"));
+  result =
+      ExecuteScriptInBackgroundPage(extension->id(), kInvalidSelectorScript);
+  ASSERT_TRUE(result.is_string());
+  EXPECT_THAT(result.GetString(), testing::ContainsRegex("valid.*: input''$"));
 
   // "Complex" CSS selector.
   static constexpr char kComplexSelectorScript[] =
@@ -921,9 +938,11 @@
          } catch (e) {
            Return(e.message);
          })";
-  EXPECT_THAT(
-      ExecuteScriptInBackgroundPage(extension->id(), kComplexSelectorScript),
-      testing::ContainsRegex("selector.*: div input$"));
+  result =
+      ExecuteScriptInBackgroundPage(extension->id(), kComplexSelectorScript);
+  ASSERT_TRUE(result.is_string());
+  EXPECT_THAT(result.GetString(),
+              testing::ContainsRegex("selector.*: div input$"));
 }
 
 // Tests that the rules with isBookmarked: true are evaluated when handling
diff --git a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
index cb393fa..5a2fbe4 100644
--- a/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
+++ b/chrome/browser/extensions/api/declarative_net_request/declarative_net_request_browsertest.cc
@@ -390,6 +390,16 @@
       EXPECT_FALSE(IsNavigationBlocked(url)) << url;
   }
 
+  std::string ExecuteScriptInBackgroundPageAndReturnString(
+      const std::string& extension_id,
+      const std::string& script,
+      browsertest_util::ScriptUserActivation script_user_activation =
+          browsertest_util::ScriptUserActivation::kActivate) {
+    base::Value result = ExecuteScriptInBackgroundPage(extension_id, script,
+                                                       script_user_activation);
+    return result.is_string() ? result.GetString() : "";
+  }
+
   TestRule CreateMainFrameBlockRule(const std::string& filter) {
     TestRule rule = CreateGenericRule();
     rule.condition->url_filter = filter;
@@ -441,7 +451,7 @@
       chrome.declarativeNetRequest.updateStaticRules(
           {rulesetId: $1, disableRuleIds: $2, enableRuleIds: $3},
           () => {
-            window.domAutomationController.send(chrome.runtime.lastError ?
+            chrome.test.sendScriptResult(chrome.runtime.lastError ?
                 chrome.runtime.lastError.message : 'success');
           });
     )";
@@ -458,8 +468,9 @@
     const std::string script = content::JsReplace(
         kScript, ruleset_id, base::Value(std::move(ids_to_disable)),
         base::Value(std::move(ids_to_enable)));
-    std::string result = ExecuteScriptInBackgroundPage(extension_id, script);
 
+    std::string result =
+        ExecuteScriptInBackgroundPageAndReturnString(extension_id, script);
     ASSERT_EQ("success", result);
   }
 
@@ -478,18 +489,18 @@
           {rulesetId: $1},
           (disabledRuleIds) => {
             if (chrome.runtime.lastError) {
-              window.domAutomationController.send(
+              chrome.test.sendScriptResult(
                   'error: ' + chrome.runtime.lastError.message);
               return;
             }
             if (!disabledRuleIds) {
-              window.domAutomationController.send('no result');
+              chrome.test.sendScriptResult('no result');
               return;
             }
 
             let actual = JSON.stringify(disabledRuleIds);
             let expected = JSON.stringify($2);
-            window.domAutomationController.send(actual == expected
+            chrome.test.sendScriptResult(actual == expected
                 ? 'success'
                 : ['expected:', expected, '; actual:', actual].join(''));
           });
@@ -498,7 +509,7 @@
                                      .Append(expected_disabled_rule_ids.begin(),
                                              expected_disabled_rule_ids.end())
                                      .Build();
-    std::string result = ExecuteScriptInBackgroundPage(
+    std::string result = ExecuteScriptInBackgroundPageAndReturnString(
         extension_id,
         content::JsReplace(kScript, ruleset_id_string, std::move(expected)));
     ASSERT_EQ("success", result);
@@ -521,13 +532,13 @@
     static constexpr char kSetExtensionActionOptionsScript[] = R"(
       chrome.declarativeNetRequest.setExtensionActionOptions(%s,
         () => {
-          window.domAutomationController.send(chrome.runtime.lastError ?
+          chrome.test.sendScriptResult(chrome.runtime.lastError ?
               chrome.runtime.lastError.message : 'success');
         }
       );
     )";
 
-    return ExecuteScriptInBackgroundPage(
+    return ExecuteScriptInBackgroundPageAndReturnString(
         extension_id,
         base::StringPrintf(kSetExtensionActionOptionsScript, options.c_str()));
   }
@@ -558,7 +569,7 @@
   // E.g. "<rule_1>,<tab_1>|<rule_2>,<tab_2>|<rule_3>,<tab_3>"
   std::string GetRuleAndTabIdsMatched(const ExtensionId& extension_id,
                                       absl::optional<int> tab_id) {
-    const char kGetMatchedRulesScript[] = R"(
+    static constexpr char kGetMatchedRulesScript[] = R"(
       chrome.declarativeNetRequest.getMatchedRules({%s}, (rules) => {
         // |ruleAndTabIds| is a list of `${ruleId},${tabId}`
         var ruleAndTabIds = rules.rulesMatchedInfo.map(rule => {
@@ -570,13 +581,13 @@
         }).map(ruleAndTabId => ruleAndTabId.join());
 
         // Join the comma separated (ruleId,tabId) pairs with '|'.
-        window.domAutomationController.send(ruleAndTabIds.join('|'));
+        chrome.test.sendScriptResult(ruleAndTabIds.join('|'));
       });
     )";
 
     std::string tab_id_param =
         tab_id ? base::StringPrintf("tabId: %d", *tab_id) : "";
-    return ExecuteScriptInBackgroundPage(
+    return ExecuteScriptInBackgroundPageAndReturnString(
         extension_id,
         base::StringPrintf(kGetMatchedRulesScript, tab_id_param.c_str()),
         browsertest_util::ScriptUserActivation::kDontActivate);
@@ -594,15 +605,15 @@
       absl::optional<base::Time> timestamp,
       browsertest_util::ScriptUserActivation script_user_activation =
           browsertest_util::ScriptUserActivation::kDontActivate) {
-    const char kGetMatchedRulesScript[] = R"(
+    static constexpr char kGetMatchedRulesScript[] = R"(
       chrome.declarativeNetRequest.getMatchedRules(%s, (rules) => {
         if (chrome.runtime.lastError) {
-          window.domAutomationController.send(chrome.runtime.lastError.message);
+          chrome.test.sendScriptResult(chrome.runtime.lastError.message);
           return;
         }
 
         var rule_count = rules.rulesMatchedInfo.length;
-        window.domAutomationController.send(rule_count.toString());
+        chrome.test.sendScriptResult(rule_count.toString());
       });
     )";
 
@@ -615,25 +626,25 @@
                                  timestamp_in_js)
             : base::StringPrintf("{minTimeStamp: %f}", timestamp_in_js);
 
-    return ExecuteScriptInBackgroundPage(
+    return ExecuteScriptInBackgroundPageAndReturnString(
         extension_id,
         base::StringPrintf(kGetMatchedRulesScript, param_string.c_str()),
         script_user_activation);
   }
 
   std::string GetAvailableStaticRuleCount(const ExtensionId& extension_id) {
-    const char kGetAvailableStaticRuleCountScript[] = R"(
+    static constexpr char kGetAvailableStaticRuleCountScript[] = R"(
       chrome.declarativeNetRequest.getAvailableStaticRuleCount((rule_count) => {
         if (chrome.runtime.lastError) {
-          window.domAutomationController.send(chrome.runtime.lastError.message);
+          chrome.test.sendScriptResult(chrome.runtime.lastError.message);
           return;
         }
 
-        window.domAutomationController.send(rule_count.toString());
+        chrome.test.sendScriptResult(rule_count.toString());
       });
     )";
 
-    return ExecuteScriptInBackgroundPage(
+    return ExecuteScriptInBackgroundPageAndReturnString(
         extension_id, kGetAvailableStaticRuleCountScript,
         browsertest_util::ScriptUserActivation::kDontActivate);
   }
@@ -707,7 +718,7 @@
       chrome.declarativeNetRequest.%s(
         {addRules: $1, removeRuleIds: $2},
         function() {
-          window.domAutomationController.send(chrome.runtime.lastError ?
+          chrome.test.sendScriptResult(chrome.runtime.lastError ?
               chrome.runtime.lastError.message : 'success');
         });
     )";
@@ -737,7 +748,8 @@
         content::JsReplace(base::StringPrintf(kScript, function_name),
                            base::Value(rules_to_add_builder.Build()),
                            base::Value(std::move(rule_ids_to_remove_value)));
-    ASSERT_EQ("success", ExecuteScriptInBackgroundPage(extension_id, script));
+    ASSERT_EQ("success", ExecuteScriptInBackgroundPageAndReturnString(
+                             extension_id, script));
   }
 
   // Helper to load an extension. |has_dynamic_ruleset| should be true if the
@@ -863,7 +875,7 @@
         disableRulesetIds: $1,
         enableRulesetIds: $2
       }, () => {
-        window.domAutomationController.send(chrome.runtime.lastError ?
+        chrome.test.sendScriptResult(chrome.runtime.lastError ?
             chrome.runtime.lastError.message : 'success');
       });
     )";
@@ -880,7 +892,7 @@
     const std::string script =
         content::JsReplace(kScript, base::Value(std::move(ids_to_remove)),
                            base::Value(std::move(ids_to_add)));
-    return ExecuteScriptInBackgroundPage(extension_id, script);
+    return ExecuteScriptInBackgroundPageAndReturnString(extension_id, script);
   }
 
   void InitializeHttpsServer() {
@@ -3305,7 +3317,7 @@
   // separated pairs of <rule_id>,<ruleset_id>, sorted by rule ids, e.g.
   // "ruleId1,rulesetId1|ruleId2,rulesetId2".
   auto get_matched_rules = [this](int tab_id) {
-    const char kGetMatchedRulesScript[] = R"(
+    static constexpr char kGetMatchedRulesScript[] = R"(
       chrome.declarativeNetRequest.getMatchedRules({tabId: %d}, (matches) => {
         // Sort by |ruleId|.
         matches.rulesMatchedInfo.sort((a, b) => a.rule.ruleId - b.rule.ruleId);
@@ -3313,11 +3325,11 @@
         var ruleAndRulesetIDs = matches.rulesMatchedInfo.map(
           match => [match.rule.ruleId, match.rule.rulesetId].join());
 
-        window.domAutomationController.send(ruleAndRulesetIDs.join('|'));
+        chrome.test.sendScriptResult(ruleAndRulesetIDs.join('|'));
       });
     )";
 
-    return ExecuteScriptInBackgroundPage(
+    return ExecuteScriptInBackgroundPageAndReturnString(
         last_loaded_extension_id(),
         base::StringPrintf(kGetMatchedRulesScript, tab_id),
         browsertest_util::ScriptUserActivation::kDontActivate);
@@ -3357,7 +3369,7 @@
                                             "/pages_with_script/index.html");
 
   // Set up web request listeners listening to request to |url|.
-  const char kWebRequestListenerScript[] = R"(
+  static constexpr char kWebRequestListenerScript[] = R"(
     let filter = {'urls' : ['%s'], 'types' : ['main_frame']};
 
     let onBeforeRequestSeen = false;
@@ -3414,7 +3426,7 @@
                              {URLPattern::kAllUrlsPattern}));
 
   // Set up a web request listener to block the request to example.com.
-  const char kWebRequestBlockScript[] = R"(
+  static constexpr char kWebRequestBlockScript[] = R"(
     let filter = {'urls' : ['%s'], 'types' : ['main_frame']};
     chrome.webRequest.onBeforeRequest.addListener((details) => {
       chrome.test.sendMessage('SEEN')
@@ -3571,11 +3583,11 @@
   auto query_badge_text = [this](const ExtensionId& extension_id, int tab_id) {
     static constexpr char kBadgeTextQueryScript[] = R"(
         chrome.browserAction.getBadgeText({tabId: %d}, badgeText => {
-          window.domAutomationController.send(badgeText);
+          chrome.test.sendScriptResult(badgeText);
         });
       )";
 
-    return ExecuteScriptInBackgroundPage(
+    return ExecuteScriptInBackgroundPageAndReturnString(
         extension_id, base::StringPrintf(kBadgeTextQueryScript, tab_id));
   };
 
@@ -4226,13 +4238,14 @@
   ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules(
       {}, "test_extension", {URLPattern::kAllUrlsPattern}));
 
-  const char kGetOnRuleMatchedDebugScript[] = R"(
+  static constexpr char kGetOnRuleMatchedDebugScript[] = R"(
     const hasEvent = !!chrome.declarativeNetRequest.onRuleMatchedDebug ?
       'true' : 'false';
-    window.domAutomationController.send(hasEvent);
+    chrome.test.sendScriptResult(hasEvent);
   )";
-  std::string actual_event_availability = ExecuteScriptInBackgroundPage(
-      last_loaded_extension_id(), kGetOnRuleMatchedDebugScript);
+  std::string actual_event_availability =
+      ExecuteScriptInBackgroundPageAndReturnString(
+          last_loaded_extension_id(), kGetOnRuleMatchedDebugScript);
 
   std::string expected_event_availability =
       GetParam() == ExtensionLoadType::UNPACKED ? "true" : "false";
@@ -4280,7 +4293,7 @@
   ASSERT_TRUE(WasFrameWithScriptLoaded(GetPrimaryMainFrame()));
 
   // Start the onRuleMatchedDebug observer.
-  const char kOnRuleMatchedDebugScript[] = R"(
+  static constexpr char kOnRuleMatchedDebugScript[] = R"(
     var matchedRules = [];
     var onRuleMatchedDebugCallback = (rule) => {
       matchedRules.push(rule);
@@ -4288,7 +4301,7 @@
 
     chrome.declarativeNetRequest.onRuleMatchedDebug.addListener(
       onRuleMatchedDebugCallback);
-    window.domAutomationController.send('ready');
+    chrome.test.sendScriptResult('ready');
   )";
 
   ASSERT_EQ("ready", ExecuteScriptInBackgroundPage(last_loaded_extension_id(),
@@ -4300,14 +4313,14 @@
   NavigateFrame(kFrameName1, set_cookie_and_referer_url);
 
   // Now query the onRuleMatchedDebug results.
-  const char kQueryMatchedRulesScript[] = R"(
+  static constexpr char kQueryMatchedRulesScript[] = R"(
     chrome.declarativeNetRequest.onRuleMatchedDebug.removeListener(
       onRuleMatchedDebugCallback);
     var ruleIds = matchedRules.map(matchedRule => matchedRule.rule.ruleId);
-    window.domAutomationController.send(ruleIds.sort().join());
+    chrome.test.sendScriptResult(ruleIds.sort().join());
   )";
 
-  std::string matched_rule_ids = ExecuteScriptInBackgroundPage(
+  std::string matched_rule_ids = ExecuteScriptInBackgroundPageAndReturnString(
       last_loaded_extension_id(), kQueryMatchedRulesScript);
 
   // The request to |set_cookie_and_referer_url| should be matched with the
@@ -4567,17 +4580,17 @@
   // |start_time|.
   NavigateFrame(kFrameName1, sub_frame_url);
 
-  const char getMatchedRuleTimestampScript[] = R"(
+  static constexpr char getMatchedRuleTimestampScript[] = R"(
     chrome.declarativeNetRequest.getMatchedRules((rules) => {
       var rule_count = rules.rulesMatchedInfo.length;
       var timestamp = rule_count === 1 ?
           rules.rulesMatchedInfo[0].timeStamp.toString() : '';
 
-      window.domAutomationController.send(timestamp);
+      chrome.test.sendScriptResult(timestamp);
     });
   )";
 
-  std::string timestamp_string = ExecuteScriptInBackgroundPage(
+  std::string timestamp_string = ExecuteScriptInBackgroundPageAndReturnString(
       extension_id, getMatchedRuleTimestampScript,
       browsertest_util::ScriptUserActivation::kDontActivate);
 
@@ -5662,7 +5675,7 @@
   rules.push_back(rule);
   ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules(rules));
 
-  const char kPageHtml[] = R"(
+  static constexpr char kPageHtml[] = R"(
         <title>Loaded</title>
         <body>
         <script>
@@ -5744,7 +5757,7 @@
   rules.push_back(rule);
   ASSERT_NO_FATAL_FAILURE(LoadExtensionWithRules(rules));
 
-  const char kPageHtml[] = R"(
+  static constexpr char kPageHtml[] = R"(
         <title>Loaded</title>
         <body>
         <script>
@@ -5805,9 +5818,9 @@
 // inside the web bundle whose URL is uuid-in-package:.
 IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestSubresourceWebBundlesBrowserTest,
                        RequestCanceledUuidInPackageUrl) {
-  const char pass_js_url[] =
+  static constexpr char pass_js_url[] =
       "uuid-in-package:fc80c15b-69e9-4a45-ab41-9c90d2b55976";
-  const char cancel_js_url[] =
+  static constexpr char cancel_js_url[] =
       "uuid-in-package:15d749ad-7d9f-49d9-94f7-83a866e7fef8";
   TestRule rule = CreateGenericRule();
   std::vector<TestRule> rules;
@@ -5877,7 +5890,7 @@
 // subresources inside the web bundle.
 IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestSubresourceWebBundlesBrowserTest,
                        RequestRedirected) {
-  const char kPageHtml[] = R"(
+  static constexpr char kPageHtml[] = R"(
         <title>Loaded</title>
         <body>
         <script>
@@ -6398,7 +6411,7 @@
       {"excluded", "DELETE,GET,HEAD,POST,PUT"},
       {"combination", "GET"}};
 
-  const char kPerformRequestWithAllMethodsScript[] = R"(
+  static constexpr char kPerformRequestWithAllMethodsScript[] = R"(
     {
       const allRequestMethods = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH",
                                  "POST", "PUT", "UNKNOWN"];
@@ -6477,7 +6490,7 @@
   std::string websocket_url =
       websocket_test_server.GetURL("echo-with-no-extension").spec();
 
-  const char kOpenWebSocketsScript[] = R"(
+  static constexpr char kOpenWebSocketsScript[] = R"(
     {
       const websocketUrl = "%s";
       const testCases = ["default", "all_methods", "some_methods",
@@ -6563,7 +6576,7 @@
   ASSERT_TRUE(
       ui_test_utils::NavigateToURL(browser(), https_server()->GetURL("/echo")));
 
-  const char kOpenWebTransportScript[] = R"((
+  static constexpr char kOpenWebTransportScript[] = R"((
     async () =>
     {
       const testCases = ["echo1_default", "echo2_include", "echo3_exclude" ];
@@ -6601,8 +6614,8 @@
 // and that if they try to redirect requests, the request is blocked, instead of
 // being redirected.
 IN_PROC_BROWSER_TEST_P(DeclarativeNetRequestBrowserTest, FledgeAuctionScripts) {
-  const char kAddedHeaderName[] = "Header-Name";
-  const char kAddedHeaderValue[] = "Header-Value";
+  static constexpr char kAddedHeaderName[] = "Header-Name";
+  static constexpr char kAddedHeaderValue[] = "Header-Value";
 
   ASSERT_TRUE(https_server()->Start());
 
diff --git a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc
index 42a9111..375aa55 100644
--- a/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc
+++ b/chrome/browser/extensions/api/extension_action/extension_action_apitest.cc
@@ -303,13 +303,13 @@
   ASSERT_TRUE(ready_listener.WaitUntilSatisfied());
 
   // The script template to update the browser action.
-  constexpr char kUpdate[] =
+  static constexpr char kUpdate[] =
       R"(chrome.browserAction.setBadgeText(%s);
-         domAutomationController.send('pass');)";
+         chrome.test.sendScriptResult('pass');)";
   content::WebContents* web_contents =
       browser()->tab_strip_model()->GetActiveWebContents();
   SessionID tab_id = sessions::SessionTabHelper::IdForTab(web_contents);
-  constexpr char kBrowserActionKey[] = "browser_action";
+  static constexpr char kBrowserActionKey[] = "browser_action";
   TestStateStoreObserver test_state_store_observer(profile(), extension->id());
 
   {
diff --git a/chrome/browser/extensions/api/messaging/messaging_apitest.cc b/chrome/browser/extensions/api/messaging/messaging_apitest.cc
index 0869507c..5b7c1c8 100644
--- a/chrome/browser/extensions/api/messaging/messaging_apitest.cc
+++ b/chrome/browser/extensions/api/messaging/messaging_apitest.cc
@@ -1260,24 +1260,27 @@
           sender->id(),
           base::StringPrintf(
               "if (chrome.test.isProcessingUserGesture()) {\n"
-              "  domAutomationController.send("
+              "  chrome.test.sendScriptResult("
               "      'Error: unexpected user gesture');\n"
               "} else {\n"
               "  chrome.runtime.sendMessage('%s', {}, function(response) {\n"
-              "    domAutomationController.send('' + response.result);\n"
+              "    chrome.test.sendScriptResult('' + response.result);\n"
               "  });\n"
               "}",
               receiver->id().c_str()),
           extensions::browsertest_util::ScriptUserActivation::kDontActivate));
 
-  EXPECT_EQ("true",
-      ExecuteScriptInBackgroundPage(sender->id(),
-                                    base::StringPrintf(
-          "chrome.test.runWithUserGesture(function() {\n"
-          "  chrome.runtime.sendMessage('%s', {}, function(response)  {\n"
-          "    window.domAutomationController.send('' + response.result);\n"
-          "  });\n"
-          "});", receiver->id().c_str())));
+  EXPECT_EQ(
+      "true",
+      ExecuteScriptInBackgroundPage(
+          sender->id(),
+          base::StringPrintf(
+              "chrome.test.runWithUserGesture(function() {\n"
+              "  chrome.runtime.sendMessage('%s', {}, function(response)  {\n"
+              "    chrome.test.sendScriptResult('' + response.result);\n"
+              "  });\n"
+              "});",
+              receiver->id().c_str())));
 }
 
 IN_PROC_BROWSER_TEST_F(MessagingApiTest, UserGestureFromContentScript) {
@@ -1365,7 +1368,7 @@
   base::CommandLine::ForCurrentProcess()->AppendSwitch(
       embedder_support::kDisablePopupBlocking);
 
-  const char kManifest[] = R"({
+  static constexpr char kManifest[] = R"({
     "name": "activation_state_thru_send_reply",
     "version": "1.0",
     "background": {
@@ -1395,13 +1398,13 @@
   const Extension* sender = LoadExtension(sender_dir.UnpackedPath());
   ASSERT_TRUE(sender);
 
-  const char send_script_template[] = R"(
+  static constexpr char send_script_template[] = R"(
     log = [];
     log.push('sender-initial:' + navigator.userActivation.isActive);
     chrome.runtime.sendMessage('%s', {}, response => {
       log.push('receiver:' + response.active);
       log.push('sender-received:' + navigator.userActivation.isActive);
-      window.domAutomationController.send(log.toString());
+      chrome.test.sendScriptResult(log.toString());
     });
     log.push('sender-sent:' + navigator.userActivation.isActive);
   )";
diff --git a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc
index 575ef02b..164b0eeb 100644
--- a/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc
+++ b/chrome/browser/extensions/api/webrtc_audio_private/webrtc_audio_private_browsertest.cc
@@ -223,8 +223,8 @@
   service->OnDevicesChanged(base::SystemMonitor::DEVTYPE_AUDIO);
 
   // Check that the extension got the notification.
-  std::string result = ExecuteScriptInBackgroundPage(extension->id(),
-                                                     "reportIfGot()");
+  std::string result =
+      ExecuteScriptInBackgroundPageDeprecated(extension->id(), "reportIfGot()");
   EXPECT_EQ("true", result);
 }
 
diff --git a/chrome/browser/extensions/back_forward_cache_browsertest.cc b/chrome/browser/extensions/back_forward_cache_browsertest.cc
index 4d2707f..58d76cc 100644
--- a/chrome/browser/extensions/back_forward_cache_browsertest.cc
+++ b/chrome/browser/extensions/back_forward_cache_browsertest.cc
@@ -171,15 +171,15 @@
   }
 
   void ExpectTitleChangeFail(const Extension& extension) {
-    constexpr char kScript[] =
+    static constexpr char kScript[] =
         R"(
           chrome.tabs.executeScript({code: "document.title='fail'"},
             () => {
               if (chrome.runtime.lastError) {
-                window.domAutomationController.send(
+                chrome.test.sendScriptResult(
                   chrome.runtime.lastError.message);
               } else {
-                window.domAutomationController.send("Unexpected success");
+                chrome.test.sendScriptResult("Unexpected success");
               }
             });
         )";
@@ -519,13 +519,13 @@
 
   // 5) Ensure that the runtime.onConnect listener in the restored page still
   // works.
-  constexpr char kScript[] =
+  static constexpr char kScript[] =
       R"HTML(
       var p;
       chrome.tabs.query({}, (t) => {
         p = chrome.tabs.connect(t[0].id);
         p.onMessage.addListener(
-         (m) => {window.domAutomationController.send(m)}
+         (m) => {chrome.test.sendScriptResult(m)}
         );
       });
     )HTML";
@@ -683,7 +683,7 @@
       ui_test_utils::NavigateToURL(browser(), url_a));
   std::u16string expected_title = u"connected";
 
-  constexpr char kScript[] =
+  static constexpr char kScript[] =
       R"HTML(
       chrome.tabs.query({}, (t) => {
         p = chrome.tabs.connect(t[0].id);
@@ -691,7 +691,7 @@
         // later.
         port = p;
         p.onMessage.addListener(
-         (m) => {window.domAutomationController.send(m)}
+         (m) => {chrome.test.sendScriptResult(m)}
         );
       });
     )HTML";
@@ -804,24 +804,24 @@
       ui_test_utils::NavigateToURL(browser(), url_a));
   std::u16string expected_title = u"connected";
 
-  constexpr char kScript[] =
+  static constexpr char kScript[] =
       R"HTML(
       var p;
       chrome.tabs.query({}, (t) => {
         p = chrome.tabs.connect(t[0].id);
         p.onMessage.addListener(
-         (m) => {window.domAutomationController.send(m)}
+         (m) => {chrome.test.sendScriptResult(m)}
         );
       });
     )HTML";
   EXPECT_EQ("connected",
             ExecuteScriptInBackgroundPage(extension->id(), kScript));
 
-  constexpr char kDisconnectScript[] =
+  static constexpr char kDisconnectScript[] =
       R"HTML(
       p.postMessage('disconnect');
       p.onDisconnect.addListener(() => {
-        window.domAutomationController.send('disconnect')
+        chrome.test.sendScriptResult('disconnect')
       });
     )HTML";
   EXPECT_EQ("disconnect",
@@ -958,13 +958,13 @@
   auto title_watcher = std::make_unique<content::TitleWatcher>(
       browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
 
-  constexpr char kScript[] =
+  static constexpr char kScript[] =
       R"HTML(
         chrome.tabs.executeScript({frameId: %d,
                                    code: "document.title='foo'",
                                    matchAboutBlank: true
                                   }, (e) => {
-          window.domAutomationController.send(chrome.runtime.lastError ? 'false'
+          chrome.test.sendScriptResult(chrome.runtime.lastError ? 'false'
         : 'true')});
       )HTML";
   EXPECT_EQ("false",
diff --git a/chrome/browser/extensions/background_xhr_browsertest.cc b/chrome/browser/extensions/background_xhr_browsertest.cc
index 35ef862..39735be2 100644
--- a/chrome/browser/extensions/background_xhr_browsertest.cc
+++ b/chrome/browser/extensions/background_xhr_browsertest.cc
@@ -63,7 +63,7 @@
       var xhr = new XMLHttpRequest();
       xhr.open('GET', '%s');
       xhr.send();
-      domAutomationController.send('');
+      chrome.test.sendScriptResult('');
     )";
     ExecuteScriptInBackgroundPage(
         extension->id(),
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc
index 755f1b1e..2966e44cd 100644
--- a/chrome/browser/extensions/content_script_apitest.cc
+++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -1023,14 +1023,14 @@
   ASSERT_TRUE(extension);
   GURL url = embedded_test_server()->GetURL("a.com", "/extensions/body1.html");
   ResultCatcher catcher;
-  constexpr char kScript[] =
+  static constexpr char kScript[] =
       R"(chrome.tabs.create({url: '%s'}, () => {
            let message = 'success';
            if (chrome.runtime.lastError)
              message = chrome.runtime.lastError.message;
-           domAutomationController.send(message);
+           chrome.test.sendScriptResult(message);
          });)";
-  std::string result = ExecuteScriptInBackgroundPage(
+  base::Value result = ExecuteScriptInBackgroundPage(
       extension->id(), base::StringPrintf(kScript, url.spec().c_str()));
 
   EXPECT_EQ("success", result);
@@ -1044,21 +1044,22 @@
   ASSERT_TRUE(extension);
   GURL url = embedded_test_server()->GetURL("b.com", "/extensions/body1.html");
   ResultCatcher catcher;
-  constexpr char kScript[] =
+  static constexpr char kScript[] =
       R"(chrome.tabs.create({url: '%s'}, (tab) => {
            if (chrome.runtime.lastError) {
-             domAutomationController.send(chrome.runtime.lastError.message);
+             chrome.test.sendScriptResult(chrome.runtime.lastError.message);
              return;
            }
            chrome.tabs.executeScript(tab.id, {file: 'cookies.js'}, () => {
              let message = 'success';
              if (chrome.runtime.lastError)
                message = chrome.runtime.lastError.message;
-             domAutomationController.send(message);
+             chrome.test.sendScriptResult(message);
            });
          });)";
-  std::string result = ExecuteScriptInBackgroundPage(
+  base::Value result = ExecuteScriptInBackgroundPage(
       extension->id(), base::StringPrintf(kScript, url.spec().c_str()));
+  ASSERT_TRUE(result.is_string());
 
   EXPECT_EQ("success", result);
   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
@@ -1071,10 +1072,10 @@
   ASSERT_TRUE(extension);
   GURL url = embedded_test_server()->GetURL("b.com", "/extensions/body1.html");
   ResultCatcher catcher;
-  constexpr char kScript[] =
+  static constexpr char kScript[] =
       R"(chrome.tabs.create({url: '%s'}, (tab) => {
            if (chrome.runtime.lastError) {
-             domAutomationController.send(chrome.runtime.lastError.message);
+             chrome.test.sendScriptResult(chrome.runtime.lastError.message);
              return;
            }
            fetch(chrome.runtime.getURL('cookies.js')).then((response) => {
@@ -1084,14 +1085,15 @@
                let message = 'success';
                if (chrome.runtime.lastError)
                  message = chrome.runtime.lastError.message;
-               domAutomationController.send(message);
+               chrome.test.sendScriptResult(message);
              });
            }).catch((e) => {
-             domAutomationController.send(e);
+             chrome.test.sendScriptResult(e);
            });
          });)";
-  std::string result = ExecuteScriptInBackgroundPage(
+  base::Value result = ExecuteScriptInBackgroundPage(
       extension->id(), base::StringPrintf(kScript, url.spec().c_str()));
+  ASSERT_TRUE(result.is_string());
 
   EXPECT_EQ("success", result);
   EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
diff --git a/chrome/browser/extensions/content_verifier_browsertest.cc b/chrome/browser/extensions/content_verifier_browsertest.cc
index 776d098..05ced4f 100644
--- a/chrome/browser/extensions/content_verifier_browsertest.cc
+++ b/chrome/browser/extensions/content_verifier_browsertest.cc
@@ -547,12 +547,12 @@
   EXPECT_EQ("Test", ExecuteScriptInBackgroundPage(
                         kStoragePermissionExtensionId,
                         R"(chrome.storage.local.set({key: "Test"}, () =>
-             domAutomationController.send("Test")))"));
+             chrome.test.sendScriptResult("Test")))"));
 
   EXPECT_EQ("Test", ExecuteScriptInBackgroundPage(
                         kStoragePermissionExtensionId,
                         R"(chrome.storage.local.get(['key'], ({key}) =>
-             domAutomationController.send(key)))"));
+             chrome.test.sendScriptResult(key)))"));
   // Corrupt the extension
   {
     base::FilePath resource_path = extension->path().Append(kResourcePath);
@@ -626,7 +626,7 @@
   EXPECT_EQ("Test", ExecuteScriptInBackgroundPage(
                         kStoragePermissionExtensionId,
                         R"(chrome.storage.local.get(['key'], ({key}) =>
-             domAutomationController.send(key)))"));
+             chrome.test.sendScriptResult(key)))"));
 }
 
 // Tests that verification failure during navigating to an extension resource
diff --git a/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc b/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
index 912f56f..b1e65b47 100644
--- a/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
+++ b/chrome/browser/extensions/corb_and_cors_extension_browsertest.cc
@@ -380,27 +380,26 @@
 
   bool RegisterServiceWorkerForExtension(
       const std::string& service_worker_script) {
-    const char kServiceWorkerPath[] = "service_worker.js";
+    static constexpr char kServiceWorkerPath[] = "service_worker.js";
     dir_.WriteFile(base::FilePath::FromASCII(kServiceWorkerPath).value(),
                    service_worker_script);
 
-    const char kRegistrationScript[] = R"(
+    static constexpr char kRegistrationScript[] = R"(
         navigator.serviceWorker.register($1).then(function() {
           // Wait until the service worker is active.
           return navigator.serviceWorker.ready;
         }).then(function(r) {
-          window.domAutomationController.send('SUCCESS');
+          chrome.test.sendScriptResult('SUCCESS');
         }).catch(function(err) {
-          window.domAutomationController.send('ERROR: ' + err.message);
+          chrome.test.sendScriptResult('ERROR: ' + err.message);
         }); )";
     std::string registration_script =
         content::JsReplace(kRegistrationScript, kServiceWorkerPath);
 
-    std::string result =
+    base::Value result =
         ExecuteScriptInBackgroundPage(extension_->id(), registration_script);
     if (result != "SUCCESS") {
       ADD_FAILURE() << "Failed to register the service worker: " << result;
-      return false;
     }
     return !::testing::Test::HasFailure();
   }
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc
index aaf2d26..5b3ae149 100644
--- a/chrome/browser/extensions/extension_browsertest.cc
+++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -847,7 +847,7 @@
   return result_host;
 }
 
-std::string ExtensionBrowserTest::ExecuteScriptInBackgroundPage(
+base::Value ExtensionBrowserTest::ExecuteScriptInBackgroundPage(
     const std::string& extension_id,
     const std::string& script,
     browsertest_util::ScriptUserActivation script_user_activation) {
@@ -855,6 +855,14 @@
       profile(), extension_id, script, script_user_activation);
 }
 
+std::string ExtensionBrowserTest::ExecuteScriptInBackgroundPageDeprecated(
+    const std::string& extension_id,
+    const std::string& script,
+    browsertest_util::ScriptUserActivation script_user_activation) {
+  return browsertest_util::ExecuteScriptInBackgroundPageDeprecated(
+      profile(), extension_id, script, script_user_activation);
+}
+
 bool ExtensionBrowserTest::ExecuteScriptInBackgroundPageNoWait(
     const std::string& extension_id,
     const std::string& script) {
diff --git a/chrome/browser/extensions/extension_browsertest.h b/chrome/browser/extensions/extension_browsertest.h
index e25b27c..20ff4e9f 100644
--- a/chrome/browser/extensions/extension_browsertest.h
+++ b/chrome/browser/extensions/extension_browsertest.h
@@ -334,19 +334,32 @@
                                   const std::string& path,
                                   int expected_hosts);
 
-  // Returns
-  // browsertest_util::ExecuteScriptInBackgroundPage(profile(),
-  // extension_id, script).
-  std::string ExecuteScriptInBackgroundPage(
+  // Waits until `script` calls "chrome.test.sendScriptResult(result)",
+  // where `result` is a serializable value, and returns `result`. Fails
+  // the test and returns an empty base::Value if `extension_id` isn't
+  // installed in the test's profile or doesn't have a background page, or
+  // if executing the script fails. The argument `script_user_activation`
+  // determines if the script should be executed after a user activation.
+  base::Value ExecuteScriptInBackgroundPage(
       const std::string& extension_id,
       const std::string& script,
       extensions::browsertest_util::ScriptUserActivation
           script_user_activation =
               extensions::browsertest_util::ScriptUserActivation::kActivate);
 
-  // Returns
-  // browsertest_util::ExecuteScriptInBackgroundPageNoWait(
-  // profile(), extension_id, script).
+  // Waits until |script| calls "window.domAutomationController.send(result)",
+  // where |result| is a string, and returns |result|. Fails the test and
+  // returns an empty base::Value if |extension_id| isn't installed in test's
+  // profile or doesn't have a background page, or if executing the script
+  // fails. The argument |script_user_activation| determines if the script
+  // should be executed after a user activation.
+  std::string ExecuteScriptInBackgroundPageDeprecated(
+      const std::string& extension_id,
+      const std::string& script,
+      extensions::browsertest_util::ScriptUserActivation
+          script_user_activation =
+              extensions::browsertest_util::ScriptUserActivation::kActivate);
+
   bool ExecuteScriptInBackgroundPageNoWait(const std::string& extension_id,
                                            const std::string& script);
 
diff --git a/chrome/browser/extensions/extension_keybinding_apitest.cc b/chrome/browser/extensions/extension_keybinding_apitest.cc
index 331778ea..a6a714f 100644
--- a/chrome/browser/extensions/extension_keybinding_apitest.cc
+++ b/chrome/browser/extensions/extension_keybinding_apitest.cc
@@ -149,15 +149,15 @@
   ASSERT_TRUE(extension_action);
   EXPECT_FALSE(extension_action->GetIsVisible(tab_id));
 
-  constexpr char kScriptTemplate[] =
+  static constexpr char kScriptTemplate[] =
       R"(chrome.pageAction.show(%d, () => {
-           domAutomationController.send(
+           chrome.test.sendScriptResult(
                chrome.runtime.lastError ?
                    chrome.runtime.lastError.message :
                    'success');
          });)";
 
-  std::string set_result = browsertest_util::ExecuteScriptInBackgroundPage(
+  base::Value set_result = browsertest_util::ExecuteScriptInBackgroundPage(
       profile, extension.id(), base::StringPrintf(kScriptTemplate, tab_id));
   EXPECT_EQ("success", set_result);
   EXPECT_TRUE(extension_action->GetIsVisible(tab_id));
@@ -195,13 +195,13 @@
   // rather than using WaitUntilSatisfied(), which in turn allows this method
   // to exercise both the case of expecting dispatch and expecting *not* to
   // dispatch.
-  constexpr char kScript[] =
+  static constexpr char kScript[] =
       R"(chrome.test.sendMessage(
              'run loop hack',
              () => {
-               domAutomationController.send('success');
+               chrome.test.sendScriptResult('success');
              });)";
-  std::string set_result = browsertest_util::ExecuteScriptInBackgroundPage(
+  base::Value set_result = browsertest_util::ExecuteScriptInBackgroundPage(
       profile, extension.id(), kScript);
   EXPECT_EQ("success", set_result);
   EXPECT_EQ(expect_dispatch, click_listener.was_satisfied());
diff --git a/chrome/browser/extensions/fetch_apitest.cc b/chrome/browser/extensions/fetch_apitest.cc
index 2465cc4..ef2db8f 100644
--- a/chrome/browser/extensions/fetch_apitest.cc
+++ b/chrome/browser/extensions/fetch_apitest.cc
@@ -45,16 +45,30 @@
 }
 
 // JavaScript snippet which performs a fetch given a URL expression to be
+// substituted as %s, then sends back the fetched content using
+// chrome.test.sendScriptResult.
+const char* kFetchScript = R"(
+  fetch(%s).then(function(result) {
+    return result.text();
+  }).then(function(text) {
+    chrome.test.sendScriptResult(text);
+  }).catch(function(err) {
+    chrome.test.sendScriptResult(String(err));
+  });
+)";
+
+// JavaScript snippet which performs a fetch given a URL expression to be
 // substituted as %s, then sends back the fetched content using the
 // domAutomationController.
-const char* kFetchScript =
-    "fetch(%s).then(function(result) {\n"
-    "  return result.text();\n"
-    "}).then(function(text) {\n"
-    "  window.domAutomationController.send(text);\n"
-    "}).catch(function(err) {\n"
-    "  window.domAutomationController.send(String(err));\n"
-    "});\n";
+const char* kDOMFetchScript = R"(
+  fetch(%s).then(function(result) {
+    return result.text();
+  }).then(function(text) {
+    window.domAutomationController.send(text);
+  }).catch(function(err) {
+    window.domAutomationController.send(String(err));
+  });
+)";
 
 constexpr char kFetchPostScript[] = R"(
   fetch($1, {method: 'POST'}).then((result) => {
@@ -82,6 +96,12 @@
     return base::StringPrintf(kFetchScript, url_expression.c_str());
   }
 
+  // Returns |kDOMFetchScript| with |url_expression| substituted as its test
+  // URL.
+  std::string GetDOMFetchScript(const std::string& url_expression) {
+    return base::StringPrintf(kDOMFetchScript, url_expression.c_str());
+  }
+
   // Returns |url| as a string surrounded by single quotes, for passing to
   // JavaScript as a string literal.
   std::string GetQuotedURL(const GURL& url) {
@@ -200,7 +220,7 @@
   std::string fetch_result;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
       empty_tab,
-      GetFetchScript(GetQuotedURL(extension->GetResourceURL("text"))),
+      GetDOMFetchScript(GetQuotedURL(extension->GetResourceURL("text"))),
       &fetch_result));
   EXPECT_EQ("text content", fetch_result);
 }
@@ -257,18 +277,18 @@
   std::string fetch_result;
   ASSERT_TRUE(content::ExecuteScriptAndExtractString(
       empty_tab,
-      GetFetchScript(GetQuotedURL(extension->GetResourceURL("text"))),
+      GetDOMFetchScript(GetQuotedURL(extension->GetResourceURL("text"))),
       &fetch_result));
   EXPECT_EQ("TypeError: Failed to fetch", fetch_result);
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionFetchTest, FetchResponseType) {
   const std::string script = base::StringPrintf(
-      "fetch(%s).then(function(response) {\n"
-      "  window.domAutomationController.send(response.type);\n"
-      "}).catch(function(err) {\n"
-      "  window.domAutomationController.send(String(err));\n"
-      "});\n",
+      R"(fetch(%s).then((response) => {
+           chrome.test.sendScriptResult(response.type);
+         }).catch((err) => {
+           chrome.test.sendScriptResult(String(err));
+         });)",
       GetQuotedTestServerURL("example.com", "/extensions/test_file.txt")
           .data());
   TestExtensionDir dir;
@@ -305,7 +325,7 @@
   std::string script = content::JsReplace(kFetchPostScript, destination_url);
   std::string origin_string = url::Origin::Create(extension->url()).Serialize();
   EXPECT_EQ(origin_string,
-            ExecuteScriptInBackgroundPage(extension->id(), script));
+            ExecuteScriptInBackgroundPageDeprecated(extension->id(), script));
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionFetchTest, OriginOnPostWithoutPermissions) {
@@ -325,7 +345,7 @@
       kFetchPostScript,
       embedded_test_server()->GetURL("example.com", "/echo-origin"));
   EXPECT_EQ(url::Origin::Create(extension->url()).Serialize(),
-            ExecuteScriptInBackgroundPage(extension->id(), script));
+            ExecuteScriptInBackgroundPageDeprecated(extension->id(), script));
 }
 
 // An extension background script should be able to fetch resources contained in
@@ -338,7 +358,7 @@
   const std::string script = base::StringPrintf(R"(
       const script = document.createElement('script');
       window.onerror = (message) => {
-        window.domAutomationController.send('onerror: ' + message);
+        chrome.test.sendScriptResult('onerror: ' + message);
       }
       script.src = 'error.js'
       document.body.appendChild(script);)");
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc
index 927b930..65759bb 100644
--- a/chrome/browser/extensions/service_worker_apitest.cc
+++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -1253,7 +1253,7 @@
   const char* kScript = R"(
     let channel = new MessageChannel();
     test.waitForMessage(channel.port1).then(message => {
-      window.domAutomationController.send(message);
+      chrome.test.sendScriptResult(message);
     });
     test.registeredServiceWorker.postMessage(
         {port: channel.port2}, [channel.port2]);
@@ -1291,7 +1291,8 @@
   EXPECT_EQ("hello", result);
   EXPECT_EQ(
       "/extensions/api_test/service_worker/webrequest/hello.txt?fallthrough",
-      ExecuteScriptInBackgroundPage(extension->id(), "getLastHookedPath()"));
+      ExecuteScriptInBackgroundPageDeprecated(extension->id(),
+                                              "getLastHookedPath()"));
 
   // Initiate a fetch that results in calling fetch() in the service worker.
   result.clear();
@@ -1301,7 +1302,8 @@
   EXPECT_EQ(
       "/extensions/api_test/service_worker/webrequest/"
       "hello.txt?respondWithFetch",
-      ExecuteScriptInBackgroundPage(extension->id(), "getLastHookedPath()"));
+      ExecuteScriptInBackgroundPageDeprecated(extension->id(),
+                                              "getLastHookedPath()"));
 }
 
 IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, SWServedBackgroundPageReceivesEvent) {
@@ -1378,7 +1380,7 @@
       "  messagePromise = test.waitForMessage(navigator.serviceWorker);\n"
       "}\n"
       "messagePromise.then(function(message) {\n"
-      "  window.domAutomationController.send(String(message == 'success'));\n"
+      "  chrome.test.sendScriptResult(String(message == 'success'));\n"
       "})\n";
   EXPECT_EQ("true", ExecuteScriptInBackgroundPage(extension->id(), kScript));
 }
@@ -1393,7 +1395,7 @@
   const char* kScript =
       "var mc = new MessageChannel();\n"
       "test.waitForMessage(mc.port1).then(function(message) {\n"
-      "  window.domAutomationController.send(String(message == 'hello'));\n"
+      "  chrome.test.sendScriptResult(String(message == 'hello'));\n"
       "});\n"
       "test.registeredServiceWorker.postMessage(\n"
       "    {message: 'hello', port: mc.port2}, [mc.port2])\n";
diff --git a/chrome/browser/extensions/wasm_app_browsertest.cc b/chrome/browser/extensions/wasm_app_browsertest.cc
index 696314ca..06750f8 100644
--- a/chrome/browser/extensions/wasm_app_browsertest.cc
+++ b/chrome/browser/extensions/wasm_app_browsertest.cc
@@ -17,8 +17,8 @@
       LoadExtension(test_data_dir_.AppendASCII("wasm_app"));
   ASSERT_TRUE(extension);
 
-  EXPECT_EQ("success", ExecuteScriptInBackgroundPage(extension->id(),
-                                                     "instantiateFetch()"));
+  EXPECT_EQ("success", ExecuteScriptInBackgroundPageDeprecated(
+                           extension->id(), "instantiateFetch()"));
 }
 
 IN_PROC_BROWSER_TEST_F(WasmAppTest, InstantiateWasmFromArrayBuffer) {
@@ -26,7 +26,7 @@
       LoadExtension(test_data_dir_.AppendASCII("wasm_app"));
   ASSERT_TRUE(extension);
 
-  EXPECT_EQ("success", ExecuteScriptInBackgroundPage(
+  EXPECT_EQ("success", ExecuteScriptInBackgroundPageDeprecated(
                            extension->id(), "instantiateArrayBuffer()"));
 }
 
diff --git a/chrome/browser/fast_checkout/fast_checkout_client_impl.cc b/chrome/browser/fast_checkout/fast_checkout_client_impl.cc
index 2ffc151..9add07e 100644
--- a/chrome/browser/fast_checkout/fast_checkout_client_impl.cc
+++ b/chrome/browser/fast_checkout/fast_checkout_client_impl.cc
@@ -368,8 +368,9 @@
         static_cast<autofill::BrowserAutofillManager*>(autofill_manager_.get())
             ->SetFastCheckoutRunId(autofill::FieldTypeGroup::kAddressHome,
                                    run_id_);
-        autofill_manager_->FillProfileForm(*autofill_profile,
-                                           form->ToFormData(), *field);
+        autofill_manager_->FillProfileForm(
+            *autofill_profile, form->ToFormData(), *field,
+            autofill::AutofillTriggerSource::kFastCheckout);
       }
     }
 
@@ -406,8 +407,9 @@
       FillingState::kFilling;
   static_cast<autofill::BrowserAutofillManager*>(autofill_manager_.get())
       ->SetFastCheckoutRunId(autofill::FieldTypeGroup::kCreditCard, run_id_);
-  autofill_manager_->FillCreditCardForm(form.ToFormData(), field, credit_card,
-                                        cvc);
+  autofill_manager_->FillCreditCardForm(
+      form.ToFormData(), field, credit_card, cvc,
+      autofill::AutofillTriggerSource::kFastCheckout);
 }
 
 autofill::AutofillProfile*
diff --git a/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc b/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc
index cc0b58e..a1a1844 100644
--- a/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc
+++ b/chrome/browser/fast_checkout/fast_checkout_client_impl_unittest.cc
@@ -133,14 +133,16 @@
               FillProfileFormImpl,
               (const autofill::FormData&,
                const autofill::FormFieldData&,
-               const autofill::AutofillProfile&),
+               const autofill::AutofillProfile&,
+               const autofill::AutofillTriggerSource),
               (override));
   MOCK_METHOD(void,
               FillCreditCardFormImpl,
               (const autofill::FormData&,
                const autofill::FormFieldData&,
                const autofill::CreditCard&,
-               const std::u16string&),
+               const std::u16string&,
+               const autofill::AutofillTriggerSource),
               (override));
   MOCK_METHOD(void,
               SetFastCheckoutRunId,
@@ -703,10 +705,12 @@
     filling_state = FastCheckoutClientImpl::FillingState::kNotFilled;
   }
 
-  EXPECT_CALL(*autofill_manager(),
-              FillProfileFormImpl(FormDataEqualTo(address_form_data),
-                                  FormFieldDataEqualTo(address_form_field_data),
-                                  Eq(*autofill_profile)));
+  EXPECT_CALL(
+      *autofill_manager(),
+      FillProfileFormImpl(FormDataEqualTo(address_form_data),
+                          FormFieldDataEqualTo(address_form_field_data),
+                          Eq(*autofill_profile),
+                          Eq(autofill::AutofillTriggerSource::kFastCheckout)));
   EXPECT_CALL(*autofill_manager(),
               SetFastCheckoutRunId(autofill::FieldTypeGroup::kAddressHome,
                                    fast_checkout_client()->run_id_));
@@ -744,7 +748,8 @@
   EXPECT_CALL(*autofill_manager(),
               FillCreditCardFormImpl(
                   FormDataEqualTo(credit_card_form->ToFormData()),
-                  FormFieldDataEqualTo(field), Eq(*credit_card), Eq(cvc)));
+                  FormFieldDataEqualTo(field), Eq(*credit_card), Eq(cvc),
+                  Eq(autofill::AutofillTriggerSource::kFastCheckout)));
   EXPECT_CALL(*autofill_manager(),
               SetFastCheckoutRunId(autofill::FieldTypeGroup::kCreditCard,
                                    fast_checkout_client()->run_id_));
@@ -906,7 +911,8 @@
   EXPECT_CALL(*autofill_manager(),
               FillCreditCardFormImpl(
                   FormDataEqualTo(credit_card_form->ToFormData()),
-                  FormFieldDataEqualTo(field), Eq(*credit_card), Eq(cvc)));
+                  FormFieldDataEqualTo(field), Eq(*credit_card), Eq(cvc),
+                  Eq(autofill::AutofillTriggerSource::kFastCheckout)));
   EXPECT_CALL(*autofill_manager(),
               SetFastCheckoutRunId(autofill::FieldTypeGroup::kCreditCard,
                                    fast_checkout_client()->run_id_));
@@ -1032,10 +1038,11 @@
   EXPECT_CALL(
       *autofill_manager(),
       SetFastCheckoutRunId(autofill::FieldTypeGroup::kCreditCard, Ne(0)));
-  EXPECT_CALL(
-      *autofill_manager(),
-      FillCreditCardFormImpl(FormDataEqualTo(credit_card_form->ToFormData()),
-                             FormFieldDataEqualTo(field), _, Eq(u"")));
+  EXPECT_CALL(*autofill_manager(),
+              FillCreditCardFormImpl(
+                  FormDataEqualTo(credit_card_form->ToFormData()),
+                  FormFieldDataEqualTo(field), _, Eq(u""),
+                  Eq(autofill::AutofillTriggerSource::kFastCheckout)));
   StartRunAndSelectOptions({credit_card_form->form_signature()},
                            /*local_card=*/true);
   EXPECT_FALSE(fast_checkout_client()->IsNotShownYet());
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json
index e3121c0..fcb6bbe 100644
--- a/chrome/browser/flag-metadata.json
+++ b/chrome/browser/flag-metadata.json
@@ -1416,7 +1416,7 @@
   {
     "name": "devtools-tab-target",
     "owners": [ "dsv", "caseq" ],
-    "expiry_milestone": 114
+    "expiry_milestone": 118
   },
   {
     "name": "disable-accelerated-2d-canvas",
@@ -3989,7 +3989,7 @@
   {
     "name": "force-password-initial-sync-when-decryption-fails",
     "owners": [ "derinel@google.com", "mamir" ],
-    "expiry_milestone": 114
+    "expiry_milestone": 118
   },
   {
     "name": "force-resync-drive",
@@ -5851,7 +5851,7 @@
   {
     "name": "password-notes",
     "owners": ["mamir", "derinel@google.com", "rgod@google.com"],
-    "expiry_milestone": 114
+    "expiry_milestone": 118
   },
   {
     "name": "password-strength-indicator",
@@ -5861,7 +5861,7 @@
   {
     "name": "password-view-page-in-settings",
     "owners": ["mamir", "derinel@google.com"],
-    "expiry_milestone": 114
+    "expiry_milestone": 118
   },
   {
     "name": "passwords-grouping",
@@ -6712,7 +6712,7 @@
   {
     "name": "skip-undecryptable-passwords",
     "owners": [ "derinel@google.com", "mamir" ],
-    "expiry_milestone": 114
+    "expiry_milestone": 118
   },
   {
     "name": "slim-compositor",
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc
index 893a017..ebd0ad35 100644
--- a/chrome/browser/flags/android/chrome_feature_list.cc
+++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -229,7 +229,6 @@
     &kContextualSearchThinWebViewImplementation,
     &kDeferKeepScreenOnDuringGesture,
     &kDeferNotifyInMotion,
-    &kDelayTransitionsForAnimation,
     &kExperimentsForAgsa,
     &kExploreSites,
     &kFocusOmniboxInIncognitoTabIntents,
@@ -727,10 +726,6 @@
              "DeferNotifyInMotion",
              base::FEATURE_DISABLED_BY_DEFAULT);
 
-BASE_FEATURE(kDelayTransitionsForAnimation,
-             "DelayTransitionsForAnimation",
-             base::FEATURE_ENABLED_BY_DEFAULT);
-
 BASE_FEATURE(kDownloadAutoResumptionThrottling,
              "DownloadAutoResumptionThrottling",
              base::FEATURE_ENABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h
index 3e90bb1..82e4cde 100644
--- a/chrome/browser/flags/android/chrome_feature_list.h
+++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -87,7 +87,6 @@
 BASE_DECLARE_FEATURE(kContextualSearchThinWebViewImplementation);
 BASE_DECLARE_FEATURE(kDeferKeepScreenOnDuringGesture);
 BASE_DECLARE_FEATURE(kDeferNotifyInMotion);
-BASE_DECLARE_FEATURE(kDelayTransitionsForAnimation);
 BASE_DECLARE_FEATURE(kDontPrefetchLibraries);
 BASE_DECLARE_FEATURE(kDownloadAutoResumptionThrottling);
 BASE_DECLARE_FEATURE(kDownloadHomeForExternalApp);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
index 94d0e79..f1e3773 100644
--- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
+++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -300,7 +300,6 @@
     public static final String DEFER_KEEP_SCREEN_ON_DURING_GESTURE =
             "DeferKeepScreenOnDuringGesture";
     public static final String DEFER_NOTIFY_IN_MOTION = "DeferNotifyInMotion";
-    public static final String DELAY_TRANSITIONS_FOR_ANIMATION = "DelayTransitionsForAnimation";
     public static final String DETAILED_LANGUAGE_SETTINGS = "DetailedLanguageSettings";
     public static final String DISCO_FEED_ENDPOINT = "DiscoFeedEndpoint";
     public static final String DNS_OVER_HTTPS = "DnsOverHttps";
diff --git a/chrome/browser/media/media_engagement_browsertest.cc b/chrome/browser/media/media_engagement_browsertest.cc
index dde11143..6f31cb2 100644
--- a/chrome/browser/media/media_engagement_browsertest.cc
+++ b/chrome/browser/media/media_engagement_browsertest.cc
@@ -977,29 +977,18 @@
                        DoNotSendEngagementLevelToRenderFrameInPrerendering) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
+  MockAutoplayConfigurationClient client;
+  OverrideInterface(GetWebContents()->GetPrimaryMainFrame(), &client);
+
   const GURL& initial_url = embedded_test_server()->GetURL("/empty.html");
   SetScores(url::Origin::Create(initial_url), 24, 20);
 
-  content::TestNavigationManager navigation_manager(GetWebContents(),
-                                                    initial_url);
-
-  content::NavigationController::LoadURLParams params(initial_url);
-  params.transition_type = ui::PAGE_TRANSITION_LINK;
-  params.frame_tree_node_id =
-      GetWebContents()->GetPrimaryMainFrame()->GetFrameTreeNodeId();
-  GetWebContents()->GetController().LoadURLWithParams(params);
-
-  EXPECT_TRUE(navigation_manager.WaitForResponse());
-
-  MockAutoplayConfigurationClient client;
-  OverrideInterface(
-      navigation_manager.GetNavigationHandle()->GetRenderFrameHost(), &client);
   // AddAutoplayFlags should be called once after navigating |initial_url| in
   // the main frame.
   EXPECT_CALL(client, AddAutoplayFlags(testing::_, testing::_)).Times(1);
 
-  navigation_manager.ResumeNavigation();
-  EXPECT_TRUE(navigation_manager.WaitForNavigationFinished());
+  // Navigate to an initial page.
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url));
 
   // Loads a page in a prerendered page.
   GURL prerender_url = embedded_test_server()->GetURL("/title1.html");
@@ -1056,29 +1045,18 @@
                        SendEngagementLevelToRenderFrameOnFencedFrame) {
   ASSERT_TRUE(embedded_test_server()->Start());
 
+  MockAutoplayConfigurationClient client;
+  OverrideInterface(GetWebContents()->GetPrimaryMainFrame(), &client);
+
   const GURL& initial_url =
       embedded_test_server()->GetURL("a.com", "/empty.html");
   SetScores(url::Origin::Create(initial_url), 24, 20);
-  content::TestNavigationManager navigation_manager(GetWebContents(),
-                                                    initial_url);
 
-  content::NavigationController::LoadURLParams params(initial_url);
-  params.transition_type = ui::PAGE_TRANSITION_LINK;
-  params.frame_tree_node_id =
-      GetWebContents()->GetPrimaryMainFrame()->GetFrameTreeNodeId();
-  GetWebContents()->GetController().LoadURLWithParams(params);
-
-  EXPECT_TRUE(navigation_manager.WaitForResponse());
-
-  MockAutoplayConfigurationClient client;
-  OverrideInterface(
-      navigation_manager.GetNavigationHandle()->GetRenderFrameHost(), &client);
-  // AddAutoplayFlags should be called once after navigating |initial_url| in
-  // the main frame.
+  // AddAutoplayFlags should be called on the primary main frame.
   EXPECT_CALL(client, AddAutoplayFlags(testing::_, testing::_)).Times(1);
 
-  navigation_manager.ResumeNavigation();
-  EXPECT_TRUE(navigation_manager.WaitForNavigationFinished());
+  // Navigate to an initial page.
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), initial_url));
 
   // Create a fenced frame.
   GURL fenced_frame_url =
@@ -1089,29 +1067,17 @@
   EXPECT_NE(nullptr, fenced_frame_host);
 
   // AddAutoplayFlags should be called on the fenced frame.
+  MockAutoplayConfigurationClient fenced_frame_client;
+  OverrideInterface(fenced_frame_host, &fenced_frame_client);
   GURL fenced_frame_navigate_url =
       embedded_test_server()->GetURL("b.com", "/fenced_frames/title2.html");
-  content::TestNavigationManager navigation_manager2(GetWebContents(),
-                                                     fenced_frame_navigate_url);
-  EXPECT_TRUE(ExecJs(
-      fenced_frame_host,
-      content::JsReplace("location.href = $1;", fenced_frame_navigate_url)));
-
-  EXPECT_TRUE(navigation_manager2.WaitForResponse());
-  MockAutoplayConfigurationClient fenced_frame_client;
-  OverrideInterface(
-      navigation_manager2.GetNavigationHandle()->GetRenderFrameHost(),
-      &fenced_frame_client);
-  // AddAutoplayFlags should be called once after navigating |initial_url| in
-  // the main frame.
   base::RunLoop run_loop;
   EXPECT_CALL(fenced_frame_client,
               AddAutoplayFlags(url::Origin::Create(fenced_frame_navigate_url),
                                testing::_))
       .Times(1)
       .WillOnce(base::test::RunClosure(run_loop.QuitClosure()));
-
-  navigation_manager2.ResumeNavigation();
-  EXPECT_TRUE(navigation_manager2.WaitForNavigationFinished());
+  fenced_frame_test_helper().NavigateFrameInFencedFrameTree(
+      fenced_frame_host, fenced_frame_navigate_url);
   run_loop.Run();
 }
diff --git a/chrome/browser/media/unified_autoplay_browsertest.cc b/chrome/browser/media/unified_autoplay_browsertest.cc
index 5124719..991765f 100644
--- a/chrome/browser/media/unified_autoplay_browsertest.cc
+++ b/chrome/browser/media/unified_autoplay_browsertest.cc
@@ -11,7 +11,6 @@
 #include "chrome/test/base/ui_test_utils.h"
 #include "components/content_settings/core/browser/host_content_settings_map.h"
 #include "components/content_settings/core/common/content_settings_pattern.h"
-#include "content/public/browser/navigation_handle.h"
 #include "content/public/browser/render_frame_host.h"
 #include "content/public/browser/render_process_host.h"
 #include "content/public/browser/render_view_host.h"
@@ -114,10 +113,12 @@
     return result;
   }
 
-  void SetAutoplayForceAllowFlag(content::RenderFrameHost* rfh,
-                                 const GURL& url) {
+  void SetAutoplayForceAllowFlag(const GURL& url) {
     mojo::AssociatedRemote<blink::mojom::AutoplayConfigurationClient> client;
-    rfh->GetRemoteAssociatedInterfaces()->GetInterface(&client);
+    GetWebContents()
+        ->GetPrimaryMainFrame()
+        ->GetRemoteAssociatedInterfaces()
+        ->GetInterface(&client);
     client->AddAutoplayFlags(url::Origin::Create(url),
                              blink::mojom::kAutoplayFlagForceAllow);
   }
@@ -254,21 +255,8 @@
 IN_PROC_BROWSER_TEST_F(UnifiedAutoplayBrowserTest, BypassUsingAutoplayFlag) {
   const GURL kTestPageUrl = embedded_test_server()->GetURL(kTestPagePath);
 
-  content::TestNavigationManager navigation_manager(
-      browser()->tab_strip_model()->GetActiveWebContents(), kTestPageUrl);
-  content::NavigationController::LoadURLParams params(kTestPageUrl);
-  params.transition_type = ui::PAGE_TRANSITION_LINK;
-  params.frame_tree_node_id =
-      GetWebContents()->GetPrimaryMainFrame()->GetFrameTreeNodeId();
-  GetWebContents()->GetController().LoadURLWithParams(params);
-  EXPECT_TRUE(navigation_manager.WaitForResponse());
-
-  // Set the flag on the RenderFrameHost we're navigating to.
-  SetAutoplayForceAllowFlag(
-      navigation_manager.GetNavigationHandle()->GetRenderFrameHost(),
-      kTestPageUrl);
-  navigation_manager.ResumeNavigation();
-  EXPECT_TRUE(navigation_manager.WaitForNavigationFinished());
+  SetAutoplayForceAllowFlag(kTestPageUrl);
+  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kTestPageUrl));
 
   EXPECT_TRUE(AttemptPlay(GetWebContents()));
 }
@@ -277,9 +265,8 @@
                        BypassUsingAutoplayFlag_SameDocument) {
   const GURL kTestPageUrl = embedded_test_server()->GetURL(kTestPagePath);
 
+  SetAutoplayForceAllowFlag(kTestPageUrl);
   ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), kTestPageUrl));
-  SetAutoplayForceAllowFlag(GetWebContents()->GetPrimaryMainFrame(),
-                            kTestPageUrl);
 
   // Simulate a same document navigation by navigating to #test.
   GURL::Replacements replace_ref;
diff --git a/chrome/browser/metrics/startup_metrics_browsertest.cc b/chrome/browser/metrics/startup_metrics_browsertest.cc
index c215f58..1e21da3 100644
--- a/chrome/browser/metrics/startup_metrics_browsertest.cc
+++ b/chrome/browser/metrics/startup_metrics_browsertest.cc
@@ -36,7 +36,6 @@
     "Startup.FirstWebContents.MainNavigationFinished",
     "Startup.FirstWebContents.MainNavigationStart",
     "Startup.FirstWebContents.NonEmptyPaint3",
-    "Startup.FirstWebContents.RenderProcessHostInit.ToNonEmptyPaint",
 #endif  // !BUILDFLAG(IS_ANDROID)
 
 #if BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/metrics/usertype_by_devicetype_metrics_provider_browsertest.cc b/chrome/browser/metrics/usertype_by_devicetype_metrics_provider_browsertest.cc
index 4e34197..547dd60 100644
--- a/chrome/browser/metrics/usertype_by_devicetype_metrics_provider_browsertest.cc
+++ b/chrome/browser/metrics/usertype_by_devicetype_metrics_provider_browsertest.cc
@@ -13,9 +13,9 @@
 #include "build/build_config.h"
 #include "chrome/browser/ash/app_mode/web_app/web_kiosk_app_manager.h"
 #include "chrome/browser/ash/login/app_mode/kiosk_launch_controller.h"
+#include "chrome/browser/ash/login/app_mode/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/existing_user_controller.h"
 #include "chrome/browser/ash/login/test/embedded_policy_test_server_mixin.h"
-#include "chrome/browser/ash/login/test/kiosk_test_helpers.h"
 #include "chrome/browser/ash/login/test/logged_in_user_mixin.h"
 #include "chrome/browser/ash/login/test/session_manager_state_waiter.h"
 #include "chrome/browser/ash/login/wizard_controller.h"
@@ -381,8 +381,9 @@
   }
 
   void WaitForSessionStart() {
-    if (IsSessionStarted())
+    if (IsSessionStarted()) {
       return;
+    }
     ash::test::WaitForPrimaryUserSessionStart();
   }
 
diff --git a/chrome/browser/net/network_context_configuration_browsertest.cc b/chrome/browser/net/network_context_configuration_browsertest.cc
index 6bbe7d1..ad2ea74 100644
--- a/chrome/browser/net/network_context_configuration_browsertest.cc
+++ b/chrome/browser/net/network_context_configuration_browsertest.cc
@@ -840,10 +840,10 @@
   std::string script = R"((url => {
     var xhr = new XMLHttpRequest();
     xhr.open('GET', url, true);
-    xhr.onload = () => domAutomationController.send(xhr.responseText);
+    xhr.onload = () => chrome.test.sendScriptResult(xhr.responseText);
     xhr.send();
   }))";
-  std::string result =
+  base::Value result =
       extensions::browsertest_util::ExecuteScriptInBackgroundPage(
           GetProfile(), extension->id(), script + "('" + url.spec() + "')");
   EXPECT_EQ("cookie", result);
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js
index d8e9df3..5650f49 100644
--- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js
+++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/background_test.js
@@ -3815,9 +3815,11 @@
       await mockFeedback.replay();
     });
 
-AX_TEST_F('ChromeVoxBackgroundTest', 'SelectWithOptGroup', async function() {
-  const mockFeedback = this.createMockFeedback();
-  const site = `
+// TODO(crbug.com/1427939): Flaky.
+AX_TEST_F(
+    'ChromeVoxBackgroundTest', 'DISABLED_SelectWithOptGroup', async function() {
+      const mockFeedback = this.createMockFeedback();
+      const site = `
     <select>
       <optgroup label="Theropods">
           <option>Tyrannosaurus</option>
@@ -3826,18 +3828,18 @@
       </optgroup>
     </select>
   `;
-  await this.runWithLoadedTree(site);
-  mockFeedback.expectSpeech('Tyrannosaurus', 'has pop up', 'Collapsed')
-      .call(doCmd('forceClickOnCurrentItem'))
-      .expectSpeech('Tyrannosaurus')
-      .call(press(KeyCode.DOWN))
-      .expectSpeech('Velociraptor')
-      .call(press(KeyCode.DOWN))
-      .expectSpeech('Deinonychus')
-      .call(press(KeyCode.UP))
-      .expectSpeech('Velociraptor');
-  await mockFeedback.replay();
-});
+      await this.runWithLoadedTree(site);
+      mockFeedback.expectSpeech('Tyrannosaurus', 'has pop up', 'Collapsed')
+          .call(doCmd('forceClickOnCurrentItem'))
+          .expectSpeech('Tyrannosaurus')
+          .call(press(KeyCode.DOWN))
+          .expectSpeech('Velociraptor')
+          .call(press(KeyCode.DOWN))
+          .expectSpeech('Deinonychus')
+          .call(press(KeyCode.UP))
+          .expectSpeech('Velociraptor');
+      await mockFeedback.replay();
+    });
 
 AX_TEST_F('ChromeVoxBackgroundTest', 'GroupNavigation', async function() {
   const mockFeedback = this.createMockFeedback();
diff --git a/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.ts b/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.ts
index 6201ff1..0ec502e0 100644
--- a/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.ts
+++ b/chrome/browser/resources/chromeos/cloud_upload/cloud_upload_dialog.ts
@@ -64,7 +64,11 @@
         ]);
 
     // TODO(b/251046341): Adjust this once the rest of the pages are in place.
-    this.pages.push(new WelcomePageElement());
+    const welcomePage = new WelcomePageElement();
+    if (isOfficeWebAppInstalled && isOdfsMounted) {
+      welcomePage.setZeroStep();
+    }
+    this.pages.push(welcomePage);
 
     if (!isOfficeWebAppInstalled) {
       this.pages.push(new OfficePwaInstallPageElement());
diff --git a/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts b/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts
index efd49ab..e128e0f 100644
--- a/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts
+++ b/chrome/browser/resources/chromeos/cloud_upload/file_handler_page.ts
@@ -64,7 +64,7 @@
       assert(dialogArgs.args.tasks);
       // Adjust the dialog's size if there are no local tasks to display.
       if (dialogArgs.args.tasks.length == 0) {
-        this.style.height = '310px';
+        this.style.height = '311px';
       }
 
       const {name, icon, type} =
diff --git a/chrome/browser/resources/chromeos/cloud_upload/welcome_page.html b/chrome/browser/resources/chromeos/cloud_upload/welcome_page.html
index cbbb830..4156abf 100644
--- a/chrome/browser/resources/chromeos/cloud_upload/welcome_page.html
+++ b/chrome/browser/resources/chromeos/cloud_upload/welcome_page.html
@@ -27,11 +27,13 @@
   Set up Microsoft 365 to open files
 </div>
 <div slot="body">
-  <ol>
-    <li>Install Microsoft 365</li>
-    <li>Connect to Microsoft OneDrive</li>
-    <li>Files will move to OneDrive when opening in Microsoft 365</li>
-  </ol>
+  <div id="description">
+    <ol>
+      <li>Install Microsoft 365</li>
+      <li>Connect to Microsoft OneDrive</li>
+      <li>Files will move to OneDrive when opening in Microsoft 365</li>
+    </ol>
+  </div>
   <p>
     <a href="#" target="_blank">Learn more</a> about Microsoft 365 on your
     Chromebook. Read the <a href="#" target="_blank">Microsoft terms and
diff --git a/chrome/browser/resources/chromeos/cloud_upload/welcome_page.ts b/chrome/browser/resources/chromeos/cloud_upload/welcome_page.ts
index 1cb77c4..e4747f69 100644
--- a/chrome/browser/resources/chromeos/cloud_upload/welcome_page.ts
+++ b/chrome/browser/resources/chromeos/cloud_upload/welcome_page.ts
@@ -11,6 +11,8 @@
  * The WelcomePageElement represents the first page in the setup flow.
  */
 export class WelcomePageElement extends BaseSetupPageElement {
+  private isZeroStep = false;
+
   constructor() {
     super();
   }
@@ -20,13 +22,26 @@
 
     this.innerHTML = getTemplate();
 
+    const description = this.querySelector('#description') as HTMLElement;
+    if (this.isZeroStep) {
+      description.innerText = 'Files will move to Microsoft OneDrive when' +
+          'opening in Microsoft 365';
+    }
+
     const actionButton = this.querySelector('.action-button') as HTMLElement;
     actionButton.addEventListener('click', this.onActionButtonClick);
+    if (this.isZeroStep) {
+      actionButton.innerText = 'Set up';
+    }
 
     const cancelButton = this.querySelector('.cancel-button') as HTMLElement;
     cancelButton.addEventListener('click', this.onCancelButtonClick);
   }
 
+  setZeroStep() {
+    this.isZeroStep = true;
+  }
+
   private onActionButtonClick() {
     this.dispatchEvent(
         new CustomEvent(NEXT_PAGE_EVENT, {bubbles: true, composed: true}));
diff --git a/chrome/browser/sync/sync_service_factory.cc b/chrome/browser/sync/sync_service_factory.cc
index 1e9e145..17022fee 100644
--- a/chrome/browser/sync/sync_service_factory.cc
+++ b/chrome/browser/sync/sync_service_factory.cc
@@ -12,7 +12,6 @@
 #include "base/no_destructor.h"
 #include "build/build_config.h"
 #include "build/chromeos_buildflags.h"
-#include "chrome/browser/autofill/personal_data_manager_factory.h"
 #include "chrome/browser/bookmarks/bookmark_model_factory.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/browser/consent_auditor/consent_auditor_factory.h"
@@ -174,11 +173,6 @@
       std::make_unique<syncer::SyncServiceImpl>(std::move(init_params));
   sync_service->Initialize();
 
-  // Hook |sync_service| into PersonalDataManager (a circular dependency).
-  autofill::PersonalDataManager* pdm =
-      autofill::PersonalDataManagerFactory::GetForProfile(profile);
-  pdm->OnSyncServiceInitialized(sync_service.get());
-
   // Notify PasswordStore of complete initialisation to resolve a circular
   // dependency.
   auto password_store = PasswordStoreFactory::GetForProfile(
@@ -230,7 +224,6 @@
   // actually plumbed in ChromeSyncClient, which this factory constructs.
   DependsOn(AboutSigninInternalsFactory::GetInstance());
   DependsOn(AccountPasswordStoreFactory::GetInstance());
-  DependsOn(autofill::PersonalDataManagerFactory::GetInstance());
   DependsOn(BookmarkModelFactory::GetInstance());
   DependsOn(BookmarkSyncServiceFactory::GetInstance());
   DependsOn(BookmarkUndoServiceFactory::GetInstance());
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc
index 4850cda..f4bf5010 100644
--- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc
+++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl.cc
@@ -201,8 +201,9 @@
 void TouchToFillDelegateAndroidImpl::OnCreditCardScanned(
     const CreditCard& card) {
   HideTouchToFill();
-  manager_->FillCreditCardFormImpl(query_form_, query_field_, card,
-                                   std::u16string());
+  manager_->FillCreditCardFormImpl(
+      query_form_, query_field_, card, std::u16string(),
+      AutofillTriggerSource::kTouchToFillCreditCard);
 }
 
 void TouchToFillDelegateAndroidImpl::ShowCreditCardSettings() {
@@ -216,13 +217,14 @@
   if (is_virtual) {
     manager_->FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kFill, unique_id, query_form_,
-        query_field_);
+        query_field_, AutofillTriggerSource::kTouchToFillCreditCard);
   } else {
     PersonalDataManager* pdm = manager_->client()->GetPersonalDataManager();
     DCHECK(pdm);
     CreditCard* card = pdm->GetCreditCardByGUID(unique_id);
-    manager_->FillOrPreviewCreditCardForm(mojom::RendererFormDataAction::kFill,
-                                          query_form_, query_field_, card);
+    manager_->FillOrPreviewCreditCardForm(
+        mojom::RendererFormDataAction::kFill, query_form_, query_field_, card,
+        AutofillTriggerSource::kTouchToFillCreditCard);
   }
 }
 
diff --git a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl_unittest.cc b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl_unittest.cc
index 14810a00..b794b63 100644
--- a/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl_unittest.cc
+++ b/chrome/browser/touch_to_fill/payments/android/touch_to_fill_delegate_android_impl_unittest.cc
@@ -112,20 +112,23 @@
               (const FormData& form,
                const FormFieldData& field,
                const CreditCard& credit_card,
-               const std::u16string& cvc),
+               const std::u16string& cvc,
+               const AutofillTriggerSource trigger_source),
               (override));
   MOCK_METHOD(void,
               FillOrPreviewCreditCardForm,
               (mojom::RendererFormDataAction action,
                const FormData& form,
                const FormFieldData& field,
-               const CreditCard* credit_card));
+               const CreditCard* credit_card,
+               const AutofillTriggerSource trigger_source));
   MOCK_METHOD(void,
               FillOrPreviewVirtualCardInformation,
               (mojom::RendererFormDataAction action,
                const std::string& guid,
                const FormData& form,
-               const FormFieldData& field));
+               const FormFieldData& field,
+               const AutofillTriggerSource trigger_source));
   MOCK_METHOD(void,
               DidShowSuggestions,
               (bool has_autofill_suggestions,
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java
index c3c3f70..70f44b2 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/ToolbarFeatures.java
@@ -22,8 +22,6 @@
             new MutableFlagWithSafeDefault(ChromeFeatureList.SUPPRESS_TOOLBAR_CAPTURES, false);
     private static final MutableFlagWithSafeDefault sRecordSuppressionMetrics =
             new MutableFlagWithSafeDefault(ChromeFeatureList.RECORD_SUPPRESSION_METRICS, true);
-    private static final MutableFlagWithSafeDefault sDelayTransitionsForAnimation =
-            new MutableFlagWithSafeDefault(ChromeFeatureList.DELAY_TRANSITIONS_FOR_ANIMATION, true);
 
     /** Private constructor to avoid instantiation. */
     private ToolbarFeatures() {}
@@ -45,16 +43,6 @@
     }
 
     /**
-     * Returns whether the layout system will delay transitions between start/done hiding/showing
-     * for Android view animations or not. When this is delayed, the toolbar code will try to
-     * always draw itself from Android views during these transitions, to avoid letting the captured
-     * bitmap leak through during transitions. With suppression enabled, the captured bitmap is less
-     * reliable during these transitions.
-     */
-    public static boolean shouldDelayTransitionsForAnimation() {
-        return sDelayTransitionsForAnimation.isEnabled();
-    }
-    /**
      * Returns whether to record metrics from suppression experiment. This allows an arm of
      * suppression to run without the overhead from reporting any extra metrics in Java. Using a
      * feature instead of a param to utilize Java side caching.
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
index 749048e..471af534 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarLayout.java
@@ -32,7 +32,6 @@
 import org.chromium.base.lifetime.DestroyChecker;
 import org.chromium.base.lifetime.Destroyable;
 import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate;
-import org.chromium.chrome.browser.layouts.LayoutStateProvider;
 import org.chromium.chrome.browser.omnibox.LocationBar;
 import org.chromium.chrome.browser.omnibox.LocationBarCoordinator;
 import org.chromium.chrome.browser.omnibox.NewTabPageDelegate;
@@ -878,16 +877,4 @@
             shadow.setVisibility(isHairlineVisible ? VISIBLE : GONE);
         }
     }
-
-    /**
-     * To be called indirectly by
-     * {@link LayoutStateProvider.LayoutStateObserver#onStartedHiding(int, boolean, boolean)}.
-     */
-    public void onTransitionStart() {}
-
-    /**
-     * To be called indirectly by
-     * {@link LayoutStateProvider.LayoutStateObserver#onFinishedShowing(int)}.
-     */
-    public void onTransitionEnd() {}
 }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
index 0bd8142..4b47198 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -271,9 +271,6 @@
 
     private boolean mDropdownListScrolled;
 
-    // If we're in a layout transition, between startHiding to doneShowing.
-    private boolean mInLayoutTransition;
-
     // The following are some properties used during animation.  We use explicit property classes
     // to avoid the cost of reflection for each animation setup.
 
@@ -801,10 +798,6 @@
                     return ChromeColors.getDefaultThemeColor(getContext(), false);
                 }
 
-                // During transition we cannot rely on the background to be opaque yet, so keep full
-                // alpha until the transition is over.
-                int alpha = mInLayoutTransition ? 255 : Math.round(mUrlExpansionFraction * 255);
-
                 // When the NTP fake search box is visible, the background color should be
                 // transparent. When the location bar reaches the top of the screen (i.e. location
                 // bar is fully expanded), the background needs to change back to the default
@@ -812,7 +805,8 @@
                 // between the transition, we set a translucent default toolbar color based on
                 // the expansion progress of the toolbar.
                 return androidx.core.graphics.ColorUtils.setAlphaComponent(
-                        ChromeColors.getDefaultThemeColor(getContext(), false), alpha);
+                        ChromeColors.getDefaultThemeColor(getContext(), false),
+                        Math.round(mUrlExpansionFraction * 255));
             case VisualState.NORMAL:
                 return ChromeColors.getDefaultThemeColor(getContext(), false);
             case VisualState.INCOGNITO:
@@ -1410,14 +1404,8 @@
      *         toolbar.
      */
     private boolean shouldDrawLocationBar() {
-        if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) {
-            // The location bar should have alpha or clip+translation when its not supposed to be
-            // shown. Needs to be drawn during transitions, such as entering/exiting tab switcher.
-            return mLocationBarBackground != null;
-        } else {
-            return mLocationBarBackground != null
-                    && (mTabSwitcherState == STATIC_TAB || mTextureCaptureMode);
-        }
+        return mLocationBarBackground != null
+                && (mTabSwitcherState == STATIC_TAB || mTextureCaptureMode);
     }
 
     private boolean drawLocationBar(Canvas canvas, long drawingTime) {
@@ -1425,6 +1413,7 @@
         boolean clipped = false;
         if (shouldDrawLocationBar()) {
             canvas.save();
+
             if (shouldDrawLocationBarBackground()) {
                 if (mActiveLocationBarBackground instanceof NtpSearchBoxDrawable) {
                     ((NtpSearchBoxDrawable) mActiveLocationBarBackground)
@@ -1817,12 +1806,6 @@
             updateViewsForTabSwitcherMode();
         }
 
-        if (ToolbarFeatures.shouldDelayTransitionsForAnimation()) {
-            // Since mTabSwitcherState has changed, we need to also check if mVisualState should
-            // change.
-            updateVisualsForLocationBarState();
-        }
-
         updateButtonsTranslationY();
 
         if (DeviceClassManager.enableAccessibilityLayout(getContext())) {
@@ -2760,17 +2743,4 @@
     private int calculateOnFocusHeightIncrease() {
         return (int) (mBackgroundHeightIncreaseWhenFocus * mUrlFocusChangeFraction / 2);
     }
-
-    @Override
-    public void onTransitionStart() {
-        setVisibility(View.VISIBLE);
-        mInLayoutTransition = true;
-        updateToolbarBackgroundFromState(mVisualState);
-    }
-
-    @Override
-    public void onTransitionEnd() {
-        mInLayoutTransition = false;
-        updateToolbarBackgroundFromState(mVisualState);
-    }
 }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
index b07f98c58..467f64e8 100644
--- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
+++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -806,12 +806,4 @@
     public boolean isBrowsingModeToolbarVisible() {
         return mToolbarLayout.getVisibility() == View.VISIBLE;
     }
-
-    public void onTransitionStart() {
-        mToolbarLayout.onTransitionStart();
-    }
-
-    public void onTransitionEnd() {
-        mToolbarLayout.onTransitionEnd();
-    }
 }
diff --git a/chrome/browser/ui/ash/login_screen_client_impl.cc b/chrome/browser/ui/ash/login_screen_client_impl.cc
index 246f250..f588d23 100644
--- a/chrome/browser/ui/ash/login_screen_client_impl.cc
+++ b/chrome/browser/ui/ash/login_screen_client_impl.cc
@@ -375,14 +375,6 @@
       account_id, locale, result);
 }
 
-void LoginScreenClientImpl::OnUserActivity() {
-  if (ash::LoginDisplayHost::default_host()) {
-    ash::LoginDisplayHost::default_host()
-        ->GetExistingUserController()
-        ->ResetAutoLoginTimer();
-  }
-}
-
 views::Widget* LoginScreenClientImpl::GetLoginWindowWidget() {
   if (ash::LoginDisplayHost::default_host()) {
     return ash::LoginDisplayHost::default_host()->GetLoginWindowWidget();
diff --git a/chrome/browser/ui/ash/login_screen_client_impl.h b/chrome/browser/ui/ash/login_screen_client_impl.h
index be940c2..bfdaa8a 100644
--- a/chrome/browser/ui/ash/login_screen_client_impl.h
+++ b/chrome/browser/ui/ash/login_screen_client_impl.h
@@ -128,7 +128,6 @@
   void OnFocusLeavingSystemTray(bool reverse) override;
   void OnSystemTrayBubbleShown() override;
   void OnLoginScreenShown() override;
-  void OnUserActivity() override;
   views::Widget* GetLoginWindowWidget() override;
 
  private:
diff --git a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
index 8c9fdf16..47d81ac 100644
--- a/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
+++ b/chrome/browser/ui/ash/shelf/chrome_shelf_controller_browsertest.cc
@@ -202,7 +202,7 @@
       window.domAutomationController.send('done');
   })())JS";
 
-  extensions::browsertest_util::ExecuteScriptInBackgroundPage(
+  extensions::browsertest_util::ExecuteScriptInBackgroundPageDeprecated(
       browser->profile(), extension_misc::kChromeVoxExtensionId,
       execute_script);
 }
diff --git a/chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller.cc b/chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller.cc
index dadae59..8bcfb02 100644
--- a/chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller.cc
+++ b/chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller.cc
@@ -200,11 +200,14 @@
   // bubble is closed (and controller is destructed) while the reauth flow is
   // running, no callback will be invoked upon the conclusion of the
   // authentication flow.
-  delegate_->AuthenticateUserWithMessage(
-      message,
+  auto on_reath_complete =
       base::BindOnce(&ItemsBubbleController::OnUserAuthenticationCompleted,
                      weak_ptr_factory_.GetWeakPtr(), std::move(password_form),
-                     std::move(completion)));
+                     std::move(completion));
+  delegate_->AuthenticateUserWithMessage(
+      message, metrics_util::TimeCallback(
+                   std::move(on_reath_complete),
+                   "PasswordManager.ManagementBubble.AuthenticationTime"));
 }
 
 bool ItemsBubbleController::UsernameExists(const std::u16string& username) {
diff --git a/chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller_unittest.cc b/chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller_unittest.cc
index 05a03057..c61fa45 100644
--- a/chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller_unittest.cc
+++ b/chrome/browser/ui/passwords/bubble_controllers/items_bubble_controller_unittest.cc
@@ -100,8 +100,11 @@
   GetCurrentForms() const;
   void DestroyController();
 
+  base::test::TaskEnvironment& task_environment() { return task_environment_; }
+
  private:
-  content::BrowserTaskEnvironment task_environment_;
+  content::BrowserTaskEnvironment task_environment_{
+      base::test::TaskEnvironment::TimeSource::MOCK_TIME};
   content::RenderViewHostTestEnabler rvh_enabler_;
   std::unique_ptr<TestingProfile> profile_;
   raw_ptr<syncer::TestSyncService> test_sync_service_;
@@ -310,12 +313,18 @@
 
 TEST_F(ItemsBubbleControllerTest,
        ShouldChangeSelectedPasswordOnSuccessfulOsAuth) {
+  // The time it takes the user to complete the authentication flow in seconds.
+  const int kTimeToAuth = 10;
+  base::HistogramTester histogram_tester;
   Init();
   password_manager::PasswordForm selected_form = CreateTestForm();
 
   EXPECT_CALL(*delegate(), AuthenticateUserWithMessage)
       .WillOnce(testing::WithArg<1>(testing::Invoke(
           [&](PasswordsModelDelegate::AvailabilityCallback callback) {
+            // Waiting for kTimeToAuth seconds to simulate the time user will
+            // need to authenticate
+            task_environment().FastForwardBy(base::Seconds(kTimeToAuth));
             // Respond with true to simulate a successful user reauth.
             std::move(callback).Run(true);
           })));
@@ -323,6 +332,9 @@
   EXPECT_CALL(mock_callback, Run(true));
   controller()->AuthenticateUserAndDisplayDetailsOf(selected_form,
                                                     mock_callback.Get());
+  histogram_tester.ExpectUniqueTimeSample(
+      "PasswordManager.ManagementBubble.AuthenticationTime",
+      base::Seconds(kTimeToAuth), 1);
   EXPECT_EQ(controller()->get_currently_selected_password(), selected_form);
 }
 
diff --git a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
index 5d19626..89b6c8a5 100644
--- a/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
+++ b/chrome/browser/ui/views/autofill/payments/migratable_card_view.cc
@@ -47,7 +47,10 @@
                    .release());
 
   checkbox_uncheck_text_container_ =
-      AddChildView(std::make_unique<views::View>());
+      AddChildView(views::Builder<views::View>()
+                       .SetBackground(views::CreateThemedSolidBackground(
+                           ui::kColorBubbleFooterBackground))
+                       .Build());
   views::BoxLayout* layout = checkbox_uncheck_text_container_->SetLayoutManager(
       std::make_unique<views::BoxLayout>(
           views::BoxLayout::Orientation::kVertical,
@@ -82,12 +85,6 @@
       .CardIdentifierStringForAutofillDisplay();
 }
 
-void MigratableCardView::OnThemeChanged() {
-  View::OnThemeChanged();
-  checkbox_uncheck_text_container_->SetBackground(views::CreateSolidBackground(
-      GetColorProvider()->GetColor(ui::kColorBubbleFooterBackground)));
-}
-
 std::unique_ptr<views::View>
 MigratableCardView::GetMigratableCardDescriptionView(
     const MigratableCreditCard& migratable_credit_card,
diff --git a/chrome/browser/ui/views/autofill/payments/migratable_card_view.h b/chrome/browser/ui/views/autofill/payments/migratable_card_view.h
index 19e4162d..b1794c73 100644
--- a/chrome/browser/ui/views/autofill/payments/migratable_card_view.h
+++ b/chrome/browser/ui/views/autofill/payments/migratable_card_view.h
@@ -38,9 +38,6 @@
   std::string GetGuid() const;
   std::u16string GetCardIdentifierString() const;
 
-  // views::View:
-  void OnThemeChanged() override;
-
  private:
   std::unique_ptr<views::View> GetMigratableCardDescriptionView(
       const MigratableCreditCard& migratable_credit_card,
diff --git a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
index da32bce9..80390db 100644
--- a/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
+++ b/chrome/browser/ui/views/location_bar/intent_chip_button_browsertest.cc
@@ -2,6 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include "base/cfi_buildflags.h"
 #include "base/functional/callback.h"
 #include "base/functional/callback_forward.h"
 #include "base/scoped_observation.h"
@@ -322,8 +323,14 @@
   ASSERT_TRUE(IntentPickerBubbleView::intent_picker_bubble());
 }
 
+// TODO(crbug.com/1427908): Flaky on Linux CFI.
+#if BUILDFLAG(CFI_ICALL_CHECK) && BUILDFLAG(IS_LINUX)
+#define MAYBE_ShowsIntentChipCollapsed DISABLED_ShowsIntentChipCollapsed
+#else
+#define MAYBE_ShowsIntentChipCollapsed ShowsIntentChipCollapsed
+#endif
 IN_PROC_BROWSER_TEST_F(IntentChipButtonSkipIntentPickerBrowserTest,
-                       ShowsIntentChipCollapsed) {
+                       MAYBE_ShowsIntentChipCollapsed) {
   const GURL in_scope_url =
       https_server().GetURL(GetAppUrlHost(), GetInScopeUrlPath());
   const GURL out_of_scope_url =
diff --git a/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc b/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc
index fea03eaf..4e0ab45 100644
--- a/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc
+++ b/chrome/browser/ui/views/passwords/manage_passwords_details_view.cc
@@ -491,10 +491,6 @@
   on_activity_callback_.Run();
   LogUserInteractionsInPasswordManagementBubble(
       PasswordManagementBubbleInteractions::kUsernameEditButtonClicked);
-  // Invoke OnUserInputChanged() to validate the current input. Relevant only
-  // for empty username to make sure the bubble is opened showing the username
-  // as invalid.
-  OnUserInputChanged();
 }
 
 void ManagePasswordsDetailsView::SwitchToEditNoteMode() {
@@ -513,13 +509,10 @@
   on_activity_callback_.Run();
   bool is_username_invalid = false;
   if (username_textfield_ && username_textfield_->IsDrawn()) {
-    bool username_empty = username_textfield_->GetText().empty();
-    bool username_exists =
-        username_empty
-            ? false
-            : username_exists_callback_.Run(username_textfield_->GetText());
-    username_error_label_->SetVisible(username_exists);
-    is_username_invalid = username_empty || username_exists;
+    is_username_invalid =
+        !username_textfield_->GetText().empty() &&
+        username_exists_callback_.Run(username_textfield_->GetText());
+    username_error_label_->SetVisible(is_username_invalid);
     username_textfield_->SetInvalid(is_username_invalid);
   }
 
diff --git a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
index 24c1918b..210c800 100644
--- a/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
+++ b/chrome/browser/ui/views/payments/payment_request_browsertest_base.cc
@@ -110,7 +110,7 @@
       base::Unretained(this)));
 
   // Set a test sync service so that all types of cards work.
-  GetDataManager()->OnSyncServiceInitialized(&sync_service_);
+  GetDataManager()->SetSyncServiceForTest(&sync_service_);
 
   // Register all prefs with our pref testing service.
   payments::RegisterProfilePrefs(prefs_.registry());
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc
index d8fcc73..42cc9e6 100644
--- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc
+++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc
@@ -893,7 +893,7 @@
 
 const int kDialogWidthForFileHandlerDialog = 512;
 const int kDialogHeightForFileHandlerDialog = 475;
-const int kDialogHeightForFileHandlerDialogNoLocalApp = 310;
+const int kDialogHeightForFileHandlerDialogNoLocalApp = 311;
 
 const int kDialogWidthForDriveSetup = 512;
 const int kDialogHeightForDriveSetup = 220;
diff --git a/chrome/browser/webapps/web_app_offline_browsertest.cc b/chrome/browser/webapps/web_app_offline_browsertest.cc
index a52ad3c..abdc1c7 100644
--- a/chrome/browser/webapps/web_app_offline_browsertest.cc
+++ b/chrome/browser/webapps/web_app_offline_browsertest.cc
@@ -496,6 +496,14 @@
  public:
   WebAppOfflineDarkModeTest() {
     std::vector<base::test::FeatureRef> disabled_features;
+#if BUILDFLAG(IS_CHROMEOS)
+    disabled_features.push_back(chromeos::features::kDarkLightMode);
+#endif
+
+#if BUILDFLAG(IS_CHROMEOS_ASH)
+    disabled_features.push_back(ash::features::kNotificationsRefresh);
+#endif
+
     feature_list_.InitWithFeatures({features::kPWAsDefaultOfflinePage,
                                     blink::features::kWebAppEnableDarkMode},
                                    {disabled_features});
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt
index 68db204e..fcf3fa7 100644
--- a/chrome/build/mac-arm.pgo.txt
+++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@
-chrome-mac-arm-main-1679888927-6448062a7d9848bb22b88058c259c32b1ab1b9ac.profdata
+chrome-mac-arm-main-1679910852-2c305d946edf15f6d3369c88945c52fad093cc1e.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt
index 969280f9..359823c 100644
--- a/chrome/build/mac.pgo.txt
+++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@
-chrome-mac-main-1679875114-d0206cbd4519591c8f8a28acc3f3a8a6ad062bcd.profdata
+chrome-mac-main-1679896740-8db1dcb09c771ca41a3ecfec9e24bc2d681d4da9.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt
index 9360a76a..5ad5d8e 100644
--- a/chrome/build/win32.pgo.txt
+++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@
-chrome-win32-main-1679885783-483ead986f33e3bbd6074670ba12c9dfef5f1501.profdata
+chrome-win32-main-1679896740-06317575d7c881f37df31cd98c16521ce0729202.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt
index df92491..f9e85cc8 100644
--- a/chrome/build/win64.pgo.txt
+++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@
-chrome-win64-main-1679875114-020fc167bdf0cde047741892afee89810ee116e2.profdata
+chrome-win64-main-1679907548-2c273ef4dd372d3892e8f0872d6dfba2844f1135.profdata
diff --git a/chrome/common/chromeos/extensions/api/_permission_features.json b/chrome/common/chromeos/extensions/api/_permission_features.json
index 5cd15b80..aab6113 100644
--- a/chrome/common/chromeos/extensions/api/_permission_features.json
+++ b/chrome/common/chromeos/extensions/api/_permission_features.json
@@ -15,6 +15,13 @@
     ],
     "dependencies": [ "manifest:chromeos_system_extension" ]
   },
+  "os.events": {
+    "channel": "stable",
+    "extension_types": [
+      "chromeos_system_extension"
+    ],
+    "dependencies": [ "manifest:chromeos_system_extension" ]
+  },
   "os.telemetry": {
     "channel": "stable",
     "extension_types": [
diff --git a/chrome/common/chromeos/extensions/chromeos_system_extensions_api_permissions.cc b/chrome/common/chromeos/extensions/chromeos_system_extensions_api_permissions.cc
index e6685ce..f129a4566 100644
--- a/chrome/common/chromeos/extensions/chromeos_system_extensions_api_permissions.cc
+++ b/chrome/common/chromeos/extensions/chromeos_system_extensions_api_permissions.cc
@@ -23,6 +23,7 @@
 constexpr APIPermissionInfo::InitInfo kPermissionsToRegister[] = {
     // Telemetry System Extension permissions.
     {APIPermissionID::kChromeOSDiagnostics, "os.diagnostics"},
+    {APIPermissionID::kChromeOSEvents, "os.events"},
     {APIPermissionID::kChromeOSTelemetry, "os.telemetry"},
     {APIPermissionID::kChromeOSTelemetrySerialNumber,
      "os.telemetry.serial_number"},
diff --git a/chrome/common/extensions/api/smart_card_provider_private.idl b/chrome/common/extensions/api/smart_card_provider_private.idl
index 0a1b9824..d5cc7df2 100644
--- a/chrome/common/extensions/api/smart_card_provider_private.idl
+++ b/chrome/common/extensions/api/smart_card_provider_private.idl
@@ -144,6 +144,12 @@
         Timeout timeout,
         ReaderStateIn[] readerStates);
 
+    // Browser requested a SCardCancel call.
+    // Extension must report the result to the browser by calling
+    // reportCancelResult.
+    [maxListeners=1] static void onCancelRequested(long requestId,
+        long scardContext);
+
     // Browser requested a SCardConnect call.
     // Extension must report the result to the browser by calling
     // reportConnectResult.
@@ -177,6 +183,10 @@
       static void reportGetStatusChangeResult(long requestId,
           ReaderStateOut[] readerStates, ResultCode resultCode);
 
+      // Reports the result of a SCardCancel call.
+      static void reportCancelResult(long requestId,
+          ResultCode resultCode);
+
       // Reports the result of a SCardConnect call.
       static void reportConnectResult(long requestId, long scardHandle,
           Protocol activeProtocol, ResultCode resultCode);
diff --git a/chrome/common/extensions/permissions/chrome_permission_message_rules.cc b/chrome/common/extensions/permissions/chrome_permission_message_rules.cc
index 649fc08..527dcf3 100644
--- a/chrome/common/extensions/permissions/chrome_permission_message_rules.cc
+++ b/chrome/common/extensions/permissions/chrome_permission_message_rules.cc
@@ -746,6 +746,9 @@
       {IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_DIAGNOSTICS,
        {APIPermissionID::kChromeOSDiagnostics},
        {}},
+      {IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_EVENTS,
+       {APIPermissionID::kChromeOSEvents},
+       {}},
       {IDS_EXTENSION_PROMPT_WARNING_CHROMEOS_TELEMETRY,
        {APIPermissionID::kChromeOSTelemetry},
        {}},
diff --git a/chrome/credential_provider/DIR_METADATA b/chrome/credential_provider/DIR_METADATA
index f37723a..bf5806c 100644
--- a/chrome/credential_provider/DIR_METADATA
+++ b/chrome/credential_provider/DIR_METADATA
@@ -1,3 +1,3 @@
 monorail: {
-  component: "Enterprise"
+  component: "Enterprise>CredentialProvider"
 }
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn
index d0e1888..7f8de569 100644
--- a/chrome/test/BUILD.gn
+++ b/chrome/test/BUILD.gn
@@ -3843,6 +3843,8 @@
         "../browser/ash/login/accessibility_browsertest.cc",
         "../browser/ash/login/active_directory_login_browsertest.cc",
         "../browser/ash/login/app_mode/test/auto_launched_kiosk_browsertest.cc",
+        "../browser/ash/login/app_mode/test/kiosk_apps_mixin.cc",
+        "../browser/ash/login/app_mode/test/kiosk_apps_mixin.h",
         "../browser/ash/login/app_mode/test/kiosk_base_test.cc",
         "../browser/ash/login/app_mode/test/kiosk_base_test.h",
         "../browser/ash/login/app_mode/test/kiosk_browsertest.cc",
@@ -3984,8 +3986,6 @@
         "../browser/ash/login/test/guest_session_mixin.h",
         "../browser/ash/login/test/hid_controller_mixin.cc",
         "../browser/ash/login/test/hid_controller_mixin.h",
-        "../browser/ash/login/test/kiosk_apps_mixin.cc",
-        "../browser/ash/login/test/kiosk_apps_mixin.h",
         "../browser/ash/login/test/network_portal_detector_mixin.cc",
         "../browser/ash/login/test/network_portal_detector_mixin.h",
         "../browser/ash/login/test/offline_login_test_mixin.cc",
diff --git a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_asus.json b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_asus.json
index fedc8d0..e6a82642 100644
--- a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_asus.json
+++ b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_asus.json
@@ -5,6 +5,7 @@
   "manifest_version": 3,
   "permissions": [
     "os.diagnostics",
+    "os.events",
     "os.telemetry",
     "os.telemetry.serial_number",
     "os.telemetry.network_info"
diff --git a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_google.json b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_google.json
index cce687f..730cc6cc 100644
--- a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_google.json
+++ b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_google.json
@@ -8,6 +8,7 @@
     "manifest_version": 3,
     "permissions": [
       "os.diagnostics",
+      "os.events",
       "os.telemetry"
     ],
     "optional_permissions": [
diff --git a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_hp.json b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_hp.json
index 20c3299..9582e08 100644
--- a/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_hp.json
+++ b/chrome/test/data/extensions/manifest_tests/chromeos_system_extension_hp.json
@@ -5,6 +5,7 @@
     "manifest_version": 3,
     "permissions": [
       "os.diagnostics",
+      "os.events",
       "os.telemetry",
       "os.telemetry.serial_number",
       "os.telemetry.network_info"
diff --git a/chrome/test/data/webui/chromeos/cloud_upload/cloud_upload_dialog_test.ts b/chrome/test/data/webui/chromeos/cloud_upload/cloud_upload_dialog_test.ts
index 6e368d3..e5f0aeb 100644
--- a/chrome/test/data/webui/chromeos/cloud_upload/cloud_upload_dialog_test.ts
+++ b/chrome/test/data/webui/chromeos/cloud_upload/cloud_upload_dialog_test.ts
@@ -37,7 +37,23 @@
   }
 
   function checkIsWelcomePage(): void {
+    // The welcome page renders the regular non-0-step UI.
     assertTrue(cloudUploadApp.currentPage instanceof WelcomePageElement);
+    assertTrue(cloudUploadApp.$('#description')
+                   .innerText.includes('Install Microsoft 365'));
+    assertTrue(cloudUploadApp.$('#description')
+                   .innerText.includes('Connect to Microsoft OneDrive'));
+    assertEquals(cloudUploadApp.$('.action-button').innerText, 'Get started');
+  }
+
+  function checkIsWelcomePageZeroStep(): void {
+    // The welcome page renders the regular 0-step UI.
+    assertTrue(cloudUploadApp.currentPage instanceof WelcomePageElement);
+    assertEquals(
+        cloudUploadApp.$('#description').innerText,
+        'Files will move to Microsoft OneDrive when' +
+            'opening in Microsoft 365');
+    assertEquals(cloudUploadApp.$('.action-button').innerText, 'Set up');
   }
 
   function checkIsInstallPage(): void {
@@ -75,6 +91,13 @@
     await nextPagePromise;
   }
 
+  async function doWelcomePageZeroStep(): Promise<void> {
+    checkIsWelcomePageZeroStep();
+    const nextPagePromise = waitForNextPage();
+    cloudUploadApp.$('.action-button').click();
+    await nextPagePromise;
+  }
+
   async function doPWAInstallPage(): Promise<void> {
     checkIsInstallPage();
     const nextPagePromise = waitForNextPage();
@@ -185,8 +208,9 @@
   });
 
   /**
-   * Tests that there is no Office PWA install page or sign in page when the
-   * Office PWA is already installed and ODFS is already mounted.
+   * Tests that when the Office PWA is already installed and ODFS is already
+   * mounted, the welcome page shows the 0-step UI and there is no Office PWA
+   * install page or sign in page.
    */
   test(
       'Set up OneDrive with Office PWA already installed and already signed in',
@@ -198,7 +222,7 @@
           dialogPage: DialogPage.kOneDriveSetup,
         });
 
-        await doWelcomePage();
+        await doWelcomePageZeroStep();
 
         checkIsOneDriveUploadPage();
       });
diff --git a/chromeos/tast_control.gni b/chromeos/tast_control.gni
index ab5a794..fb10b52 100644
--- a/chromeos/tast_control.gni
+++ b/chromeos/tast_control.gni
@@ -348,4 +348,8 @@
   "tast.inputs.VirtualKeyboardDeadKeys.*@jacuzzi",
   "tast.inputs.PhysicalKeyboardShapeBasedChineseTyping.array_lacros",
   "tast.inputs.VirtualKeyboardSpeech.lacros",
+
+  # https://crbug.com/1427905
+  "tast.inputs.VirtualKeyboardHandwriting.floating",
+  "tast.inputs.VirtualKeyboardTypingUserMode.incognito",
 ]
diff --git a/components/android_autofill/browser/android_autofill_manager.cc b/components/android_autofill/browser/android_autofill_manager.cc
index 31a8cea..b9d26e9 100644
--- a/components/android_autofill/browser/android_autofill_manager.cc
+++ b/components/android_autofill/browser/android_autofill_manager.cc
@@ -50,14 +50,16 @@
     const FormData& form,
     const FormFieldData& field,
     const CreditCard& credit_card,
-    const std::u16string& cvc) {
+    const std::u16string& cvc,
+    AutofillTriggerSource trigger_source) {
   NOTREACHED();
 }
 
 void AndroidAutofillManager::FillProfileFormImpl(
     const FormData& form,
     const FormFieldData& field,
-    const autofill::AutofillProfile& profile) {
+    const autofill::AutofillProfile& profile,
+    AutofillTriggerSource trigger_source) {
   NOTREACHED();
 }
 
diff --git a/components/android_autofill/browser/android_autofill_manager.h b/components/android_autofill/browser/android_autofill_manager.h
index c1cda29..ebe7951 100644
--- a/components/android_autofill/browser/android_autofill_manager.h
+++ b/components/android_autofill/browser/android_autofill_manager.h
@@ -47,10 +47,12 @@
   void FillCreditCardFormImpl(const FormData& form,
                               const FormFieldData& field,
                               const CreditCard& credit_card,
-                              const std::u16string& cvc) override;
+                              const std::u16string& cvc,
+                              AutofillTriggerSource trigger_source) override;
   void FillProfileFormImpl(const FormData& form,
                            const FormFieldData& field,
-                           const autofill::AutofillProfile& profile) override;
+                           const autofill::AutofillProfile& profile,
+                           AutofillTriggerSource trigger_source) override;
 
   void OnFocusNoLongerOnFormImpl(bool had_interacted_form) override;
 
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index 720ae0ad..9e62215 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -109,6 +109,7 @@
     "autofill_subject.h",
     "autofill_suggestion_generator.cc",
     "autofill_suggestion_generator.h",
+    "autofill_trigger_source.h",
     "autofill_type.cc",
     "autofill_type.h",
     "browser_autofill_manager.cc",
diff --git a/components/autofill/core/browser/autofill_external_delegate.cc b/components/autofill/core/browser/autofill_external_delegate.cc
index f19cc94..5bb33287 100644
--- a/components/autofill/core/browser/autofill_external_delegate.cc
+++ b/components/autofill/core/browser/autofill_external_delegate.cc
@@ -21,6 +21,7 @@
 #include "build/build_config.h"
 #include "components/autofill/core/browser/autocomplete_history_manager.h"
 #include "components/autofill/core/browser/autofill_driver.h"
+#include "components/autofill/core/browser/autofill_trigger_source.h"
 #include "components/autofill/core/browser/browser_autofill_manager.h"
 #include "components/autofill/core/browser/metrics/autofill_metrics.h"
 #include "components/autofill/core/browser/metrics/suggestions_list_metrics.h"
@@ -214,7 +215,8 @@
 
   // Only preview the data if it is a profile or a virtual card.
   if (frontend_id > 0) {
-    FillAutofillFormData(frontend_id, true);
+    FillAutofillFormData(frontend_id, true,
+                         AutofillTriggerSource::kKeyboardAccessory);
   } else if (frontend_id == POPUP_ITEM_ID_AUTOCOMPLETE_ENTRY ||
              frontend_id == POPUP_ITEM_ID_IBAN_ENTRY ||
              frontend_id == POPUP_ITEM_ID_MERCHANT_PROMO_CODE_ENTRY) {
@@ -223,7 +225,7 @@
   } else if (frontend_id == POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY) {
     manager_->FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kPreview, backend_id.value(),
-        query_form_, query_field_);
+        query_form_, query_field_, AutofillTriggerSource::kKeyboardAccessory);
   }
 }
 
@@ -273,8 +275,9 @@
                                                 query_form_, query_field_);
       break;
     case POPUP_ITEM_ID_SCAN_CREDIT_CARD:
-      manager_->client()->ScanCreditCard(base::BindOnce(
-          &AutofillExternalDelegate::OnCreditCardScanned, GetWeakPtr()));
+      manager_->client()->ScanCreditCard(
+          base::BindOnce(&AutofillExternalDelegate::OnCreditCardScanned,
+                         GetWeakPtr(), AutofillTriggerSource::kPopup));
       break;
     case POPUP_ITEM_ID_CREDIT_CARD_SIGNIN_PROMO:
       manager_->client()->ExecuteCommand(suggestion.frontend_id);
@@ -297,7 +300,7 @@
       manager_->FillOrPreviewVirtualCardInformation(
           mojom::RendererFormDataAction::kFill,
           suggestion.GetPayload<Suggestion::BackendId>().value(), query_form_,
-          query_field_);
+          query_field_, AutofillTriggerSource::kPopup);
       break;
     case POPUP_ITEM_ID_SEE_PROMO_CODE_DETAILS:
       manager_->OnSeePromoCodeOfferDetailsSelected(
@@ -309,7 +312,8 @@
         autofill_metrics::LogAutofillSuggestionAcceptedIndex(
             position, popup_type_, manager_->client()->IsOffTheRecord());
       }
-      FillAutofillFormData(suggestion.frontend_id, false);
+      FillAutofillFormData(suggestion.frontend_id, false,
+                           AutofillTriggerSource::kPopup);
       break;
   }
 
@@ -386,13 +390,17 @@
   return weak_ptr_factory_.GetWeakPtr();
 }
 
-void AutofillExternalDelegate::OnCreditCardScanned(const CreditCard& card) {
+void AutofillExternalDelegate::OnCreditCardScanned(
+    const AutofillTriggerSource trigger_source,
+    const CreditCard& card) {
   manager_->FillCreditCardFormImpl(query_form_, query_field_, card,
-                                   std::u16string());
+                                   std::u16string(), trigger_source);
 }
 
-void AutofillExternalDelegate::FillAutofillFormData(int unique_id,
-                                                    bool is_preview) {
+void AutofillExternalDelegate::FillAutofillFormData(
+    int unique_id,
+    bool is_preview,
+    const AutofillTriggerSource trigger_source) {
   // If the selected element is a warning we don't want to do anything.
   if (IsAutofillWarningEntry(unique_id))
     return;
@@ -404,7 +412,7 @@
   DCHECK(driver_->RendererIsAvailable());
   // Fill the values for the whole form.
   manager_->FillOrPreviewForm(renderer_action, query_form_, query_field_,
-                              unique_id);
+                              unique_id, trigger_source);
 }
 
 void AutofillExternalDelegate::PossiblyRemoveAutofillWarnings(
diff --git a/components/autofill/core/browser/autofill_external_delegate.h b/components/autofill/core/browser/autofill_external_delegate.h
index 4ff2e907..c97a484 100644
--- a/components/autofill/core/browser/autofill_external_delegate.h
+++ b/components/autofill/core/browser/autofill_external_delegate.h
@@ -13,6 +13,7 @@
 #include "base/gtest_prod_util.h"
 #include "base/memory/raw_ptr.h"
 #include "base/memory/weak_ptr.h"
+#include "components/autofill/core/browser/autofill_trigger_source.h"
 #include "components/autofill/core/browser/ui/autofill_popup_delegate.h"
 #include "components/autofill/core/browser/ui/suggestion.h"
 #include "components/autofill/core/common/aliases.h"
@@ -120,13 +121,16 @@
                            FillCreditCardFormImpl);
 
   // Called when a credit card is scanned using device camera.
-  void OnCreditCardScanned(const CreditCard& card);
+  void OnCreditCardScanned(const AutofillTriggerSource trigger_source,
+                           const CreditCard& card);
 
   // Fills the form with the Autofill data corresponding to |unique_id|.
   // If |is_preview| is true then this is just a preview to show the user what
   // would be selected and if |is_preview| is false then the user has selected
   // this data.
-  void FillAutofillFormData(int unique_id, bool is_preview);
+  void FillAutofillFormData(int unique_id,
+                            bool is_preview,
+                            const AutofillTriggerSource trigger_source);
 
   // Will remove Autofill warnings from |suggestions| if there are also
   // autocomplete entries in the vector. Note: at this point, it is assumed that
diff --git a/components/autofill/core/browser/autofill_external_delegate_unittest.cc b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
index 47af5e9d..1ff39aa 100644
--- a/components/autofill/core/browser/autofill_external_delegate_unittest.cc
+++ b/components/autofill/core/browser/autofill_external_delegate_unittest.cc
@@ -140,7 +140,8 @@
               (mojom::RendererFormDataAction action,
                const std::string& guid,
                const FormData& form,
-               const FormFieldData& field),
+               const FormFieldData& field,
+               const AutofillTriggerSource trigger_source),
               (override));
 
   bool ShouldShowCardsFromAccountOption(const FormData& form,
@@ -157,14 +158,16 @@
               (mojom::RendererFormDataAction action,
                const FormData& form,
                const FormFieldData& field,
-               int unique_id),
+               int unique_id,
+               const AutofillTriggerSource trigger_source),
               (override));
   MOCK_METHOD(void,
               FillCreditCardFormImpl,
               (const FormData& form,
                const FormFieldData& field,
                const CreditCard& credit_card,
-               const std::u16string& cvc),
+               const std::u16string& cvc,
+               const AutofillTriggerSource trigger_source),
               (override));
 
  private:
@@ -261,8 +264,9 @@
   EXPECT_THAT(open_args.suggestions, SuggestionVectorIdsAre(element_ids));
   EXPECT_FALSE(open_args.autoselect_first_suggestion);
 
-  EXPECT_CALL(*browser_autofill_manager_,
-              FillOrPreviewForm(mojom::RendererFormDataAction::kFill, _, _, _));
+  EXPECT_CALL(
+      *browser_autofill_manager_,
+      FillOrPreviewForm(mojom::RendererFormDataAction::kFill, _, _, _, _));
   EXPECT_CALL(autofill_client_,
               HideAutofillPopup(PopupHidingReason::kAcceptSuggestion));
 
@@ -304,8 +308,9 @@
   EXPECT_THAT(open_args.suggestions, SuggestionVectorIdsAre(element_ids));
   EXPECT_FALSE(open_args.autoselect_first_suggestion);
 
-  EXPECT_CALL(*browser_autofill_manager_,
-              FillOrPreviewForm(mojom::RendererFormDataAction::kFill, _, _, _));
+  EXPECT_CALL(
+      *browser_autofill_manager_,
+      FillOrPreviewForm(mojom::RendererFormDataAction::kFill, _, _, _, _));
   EXPECT_CALL(autofill_client_,
               HideAutofillPopup(PopupHidingReason::kAcceptSuggestion));
 
@@ -609,7 +614,7 @@
 // negative unique id.
 TEST_F(AutofillExternalDelegateUnitTest, ExternalDelegateInvalidUniqueId) {
   // Ensure it doesn't try to preview the negative id.
-  EXPECT_CALL(*browser_autofill_manager_, FillOrPreviewForm(_, _, _, _))
+  EXPECT_CALL(*browser_autofill_manager_, FillOrPreviewForm(_, _, _, _, _))
       .Times(0);
   EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
   external_delegate_->DidSelectSuggestion(std::u16string(), -1,
@@ -618,7 +623,7 @@
   // Ensure it doesn't try to fill the form in with the negative id.
   EXPECT_CALL(autofill_client_,
               HideAutofillPopup(PopupHidingReason::kAcceptSuggestion));
-  EXPECT_CALL(*browser_autofill_manager_, FillOrPreviewForm(_, _, _, _))
+  EXPECT_CALL(*browser_autofill_manager_, FillOrPreviewForm(_, _, _, _, _))
       .Times(0);
 
   external_delegate_->DidAcceptSuggestion(Suggestion(-1), 0);
@@ -729,7 +734,7 @@
   EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
   EXPECT_CALL(
       *browser_autofill_manager_,
-      FillOrPreviewForm(mojom::RendererFormDataAction::kPreview, _, _, _));
+      FillOrPreviewForm(mojom::RendererFormDataAction::kPreview, _, _, _, _));
   external_delegate_->DidSelectSuggestion(u"baz foo", 1,
                                           Suggestion::BackendId());
 
@@ -746,7 +751,7 @@
   EXPECT_CALL(*autofill_driver_, RendererShouldClearPreviewedForm()).Times(1);
   EXPECT_CALL(*browser_autofill_manager_,
               FillOrPreviewVirtualCardInformation(
-                  mojom::RendererFormDataAction::kPreview, _, _, _));
+                  mojom::RendererFormDataAction::kPreview, _, _, _, _));
   external_delegate_->DidSelectSuggestion(
       std::u16string(), POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY,
       Suggestion::BackendId());
@@ -788,7 +793,7 @@
   std::u16string dummy_string(u"John Legend");
   EXPECT_CALL(*browser_autofill_manager_,
               FillOrPreviewForm(mojom::RendererFormDataAction::kFill, _, _,
-                                kAutofillProfileId));
+                                kAutofillProfileId, _));
 
   external_delegate_->DidAcceptSuggestion(
       test::CreateAutofillSuggestion(kAutofillProfileId, dummy_string),
@@ -902,10 +907,10 @@
 TEST_F(AutofillExternalDelegateUnitTest, FillCreditCardFormImpl) {
   CreditCard card;
   test::SetCreditCardInfo(&card, "Alice", "4111", "1", "3000", "1");
-  EXPECT_CALL(
-      *browser_autofill_manager_,
-      FillCreditCardFormImpl(_, _, CreditCardMatches(card), std::u16string()));
-  external_delegate_->OnCreditCardScanned(card);
+  EXPECT_CALL(*browser_autofill_manager_,
+              FillCreditCardFormImpl(_, _, CreditCardMatches(card),
+                                     std::u16string(), _));
+  external_delegate_->OnCreditCardScanned(AutofillTriggerSource::kPopup, card);
 }
 
 TEST_F(AutofillExternalDelegateUnitTest, IgnoreAutocompleteOffForAutofill) {
@@ -1064,7 +1069,7 @@
   FormData form;
   EXPECT_CALL(*browser_autofill_manager_,
               FillOrPreviewVirtualCardInformation(
-                  mojom::RendererFormDataAction::kFill, _, _, _));
+                  mojom::RendererFormDataAction::kFill, _, _, _, _));
   external_delegate_->DidAcceptSuggestion(
       Suggestion(POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY), 0);
 }
@@ -1072,7 +1077,7 @@
 TEST_F(AutofillExternalDelegateUnitTest, SelectVirtualCardOptionItem) {
   EXPECT_CALL(*browser_autofill_manager_,
               FillOrPreviewVirtualCardInformation(
-                  mojom::RendererFormDataAction::kPreview, _, _, _));
+                  mojom::RendererFormDataAction::kPreview, _, _, _, _));
   external_delegate_->DidSelectSuggestion(
       std::u16string(), POPUP_ITEM_ID_VIRTUAL_CREDIT_CARD_ENTRY,
       Suggestion::BackendId());
diff --git a/components/autofill/core/browser/autofill_manager.cc b/components/autofill/core/browser/autofill_manager.cc
index 8fa3fc78..4ee74fe 100644
--- a/components/autofill/core/browser/autofill_manager.cc
+++ b/components/autofill/core/browser/autofill_manager.cc
@@ -254,28 +254,32 @@
   return LanguageCode(language_state->current_language());
 }
 
-void AutofillManager::FillCreditCardForm(const FormData& form,
-                                         const FormFieldData& field,
-                                         const CreditCard& credit_card,
-                                         const std::u16string& cvc) {
+void AutofillManager::FillCreditCardForm(
+    const FormData& form,
+    const FormFieldData& field,
+    const CreditCard& credit_card,
+    const std::u16string& cvc,
+    const AutofillTriggerSource trigger_source) {
   if (!base::FeatureList::IsEnabled(features::kAutofillParseAsync)) {
-    FillCreditCardFormImpl(form, field, credit_card, cvc);
+    FillCreditCardFormImpl(form, field, credit_card, cvc, trigger_source);
     return;
   }
   ParseFormAsync(form, ParsingCallback(&AutofillManager::FillCreditCardFormImpl,
-                                       field, credit_card, cvc)
+                                       field, credit_card, cvc, trigger_source)
                            .Then(NotifyNoObserversCallback()));
 }
 
-void AutofillManager::FillProfileForm(const AutofillProfile& profile,
-                                      const FormData& form,
-                                      const FormFieldData& field) {
+void AutofillManager::FillProfileForm(
+    const AutofillProfile& profile,
+    const FormData& form,
+    const FormFieldData& field,
+    const AutofillTriggerSource trigger_source) {
   if (!base::FeatureList::IsEnabled(features::kAutofillParseAsync)) {
-    FillProfileFormImpl(form, field, profile);
+    FillProfileFormImpl(form, field, profile, trigger_source);
     return;
   }
   ParseFormAsync(form, ParsingCallback(&AutofillManager::FillProfileFormImpl,
-                                       field, profile)
+                                       field, profile, trigger_source)
                            .Then(NotifyNoObserversCallback()));
 }
 
diff --git a/components/autofill/core/browser/autofill_manager.h b/components/autofill/core/browser/autofill_manager.h
index 49ed7749..fecdb76 100644
--- a/components/autofill/core/browser/autofill_manager.h
+++ b/components/autofill/core/browser/autofill_manager.h
@@ -24,6 +24,7 @@
 #include "build/build_config.h"
 #include "components/autofill/core/browser/autofill_download_manager.h"
 #include "components/autofill/core/browser/autofill_driver.h"
+#include "components/autofill/core/browser/autofill_trigger_source.h"
 #include "components/autofill/core/browser/metrics/autofill_metrics.h"
 #include "components/autofill/core/common/dense_set.h"
 #include "components/autofill/core/common/form_data.h"
@@ -219,11 +220,13 @@
   void FillCreditCardForm(const FormData& form,
                           const FormFieldData& field,
                           const CreditCard& credit_card,
-                          const std::u16string& cvc);
+                          const std::u16string& cvc,
+                          const AutofillTriggerSource trigger_source);
 
   void FillProfileForm(const AutofillProfile& profile,
                        const FormData& form,
-                       const FormFieldData& field);
+                       const FormFieldData& field,
+                       const AutofillTriggerSource trigger_source);
 
   // Invoked when |form| has been filled with the value given by
   // FillOrPreviewForm.
@@ -419,10 +422,12 @@
   virtual void FillCreditCardFormImpl(const FormData& form,
                                       const FormFieldData& field,
                                       const CreditCard& credit_card,
-                                      const std::u16string& cvc) = 0;
+                                      const std::u16string& cvc,
+                                      AutofillTriggerSource trigger_source) = 0;
   virtual void FillProfileFormImpl(const FormData& form,
                                    const FormFieldData& field,
-                                   const AutofillProfile& profile) = 0;
+                                   const AutofillProfile& profile,
+                                   AutofillTriggerSource trigger_source) = 0;
 
   virtual void OnFocusNoLongerOnFormImpl(bool had_interacted_form) = 0;
 
diff --git a/components/autofill/core/browser/autofill_manager_unittest.cc b/components/autofill/core/browser/autofill_manager_unittest.cc
index 30feb8e..e4d95f2 100644
--- a/components/autofill/core/browser/autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/autofill_manager_unittest.cc
@@ -95,13 +95,15 @@
               (const FormData& form,
                const FormFieldData& field,
                const CreditCard& credit_card,
-               const std::u16string& cvc),
+               const std::u16string& cvc,
+               const AutofillTriggerSource trigger_source),
               (override));
   MOCK_METHOD(void,
               FillProfileFormImpl,
               (const FormData& form,
                const FormFieldData& field,
-               const AutofillProfile& profile),
+               const AutofillProfile& profile,
+               const AutofillTriggerSource trigger_source),
               (override));
   MOCK_METHOD(void,
               OnFocusNoLongerOnFormImpl,
diff --git a/components/autofill/core/browser/autofill_optimization_guide_unittest.cc b/components/autofill/core/browser/autofill_optimization_guide_unittest.cc
index 0841335e..4b726d0 100644
--- a/components/autofill/core/browser/autofill_optimization_guide_unittest.cc
+++ b/components/autofill/core/browser/autofill_optimization_guide_unittest.cc
@@ -73,6 +73,7 @@
         /*local_state=*/pref_service_.get(),
         /*identity_manager=*/nullptr,
         /*history_service=*/nullptr,
+        /*sync_service=*/nullptr,
         /*strike_database=*/nullptr,
         /*image_fetcher=*/nullptr,
         /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
index 9dc1328..b5f4be0 100644
--- a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
+++ b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
@@ -77,6 +77,7 @@
                           /*local_state=*/autofill_client_.GetPrefs(),
                           /*identity_manager=*/nullptr,
                           /*history_service=*/nullptr,
+                          /*sync_service=*/nullptr,
                           /*strike_database=*/nullptr,
                           /*image_fetcher=*/nullptr,
                           /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/autofill_trigger_source.h b/components/autofill/core/browser/autofill_trigger_source.h
new file mode 100644
index 0000000..3eac4c8
--- /dev/null
+++ b/components/autofill/core/browser/autofill_trigger_source.h
@@ -0,0 +1,39 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_TRIGGER_SOURCE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_TRIGGER_SOURCE_H_
+
+namespace autofill {
+
+// Specifies the source that triggered autofilling a form.
+enum class AutofillTriggerSource {
+  // Autofill was triggered from accepting a suggestion in the Autofill popup.
+  kPopup = 0,
+  // Autofill was triggered from accepting a suggestion in the keyboard
+  // accessory.
+  kKeyboardAccessory = 1,
+  // Autofill was triggered from accepting a suggestion in the touch to fill for
+  // credit cards bottom sheet.
+  kTouchToFillCreditCard = 2,
+  // Refill was triggered from the forms seen event. This includes cases where a
+  // refill was triggered right after a non-refill Autofill invocation - in this
+  // case the original trigger source got lost.
+  kFormsSeen = 3,
+  // Refill was triggered from blink when the selected option of a <select>
+  // control is changed.
+  kSelectOptionsChanged = 4,
+  // Refill was triggered from blink when the input element is in the autofilled
+  // state and the value has been changed by JavaScript.
+  kJavaScriptChangedAutofilledValue = 5,
+  // Autofill was applied after unlocking a server card with the CVC. The
+  // original trigger source got lost. This should not happen.
+  kCreditCardCvcPopup = 6,
+  // Autofill was triggered from a Fast Checkout run.
+  kFastCheckout = 7
+};
+
+}  // namespace autofill
+
+#endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_AUTOFILL_TRIGGER_SOURCE_H_
diff --git a/components/autofill/core/browser/browser_autofill_manager.cc b/components/autofill/core/browser/browser_autofill_manager.cc
index a192432..3bd9391 100644
--- a/components/autofill/core/browser/browser_autofill_manager.cc
+++ b/components/autofill/core/browser/browser_autofill_manager.cc
@@ -1301,7 +1301,8 @@
     mojom::RendererFormDataAction action,
     const FormData& form,
     const FormFieldData& field,
-    const CreditCard* credit_card) {
+    const CreditCard* credit_card,
+    const AutofillTriggerSource trigger_source) {
   FormStructure* form_structure = nullptr;
   AutofillField* autofill_field = nullptr;
   if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field))
@@ -1321,6 +1322,7 @@
 
     // CreditCardAccessManager::FetchCreditCard() will call
     // OnCreditCardFetched() in this class after successfully fetching the card.
+    fetched_credit_card_trigger_source_ = trigger_source;
     credit_card_access_manager_->FetchCreditCard(
         credit_card, weak_ptr_factory_.GetWeakPtr());
     return;
@@ -1328,28 +1330,30 @@
 
   FillOrPreviewDataModelForm(action, form, field, &credit_card_,
                              /*optional_cvc=*/nullptr, form_structure,
-                             autofill_field);
+                             autofill_field, trigger_source);
 }
 
 void BrowserAutofillManager::FillOrPreviewProfileForm(
     mojom::RendererFormDataAction action,
     const FormData& form,
     const FormFieldData& field,
-    const AutofillProfile& profile) {
+    const AutofillProfile& profile,
+    const AutofillTriggerSource trigger_source) {
   FormStructure* form_structure = nullptr;
   AutofillField* autofill_field = nullptr;
   if (!GetCachedFormAndField(form, field, &form_structure, &autofill_field))
     return;
   FillOrPreviewDataModelForm(action, form, field, &profile,
                              /*optional_cvc=*/nullptr, form_structure,
-                             autofill_field);
+                             autofill_field, trigger_source);
 }
 
 void BrowserAutofillManager::FillOrPreviewForm(
     mojom::RendererFormDataAction action,
     const FormData& form,
     const FormFieldData& field,
-    int unique_id) {
+    int unique_id,
+    const AutofillTriggerSource trigger_source) {
   if (!IsValidFormData(form) || !IsValidFormFieldData(field))
     return;
 
@@ -1362,9 +1366,10 @@
   const CreditCard* credit_card = GetCreditCard(unique_id);
 
   if (credit_card) {
-    FillOrPreviewCreditCardForm(action, form, field, credit_card);
+    FillOrPreviewCreditCardForm(action, form, field, credit_card,
+                                trigger_source);
   } else if (profile) {
-    FillOrPreviewProfileForm(action, form, field, *profile);
+    FillOrPreviewProfileForm(action, form, field, *profile, trigger_source);
   }
 }
 
@@ -1372,7 +1377,8 @@
     const FormData& form,
     const FormFieldData& field,
     const CreditCard& credit_card,
-    const std::u16string& cvc) {
+    const std::u16string& cvc,
+    AutofillTriggerSource trigger_source) {
   if (!IsValidFormData(form) || !IsValidFormFieldData(field) ||
       !driver()->RendererIsAvailable()) {
     return;
@@ -1384,23 +1390,26 @@
     return;
 
   FillOrPreviewDataModelForm(mojom::RendererFormDataAction::kFill, form, field,
-                             &credit_card, &cvc, form_structure,
-                             autofill_field);
+                             &credit_card, &cvc, form_structure, autofill_field,
+                             trigger_source,
+                             /*is_refill=*/false);
 }
 
 void BrowserAutofillManager::FillProfileFormImpl(
     const FormData& form,
     const FormFieldData& field,
-    const AutofillProfile& profile) {
+    const AutofillProfile& profile,
+    AutofillTriggerSource trigger_source) {
   FillOrPreviewProfileForm(mojom::RendererFormDataAction::kFill, form, field,
-                           profile);
+                           profile, trigger_source);
 }
 
 void BrowserAutofillManager::FillOrPreviewVirtualCardInformation(
     mojom::RendererFormDataAction action,
     const std::string& guid,
     const FormData& form,
-    const FormFieldData& field) {
+    const FormFieldData& field,
+    const AutofillTriggerSource trigger_source) {
   if (!IsValidFormData(form) || !IsValidFormFieldData(field) ||
       !RefreshDataModels() || !driver()->RendererIsAvailable()) {
     return;
@@ -1411,7 +1420,7 @@
   if (credit_card) {
     CreditCard copy = *credit_card;
     copy.set_record_type(CreditCard::VIRTUAL_CARD);
-    FillOrPreviewCreditCardForm(action, form, field, &copy);
+    FillOrPreviewCreditCardForm(action, form, field, &copy, trigger_source);
   }
 }
 
@@ -1701,7 +1710,7 @@
   driver()->SendAutofillTypePredictionsToRenderer({form_structure});
 
   if (ShouldTriggerRefill(*form_structure))
-    TriggerRefill(form);
+    TriggerRefill(form, AutofillTriggerSource::kSelectOptionsChanged);
 }
 
 void BrowserAutofillManager::OnJavaScriptChangedAutofilledValueImpl(
@@ -1744,13 +1753,16 @@
                         << std::move(change);
 
   AnalyzeJavaScriptChangedAutofilledValue(form, field);
-  MaybeTriggerRefillForExpirationDate(form, field, old_value);
+  MaybeTriggerRefillForExpirationDate(
+      form, field, old_value,
+      AutofillTriggerSource::kJavaScriptChangedAutofilledValue);
 }
 
 void BrowserAutofillManager::MaybeTriggerRefillForExpirationDate(
     const FormData& form,
     const FormFieldData& field,
-    const std::u16string& old_value) {
+    const std::u16string& old_value,
+    const AutofillTriggerSource trigger_source) {
   // We currently support a single case of refilling credit card expiration
   // dates: If we filled the expiration date in a format "05/2023" and the
   // website turned it into "05 / 20" (i.e. it broke the year by cutting the
@@ -1795,7 +1807,7 @@
     FillingContext* filling_context = GetFillingContext(*form_structure);
     DCHECK(filling_context);  // This is enforced by ShouldTriggerRefill.
     filling_context->forced_fill_values[field.global_id()] = refill_value;
-    ScheduleRefill(form);
+    ScheduleRefill(form, trigger_source);
   }
 }
 
@@ -1876,7 +1888,9 @@
       credit_card->instrument_id());
 
   FillCreditCardFormImpl(credit_card_form_, credit_card_field_, *credit_card,
-                         cvc);
+                         cvc,
+                         fetched_credit_card_trigger_source_.value_or(
+                             AutofillTriggerSource::kCreditCardCvcPopup));
   if (credit_card->record_type() == CreditCard::FULL_SERVER_CARD ||
       credit_card->record_type() == CreditCard::VIRTUAL_CARD) {
     credit_card_access_manager_->CacheUnmaskedCardInfo(*credit_card, cvc);
@@ -2073,6 +2087,7 @@
   last_unlocked_credit_card_cvc_.clear();
   credit_card_action_ = mojom::RendererFormDataAction::kPreview;
   initial_interaction_timestamp_ = TimeTicks();
+  fetched_credit_card_trigger_source_ = absl::nullopt;
   external_delegate_->Reset();
   if (touch_to_fill_delegate_) {
     touch_to_fill_delegate_->Reset();
@@ -2151,6 +2166,7 @@
     const std::u16string* optional_cvc,
     FormStructure* form_structure,
     AutofillField* autofill_trigger_field,
+    const AutofillTriggerSource trigger_source,
     bool is_refill) {
   bool is_credit_card =
       absl::holds_alternative<const CreditCard*>(profile_or_credit_card);
@@ -2502,13 +2518,15 @@
       credit_card_form_event_logger_->OnDidFillSuggestion(
           credit_card_, *form_structure, *autofill_trigger_field,
           newly_filled_fields,
-          base::flat_set<FieldGlobalId>(std::move(safe_fields)), sync_state_);
+          base::flat_set<FieldGlobalId>(std::move(safe_fields)), sync_state_,
+          trigger_source);
     }
 
     if (!is_credit_card) {
       address_form_event_logger_->OnDidFillSuggestion(
           *absl::get<const AutofillProfile*>(profile_or_credit_card),
-          *form_structure, *autofill_trigger_field, sync_state_);
+          *form_structure, *autofill_trigger_field, sync_state_,
+          trigger_source);
     }
   }
 
@@ -2715,7 +2733,7 @@
   // been a refill attempt on that form yet, start the process of triggering a
   // refill.
   if (ShouldTriggerRefill(form_structure))
-    ScheduleRefill(form);
+    ScheduleRefill(form, AutofillTriggerSource::kFormsSeen);
 }
 
 void BrowserAutofillManager::OnAfterProcessParsedForms(
@@ -3061,7 +3079,9 @@
   return !filling_context->attempted_refill && delta < kLimitBeforeRefill;
 }
 
-void BrowserAutofillManager::ScheduleRefill(const FormData& form) {
+void BrowserAutofillManager::ScheduleRefill(
+    const FormData& form,
+    const AutofillTriggerSource trigger_source) {
   FormStructure* form_structure = FindCachedFormById(form.global_id());
   if (!form_structure)
     return;
@@ -3078,10 +3098,13 @@
   filling_context->on_refill_timer.Start(
       FROM_HERE, kWaitTimeForDynamicForms,
       base::BindRepeating(&BrowserAutofillManager::TriggerRefill,
-                          weak_ptr_factory_.GetWeakPtr(), form));
+                          weak_ptr_factory_.GetWeakPtr(), form,
+                          trigger_source));
 }
 
-void BrowserAutofillManager::TriggerRefill(const FormData& form) {
+void BrowserAutofillManager::TriggerRefill(
+    const FormData& form,
+    const AutofillTriggerSource trigger_source) {
   FormStructure* form_structure = FindCachedFormById(form.global_id());
   if (!form_structure)
     return;
@@ -3138,7 +3161,7 @@
             filling_context->profile_or_credit_card_with_cvc);
     FillOrPreviewDataModelForm(mojom::RendererFormDataAction::kFill, form,
                                field, &credit_card, &cvc, form_structure,
-                               autofill_field,
+                               autofill_field, trigger_source,
                                /*is_refill=*/true);
   } else if (absl::holds_alternative<AutofillProfile>(
                  filling_context->profile_or_credit_card_with_cvc)) {
@@ -3147,6 +3170,7 @@
         &absl::get<AutofillProfile>(
             filling_context->profile_or_credit_card_with_cvc),
         /*optional_cvc=*/nullptr, form_structure, autofill_field,
+        trigger_source,
         /*is_refill=*/true);
   } else {
     NOTREACHED();
diff --git a/components/autofill/core/browser/browser_autofill_manager.h b/components/autofill/core/browser/browser_autofill_manager.h
index f08d647..2e050b0 100644
--- a/components/autofill/core/browser/browser_autofill_manager.h
+++ b/components/autofill/core/browser/browser_autofill_manager.h
@@ -151,11 +151,13 @@
   virtual void FillOrPreviewForm(mojom::RendererFormDataAction action,
                                  const FormData& form,
                                  const FormFieldData& field,
-                                 int unique_id);
+                                 int unique_id,
+                                 const AutofillTriggerSource trigger_source);
   void FillCreditCardFormImpl(const FormData& form,
                               const FormFieldData& field,
                               const CreditCard& credit_card,
-                              const std::u16string& cvc) override;
+                              const std::u16string& cvc,
+                              AutofillTriggerSource trigger_source) override;
   // Virtual for testing
   virtual void DidShowSuggestions(bool has_autofill_suggestions,
                                   const FormData& form,
@@ -165,15 +167,18 @@
   // Assumes the form and field are valid.
   // Asks for authentication via CVC before filling with server card data.
   // TODO(crbug.com/1330108): Clean up the API.
-  virtual void FillOrPreviewCreditCardForm(mojom::RendererFormDataAction action,
-                                           const FormData& form,
-                                           const FormFieldData& field,
-                                           const CreditCard* credit_card);
+  virtual void FillOrPreviewCreditCardForm(
+      mojom::RendererFormDataAction action,
+      const FormData& form,
+      const FormFieldData& field,
+      const CreditCard* credit_card,
+      const AutofillTriggerSource trigger_source);
 
   // TODO(crbug.com/1330108): Clean up the API.
   void FillProfileFormImpl(const FormData& form,
                            const FormFieldData& field,
-                           const AutofillProfile& profile) override;
+                           const AutofillProfile& profile,
+                           AutofillTriggerSource trigger_source) override;
 
   // Fetches the related virtual card information given the related actual card
   // |guid| and fills the information into the form.
@@ -182,7 +187,8 @@
       mojom::RendererFormDataAction action,
       const std::string& guid,
       const FormData& form,
-      const FormFieldData& field);
+      const FormFieldData& field,
+      const AutofillTriggerSource trigger_source);
 
   // Returns true if the value/identifier is deletable. Fills out
   // |title| and |body| with relevant user-facing text.
@@ -345,7 +351,10 @@
     return ShouldTriggerRefill(form_structure);
   }
 
-  void TriggerRefillForTest(const FormData& form) { TriggerRefill(form); }
+  void TriggerRefillForTest(const FormData& form,
+                            const AutofillTriggerSource trigger_source) {
+    TriggerRefill(form, trigger_source);
+  }
 
   void PreProcessStateMatchingTypesForTest(
       const std::vector<AutofillProfile>& profiles,
@@ -392,9 +401,9 @@
       const std::u16string* optional_cvc,
       FormStructure* form_structure,
       AutofillField* autofill_field) {
-    return FillOrPreviewDataModelForm(action, form, field,
-                                      profile_or_credit_card, optional_cvc,
-                                      form_structure, autofill_field);
+    return FillOrPreviewDataModelForm(
+        action, form, field, profile_or_credit_card, optional_cvc,
+        form_structure, autofill_field, AutofillTriggerSource::kPopup);
   }
 
   FormData* pending_form_data_for_test() { return pending_form_data_.get(); }
@@ -526,7 +535,8 @@
   void FillOrPreviewProfileForm(mojom::RendererFormDataAction action,
                                 const FormData& form,
                                 const FormFieldData& field,
-                                const AutofillProfile& profile);
+                                const AutofillProfile& profile,
+                                const AutofillTriggerSource trigger_source);
 
   // Fills or previews |data_model| in the |form|.
   // TODO(crbug.com/1330108): Clean up the API.
@@ -539,6 +549,7 @@
       const std::u16string* optional_cvc,
       FormStructure* form_structure,
       AutofillField* autofill_field,
+      const AutofillTriggerSource trigger_source,
       bool is_refill = false);
 
   // Returns true if the field value should not be overridden by Autofill.
@@ -659,19 +670,23 @@
   bool ShouldTriggerRefill(const FormStructure& form_structure);
 
   // Schedules a call of TriggerRefill. Virtual for testing.
-  virtual void ScheduleRefill(const FormData& form);
+  virtual void ScheduleRefill(const FormData& form,
+                              const AutofillTriggerSource trigger_source);
 
   // Attempts to refill the form that was changed dynamically. Should only be
   // called if ShouldTriggerRefill returns true.
-  void TriggerRefill(const FormData& form);
+  void TriggerRefill(const FormData& form,
+                     const AutofillTriggerSource trigger_source);
 
   // This function is called by JavaScriptChangedAutofilledValue and may trigger
   // a refill in case the website used JavaScript to reformat an expiration date
   // like "05/2023" into "05 / 20" (i.e. it broke the year by cutting the last
   // two digits instead of stripping the first two digits).
-  void MaybeTriggerRefillForExpirationDate(const FormData& form,
-                                           const FormFieldData& field,
-                                           const std::u16string& old_value);
+  void MaybeTriggerRefillForExpirationDate(
+      const FormData& form,
+      const FormFieldData& field,
+      const std::u16string& old_value,
+      const AutofillTriggerSource trigger_source);
 
   // Checks whether JavaScript cleared an autofilled value within
   // kLimitBeforeRefill after the filling and records metrics for this. This
@@ -839,6 +854,9 @@
   // When the form was submitted.
   base::TimeTicks form_submitted_timestamp_;
 
+  // The source that triggered unlocking a server card with the CVC.
+  absl::optional<AutofillTriggerSource> fetched_credit_card_trigger_source_;
+
   base::WeakPtrFactory<BrowserAutofillManager> weak_ptr_factory_{this};
 };
 
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
index deca670..23d83fed 100644
--- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc
+++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -423,6 +423,7 @@
                          /*local_state=*/autofill_client_.GetPrefs(),
                          /*identity_manager=*/nullptr,
                          /*history_service=*/nullptr,
+                         /*sync_service=*/nullptr,
                          /*strike_database=*/nullptr,
                          /*image_fetcher=*/nullptr,
                          /*is_off_the_record=*/false);
@@ -610,7 +611,8 @@
         form, field, {}, AutoselectFirstSuggestion(true),
         FormElementWasClicked(false));
     browser_autofill_manager_->FillOrPreviewForm(
-        mojom::RendererFormDataAction::kFill, form, field, unique_id);
+        mojom::RendererFormDataAction::kFill, form, field, unique_id,
+        AutofillTriggerSource::kPopup);
   }
 
   // Calls |browser_autofill_manager_->OnFillAutofillFormData()| with the
@@ -637,7 +639,7 @@
         .WillOnce((DoAll(testing::SaveArg<1>(response_data),
                          testing::Return(std::vector<FieldGlobalId>{}))));
     browser_autofill_manager_->FillOrPreviewVirtualCardInformation(
-        action, guid, input_form, input_field);
+        action, guid, input_form, input_field, AutofillTriggerSource::kPopup);
   }
 
   int MakeFrontendId(
@@ -715,7 +717,8 @@
     EXPECT_CALL(*autofill_driver_, FillOrPreviewForm(_, _, _, _))
         .Times(AtLeast(1));
     browser_autofill_manager_->FillOrPreviewCreditCardForm(
-        mojom::RendererFormDataAction::kFill, *form, form->fields[0], card);
+        mojom::RendererFormDataAction::kFill, *form, form->fields[0], card,
+        AutofillTriggerSource::kPopup);
   }
 
   void OnDidGetRealPan(AutofillClient::PaymentsRpcResult result,
@@ -2445,7 +2448,8 @@
   FormsSeen({form});
   CreditCard credit_card = test::GetMaskedServerCard();
   browser_autofill_manager_->FillOrPreviewCreditCardForm(
-      mojom::RendererFormDataAction::kFill, form, form.fields[0], &credit_card);
+      mojom::RendererFormDataAction::kFill, form, form.fields[0], &credit_card,
+      AutofillTriggerSource::kPopup);
 
   browser_autofill_manager_->OnCreditCardFetchedForTest(
       CreditCardFetchResult::kSuccess, &credit_card,
diff --git a/components/autofill/core/browser/field_types.cc b/components/autofill/core/browser/field_types.cc
index 241f72f..23d6c20f 100644
--- a/components/autofill/core/browser/field_types.cc
+++ b/components/autofill/core/browser/field_types.cc
@@ -33,7 +33,7 @@
            // Fax numbers (values [20,24]) are deprecated.
            !(20 <= t && t <= 24) &&
            // Reserved for server-side only use.
-           t != 127 && !(130 <= t && t <= 137);
+           t != 127 && !(130 <= t && t <= 140);
   };
   return IsValid(raw_value) ? static_cast<ServerFieldType>(raw_value)
                             : fallback_value;
diff --git a/components/autofill/core/browser/field_types.h b/components/autofill/core/browser/field_types.h
index e9da343..fb93c961 100644
--- a/components/autofill/core/browser/field_types.h
+++ b/components/autofill/core/browser/field_types.h
@@ -356,7 +356,7 @@
   // One-time code used for verifying user identity.
   ONE_TIME_CODE = 129,
 
-  // Reserved for a server-side-only use: 130-137
+  // Reserved for a server-side-only use: 130-140
 
   // No new types can be added without a corresponding change to the Autofill
   // server.
@@ -365,7 +365,7 @@
   // - `AutofillServerFieldType`
   // - `AutofilledFieldUserEditingStatusByFieldType` (16 * type + x)
   // - `AutofillPredictionsComparisonResult` (6 * type + x)
-  MAX_VALID_FIELD_TYPE = 137,
+  MAX_VALID_FIELD_TYPE = 140,
 };
 
 enum class FieldTypeGroup {
diff --git a/components/autofill/core/browser/form_data_importer_unittest.cc b/components/autofill/core/browser/form_data_importer_unittest.cc
index dd27252..5227654 100644
--- a/components/autofill/core/browser/form_data_importer_unittest.cc
+++ b/components/autofill/core/browser/form_data_importer_unittest.cc
@@ -508,11 +508,11 @@
         /*local_state=*/prefs_.get(),
         /*identity_manager=*/identity_test_env_.identity_manager(),
         /*history_service=*/nullptr,
+        /*sync_service=*/nullptr,
         /*strike_database=*/nullptr,
         /*image_fetcher=*/nullptr,
         /*is_off_the_record=*/(user_mode == USER_MODE_INCOGNITO));
     personal_data_manager_->AddObserver(&personal_data_observer_);
-    personal_data_manager_->OnSyncServiceInitialized(nullptr);
 
     WaitForOnPersonalDataChanged();
 
@@ -4493,13 +4493,13 @@
   // We need a sync service so that
   // LocalCardMigrationManager::ShouldOfferLocalCardMigration() does not crash.
   syncer::TestSyncService sync_service;
-  personal_data_manager_->OnSyncServiceInitialized(&sync_service);
+  personal_data_manager_->SetSyncServiceForTest(&sync_service);
 
   EXPECT_FALSE(form_data_importer().ProcessCreditCardImportCandidate(
       *form_structure, credit_card_import_candidate, extracted_upi_id,
       /*payment_methods_autofill_enabled=*/true,
       /*is_credit_card_upstream_enabled=*/true));
-  personal_data_manager_->OnSyncServiceInitialized(nullptr);
+  personal_data_manager_->SetSyncServiceForTest(nullptr);
 }
 
 #if !BUILDFLAG(IS_IOS)
@@ -4524,7 +4524,7 @@
   // LocalCardMigrationManager::ShouldOfferLocalCardMigration() does not
   // crash.
   syncer::TestSyncService sync_service;
-  personal_data_manager_->OnSyncServiceInitialized(&sync_service);
+  personal_data_manager_->SetSyncServiceForTest(&sync_service);
 
   EXPECT_CALL(*virtual_card_enrollment_manager_,
               InitVirtualCardEnroll(_, VirtualCardEnrollmentSource::kDownstream,
@@ -4545,7 +4545,7 @@
       /*payment_methods_autofill_enabled=*/true,
       /*is_credit_card_upstream_enabled=*/true));
 
-  personal_data_manager_->OnSyncServiceInitialized(nullptr);
+  personal_data_manager_->SetSyncServiceForTest(nullptr);
 }
 #endif
 
diff --git a/components/autofill/core/browser/geo/alternative_state_name_map_updater_unittest.cc b/components/autofill/core/browser/geo/alternative_state_name_map_updater_unittest.cc
index b348dbc..6a7feae 100644
--- a/components/autofill/core/browser/geo/alternative_state_name_map_updater_unittest.cc
+++ b/components/autofill/core/browser/geo/alternative_state_name_map_updater_unittest.cc
@@ -51,6 +51,7 @@
                                 /*local_state=*/autofill_client_.GetPrefs(),
                                 /*identity_manager=*/nullptr,
                                 /*history_service=*/nullptr,
+                                /*sync_service=*/nullptr,
                                 /*strike_database=*/nullptr,
                                 /*image_fetcher=*/nullptr,
                                 /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc b/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
index 05851392..bf2522f2 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
+++ b/components/autofill/core/browser/metrics/autofill_metrics_test_base.cc
@@ -45,7 +45,6 @@
 
   personal_data().set_auto_accept_address_imports_for_testing(true);
   personal_data().SetPrefService(autofill_client_->GetPrefs());
-  personal_data().OnSyncServiceInitialized(&sync_service_);
 
   autofill_driver_ = std::make_unique<TestAutofillDriver>();
   autofill_driver_->SetIsInAnyMainFrame(is_in_any_main_frame_);
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_test_base.h b/components/autofill/core/browser/metrics/autofill_metrics_test_base.h
index a6e19064..a62a9e1 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_test_base.h
+++ b/components/autofill/core/browser/metrics/autofill_metrics_test_base.h
@@ -168,7 +168,8 @@
   void FillTestProfile(const FormData& form) {
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.profile_id = kTestProfileId}));
+        MakeFrontendId({.profile_id = kTestProfileId}),
+        AutofillTriggerSource::kPopup);
   }
 
   int MakeFrontendId(
diff --git a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
index 213872b..3f81087 100644
--- a/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/metrics/autofill_metrics_unittest.cc
@@ -1702,6 +1702,7 @@
                        /*local_state=*/autofill_client_->GetPrefs(),
                        /*identity_manager=*/nullptr,
                        /*history_service=*/nullptr,
+                       /*sync_service=*/nullptr,
                        /*strike_database=*/nullptr,
                        /*image_fetcher=*/nullptr,
                        /*is_off_the_record=*/false);
@@ -1719,6 +1720,7 @@
                        /*local_state=*/autofill_client_->GetPrefs(),
                        /*identity_manager=*/nullptr,
                        /*history_service=*/nullptr,
+                       /*sync_service=*/nullptr,
                        /*strike_database=*/nullptr,
                        /*image_fetcher=*/nullptr,
                        /*is_off_the_record=*/false);
@@ -1736,6 +1738,7 @@
                        /*local_state=*/autofill_client_->GetPrefs(),
                        /*identity_manager=*/nullptr,
                        /*history_service=*/nullptr,
+                       /*sync_service=*/nullptr,
                        /*strike_database=*/nullptr,
                        /*image_fetcher=*/nullptr,
                        /*is_off_the_record=*/false);
@@ -1753,6 +1756,7 @@
                        /*local_state=*/autofill_client_->GetPrefs(),
                        /*identity_manager=*/nullptr,
                        /*history_service=*/nullptr,
+                       /*sync_service=*/nullptr,
                        /*strike_database=*/nullptr,
                        /*image_fetcher=*/nullptr,
                        /*is_off_the_record=*/false);
@@ -1944,7 +1948,8 @@
     base::UserActionTester user_action_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+        MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+        AutofillTriggerSource::kPopup);
     EXPECT_EQ(1, user_action_tester.GetActionCount(
                      "Autofill_FilledCreditCardSuggestion"));
   }
@@ -2633,7 +2638,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields[2],
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
         BucketsInclude(
@@ -2656,10 +2662,12 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields[2],
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields[2],
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
         BucketsInclude(
@@ -2683,7 +2691,7 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kFill, kTestMaskedCardId, form,
-        form.fields[2]);
+        form.fields[2], AutofillTriggerSource::kPopup);
     OnCreditCardFetchingSuccessful(u"6011000990139424",
                                    /*is_virtual_card=*/true);
     EXPECT_THAT(
@@ -2708,12 +2716,12 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kFill, kTestMaskedCardId, form,
-        form.fields[2]);
+        form.fields[2], AutofillTriggerSource::kPopup);
     OnCreditCardFetchingSuccessful(u"6011000990139424",
                                    /*is_virtual_card=*/true);
     autofill_manager().FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kFill, kTestMaskedCardId, form,
-        form.fields[2]);
+        form.fields[2], AutofillTriggerSource::kPopup);
     OnCreditCardFetchingSuccessful(u"6011000990139424",
                                    /*is_virtual_card=*/true);
     EXPECT_THAT(
@@ -2752,7 +2760,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+        MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+        AutofillTriggerSource::kPopup);
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
         BucketsInclude(Bucket(FORM_EVENT_LOCAL_SUGGESTION_FILLED, 1),
@@ -2774,7 +2783,7 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kFill, kTestMaskedCardId, form,
-        form.fields.front());
+        form.fields.front(), AutofillTriggerSource::kPopup);
     OnCreditCardFetchingSuccessful(u"6011000990139424",
                                    /*is_virtual_card=*/true);
     EXPECT_THAT(
@@ -2798,7 +2807,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     OnCreditCardFetchingSuccessful(u"6011000990139424");
     SubmitForm(form);
     EXPECT_THAT(
@@ -2830,7 +2840,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestFullServerCardId}));
+        MakeFrontendId({.credit_card_id = kTestFullServerCardId}),
+        AutofillTriggerSource::kPopup);
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
         BucketsInclude(Bucket(FORM_EVENT_SERVER_SUGGESTION_FILLED, 1),
@@ -2851,10 +2862,12 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+        MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+        AutofillTriggerSource::kPopup);
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+        MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+        AutofillTriggerSource::kPopup);
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
         BucketsInclude(Bucket(FORM_EVENT_LOCAL_SUGGESTION_FILLED, 2),
@@ -2890,7 +2903,8 @@
   base::HistogramTester histogram_tester;
   autofill_manager().FillOrPreviewForm(
       mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-      MakeFrontendId({.credit_card_id = local_guid}));
+      MakeFrontendId({.credit_card_id = local_guid}),
+      AutofillTriggerSource::kPopup);
 
   EXPECT_THAT(
       histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
@@ -2931,7 +2945,8 @@
   // Local card with a duplicate server card present at index 0.
   autofill_manager().FillOrPreviewForm(
       mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-      MakeFrontendId({.credit_card_id = local_guid}));
+      MakeFrontendId({.credit_card_id = local_guid}),
+      AutofillTriggerSource::kPopup);
 
   EXPECT_THAT(
       histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
@@ -2973,7 +2988,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     OnDidGetRealPan(AutofillClient::PaymentsRpcResult::kSuccess,
                     "6011000990139424");
     histogram_tester.ExpectTotalCount(
@@ -2996,7 +3012,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     OnDidGetRealPan(AutofillClient::PaymentsRpcResult::kPermanentFailure,
                     std::string());
     histogram_tester.ExpectTotalCount(
@@ -3032,7 +3049,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     OnDidGetRealPanWithNonHttpOkResponse();
     histogram_tester.ExpectTotalCount(
         "Autofill.UnmaskPrompt.GetRealPanDuration", 1);
@@ -3309,7 +3327,8 @@
   autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
   autofill_manager().FillOrPreviewForm(
       mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-      MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+      MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+      AutofillTriggerSource::kPopup);
 
   SubmitForm(form);
   EXPECT_THAT(
@@ -3488,7 +3507,8 @@
     autofill_manager().OnAskForValuesToFillTest(form, form.fields.back());
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+        MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+        AutofillTriggerSource::kPopup);
     SubmitForm(form);
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
@@ -3529,7 +3549,7 @@
     autofill_manager().OnAskForValuesToFillTest(form, form.fields.back());
     autofill_manager().FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kFill, kTestMaskedCardId, form,
-        form.fields.front());
+        form.fields.front(), AutofillTriggerSource::kPopup);
     OnCreditCardFetchingSuccessful(u"6011000990139424",
                                    /*is_virtual_card=*/true);
     SubmitForm(form);
@@ -3573,7 +3593,8 @@
     autofill_manager().OnAskForValuesToFillTest(form, form.fields.back());
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestFullServerCardId}));
+        MakeFrontendId({.credit_card_id = kTestFullServerCardId}),
+        AutofillTriggerSource::kPopup);
     SubmitForm(form);
 
     EXPECT_THAT(
@@ -3613,7 +3634,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     OnCreditCardFetchingSuccessful(u"6011000990139424");
     SubmitForm(form);
     EXPECT_THAT(
@@ -3858,7 +3880,8 @@
     autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+        MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+        AutofillTriggerSource::kPopup);
     SubmitForm(form);
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
@@ -3882,7 +3905,7 @@
     autofill_manager().OnAskForValuesToFillTest(form, form.fields[0]);
     autofill_manager().FillOrPreviewVirtualCardInformation(
         mojom::RendererFormDataAction::kFill, kTestMaskedCardId, form,
-        form.fields.front());
+        form.fields.front(), AutofillTriggerSource::kPopup);
     OnCreditCardFetchingSuccessful(u"6011000990139424",
                                    /*is_virtual_card=*/true);
     SubmitForm(form);
@@ -3910,7 +3933,8 @@
     // Full server card.
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestFullServerCardId}));
+        MakeFrontendId({.credit_card_id = kTestFullServerCardId}),
+        AutofillTriggerSource::kPopup);
     SubmitForm(form);
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
@@ -3932,7 +3956,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     OnCreditCardFetchingSuccessful(u"6011000990139424");
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
@@ -4072,7 +4097,8 @@
                                           form.fields.back());
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+        MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+        AutofillTriggerSource::kPopup);
     EXPECT_THAT(
         histogram_tester.GetAllSamples("Autofill.FormEvents.CreditCard"),
         BucketsInclude(Bucket(FORM_EVENT_SUGGESTIONS_SHOWN, 1),
@@ -4119,7 +4145,8 @@
     // Select the masked server card with the linked offer.
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[0]}));
+        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[0]}),
+        AutofillTriggerSource::kPopup);
     OnDidGetRealPan(AutofillClient::PaymentsRpcResult::kSuccess,
                     "6011000990139424");
     SubmitForm(form);
@@ -4166,7 +4193,8 @@
     // sub-histogram because user has another masked server card with offer.
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+        MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+        AutofillTriggerSource::kPopup);
     OnDidGetRealPan(AutofillClient::PaymentsRpcResult::kSuccess,
                     "6011000990139424");
     SubmitForm(form);
@@ -4219,7 +4247,8 @@
     // since the offer is expired.
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[1]}));
+        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[1]}),
+        AutofillTriggerSource::kPopup);
     OnDidGetRealPan(AutofillClient::PaymentsRpcResult::kSuccess,
                     "6011000990139424");
     SubmitForm(form);
@@ -4284,7 +4313,8 @@
     // Select the masked server card with the linked offer.
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[2]}));
+        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[2]}),
+        AutofillTriggerSource::kPopup);
     OnDidGetRealPan(AutofillClient::PaymentsRpcResult::kSuccess,
                     "6011000990139424");
 
@@ -4337,7 +4367,8 @@
     // check.
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[2]}));
+        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[2]}),
+        AutofillTriggerSource::kPopup);
     OnDidGetRealPan(AutofillClient::PaymentsRpcResult::kPermanentFailure,
                     std::string());
 
@@ -4386,7 +4417,8 @@
                                           form.fields.back());
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[2]}));
+        MakeFrontendId({.credit_card_id = kMaskedServerCardIds[2]}),
+        AutofillTriggerSource::kPopup);
     OnDidGetRealPan(AutofillClient::PaymentsRpcResult::kSuccess,
                     "6011000990139424");
 
@@ -4396,7 +4428,8 @@
                                           form.fields.back());
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.back(),
-        MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+        MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+        AutofillTriggerSource::kPopup);
     SubmitForm(form);
     EXPECT_THAT(
         histogram_tester.GetAllSamples(
@@ -5836,7 +5869,8 @@
     base::HistogramTester histogram_tester;
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.credit_card_id = kTestLocalCardId}));
+        MakeFrontendId({.credit_card_id = kTestLocalCardId}),
+        AutofillTriggerSource::kPopup);
     SimulateUserChangedTextField(form, form.fields.front());
     // Simulate a second keystroke; make sure we don't log the metric twice.
     SimulateUserChangedTextField(form, form.fields.front());
@@ -6982,7 +7016,7 @@
                      Bucket(FORM_EVENT_DYNAMIC_CHANGE_AFTER_REFILL, 0)));
 
   // Trigger a refill, the refill metric should be updated.
-  autofill_manager().TriggerRefillForTest(form);
+  autofill_manager().TriggerRefillForTest(form, AutofillTriggerSource::kPopup);
   EXPECT_THAT(
       histogram_tester.GetAllSamples("Autofill.FormEvents.Address"),
       BucketsInclude(Bucket(FORM_EVENT_DID_SEE_FILLABLE_DYNAMIC_FORM, 1),
@@ -7944,7 +7978,8 @@
   // mimic its effect on |form_|.
   void FillForm(const FormFieldData& triggering_field) {
     autofill_manager().FillCreditCardForm(
-        form_, triggering_field, fill_data().credit_card, fill_data().cvc);
+        form_, triggering_field, fill_data().credit_card, fill_data().cvc,
+        AutofillTriggerSource::kPopup);
   }
 
   // Sets the field values of |form_| according to the parameters.
@@ -8961,7 +8996,8 @@
   autofill_manager().FillOrPreviewForm(
       mojom::RendererFormDataAction::kFill, form, form.fields.front(),
       is_cc_form ? MakeFrontendId({.credit_card_id = kTestLocalCardId})
-                 : MakeFrontendId({.profile_id = kTestProfileId}));
+                 : MakeFrontendId({.profile_id = kTestProfileId}),
+      AutofillTriggerSource::kPopup);
 
   if (GetParam().change_form_after_filling)
     SimulateUserChangedTextField(form, form.fields[0]);
diff --git a/components/autofill/core/browser/metrics/form_events/address_form_event_logger.cc b/components/autofill/core/browser/metrics/form_events/address_form_event_logger.cc
index 3fd5e734..c01d8284 100644
--- a/components/autofill/core/browser/metrics/form_events/address_form_event_logger.cc
+++ b/components/autofill/core/browser/metrics/form_events/address_form_event_logger.cc
@@ -12,6 +12,7 @@
 #include "base/metrics/user_metrics.h"
 #include "base/metrics/user_metrics_action.h"
 #include "components/autofill/core/browser/autofill_data_util.h"
+#include "components/autofill/core/browser/autofill_trigger_source.h"
 #include "components/autofill/core/browser/logging/log_manager.h"
 #include "components/autofill/core/browser/metrics/autofill_metrics_utils.h"
 #include "components/autofill/core/common/autofill_features.h"
@@ -35,7 +36,8 @@
     const AutofillProfile& profile,
     const FormStructure& form,
     const AutofillField& field,
-    AutofillSyncSigninState sync_state) {
+    AutofillSyncSigninState sync_state,
+    const AutofillTriggerSource trigger_source) {
   AutofillProfile::RecordType record_type = profile.record_type();
   sync_state_ = sync_state;
 
@@ -62,7 +64,9 @@
   base::RecordAction(
       base::UserMetricsAction("Autofill_FilledProfileSuggestion"));
 
-  ++form_interaction_counts_.autofill_fills;
+  if (trigger_source != AutofillTriggerSource::kFastCheckout) {
+    ++form_interaction_counts_.autofill_fills;
+  }
   UpdateFlowId();
 
   if (base::FeatureList::IsEnabled(
diff --git a/components/autofill/core/browser/metrics/form_events/address_form_event_logger.h b/components/autofill/core/browser/metrics/form_events/address_form_event_logger.h
index decd04b7..49b402e 100644
--- a/components/autofill/core/browser/metrics/form_events/address_form_event_logger.h
+++ b/components/autofill/core/browser/metrics/form_events/address_form_event_logger.h
@@ -8,6 +8,7 @@
 #include <string>
 
 #include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_trigger_source.h"
 #include "components/autofill/core/browser/data_model/autofill_profile.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/metrics/autofill_metrics.h"
@@ -44,7 +45,8 @@
   void OnDidFillSuggestion(const AutofillProfile& profile,
                            const FormStructure& form,
                            const AutofillField& field,
-                           AutofillSyncSigninState sync_state);
+                           AutofillSyncSigninState sync_state,
+                           const AutofillTriggerSource trigger_source);
 
   void OnDidSeeFillableDynamicForm(AutofillSyncSigninState sync_state,
                                    const FormStructure& form);
diff --git a/components/autofill/core/browser/metrics/form_events/address_form_event_logger_unittest.cc b/components/autofill/core/browser/metrics/form_events/address_form_event_logger_unittest.cc
index 287663119..4bcffec 100644
--- a/components/autofill/core/browser/metrics/form_events/address_form_event_logger_unittest.cc
+++ b/components/autofill/core/browser/metrics/form_events/address_form_event_logger_unittest.cc
@@ -98,7 +98,8 @@
     autofill_manager().OnAskForValuesToFillTest(form, form.fields.front());
     autofill_manager().FillOrPreviewForm(
         mojom::RendererFormDataAction::kFill, form, form.fields.front(),
-        MakeFrontendId({.profile_id = profile.guid()}));
+        MakeFrontendId({.profile_id = profile.guid()}),
+        AutofillTriggerSource::kPopup);
   }
 
  protected:
diff --git a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc
index 2346210..3f02b3e 100644
--- a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc
+++ b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.cc
@@ -130,7 +130,8 @@
     const AutofillField& field,
     const base::flat_set<FieldGlobalId>& newly_filled_fields,
     const base::flat_set<FieldGlobalId>& safe_fields,
-    AutofillSyncSigninState sync_state) {
+    AutofillSyncSigninState sync_state,
+    const AutofillTriggerSource trigger_source) {
   CreditCard::RecordType record_type = credit_card.record_type();
   sync_state_ = sync_state;
   ukm::builders::Autofill_CreditCardFill builder =
@@ -201,7 +202,9 @@
 
   form_interactions_ukm_logger_->Record(std::move(builder));
 
-  ++form_interaction_counts_.autofill_fills;
+  if (trigger_source != AutofillTriggerSource::kFastCheckout) {
+    ++form_interaction_counts_.autofill_fills;
+  }
   UpdateFlowId();
 }
 
diff --git a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.h b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.h
index 9962f22..ff976da 100644
--- a/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.h
+++ b/components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.h
@@ -10,6 +10,7 @@
 #include "base/memory/raw_ptr.h"
 #include "components/autofill/core/browser/autofill_client.h"
 #include "components/autofill/core/browser/autofill_field.h"
+#include "components/autofill/core/browser/autofill_trigger_source.h"
 #include "components/autofill/core/browser/data_model/credit_card.h"
 #include "components/autofill/core/browser/form_structure.h"
 #include "components/autofill/core/browser/metrics/autofill_metrics.h"
@@ -87,7 +88,8 @@
       const AutofillField& field,
       const base::flat_set<FieldGlobalId>& newly_filled_fields,
       const base::flat_set<FieldGlobalId>& safe_fields,
-      AutofillSyncSigninState sync_state);
+      AutofillSyncSigninState sync_state,
+      const AutofillTriggerSource trigger_source);
 
   // Logging what type of authentication flow was prompted.
   void LogCardUnmaskAuthenticationPromptShown(UnmaskAuthFlowType flow);
diff --git a/components/autofill/core/browser/metrics/payments/card_metadata_metrics_unittest.cc b/components/autofill/core/browser/metrics/payments/card_metadata_metrics_unittest.cc
index 0e466c8..0979720 100644
--- a/components/autofill/core/browser/metrics/payments/card_metadata_metrics_unittest.cc
+++ b/components/autofill/core/browser/metrics/payments/card_metadata_metrics_unittest.cc
@@ -101,7 +101,8 @@
                                         form(), form().fields.back());
   autofill_manager().FillOrPreviewForm(
       mojom::RendererFormDataAction::kFill, form(), form().fields.back(),
-      MakeFrontendId({.credit_card_id = kCardGuid}));
+      MakeFrontendId({.credit_card_id = kCardGuid}),
+      AutofillTriggerSource::kPopup);
 
   // Verify that:
   // 1. if the selected card had metadata,
@@ -210,7 +211,8 @@
   test_clock.SetNowTicks(now + base::Seconds(2));
   autofill_manager().FillOrPreviewForm(
       mojom::RendererFormDataAction::kFill, form(), form().fields.front(),
-      MakeFrontendId({.credit_card_id = kTestMaskedCardId}));
+      MakeFrontendId({.credit_card_id = kTestMaskedCardId}),
+      AutofillTriggerSource::kPopup);
 
   std::string latency_histogram_prefix =
       "Autofill.CreditCard.SelectionLatencySinceShown.";
diff --git a/components/autofill/core/browser/payments/autofill_offer_manager_unittest.cc b/components/autofill/core/browser/payments/autofill_offer_manager_unittest.cc
index 20e6be0..662f1a14 100644
--- a/components/autofill/core/browser/payments/autofill_offer_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/autofill_offer_manager_unittest.cc
@@ -57,6 +57,7 @@
                                 /*local_state=*/autofill_client_.GetPrefs(),
                                 /*identity_manager=*/nullptr,
                                 /*history_service=*/nullptr,
+                                /*sync_service=*/nullptr,
                                 /*strike_database=*/nullptr,
                                 /*image_fetcher=*/nullptr,
                                 /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
index 7cc6cf0..0e2d991 100644
--- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -186,6 +186,7 @@
                          /*local_state=*/autofill_client_.GetPrefs(),
                          /*identity_manager=*/nullptr,
                          /*history_service=*/nullptr,
+                         /*sync_service=*/nullptr,
                          /*strike_database=*/nullptr,
                          /*image_fetcher=*/nullptr,
                          /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/payments/credit_card_cvc_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_cvc_authenticator_unittest.cc
index 9a07a4f9..79c6eb9 100644
--- a/components/autofill/core/browser/payments/credit_card_cvc_authenticator_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_cvc_authenticator_unittest.cc
@@ -84,6 +84,7 @@
                                 /*local_state=*/autofill_client_.GetPrefs(),
                                 /*identity_manager=*/nullptr,
                                 /*history_service=*/nullptr,
+                                /*sync_service=*/nullptr,
                                 /*strike_database=*/nullptr,
                                 /*image_fetcher=*/nullptr,
                                 /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc
index dab9941..ca5f5037 100644
--- a/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_fido_authenticator_unittest.cc
@@ -112,6 +112,7 @@
                                 /*local_state=*/autofill_client_.GetPrefs(),
                                 /*identity_manager=*/nullptr,
                                 /*history_service=*/nullptr,
+                                /*sync_service=*/nullptr,
                                 /*strike_database=*/nullptr,
                                 /*image_fetcher=*/nullptr,
                                 /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc b/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc
index 0f24dff9..793dcf9 100644
--- a/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_otp_authenticator_unittest.cc
@@ -42,6 +42,7 @@
                                 /*local_state=*/autofill_client_.GetPrefs(),
                                 /*identity_manager=*/nullptr,
                                 /*history_service=*/nullptr,
+                                /*sync_service=*/nullptr,
                                 /*strike_database=*/nullptr,
                                 /*image_fetcher=*/nullptr,
                                 /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
index 6b3bf28..8f832078 100644
--- a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -186,11 +186,10 @@
                          /*pref_service=*/autofill_client_.GetPrefs(),
                          /*local_state=*/autofill_client_.GetPrefs(),
                          /*identity_manager=*/nullptr,
-                         /*history_service=*/nullptr,
+                         /*history_service=*/nullptr, &sync_service_,
                          /*strike_database=*/nullptr,
                          /*image_fetcher=*/nullptr,
                          /*is_off_the_record=*/false);
-    personal_data().OnSyncServiceInitialized(&sync_service_);
     autofill_driver_ = std::make_unique<TestAutofillDriver>();
     payments_client_ = new payments::TestPaymentsClient(
         autofill_client_.GetURLLoaderFactory(),
@@ -399,14 +398,14 @@
 
   base::test::TaskEnvironment task_environment_;
   test::AutofillUnitTestEnvironment autofill_test_environment_;
-  MockAutofillClient autofill_client_{
-      std::make_unique<MockPersonalDataManager>()};
   std::unique_ptr<MockVirtualCardEnrollmentManager>
       virtual_card_enrollment_manager_;
   std::unique_ptr<TestAutofillDriver> autofill_driver_;
   std::unique_ptr<TestBrowserAutofillManager> browser_autofill_manager_;
   scoped_refptr<AutofillWebDataService> database_;
   syncer::TestSyncService sync_service_;
+  MockAutofillClient autofill_client_{
+      std::make_unique<MockPersonalDataManager>()};
   // TODO(crbug.com/1291003): Refactor to use the real CreditCardSaveManager.
   // Ends up getting owned (and destroyed) by TestFormDataImporter:
   raw_ptr<TestCreditCardSaveManager> credit_card_save_manager_;
diff --git a/components/autofill/core/browser/payments/iban_save_manager_unittest.cc b/components/autofill/core/browser/payments/iban_save_manager_unittest.cc
index f235d96..1d737561 100644
--- a/components/autofill/core/browser/payments/iban_save_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/iban_save_manager_unittest.cc
@@ -41,6 +41,7 @@
                          /*local_state=*/autofill_client_.GetPrefs(),
                          /*identity_manager=*/nullptr,
                          /*history_service=*/nullptr,
+                         /*sync_service=*/nullptr,
                          /*strike_database=*/nullptr,
                          /*image_fetcher=*/nullptr,
                          /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc b/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc
index 3fc177d..f067c25 100644
--- a/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/local_card_migration_manager_unittest.cc
@@ -68,7 +68,7 @@
   void SetUp() override {
     autofill_client_.SetPrefs(test::PrefServiceForTesting());
     personal_data().SetPrefService(autofill_client_.GetPrefs());
-    personal_data().OnSyncServiceInitialized(&sync_service_);
+    personal_data().SetSyncServiceForTest(&sync_service_);
     autofill_driver_ = std::make_unique<TestAutofillDriver>();
     payments_client_ = new payments::TestPaymentsClient(
         autofill_client_.GetURLLoaderFactory(),
diff --git a/components/autofill/core/browser/payments/virtual_card_enrollment_manager_unittest.cc b/components/autofill/core/browser/payments/virtual_card_enrollment_manager_unittest.cc
index 54c14f4..89b9fa9 100644
--- a/components/autofill/core/browser/payments/virtual_card_enrollment_manager_unittest.cc
+++ b/components/autofill/core/browser/payments/virtual_card_enrollment_manager_unittest.cc
@@ -62,6 +62,7 @@
         /*local_state=*/autofill_client_->GetPrefs(),
         /*identity_manager=*/nullptr,
         /*history_service=*/nullptr,
+        /*sync_service=*/nullptr,
         /*strike_database=*/nullptr,
         /*image_fetcher=*/nullptr,
         /*is_off_the_record=*/false);
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 39317cdb..b2314a20d 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -286,6 +286,7 @@
     PrefService* local_state,
     signin::IdentityManager* identity_manager,
     history::HistoryService* history_service,
+    syncer::SyncService* sync_service,
     StrikeDatabaseBase* strike_database,
     AutofillImageFetcher* image_fetcher,
     bool is_off_the_record) {
@@ -311,6 +312,8 @@
   if (identity_manager_)
     identity_manager_->AddObserver(this);
 
+  SetSyncService(sync_service);
+
   image_fetcher_ = image_fetcher;
 
   is_off_the_record_ = is_off_the_record;
@@ -377,32 +380,6 @@
   identity_manager_ = nullptr;
 }
 
-void PersonalDataManager::OnSyncServiceInitialized(
-    syncer::SyncService* sync_service) {
-  // Before the sync service pointer gets changed, remove the observer.
-  if (sync_service_)
-    sync_service_->RemoveObserver(this);
-  sync_service_ = sync_service;
-  if (sync_service_)
-    sync_service_->AddObserver(this);
-
-  // Re-mask all server cards if the upload state is not active.
-  const bool is_upload_not_active =
-      syncer::GetUploadToGoogleState(sync_service_,
-                                     syncer::ModelType::AUTOFILL_WALLET_DATA) ==
-      syncer::UploadState::NOT_ACTIVE;
-  if (is_upload_not_active)
-    ResetFullServerCards();
-
-  if (base::FeatureList::IsEnabled(
-          features::kAutofillEnableAccountWalletStorage)) {
-    // Use the ephemeral account storage when the user didn't enable the sync
-    // feature explicitly.
-    database_helper_->SetUseAccountStorageForServerData(
-        sync_service && !sync_service_->IsSyncFeatureEnabled());
-  }
-}
-
 void PersonalDataManager::OnURLsDeleted(
     history::HistoryService* /* history_service */,
     const history::DeletionInfo& deletion_info) {
@@ -561,7 +538,7 @@
   if (!database_helper_->GetServerDatabase()) {
     DLOG(WARNING) << "There are no pending queries but the server database "
                      "wasn't set yet, so some data might be missing. Maybe "
-                     "OnSyncServiceInitialized() wasn't called yet.";
+                     "SetSyncService() wasn't called yet.";
     return;
   }
 
@@ -594,6 +571,8 @@
 }
 
 void PersonalDataManager::OnStateChanged(syncer::SyncService* sync_service) {
+  DCHECK_EQ(sync_service_, sync_service);
+
   for (PersonalDataManagerObserver& observer : observers_) {
     observer.OnPersonalDataSyncStateChanged();
   }
@@ -601,9 +580,11 @@
   if (base::FeatureList::IsEnabled(
           features::kAutofillEnableAccountWalletStorage)) {
     // Use the ephemeral account storage when the user didn't enable the sync
-    // feature explicitly.
+    // feature explicitly. `sync_service` is nullptr-checked because this
+    // method can also be used (apart from the Sync service observer's calls) in
+    // SetSyncService() where setting a nullptr is possible.
     database_helper_->SetUseAccountStorageForServerData(
-        !sync_service->IsSyncFeatureEnabled());
+        sync_service && !sync_service->IsSyncFeatureEnabled());
   }
 }
 
@@ -1106,6 +1087,16 @@
   autofill_offer_data_.push_back(std::move(offer_data));
 }
 
+void PersonalDataManager::SetSyncServiceForTest(
+    syncer::SyncService* sync_service) {
+  // Before the sync service pointer gets changed, remove the observer.
+  if (sync_service_) {
+    sync_service_->RemoveObserver(this);
+    sync_service_ = nullptr;
+  }
+  SetSyncService(sync_service);
+}
+
 void PersonalDataManager::
     RemoveAutofillProfileByGUIDAndBlankCreditCardReference(
         const std::string& guid) {
@@ -2111,6 +2102,26 @@
   return SaveImportedIBAN(imported_iban);
 }
 
+void PersonalDataManager::SetSyncService(syncer::SyncService* sync_service) {
+  CHECK(!sync_service_);
+
+  sync_service_ = sync_service;
+  if (sync_service_) {
+    sync_service_->AddObserver(this);
+  }
+
+  // Re-mask all server cards if the upload state is not active.
+  const bool is_upload_not_active =
+      syncer::GetUploadToGoogleState(sync_service_,
+                                     syncer::ModelType::AUTOFILL_WALLET_DATA) ==
+      syncer::UploadState::NOT_ACTIVE;
+  if (is_upload_not_active) {
+    ResetFullServerCards();
+  }
+
+  OnStateChanged(sync_service_);
+}
+
 std::string PersonalDataManager::SaveImportedCreditCard(
     const CreditCard& imported_card) {
   // Set to true if |imported_card| is merged into the credit card list.
diff --git a/components/autofill/core/browser/personal_data_manager.h b/components/autofill/core/browser/personal_data_manager.h
index 8699162..5c04c0e9e 100644
--- a/components/autofill/core/browser/personal_data_manager.h
+++ b/components/autofill/core/browser/personal_data_manager.h
@@ -99,7 +99,9 @@
   // account, and is wiped on signout and browser exit. This can be a nullptr
   // if personal_data_manager should use |profile_database| for all data.
   // If passed in, the |account_database| is used by default for server cards.
-  // |pref_service| must outlive this instance. |image_fetcher| is to fetch the
+  // |pref_service| must outlive this instance. |sync_service| is either null
+  // (sync disabled by CLI) or outlives this object, it may not have started yet
+  // but its preferences can already be queried. |image_fetcher| is to fetch the
   // customized images for autofill data. |is_off_the_record| informs this
   // instance whether the user is currently operating in an off-the-record
   // context.
@@ -109,6 +111,7 @@
             PrefService* local_state,
             signin::IdentityManager* identity_manager,
             history::HistoryService* history_service,
+            syncer::SyncService* sync_service,
             StrikeDatabaseBase* strike_database,
             AutofillImageFetcher* image_fetcher,
             bool is_off_the_record);
@@ -116,13 +119,6 @@
   // KeyedService:
   void Shutdown() override;
 
-  // Wires the circular sync service dependency. |sync_service| is either null
-  // (sync disabled by CLI) or outlives this object. This method is called once
-  // in production code, but may be called again in tests to replace the real
-  // service with a stub. |sync_service| may not have started yet but its
-  // preferences can already be queried.
-  virtual void OnSyncServiceInitialized(syncer::SyncService* sync_service);
-
   // history::HistoryServiceObserver
   void OnURLsDeleted(history::HistoryService* history_service,
                      const history::DeletionInfo& deletion_info) override;
@@ -291,6 +287,9 @@
   // the real database.
   void AddOfferDataForTest(std::unique_ptr<AutofillOfferData> offer_data);
 
+  // TODO(1426498): rewrite tests that rely on this method to use Init instead.
+  void SetSyncServiceForTest(syncer::SyncService* sync_service);
+
   // Returns the iban with the specified |guid|, or nullptr if there is no iban
   // with the specified |guid|.
   virtual IBAN* GetIBANByGUID(const std::string& guid);
@@ -817,6 +816,11 @@
       alternative_state_name_map_updater_;
 
  private:
+  // Sets (or resets) the Sync service, which may not have started yet
+  // but its preferences can already be queried. Can also be a nullptr
+  // if it is disabled by CLI.
+  void SetSyncService(syncer::SyncService* sync_service);
+
   // Saves |imported_credit_card| to the WebDB if it exists. Returns the guid of
   // the new or updated card, or the empty string if no card was saved.
   virtual std::string SaveImportedCreditCard(
diff --git a/components/autofill/core/browser/personal_data_manager_cleaner.cc b/components/autofill/core/browser/personal_data_manager_cleaner.cc
index 74616f3..86672f6 100644
--- a/components/autofill/core/browser/personal_data_manager_cleaner.cc
+++ b/components/autofill/core/browser/personal_data_manager_cleaner.cc
@@ -96,12 +96,10 @@
   }
 
   // Run deferred autofill address profile startup code.
-  // See: PersonalDataManager::OnSyncServiceInitialized
   if (model_type == syncer::AUTOFILL_PROFILE)
     ApplyAddressFixesAndCleanups();
 
   // Run deferred credit card startup code.
-  // See: PersonalDataManager::OnSyncServiceInitialized
   if (model_type == syncer::AUTOFILL_WALLET_DATA)
     ApplyCardFixesAndCleanups();
 }
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 cc945c2..12180331 100644
--- a/components/autofill/core/browser/personal_data_manager_test_base.cc
+++ b/components/autofill/core/browser/personal_data_manager_test_base.cc
@@ -93,17 +93,6 @@
     bool is_incognito,
     bool use_sync_transport_mode,
     PersonalDataManager* personal_data) {
-  personal_data->Init(
-      scoped_refptr<AutofillWebDataService>(profile_database_service_),
-      base::FeatureList::IsEnabled(
-          features::kAutofillEnableAccountWalletStorage)
-          ? scoped_refptr<AutofillWebDataService>(account_database_service_)
-          : nullptr,
-      prefs_.get(), prefs_.get(), identity_test_env_.identity_manager(),
-      /*history_service=*/nullptr, strike_database_.get(),
-      /*image_fetcher=*/nullptr, is_incognito);
-
-  personal_data->AddObserver(&personal_data_observer_);
   std::string email = use_sync_transport_mode ? kSyncTransportAccountEmail
                                               : kPrimaryAccountEmail;
   // Set the account in both IdentityManager and SyncService.
@@ -129,7 +118,18 @@
 #endif
   sync_service_.SetAccountInfo(account_info);
   sync_service_.SetHasSyncConsent(!use_sync_transport_mode);
-  personal_data->OnSyncServiceInitialized(&sync_service_);
+
+  personal_data->Init(
+      scoped_refptr<AutofillWebDataService>(profile_database_service_),
+      base::FeatureList::IsEnabled(
+          features::kAutofillEnableAccountWalletStorage)
+          ? scoped_refptr<AutofillWebDataService>(account_database_service_)
+          : nullptr,
+      prefs_.get(), prefs_.get(), identity_test_env_.identity_manager(),
+      /*history_service=*/nullptr, &sync_service_, strike_database_.get(),
+      /*image_fetcher=*/nullptr, is_incognito);
+
+  personal_data->AddObserver(&personal_data_observer_);
   personal_data->OnStateChanged(&sync_service_);
 
   WaitForOnPersonalDataChangedRepeatedly();
diff --git a/components/autofill/core/browser/personal_data_manager_unittest.cc b/components/autofill/core/browser/personal_data_manager_unittest.cc
index 3caf048..505c64e2 100644
--- a/components/autofill/core/browser/personal_data_manager_unittest.cc
+++ b/components/autofill/core/browser/personal_data_manager_unittest.cc
@@ -4854,14 +4854,13 @@
 // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch
 // of lacros-chrome is complete.
 #if !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
-// Test that calling OnSyncServiceInitialized with a null sync service remasks
-// full server cards.
+// Test that setting a null sync service remasks full server cards.
 TEST_F(PersonalDataManagerTest, OnSyncServiceInitialized_NoSyncService) {
   base::HistogramTester histogram_tester;
   SetUpThreeCardTypes();
 
-  // Call OnSyncServiceInitialized with no sync service.
-  personal_data_->OnSyncServiceInitialized(nullptr);
+  // Set no sync service.
+  personal_data_->SetSyncServiceForTest(nullptr);
   WaitForOnPersonalDataChanged();
 
   // Check that cards were masked and other were untouched.
@@ -4873,16 +4872,15 @@
     EXPECT_TRUE(card->record_type() == CreditCard::MASKED_SERVER_CARD);
 }
 
-// Test that calling OnSyncServiceInitialized with a sync service in auth error
-// remasks full server cards.
+// Test that setting a sync service in auth error remasks full server cards.
 TEST_F(PersonalDataManagerTest, OnSyncServiceInitialized_NotActiveSyncService) {
   base::HistogramTester histogram_tester;
   SetUpThreeCardTypes();
 
-  // Call OnSyncServiceInitialized with a sync service in auth error.
+  // Set a sync service in auth error.
   syncer::TestSyncService sync_service;
   sync_service.SetPersistentAuthError();
-  personal_data_->OnSyncServiceInitialized(&sync_service);
+  personal_data_->SetSyncServiceForTest(&sync_service);
   WaitForOnPersonalDataChanged();
 
   // Remove the auth error to be able to get the server cards.
@@ -4897,7 +4895,7 @@
     EXPECT_TRUE(card->record_type() == CreditCard::MASKED_SERVER_CARD);
 
   // Call OnSyncShutdown to ensure removing observer added by
-  // OnSyncServiceInitialized.
+  // SetSyncServiceForTest.
   personal_data_->OnSyncShutdown(&sync_service);
 }
 #endif  // !(BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS))
@@ -5468,7 +5466,7 @@
   EXPECT_TRUE(personal_data_->ShouldShowCardsFromAccountOption());
 
   // Set a null sync service. Check that the function now returns false.
-  personal_data_->OnSyncServiceInitialized(nullptr);
+  personal_data_->SetSyncServiceForTest(nullptr);
   EXPECT_FALSE(personal_data_->ShouldShowCardsFromAccountOption());
 }
 #else   // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) &&
@@ -5541,7 +5539,7 @@
   EXPECT_FALSE(personal_data_->ShouldShowCardsFromAccountOption());
 
   // Set a null sync service. Check that the function still returns false.
-  personal_data_->OnSyncServiceInitialized(nullptr);
+  personal_data_->SetSyncServiceForTest(nullptr);
   EXPECT_FALSE(personal_data_->ShouldShowCardsFromAccountOption());
 }
 #endif  // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) &&
diff --git a/components/autofill/core/browser/test_browser_autofill_manager.cc b/components/autofill/core/browser/test_browser_autofill_manager.cc
index fba27cd..21936de 100644
--- a/components/autofill/core/browser/test_browser_autofill_manager.cc
+++ b/components/autofill/core/browser/test_browser_autofill_manager.cc
@@ -177,8 +177,10 @@
   return card_image_;
 }
 
-void TestBrowserAutofillManager::ScheduleRefill(const FormData& form) {
-  TriggerRefillForTest(form);
+void TestBrowserAutofillManager::ScheduleRefill(
+    const FormData& form,
+    const AutofillTriggerSource trigger_source) {
+  TriggerRefillForTest(form, trigger_source);
 }
 
 bool TestBrowserAutofillManager::MaybeStartVoteUploadProcess(
diff --git a/components/autofill/core/browser/test_browser_autofill_manager.h b/components/autofill/core/browser/test_browser_autofill_manager.h
index a7dea91..2376cfe 100644
--- a/components/autofill/core/browser/test_browser_autofill_manager.h
+++ b/components/autofill/core/browser/test_browser_autofill_manager.h
@@ -13,6 +13,7 @@
 #include "base/memory/raw_ptr.h"
 #include "base/run_loop.h"
 #include "base/time/time.h"
+#include "components/autofill/core/browser/autofill_trigger_source.h"
 #include "components/autofill/core/browser/browser_autofill_manager.h"
 #include "third_party/abseil-cpp/absl/types/optional.h"
 #include "ui/gfx/image/image_unittest_util.h"
@@ -76,7 +77,8 @@
       std::unique_ptr<FormStructure> form_structure,
       bool observed_submission) override;
   // Immediately triggers the refill.
-  void ScheduleRefill(const FormData& form) override;
+  void ScheduleRefill(const FormData& form,
+                      const AutofillTriggerSource trigger_source) override;
 
   // Unique to TestBrowserAutofillManager:
 
diff --git a/components/autofill/core/browser/test_personal_data_manager.cc b/components/autofill/core/browser/test_personal_data_manager.cc
index a8f488ea..437efaf 100644
--- a/components/autofill/core/browser/test_personal_data_manager.cc
+++ b/components/autofill/core/browser/test_personal_data_manager.cc
@@ -17,11 +17,6 @@
 
 TestPersonalDataManager::~TestPersonalDataManager() = default;
 
-void TestPersonalDataManager::OnSyncServiceInitialized(
-    syncer::SyncService* sync_service) {
-  sync_service_initialized_ = true;
-}
-
 AutofillSyncSigninState TestPersonalDataManager::GetSyncSigninState() const {
   return sync_and_signin_state_;
 }
diff --git a/components/autofill/core/browser/test_personal_data_manager.h b/components/autofill/core/browser/test_personal_data_manager.h
index 6ffbd25..e924693c 100644
--- a/components/autofill/core/browser/test_personal_data_manager.h
+++ b/components/autofill/core/browser/test_personal_data_manager.h
@@ -40,7 +40,6 @@
   // PersonalDataManager overrides.  These functions are overridden as needed
   // for various tests, whether to skip calls to uncreated databases/services,
   // or to make things easier in general to toggle.
-  void OnSyncServiceInitialized(syncer::SyncService* sync_service) override;
   AutofillSyncSigninState GetSyncSigninState() const override;
   void RecordUseOf(absl::variant<const AutofillProfile*, const CreditCard*>
                        profile_or_credit_card) override;
@@ -136,8 +135,6 @@
     return num_times_save_upi_id_called_;
   }
 
-  bool sync_service_initialized() const { return sync_service_initialized_; }
-
   void SetAutofillCreditCardEnabled(bool autofill_credit_card_enabled) {
     autofill_credit_card_enabled_ = autofill_credit_card_enabled;
   }
@@ -184,7 +181,6 @@
   bool sync_feature_enabled_ = false;
   AutofillSyncSigninState sync_and_signin_state_ =
       AutofillSyncSigninState::kSignedInAndSyncFeatureEnabled;
-  bool sync_service_initialized_ = false;
   CoreAccountInfo account_info_;
 
   TestInMemoryStrikeDatabase inmemory_strike_database_;
diff --git a/components/browser_sync/sync_api_component_factory_impl.cc b/components/browser_sync/sync_api_component_factory_impl.cc
index 340b9f6..20e68c3 100644
--- a/components/browser_sync/sync_api_component_factory_impl.cc
+++ b/components/browser_sync/sync_api_component_factory_impl.cc
@@ -43,6 +43,7 @@
 #include "components/send_tab_to_self/send_tab_to_self_sync_service.h"
 #include "components/sync/base/features.h"
 #include "components/sync/base/legacy_directory_deletion.h"
+#include "components/sync/base/model_type.h"
 #include "components/sync/base/report_unrecoverable_error.h"
 #include "components/sync/base/sync_prefs.h"
 #include "components/sync/driver/data_type_manager_impl.h"
@@ -54,6 +55,7 @@
 #include "components/sync/invalidations/sync_invalidations_service.h"
 #include "components/sync/model/forwarding_model_type_controller_delegate.h"
 #include "components/sync/model/proxy_model_type_controller_delegate.h"
+#include "components/sync_bookmarks/bookmark_model_type_controller.h"
 #include "components/sync_bookmarks/bookmark_sync_service.h"
 #include "components/sync_device_info/device_info_sync_service.h"
 #include "components/sync_preferences/pref_service_syncable.h"
@@ -327,9 +329,10 @@
                         ->GetBookmarkSyncControllerDelegate(favicon_service)
                         .get())
               : nullptr;
-      controllers.push_back(std::make_unique<ModelTypeController>(
-          syncer::BOOKMARKS, std::move(full_mode_delegate),
-          std::move(transport_mode_delegate)));
+      controllers.push_back(
+          std::make_unique<sync_bookmarks::BookmarkModelTypeController>(
+              std::move(full_mode_delegate),
+              std::move(transport_mode_delegate)));
     }
 
     if (!disabled_types.Has(syncer::POWER_BOOKMARK) &&
diff --git a/components/chromeos_camera/common/dmabuf.mojom b/components/chromeos_camera/common/dmabuf.mojom
index 50400277..c18f2653 100644
--- a/components/chromeos_camera/common/dmabuf.mojom
+++ b/components/chromeos_camera/common/dmabuf.mojom
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Next min version: 2
+
 module chromeos_camera.mojom;
 
 import "media/mojo/mojom/media_types.mojom";
@@ -18,10 +20,13 @@
 // This structure defines a simplified version of media::VideoFrame backed by
 // DMA-bufs (see media/base/video_frame.h) for Chrome OS usage. The video frame
 // has pixel format |format| and coded size |coded_width|x|coded_height|.
-// Per-plane DMA-buf FDs and layouts are defined in |planes|.
+// Per-plane DMA-buf FDs and layouts are defined in |planes|. The |modifier| of
+// buffer is valid only if |has_modifier| is true.
 struct DmaBufVideoFrame {
   media.mojom.VideoPixelFormat format;
   uint32 coded_width;
   uint32 coded_height;
   array<DmaBufPlane> planes;
+  [MinVersion=1] bool has_modifier;
+  [MinVersion=1] uint64 modifier;
 };
diff --git a/components/chromeos_camera/common/jpeg_encode_accelerator.mojom b/components/chromeos_camera/common/jpeg_encode_accelerator.mojom
index 37fa42a1..cd461eb 100644
--- a/components/chromeos_camera/common/jpeg_encode_accelerator.mojom
+++ b/components/chromeos_camera/common/jpeg_encode_accelerator.mojom
@@ -2,6 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+// Next min version: 2
+
 module chromeos_camera.mojom;
 
 import "components/chromeos_camera/common/dmabuf.mojom";
@@ -59,7 +61,9 @@
   // onto APP1 segment in the output JPEG image. |quality| is the quality of
   // JPEG image. The range is from 1~100. High value means high quality. When
   // the task ends, it returns |status| as the status code and
-  // |encoded_buffer_size| is the actual size of the encoded JPEG.
+  // |encoded_buffer_size| is the actual size of the encoded JPEG. The
+  // |input_modifier| of input buffer is valid only if |has_input_modifier| is
+  // true.
   EncodeWithDmaBuf(
       int32 task_id,
       uint32 input_format,
@@ -69,6 +73,8 @@
       uint32 exif_buffer_size,
       int32 coded_size_width,
       int32 coded_size_height,
-      int32 quality)
+      int32 quality,
+      [MinVersion=1] bool has_input_modifier,
+      [MinVersion=1] uint64 input_modifier)
       => (uint32 encoded_buffer_size, EncodeStatus status);
 };
diff --git a/components/chromeos_camera/dmabuf_utils.cc b/components/chromeos_camera/dmabuf_utils.cc
index 5ac7426..38986f0 100644
--- a/components/chromeos_camera/dmabuf_utils.cc
+++ b/components/chromeos_camera/dmabuf_utils.cc
@@ -56,7 +56,8 @@
 scoped_refptr<media::VideoFrame> ConstructVideoFrame(
     std::vector<mojom::DmaBufPlanePtr> dma_buf_planes,
     media::VideoPixelFormat pixel_format,
-    const gfx::Size& coded_size) {
+    const gfx::Size& coded_size,
+    uint64_t modifier) {
   const size_t num_planes = media::VideoFrame::NumPlanes(pixel_format);
   if (num_planes != dma_buf_planes.size()) {
     DLOG(ERROR) << "The number of DMA buf planes does not match the format";
@@ -72,6 +73,7 @@
   gfx::GpuMemoryBufferHandle gmb_handle;
   gmb_handle.type = gfx::GpuMemoryBufferType::NATIVE_PIXMAP;
   gmb_handle.native_pixmap_handle.planes.resize(num_planes);
+  gmb_handle.native_pixmap_handle.modifier = modifier;
   for (size_t i = 0; i < num_planes; ++i) {
     mojo::PlatformHandle handle =
         mojo::UnwrapPlatformHandle(std::move(dma_buf_planes[i]->fd_handle));
@@ -112,8 +114,9 @@
         base::strict_cast<size_t>(dma_buf_planes[i]->size));
   }
   const absl::optional<media::VideoFrameLayout> layout =
-      media::VideoFrameLayout::CreateWithPlanes(pixel_format, coded_size,
-                                                std::move(planes));
+      media::VideoFrameLayout::CreateWithPlanes(
+          pixel_format, coded_size, std::move(planes),
+          media::VideoFrameLayout::kBufferAddressAlignment, modifier);
   if (!layout) {
     DLOG(ERROR) << "Failed to create video frame layout";
     return nullptr;
diff --git a/components/chromeos_camera/dmabuf_utils.h b/components/chromeos_camera/dmabuf_utils.h
index 53b8727..9affba3e 100644
--- a/components/chromeos_camera/dmabuf_utils.h
+++ b/components/chromeos_camera/dmabuf_utils.h
@@ -23,7 +23,8 @@
 scoped_refptr<media::VideoFrame> ConstructVideoFrame(
     std::vector<mojom::DmaBufPlanePtr> dma_buf_planes,
     media::VideoPixelFormat pixel_format,
-    const gfx::Size& coded_size);
+    const gfx::Size& coded_size,
+    uint64_t modifier = gfx::NativePixmapHandle::kNoModifier);
 
 }  // namespace chromeos_camera
 
diff --git a/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.cc b/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.cc
index 05d2dde..9a2c92b 100644
--- a/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.cc
+++ b/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.cc
@@ -297,6 +297,8 @@
     int32_t coded_size_width,
     int32_t coded_size_height,
     int32_t quality,
+    bool has_input_modifier,
+    uint64_t input_modifier,
     EncodeWithDmaBufCallback callback) {
   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
 
@@ -326,7 +328,9 @@
   }
 
   auto input_video_frame = ConstructVideoFrame(
-      std::move(input_planes), ToVideoPixelFormat(input_format), coded_size);
+      std::move(input_planes), ToVideoPixelFormat(input_format), coded_size,
+      has_input_modifier ? input_modifier
+                         : gfx::NativePixmapHandle::kNoModifier);
   if (!input_video_frame) {
     std::move(callback).Run(
         0, ::chromeos_camera::JpegEncodeAccelerator::Status::PLATFORM_FAILURE);
diff --git a/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.h b/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.h
index cc07854..f57bd5b 100644
--- a/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.h
+++ b/components/chromeos_camera/mojo_jpeg_encode_accelerator_service.h
@@ -85,6 +85,8 @@
       int32_t coded_size_width,
       int32_t coded_size_height,
       int32_t quality,
+      bool has_input_modifier,
+      uint64_t input_modifier,
       EncodeWithDmaBufCallback callback) override;
 
   void NotifyEncodeStatus(
diff --git a/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.cc b/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.cc
index 34295e8a..7255f031 100644
--- a/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.cc
+++ b/components/chromeos_camera/mojo_mjpeg_decode_accelerator_service.cc
@@ -261,7 +261,9 @@
   const gfx::Size coded_size(base::checked_cast<int>(dst_frame->coded_width),
                              base::checked_cast<int>(dst_frame->coded_height));
   scoped_refptr<media::VideoFrame> frame = ConstructVideoFrame(
-      std::move(dst_frame->planes), dst_frame->format, coded_size);
+      std::move(dst_frame->planes), dst_frame->format, coded_size,
+      dst_frame->has_modifier ? dst_frame->modifier
+                              : gfx::NativePixmapHandle::kNoModifier);
   if (!frame) {
     LOG(ERROR) << "Failed to create video frame";
     std::move(callback).Run(
diff --git a/components/page_info/core/features.cc b/components/page_info/core/features.cc
index a04d3e92..1c468df 100644
--- a/components/page_info/core/features.cc
+++ b/components/page_info/core/features.cc
@@ -56,11 +56,7 @@
 
 BASE_FEATURE(kPageInfoAboutThisSiteMoreInfo,
              "PageInfoAboutThisSiteMoreInfo",
-#if BUILDFLAG(IS_ANDROID)
              base::FEATURE_ENABLED_BY_DEFAULT);
-#else
-             base::FEATURE_DISABLED_BY_DEFAULT);
-#endif
 
 #if !BUILDFLAG(IS_ANDROID)
 BASE_FEATURE(kPageInfoAboutThisSiteKeepSidePanelOnSameTabNavs,
diff --git a/components/policy/resources/templates/device_policy_proto_map.yaml b/components/policy/resources/templates/device_policy_proto_map.yaml
index 4320b69..4d74d045 100644
--- a/components/policy/resources/templates/device_policy_proto_map.yaml
+++ b/components/policy/resources/templates/device_policy_proto_map.yaml
@@ -15,6 +15,7 @@
 DeviceAllowNewUsers: allow_new_users.allow_new_users
 DeviceAllowRedeemChromeOsRegistrationOffers: allow_redeem_offers.allow_redeem_offers
 DeviceAllowedBluetoothServices: device_allowed_bluetooth_services.allowlist
+DeviceArcDataSnapshotHours: arc_data_snapshot_hours.arc_data_snapshot_hours
 DeviceAuthDataCacheLifetime: device_auth_data_cache_lifetime.lifetime_hours
 DeviceAutoUpdateDisabled: auto_update_settings.update_disabled
 DeviceAutoUpdateP2PEnabled: auto_update_settings.p2p_enabled
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc
index dc0f764..89b0d80 100644
--- a/components/startup_metric_utils/browser/startup_metric_utils.cc
+++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -506,11 +506,6 @@
       &base::UmaHistogramLongTimes100,
       "Startup.BrowserMessageLoopStart.To.NonEmptyPaint2",
       now - g_message_loop_start_ticks);
-
-  UmaHistogramWithTemperature(
-      &base::UmaHistogramLongTimes100,
-      "Startup.FirstWebContents.RenderProcessHostInit.ToNonEmptyPaint",
-      now - render_process_host_init_time);
 }
 
 void RecordFirstWebContentsMainNavigationStart(base::TimeTicks ticks) {
diff --git a/components/sync/engine/syncer_proto_util.cc b/components/sync/engine/syncer_proto_util.cc
index 31aac4d..d95d061 100644
--- a/components/sync/engine/syncer_proto_util.cc
+++ b/components/sync/engine/syncer_proto_util.cc
@@ -52,7 +52,6 @@
       return SyncerError::HttpError(http_status_code);
     case HttpResponse::SERVER_CONNECTION_OK:
     case HttpResponse::NONE:
-    default:
       NOTREACHED();
       return SyncerError();
   }
@@ -379,7 +378,12 @@
         cycle->context()->connection_manager()->server_status();
 
     DCHECK_NE(server_status, HttpResponse::NONE);
-    DCHECK_NE(server_status, HttpResponse::SERVER_CONNECTION_OK);
+
+    if (server_status == HttpResponse::SERVER_CONNECTION_OK) {
+      // The server returned a response but there was a failure in processing
+      // it.
+      return SyncerError(SyncerError::SERVER_RESPONSE_VALIDATION_FAILED);
+    }
 
     return ServerConnectionErrorAsSyncerError(
         server_status, cycle->context()->connection_manager()->net_error_code(),
diff --git a/components/sync_bookmarks/BUILD.gn b/components/sync_bookmarks/BUILD.gn
index 7313f54c..21d3833 100644
--- a/components/sync_bookmarks/BUILD.gn
+++ b/components/sync_bookmarks/BUILD.gn
@@ -12,6 +12,8 @@
     "bookmark_model_merger.h",
     "bookmark_model_observer_impl.cc",
     "bookmark_model_observer_impl.h",
+    "bookmark_model_type_controller.cc",
+    "bookmark_model_type_controller.h",
     "bookmark_model_type_processor.cc",
     "bookmark_model_type_processor.h",
     "bookmark_remote_updates_handler.cc",
diff --git a/components/sync_bookmarks/bookmark_model_type_controller.cc b/components/sync_bookmarks/bookmark_model_type_controller.cc
new file mode 100644
index 0000000..da3c524
--- /dev/null
+++ b/components/sync_bookmarks/bookmark_model_type_controller.cc
@@ -0,0 +1,29 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/sync_bookmarks/bookmark_model_type_controller.h"
+
+#include <utility>
+
+#include "components/bookmarks/common/bookmark_features.h"
+
+namespace sync_bookmarks {
+
+BookmarkModelTypeController::BookmarkModelTypeController(
+    std::unique_ptr<syncer::ModelTypeControllerDelegate>
+        delegate_for_full_sync_mode,
+    std::unique_ptr<syncer::ModelTypeControllerDelegate>
+        delegate_for_transport_mode)
+    : ModelTypeController(syncer::BOOKMARKS,
+                          std::move(delegate_for_full_sync_mode),
+                          std::move(delegate_for_transport_mode)) {}
+
+BookmarkModelTypeController::~BookmarkModelTypeController() = default;
+
+bool BookmarkModelTypeController::ShouldRunInTransportOnlyMode() const {
+  return base::FeatureList::IsEnabled(
+      bookmarks::kEnableBookmarksAccountStorage);
+}
+
+}  // namespace sync_bookmarks
diff --git a/components/sync_bookmarks/bookmark_model_type_controller.h b/components/sync_bookmarks/bookmark_model_type_controller.h
new file mode 100644
index 0000000..9bd6c39
--- /dev/null
+++ b/components/sync_bookmarks/bookmark_model_type_controller.h
@@ -0,0 +1,34 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_MODEL_TYPE_CONTROLLER_H_
+#define COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_MODEL_TYPE_CONTROLLER_H_
+
+#include <memory>
+
+#include "components/sync/driver/model_type_controller.h"
+
+namespace sync_bookmarks {
+
+class BookmarkModelTypeController : public syncer::ModelTypeController {
+ public:
+  BookmarkModelTypeController(
+      std::unique_ptr<syncer::ModelTypeControllerDelegate>
+          delegate_for_full_sync_mode,
+      std::unique_ptr<syncer::ModelTypeControllerDelegate>
+          delegate_for_transport_mode);
+
+  BookmarkModelTypeController(const BookmarkModelTypeController&) = delete;
+  BookmarkModelTypeController& operator=(const BookmarkModelTypeController&) =
+      delete;
+
+  ~BookmarkModelTypeController() override;
+
+  // DataTypeController overrides.
+  bool ShouldRunInTransportOnlyMode() const override;
+};
+
+}  // namespace sync_bookmarks
+
+#endif  // COMPONENTS_SYNC_BOOKMARKS_BOOKMARK_MODEL_TYPE_CONTROLLER_H_
diff --git a/components/sync_preferences/dual_layer_user_pref_store.cc b/components/sync_preferences/dual_layer_user_pref_store.cc
index 777c981..bb6e66877 100644
--- a/components/sync_preferences/dual_layer_user_pref_store.cc
+++ b/components/sync_preferences/dual_layer_user_pref_store.cc
@@ -12,6 +12,7 @@
 #include "base/strings/string_piece.h"
 #include "base/values.h"
 #include "build/chromeos_buildflags.h"
+#include "components/sync_preferences/pref_model_associator_client.h"
 #include "components/sync_preferences/syncable_prefs_database.h"
 
 namespace sync_preferences {
@@ -67,12 +68,12 @@
 
 DualLayerUserPrefStore::DualLayerUserPrefStore(
     scoped_refptr<PersistentPrefStore> local_pref_store,
-    const SyncablePrefsDatabase* syncable_prefs_database)
+    const PrefModelAssociatorClient* pref_model_associator_client)
     : local_pref_store_(std::move(local_pref_store)),
       account_pref_store_(base::MakeRefCounted<ValueMapPrefStore>()),
       local_pref_store_observer_(this, /*is_account_store=*/false),
       account_pref_store_observer_(this, /*is_account_store=*/true),
-      syncable_prefs_database_(syncable_prefs_database) {
+      pref_model_associator_client_(pref_model_associator_client) {
   local_pref_store_->AddObserver(&local_pref_store_observer_);
   account_pref_store_->AddObserver(&account_pref_store_observer_);
 }
@@ -310,11 +311,12 @@
 }
 
 bool DualLayerUserPrefStore::IsPrefKeySyncable(const std::string& key) const {
-  if (!syncable_prefs_database_) {
+  if (!pref_model_associator_client_) {
     // Safer this way.
     return false;
   }
-  auto metadata = syncable_prefs_database_->GetSyncablePrefMetadata(key);
+  auto metadata = pref_model_associator_client_->GetSyncablePrefsDatabase()
+                      .GetSyncablePrefMetadata(key);
   return metadata.has_value() && active_types_.count(metadata->model_type());
 }
 
@@ -340,7 +342,7 @@
   );
   active_types_.erase(model_type);
 
-  if (!syncable_prefs_database_) {
+  if (!pref_model_associator_client_) {
     // No pref is treated as syncable in this case. No need to clear the account
     // store.
     return;
diff --git a/components/sync_preferences/dual_layer_user_pref_store.h b/components/sync_preferences/dual_layer_user_pref_store.h
index e2bd2ae..ae8f102 100644
--- a/components/sync_preferences/dual_layer_user_pref_store.h
+++ b/components/sync_preferences/dual_layer_user_pref_store.h
@@ -20,7 +20,7 @@
 
 namespace sync_preferences {
 
-class SyncablePrefsDatabase;
+class PrefModelAssociatorClient;
 
 // A two-layer user PrefStore that combines local preferences (scoped to this
 // profile) with account-scoped preferences (scoped to the user's signed-in
@@ -33,8 +33,9 @@
 //   account store.
 class DualLayerUserPrefStore : public PersistentPrefStore {
  public:
-  DualLayerUserPrefStore(scoped_refptr<PersistentPrefStore> local_pref_store,
-                         const SyncablePrefsDatabase* syncable_prefs_database);
+  DualLayerUserPrefStore(
+      scoped_refptr<PersistentPrefStore> local_pref_store,
+      const PrefModelAssociatorClient* pref_model_associator_client);
 
   DualLayerUserPrefStore(const DualLayerUserPrefStore&) = delete;
   DualLayerUserPrefStore& operator=(const DualLayerUserPrefStore&) = delete;
@@ -129,7 +130,8 @@
 
   base::ObserverList<PrefStore::Observer, true>::Unchecked observers_;
 
-  const SyncablePrefsDatabase* const syncable_prefs_database_ = nullptr;
+  const PrefModelAssociatorClient* const pref_model_associator_client_ =
+      nullptr;
 };
 
 }  // namespace sync_preferences
diff --git a/components/sync_preferences/dual_layer_user_pref_store_unittest.cc b/components/sync_preferences/dual_layer_user_pref_store_unittest.cc
index 5e95f981..18b27252 100644
--- a/components/sync_preferences/dual_layer_user_pref_store_unittest.cc
+++ b/components/sync_preferences/dual_layer_user_pref_store_unittest.cc
@@ -8,7 +8,7 @@
 #include "base/values.h"
 #include "build/chromeos_buildflags.h"
 #include "components/prefs/testing_pref_store.h"
-#include "components/sync_preferences/syncable_prefs_database.h"
+#include "components/sync_preferences/pref_model_associator_client.h"
 #include "components/sync_preferences/test_syncable_prefs_database.h"
 #include "testing/gmock/include/gmock/gmock.h"
 #include "testing/gtest/include/gtest/gtest.h"
@@ -86,15 +86,44 @@
   MOCK_METHOD(void, OnInitializationCompleted, (bool succeeded), (override));
 };
 
+class TestPrefModelAssociatorClient : public PrefModelAssociatorClient {
+ public:
+  TestPrefModelAssociatorClient()
+      : syncable_prefs_database_(kSyncablePrefsDatabase) {}
+
+  // PrefModelAssociatorClient implementation.
+  bool IsMergeableListPreference(const std::string& pref_name) const override {
+    return false;
+  }
+
+  bool IsMergeableDictionaryPreference(
+      const std::string& pref_name) const override {
+    return false;
+  }
+
+  base::Value MaybeMergePreferenceValues(
+      const std::string& pref_name,
+      const base::Value& local_value,
+      const base::Value& server_value) const override {
+    return base::Value();
+  }
+
+  const SyncablePrefsDatabase& GetSyncablePrefsDatabase() const override {
+    return syncable_prefs_database_;
+  }
+
+ private:
+  TestSyncablePrefsDatabase syncable_prefs_database_;
+};
+
 }  // namespace
 
 class DualLayerUserPrefStoreTestBase : public testing::Test {
  public:
-  explicit DualLayerUserPrefStoreTestBase(bool initialize)
-      : syncable_prefs_database_(kSyncablePrefsDatabase) {
+  explicit DualLayerUserPrefStoreTestBase(bool initialize) {
     local_store_ = base::MakeRefCounted<TestingPrefStore>();
     dual_layer_store_ = base::MakeRefCounted<DualLayerUserPrefStore>(
-        local_store_, &syncable_prefs_database_);
+        local_store_, &pref_model_associator_client_);
 
     if (initialize) {
       local_store_->NotifyInitializationCompleted();
@@ -107,7 +136,7 @@
  protected:
   scoped_refptr<TestingPrefStore> local_store_;
   scoped_refptr<DualLayerUserPrefStore> dual_layer_store_;
-  TestSyncablePrefsDatabase syncable_prefs_database_;
+  TestPrefModelAssociatorClient pref_model_associator_client_;
 };
 
 class DualLayerUserPrefStoreTest : public DualLayerUserPrefStoreTestBase {
diff --git a/components/sync_preferences/pref_service_syncable_factory.cc b/components/sync_preferences/pref_service_syncable_factory.cc
index 9ca7c08..1d16d15 100644
--- a/components/sync_preferences/pref_service_syncable_factory.cc
+++ b/components/sync_preferences/pref_service_syncable_factory.cc
@@ -58,14 +58,9 @@
     // If EnablePreferencesAccountStorage is enabled, then a
     // DualLayerUserPrefStore is used as the main user pref store, and sync is
     // hooked up directly to the underlying account store.
-    const SyncablePrefsDatabase* syncable_prefs_database = nullptr;
-    if (pref_model_associator_client_) {
-      syncable_prefs_database =
-          &pref_model_associator_client_->GetSyncablePrefsDatabase();
-    }
     auto dual_layer_user_pref_store =
         base::MakeRefCounted<sync_preferences::DualLayerUserPrefStore>(
-            user_prefs_, syncable_prefs_database);
+            user_prefs_, pref_model_associator_client_);
     auto pref_value_store = std::make_unique<PrefValueStore>(
         managed_prefs_.get(), supervised_user_prefs_.get(),
         extension_prefs_.get(), standalone_browser_prefs_.get(),
diff --git a/components/viz/common/quads/draw_quad_unittest.cc b/components/viz/common/quads/draw_quad_unittest.cc
index 6c0227a..3920184 100644
--- a/components/viz/common/quads/draw_quad_unittest.cc
+++ b/components/viz/common/quads/draw_quad_unittest.cc
@@ -449,7 +449,6 @@
   gfx::RectF tex_coord_rect(31.f, 12.f, 54.f, 20.f);
   gfx::Size texture_size(85, 32);
   bool nearest_neighbor = true;
-  ResourceFormat texture_format = RGBA_8888;
   gfx::Rect content_rect(30, 40, 20, 30);
   float contents_scale = 3.141592f;
   scoped_refptr<cc::DisplayItemList> display_item_list =
@@ -458,15 +457,14 @@
   CREATE_SHARED_STATE();
 
   CREATE_QUAD_NEW(PictureDrawQuad, visible_rect, blending, tex_coord_rect,
-                  texture_size, nearest_neighbor, texture_format, content_rect,
-                  contents_scale, {}, display_item_list);
+                  texture_size, nearest_neighbor, content_rect, contents_scale,
+                  {}, display_item_list);
   EXPECT_EQ(DrawQuad::Material::kPictureContent, copy_quad->material);
   EXPECT_EQ(visible_rect, copy_quad->visible_rect);
   EXPECT_EQ(blending, copy_quad->needs_blending);
   EXPECT_EQ(tex_coord_rect, copy_quad->tex_coord_rect);
   EXPECT_EQ(texture_size, copy_quad->texture_size);
   EXPECT_EQ(nearest_neighbor, copy_quad->nearest_neighbor);
-  EXPECT_EQ(texture_format, copy_quad->texture_format);
   EXPECT_EQ(content_rect, copy_quad->content_rect);
   EXPECT_EQ(contents_scale, copy_quad->contents_scale);
   EXPECT_EQ(display_item_list, copy_quad->display_item_list);
diff --git a/components/viz/common/quads/picture_draw_quad.cc b/components/viz/common/quads/picture_draw_quad.cc
index e553097..865cbaf1 100644
--- a/components/viz/common/quads/picture_draw_quad.cc
+++ b/components/viz/common/quads/picture_draw_quad.cc
@@ -26,7 +26,6 @@
                              const gfx::RectF& tex_coord_rect,
                              const gfx::Size& texture_size,
                              bool nearest_neighbor,
-                             ResourceFormat format,
                              const gfx::Rect& content,
                              float scale,
                              ImageAnimationMap animation_map,
@@ -39,7 +38,6 @@
   contents_scale = scale;
   image_animation_map = std::move(animation_map);
   display_item_list = std::move(display_items);
-  texture_format = format;
 }
 
 const PictureDrawQuad* PictureDrawQuad::MaterialCast(const DrawQuad* quad) {
@@ -51,7 +49,6 @@
   ContentDrawQuadBase::ExtendValue(value);
   cc::MathUtil::AddToTracedValue("content_rect", content_rect, value);
   value->SetDouble("contents_scale", contents_scale);
-  value->SetInteger("texture_format", texture_format);
   // TODO(piman): display_item_list?
 }
 
diff --git a/components/viz/common/quads/picture_draw_quad.h b/components/viz/common/quads/picture_draw_quad.h
index 3e5519f..94c56e7 100644
--- a/components/viz/common/quads/picture_draw_quad.h
+++ b/components/viz/common/quads/picture_draw_quad.h
@@ -10,7 +10,6 @@
 #include "cc/paint/display_item_list.h"
 #include "cc/paint/paint_image.h"
 #include "components/viz/common/quads/content_draw_quad_base.h"
-#include "components/viz/common/resources/resource_format.h"
 #include "components/viz/common/viz_common_export.h"
 #include "ui/gfx/geometry/rect.h"
 #include "ui/gfx/geometry/rect_f.h"
@@ -35,7 +34,6 @@
               const gfx::RectF& tex_coord_rect,
               const gfx::Size& texture_size,
               bool nearest_neighbor,
-              ResourceFormat format,
               const gfx::Rect& content,
               float scale,
               ImageAnimationMap animation_map,
@@ -45,7 +43,6 @@
   float contents_scale;
   ImageAnimationMap image_animation_map;
   scoped_refptr<cc::DisplayItemList> display_item_list;
-  ResourceFormat texture_format;
 
   static const PictureDrawQuad* MaterialCast(const DrawQuad* quad);
 
diff --git a/components/viz/common/resources/bitmap_allocation.cc b/components/viz/common/resources/bitmap_allocation.cc
index 9d35010..52e58b29 100644
--- a/components/viz/common/resources/bitmap_allocation.cc
+++ b/components/viz/common/resources/bitmap_allocation.cc
@@ -44,11 +44,6 @@
 namespace bitmap_allocation {
 
 base::MappedReadOnlyRegion AllocateSharedBitmap(const gfx::Size& size,
-                                                ResourceFormat format) {
-  return AllocateSharedBitmap(size, SharedImageFormat::SinglePlane(format));
-}
-
-base::MappedReadOnlyRegion AllocateSharedBitmap(const gfx::Size& size,
                                                 SharedImageFormat format) {
   DCHECK(format.IsBitmapFormatSupported())
       << "(format = " << format.ToString() << ")";
diff --git a/components/viz/common/resources/bitmap_allocation.h b/components/viz/common/resources/bitmap_allocation.h
index c3034157..b4f2638 100644
--- a/components/viz/common/resources/bitmap_allocation.h
+++ b/components/viz/common/resources/bitmap_allocation.h
@@ -24,12 +24,6 @@
     const gfx::Size& size,
     SharedImageFormat format);
 
-// Deprecated version of the above that takes in ResourceFormat.
-// TODO(crbug.com/1378708): Convert all clients and eliminate this function.
-VIZ_COMMON_EXPORT base::MappedReadOnlyRegion AllocateSharedBitmap(
-    const gfx::Size& size,
-    ResourceFormat format);
-
 }  // namespace bitmap_allocation
 
 }  // namespace viz
diff --git a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc
index 09185960..aa706eb17 100644
--- a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc
+++ b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc
@@ -398,8 +398,8 @@
     const gfx::Size& size,
     SkColor4f color) {
   SharedBitmapId shared_bitmap_id = SharedBitmap::GenerateId();
-  base::MappedReadOnlyRegion shm =
-      bitmap_allocation::AllocateSharedBitmap(size, RGBA_8888);
+  base::MappedReadOnlyRegion shm = bitmap_allocation::AllocateSharedBitmap(
+      size, SinglePlaneFormat::kRGBA_8888);
 
   SkBitmap bitmap;
   SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
diff --git a/components/viz/service/display/display_resource_provider_software_unittest.cc b/components/viz/service/display/display_resource_provider_software_unittest.cc
index d509e86..5a83f61 100644
--- a/components/viz/service/display/display_resource_provider_software_unittest.cc
+++ b/components/viz/service/display/display_resource_provider_software_unittest.cc
@@ -58,8 +58,8 @@
                                                 uint32_t value) {
   SharedBitmapId shared_bitmap_id = SharedBitmap::GenerateId();
 
-  base::MappedReadOnlyRegion shm =
-      bitmap_allocation::AllocateSharedBitmap(size, RGBA_8888);
+  base::MappedReadOnlyRegion shm = bitmap_allocation::AllocateSharedBitmap(
+      size, SinglePlaneFormat::kRGBA_8888);
   manager->ChildAllocatedSharedBitmap(shm.region.Map(), shared_bitmap_id);
   base::span<uint32_t> span =
       shm.mapping.GetMemoryAsSpan<uint32_t>(size.GetArea());
diff --git a/components/viz/service/display/renderer_pixeltest.cc b/components/viz/service/display/renderer_pixeltest.cc
index 9134bb2..c8ce716 100644
--- a/components/viz/service/display/renderer_pixeltest.cc
+++ b/components/viz/service/display/renderer_pixeltest.cc
@@ -97,8 +97,8 @@
     const SharedBitmapId& id,
     const gfx::Size& size,
     SharedBitmapManager* shared_bitmap_manager) {
-  base::MappedReadOnlyRegion shm =
-      bitmap_allocation::AllocateSharedBitmap(size, RGBA_8888);
+  base::MappedReadOnlyRegion shm = bitmap_allocation::AllocateSharedBitmap(
+      size, SinglePlaneFormat::kRGBA_8888);
   shared_bitmap_manager->ChildAllocatedSharedBitmap(shm.region.Map(), id);
   return std::move(shm.mapping);
 }
@@ -1533,8 +1533,8 @@
 
   blue_quad->SetNew(this->front_quad_state_, this->quad_rect_, this->quad_rect_,
                     needs_blending, gfx::RectF(this->quad_rect_),
-                    this->quad_rect_.size(), false, RGBA_8888, this->quad_rect_,
-                    1.f, {}, blue_raster_source->GetDisplayItemList());
+                    this->quad_rect_.size(), false, this->quad_rect_, 1.f, {},
+                    blue_raster_source->GetDisplayItemList());
 
   std::unique_ptr<cc::FakeRecordingSource> green_recording =
       cc::FakeRecordingSource::CreateFilledRecordingSource(
@@ -1549,8 +1549,7 @@
       this->render_pass_->template CreateAndAppendDrawQuad<PictureDrawQuad>();
   green_quad->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_,
                      needs_blending, gfx::RectF(this->quad_rect_),
-                     this->quad_rect_.size(), false, RGBA_8888,
-                     this->quad_rect_, 1.f, {},
+                     this->quad_rect_.size(), false, this->quad_rect_, 1.f, {},
                      green_raster_source->GetDisplayItemList());
   this->AppendBackgroundAndRunTest(
       cc::FuzzyPixelComparator().SetErrorPixelsPercentageLimit(2.f),
@@ -3531,7 +3530,6 @@
 TEST_F(SoftwareRendererPixelTest, PictureDrawQuadIdentityScale) {
   gfx::Rect viewport(this->device_viewport_size_);
   // TODO(enne): the renderer should figure this out on its own.
-  ResourceFormat texture_format = RGBA_8888;
   bool nearest_neighbor = false;
 
   AggregatedRenderPassId id{1};
@@ -3571,8 +3569,8 @@
   blue_quad->SetNew(blue_shared_state,
                     viewport,  // Intentionally bigger than clip.
                     viewport, needs_blending, gfx::RectF(viewport),
-                    viewport.size(), nearest_neighbor, texture_format, viewport,
-                    1.f, {}, blue_raster_source->GetDisplayItemList());
+                    viewport.size(), nearest_neighbor, viewport, 1.f, {},
+                    blue_raster_source->GetDisplayItemList());
 
   // One viewport-filling green quad.
   std::unique_ptr<cc::FakeRecordingSource> green_recording =
@@ -3591,7 +3589,7 @@
   auto* green_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
   green_quad->SetNew(green_shared_state, viewport, viewport, needs_blending,
                      gfx::RectF(0.f, 0.f, 1.f, 1.f), viewport.size(),
-                     nearest_neighbor, texture_format, viewport, 1.f, {},
+                     nearest_neighbor, viewport, 1.f, {},
                      green_raster_source->GetDisplayItemList());
 
   AggregatedRenderPassList pass_list;
@@ -3607,7 +3605,6 @@
 TEST_F(SoftwareRendererPixelTest, PictureDrawQuadOpacity) {
   gfx::Rect viewport(this->device_viewport_size_);
   bool needs_blending = true;
-  ResourceFormat texture_format = RGBA_8888;
   bool nearest_neighbor = false;
 
   AggregatedRenderPassId id{1};
@@ -3632,7 +3629,7 @@
   auto* green_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
   green_quad->SetNew(green_shared_state, viewport, viewport, needs_blending,
                      gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
-                     texture_format, viewport, 1.f, {},
+                     viewport, 1.f, {},
                      green_raster_source->GetDisplayItemList());
 
   // One viewport-filling white quad.
@@ -3652,7 +3649,7 @@
   auto* white_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
   white_quad->SetNew(white_shared_state, viewport, viewport, needs_blending,
                      gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
-                     texture_format, viewport, 1.f, {},
+                     viewport, 1.f, {},
                      white_raster_source->GetDisplayItemList());
 
   AggregatedRenderPassList pass_list;
@@ -3666,7 +3663,6 @@
 TEST_F(SoftwareRendererPixelTest, PictureDrawQuadOpacityWithAlpha) {
   gfx::Rect viewport(this->device_viewport_size_);
   bool needs_blending = true;
-  ResourceFormat texture_format = RGBA_8888;
   bool nearest_neighbor = false;
 
   AggregatedRenderPassId id{1};
@@ -3689,10 +3685,10 @@
   transparent_shared_state->opacity = 0.5f;
 
   auto* transparent_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  transparent_quad->SetNew(
-      transparent_shared_state, viewport, viewport, needs_blending,
-      gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor, texture_format,
-      viewport, 1.f, {}, transparent_raster_source->GetDisplayItemList());
+  transparent_quad->SetNew(transparent_shared_state, viewport, viewport,
+                           needs_blending, gfx::RectF(0, 0, 1, 1),
+                           viewport.size(), nearest_neighbor, viewport, 1.f, {},
+                           transparent_raster_source->GetDisplayItemList());
 
   // One viewport-filling white quad.
   std::unique_ptr<cc::FakeRecordingSource> white_recording =
@@ -3711,7 +3707,7 @@
   auto* white_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
   white_quad->SetNew(white_shared_state, viewport, viewport, needs_blending,
                      gfx::RectF(0, 0, 1, 1), viewport.size(), nearest_neighbor,
-                     texture_format, viewport, 1.f, {},
+                     viewport, 1.f, {},
                      white_raster_source->GetDisplayItemList());
 
   AggregatedRenderPassList pass_list;
@@ -3735,7 +3731,6 @@
 // huge sharp squares.
 TEST_F(SoftwareRendererPixelTest, PictureDrawQuadDisableImageFiltering) {
   gfx::Rect viewport(this->device_viewport_size_);
-  ResourceFormat texture_format = RGBA_8888;
   bool needs_blending = true;
   bool nearest_neighbor = false;
 
@@ -3768,8 +3763,7 @@
   auto* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
   quad->SetNew(shared_state, viewport, viewport, needs_blending,
                gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
-               texture_format, viewport, 1.f, {},
-               raster_source->GetDisplayItemList());
+               viewport, 1.f, {}, raster_source->GetDisplayItemList());
 
   AggregatedRenderPassList pass_list;
   pass_list.push_back(std::move(pass));
@@ -3786,7 +3780,6 @@
 // PictureDrawQuad.
 TEST_F(SoftwareRendererPixelTest, PictureDrawQuadNearestNeighbor) {
   gfx::Rect viewport(this->device_viewport_size_);
-  ResourceFormat texture_format = RGBA_8888;
   bool needs_blending = true;
   bool nearest_neighbor = true;
 
@@ -3819,8 +3812,7 @@
   auto* quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
   quad->SetNew(shared_state, viewport, viewport, needs_blending,
                gfx::RectF(0, 0, 2, 2), viewport.size(), nearest_neighbor,
-               texture_format, viewport, 1.f, {},
-               raster_source->GetDisplayItemList());
+               viewport, 1.f, {}, raster_source->GetDisplayItemList());
 
   AggregatedRenderPassList pass_list;
   pass_list.push_back(std::move(pass));
@@ -4008,7 +4000,6 @@
 TEST_F(SoftwareRendererPixelTest, PictureDrawQuadNonIdentityScale) {
   gfx::Rect viewport(this->device_viewport_size_);
   // TODO(enne): the renderer should figure this out on its own.
-  ResourceFormat texture_format = RGBA_8888;
   bool needs_blending = true;
   bool nearest_neighbor = false;
 
@@ -4043,18 +4034,18 @@
                                 pass.get(), gfx::MaskFilterInfo());
 
   auto* green_quad1 = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  green_quad1->SetNew(
-      top_right_green_shared_quad_state, green_rect1, green_rect1,
-      needs_blending, gfx::RectF(gfx::SizeF(green_rect1.size())),
-      green_rect1.size(), nearest_neighbor, texture_format, green_rect1, 1.f,
-      {}, green_raster_source->GetDisplayItemList());
+  green_quad1->SetNew(top_right_green_shared_quad_state, green_rect1,
+                      green_rect1, needs_blending,
+                      gfx::RectF(gfx::SizeF(green_rect1.size())),
+                      green_rect1.size(), nearest_neighbor, green_rect1, 1.f,
+                      {}, green_raster_source->GetDisplayItemList());
 
   auto* green_quad2 = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
-  green_quad2->SetNew(
-      top_right_green_shared_quad_state, green_rect2, green_rect2,
-      needs_blending, gfx::RectF(gfx::SizeF(green_rect2.size())),
-      green_rect2.size(), nearest_neighbor, texture_format, green_rect2, 1.f,
-      {}, green_raster_source->GetDisplayItemList());
+  green_quad2->SetNew(top_right_green_shared_quad_state, green_rect2,
+                      green_rect2, needs_blending,
+                      gfx::RectF(gfx::SizeF(green_rect2.size())),
+                      green_rect2.size(), nearest_neighbor, green_rect2, 1.f,
+                      {}, green_raster_source->GetDisplayItemList());
 
   // Add a green clipped checkerboard in the bottom right to help test
   // interleaving picture quad content and solid color content.
@@ -4117,7 +4108,7 @@
   auto* blue_quad = pass->CreateAndAppendDrawQuad<PictureDrawQuad>();
   blue_quad->SetNew(blue_shared_state, quad_content_rect, quad_content_rect,
                     needs_blending, gfx::RectF(quad_content_rect),
-                    content_union_rect.size(), nearest_neighbor, texture_format,
+                    content_union_rect.size(), nearest_neighbor,
                     content_union_rect, contents_scale, {},
                     raster_source->GetDisplayItemList());
 
diff --git a/components/viz/service/display/software_renderer_unittest.cc b/components/viz/service/display/software_renderer_unittest.cc
index 486ffd3..52e5e293 100644
--- a/components/viz/service/display/software_renderer_unittest.cc
+++ b/components/viz/service/display/software_renderer_unittest.cc
@@ -81,8 +81,8 @@
 
   ResourceId AllocateAndFillSoftwareResource(const gfx::Size& size,
                                              const SkBitmap& source) {
-    base::MappedReadOnlyRegion shm =
-        bitmap_allocation::AllocateSharedBitmap(size, RGBA_8888);
+    base::MappedReadOnlyRegion shm = bitmap_allocation::AllocateSharedBitmap(
+        size, SinglePlaneFormat::kRGBA_8888);
     SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height());
     source.readPixels(info, shm.mapping.memory(), info.minRowBytes(), 0, 0);
 
diff --git a/components/viz/service/display_embedder/server_shared_bitmap_manager_unittest.cc b/components/viz/service/display_embedder/server_shared_bitmap_manager_unittest.cc
index ebfde64..fae2e46 100644
--- a/components/viz/service/display_embedder/server_shared_bitmap_manager_unittest.cc
+++ b/components/viz/service/display_embedder/server_shared_bitmap_manager_unittest.cc
@@ -35,8 +35,8 @@
 
 TEST_F(ServerSharedBitmapManagerTest, TestCreate) {
   gfx::Size bitmap_size(1, 1);
-  base::MappedReadOnlyRegion shm =
-      bitmap_allocation::AllocateSharedBitmap(bitmap_size, RGBA_8888);
+  base::MappedReadOnlyRegion shm = bitmap_allocation::AllocateSharedBitmap(
+      bitmap_size, SinglePlaneFormat::kRGBA_8888);
   EXPECT_TRUE(shm.IsValid());
   base::span<uint8_t> span = shm.mapping.GetMemoryAsSpan<uint8_t>();
   std::fill(span.begin(), span.end(), 0xff);
@@ -121,8 +121,8 @@
 
 TEST_F(ServerSharedBitmapManagerTest, AddDuplicate) {
   gfx::Size bitmap_size(1, 1);
-  base::MappedReadOnlyRegion shm =
-      bitmap_allocation::AllocateSharedBitmap(bitmap_size, RGBA_8888);
+  base::MappedReadOnlyRegion shm = bitmap_allocation::AllocateSharedBitmap(
+      bitmap_size, SinglePlaneFormat::kRGBA_8888);
   EXPECT_TRUE(shm.IsValid());
   base::span<uint8_t> span = shm.mapping.GetMemoryAsSpan<uint8_t>();
   std::fill(span.begin(), span.end(), 0xff);
@@ -131,8 +131,8 @@
   // NOTE: Duplicate the mapping to compare its content later.
   manager()->ChildAllocatedSharedBitmap(shm.region.Map(), id);
 
-  base::MappedReadOnlyRegion shm2 =
-      bitmap_allocation::AllocateSharedBitmap(bitmap_size, RGBA_8888);
+  base::MappedReadOnlyRegion shm2 = bitmap_allocation::AllocateSharedBitmap(
+      bitmap_size, SinglePlaneFormat::kRGBA_8888);
   EXPECT_TRUE(shm2.IsValid());
   base::span<uint8_t> span2 = shm.mapping.GetMemoryAsSpan<uint8_t>();
   std::fill(span2.begin(), span2.end(), 0x00);
@@ -148,8 +148,8 @@
 
 TEST_F(ServerSharedBitmapManagerTest, SharedMemoryHandle) {
   gfx::Size bitmap_size(1, 1);
-  base::MappedReadOnlyRegion shm =
-      bitmap_allocation::AllocateSharedBitmap(bitmap_size, RGBA_8888);
+  base::MappedReadOnlyRegion shm = bitmap_allocation::AllocateSharedBitmap(
+      bitmap_size, SinglePlaneFormat::kRGBA_8888);
   EXPECT_TRUE(shm.IsValid());
   base::span<uint8_t> span = shm.mapping.GetMemoryAsSpan<uint8_t>();
   std::fill(span.begin(), span.end(), 0xff);
diff --git a/content/app/android/content_jni_onload.cc b/content/app/android/content_jni_onload.cc
index 895cf44..0a9801d 100644
--- a/content/app/android/content_jni_onload.cc
+++ b/content/app/android/content_jni_onload.cc
@@ -9,9 +9,9 @@
 #include "base/android/base_jni_onload.h"
 #include "base/android/jni_android.h"
 #include "base/android/library_loader/library_loader_hooks.h"
-#include "base/i18n/icu_util.h"
-#include "base/trace_event/trace_event.h"
+#include "base/functional/bind.h"
 #include "content/app/android/library_loader_hooks.h"
+#include "content/public/app/content_main.h"
 
 namespace content {
 namespace android {
@@ -21,13 +21,6 @@
     return false;
 
   base::android::SetLibraryLoadedHook(&content::LibraryLoaded);
-
-#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
-  // Initialize ICU early so that it can be used by JNI calls before
-  // ContentMain() is called.
-  TRACE_EVENT0("startup", "InitializeICU");
-  CHECK(base::i18n::InitializeICU());
-#endif
   return true;
 }
 
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc
index 4e3ff63c..4ae1966c 100644
--- a/content/app/content_main_runner_impl.cc
+++ b/content/app/content_main_runner_impl.cc
@@ -956,10 +956,26 @@
 
   RegisterPathProvider();
 
-// On Android, InitializeICU() is called from content_jni_onload.cc
-// so that it is available before Content::main() is called.
-// https://crbug.com/1418738
-#if !BUILDFLAG(IS_ANDROID)
+#if BUILDFLAG(IS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
+  if (process_type.empty()) {
+    TRACE_EVENT0("startup", "InitializeICU");
+    // In browser process load ICU data files from disk.
+    if (!base::i18n::InitializeICU()) {
+      return TerminateForFatalInitializationError();
+    }
+  } else {
+    // In child process map ICU data files loaded by browser process.
+    int icu_data_fd = g_fds->MaybeGet(kAndroidICUDataDescriptor);
+    if (icu_data_fd == -1) {
+      return TerminateForFatalInitializationError();
+    }
+    auto icu_data_region = g_fds->GetRegion(kAndroidICUDataDescriptor);
+    if (!base::i18n::InitializeICUWithFileDescriptor(icu_data_fd,
+                                                     icu_data_region)) {
+      return TerminateForFatalInitializationError();
+    }
+  }
+#else
   if (!base::i18n::InitializeICU())
     return TerminateForFatalInitializationError();
 #endif  // BUILDFLAG(IS_ANDROID) && (ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE)
diff --git a/content/browser/child_process_launcher_helper_android.cc b/content/browser/child_process_launcher_helper_android.cc
index 0a5bf246..64e05bfc 100644
--- a/content/browser/child_process_launcher_helper_android.cc
+++ b/content/browser/child_process_launcher_helper_android.cc
@@ -68,6 +68,12 @@
           child_process_id(), mojo_channel_->remote_endpoint(),
           file_data_->files_to_preload, GetProcessType(), command_line());
 
+#if ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
+  base::MemoryMappedFile::Region icu_region;
+  int fd = base::i18n::GetIcuDataFileHandle(&icu_region);
+  files_to_register->ShareWithRegion(kAndroidICUDataDescriptor, fd, icu_region);
+#endif  // ICU_UTIL_DATA_IMPL == ICU_UTIL_DATA_FILE
+
   return files_to_register;
 }
 
diff --git a/content/browser/first_party_sets/database/first_party_sets_database.cc b/content/browser/first_party_sets/database/first_party_sets_database.cc
index 78a87a9..a360af0 100644
--- a/content/browser/first_party_sets/database/first_party_sets_database.cc
+++ b/content/browser/first_party_sets/database/first_party_sets_database.cc
@@ -14,7 +14,6 @@
 #include "base/check.h"
 #include "base/check_op.h"
 #include "base/files/file_path.h"
-#include "base/files/file_util.h"
 #include "base/logging.h"
 #include "base/metrics/histogram_functions.h"
 #include "base/sequence_checker.h"
@@ -908,7 +907,7 @@
   if (db_path_.empty())
     return true;
 
-  return base::DeleteFile(db_path_);
+  return sql::Database::Delete(db_path_);
 }
 
 }  // namespace content
diff --git a/content/browser/renderer_host/input/fling_browsertest.cc b/content/browser/renderer_host/input/fling_browsertest.cc
index d4f59aa..48178268 100644
--- a/content/browser/renderer_host/input/fling_browsertest.cc
+++ b/content/browser/renderer_host/input/fling_browsertest.cc
@@ -485,8 +485,10 @@
 
 // Checks that the fling controller of the oopif stops the fling when the
 // bubbled inertial GSUs are not consumed by the parent's renderer.
-IN_PROC_BROWSER_TEST_F(BrowserSideFlingBrowserTest,
-                       DISABLE_InertialGSUBubblingStopsWhenParentCannotScroll) {
+// Flaky test https://crbug.com/1344075
+IN_PROC_BROWSER_TEST_F(
+    BrowserSideFlingBrowserTest,
+    DISABLED_InertialGSUBubblingStopsWhenParentCannotScroll) {
   LoadPageWithOOPIF();
   // Scroll the parent down so that it is scrollable upward.
 
diff --git a/content/browser/renderer_host/render_widget_host_input_event_router.h b/content/browser/renderer_host/render_widget_host_input_event_router.h
index 4802f5e..a731557 100644
--- a/content/browser/renderer_host/render_widget_host_input_event_router.h
+++ b/content/browser/renderer_host/render_widget_host_input_event_router.h
@@ -203,7 +203,7 @@
  private:
   FRIEND_TEST_ALL_PREFIXES(
       BrowserSideFlingBrowserTest,
-      DISABLE_InertialGSUBubblingStopsWhenParentCannotScroll);
+      DISABLED_InertialGSUBubblingStopsWhenParentCannotScroll);
 
   using FrameSinkIdOwnerMap =
       std::unordered_map<viz::FrameSinkId,
diff --git a/content/browser/site_per_process_sad_frame_browsertest.cc b/content/browser/site_per_process_sad_frame_browsertest.cc
index f4c76f3..18c8335d 100644
--- a/content/browser/site_per_process_sad_frame_browsertest.cc
+++ b/content/browser/site_per_process_sad_frame_browsertest.cc
@@ -504,7 +504,7 @@
 // scrolled out of view.
 IN_PROC_BROWSER_TEST_P(SitePerProcessBrowserTestWithSadFrameTabReload,
                        // TODO(crbug.com/1370766): Re-enable this test
-                       DISABLE_ReloadHiddenTabWithCrashedSubframeOutOfView) {
+                       DISABLED_ReloadHiddenTabWithCrashedSubframeOutOfView) {
   // Set WebContents to VISIBLE to avoid hitting the |!did_first_set_visible_|
   // case when we hide it later.
   web_contents()->UpdateWebContentsVisibility(Visibility::VISIBLE);
diff --git a/content/browser/smart_card/mock_smart_card_context_factory.h b/content/browser/smart_card/mock_smart_card_context_factory.h
index e9f474e..e27e6eb4 100644
--- a/content/browser/smart_card/mock_smart_card_context_factory.h
+++ b/content/browser/smart_card/mock_smart_card_context_factory.h
@@ -32,6 +32,7 @@
        std::vector<device::mojom::SmartCardReaderStateInPtr> reader_states,
        GetStatusChangeCallback callback),
       (override));
+  MOCK_METHOD(void, Cancel, (CancelCallback callback), (override));
   MOCK_METHOD(void,
               Connect,
               (const std::string& reader,
diff --git a/content/public/common/content_descriptors.h b/content/public/common/content_descriptors.h
index 4ecb004..9a3d192 100644
--- a/content/public/common/content_descriptors.h
+++ b/content/public/common/content_descriptors.h
@@ -17,6 +17,7 @@
 
 #if BUILDFLAG(IS_ANDROID)
   kAndroidPropertyDescriptor,
+  kAndroidICUDataDescriptor,
 #endif
 
   // Reserves 100 to 199 for dynamically generated IDs.
diff --git a/content/public/common/network_service_util.cc b/content/public/common/network_service_util.cc
index 69d84f6..0c8c108 100644
--- a/content/public/common/network_service_util.cc
+++ b/content/public/common/network_service_util.cc
@@ -41,19 +41,22 @@
 }
 
 bool IsInProcessNetworkService() {
+#if BUILDFLAG(IS_ANDROID)
+  // Check RAM size before looking at kNetworkServiceInProcess flag
+  // so that we can throttle the finch groups including control.
+  if (base::SysInfo::AmountOfPhysicalMemoryMB() <=
+      kNetworkServiceOutOfProcessThresholdMb.Get()) {
+    return true;
+  }
+#endif
+
   if (g_force_in_process_network_service ||
       base::FeatureList::IsEnabled(features::kNetworkServiceInProcess) ||
       base::CommandLine::ForCurrentProcess()->HasSwitch(
           switches::kSingleProcess)) {
     return true;
   }
-
-#if BUILDFLAG(IS_ANDROID)
-  return base::SysInfo::AmountOfPhysicalMemoryMB() <=
-         kNetworkServiceOutOfProcessThresholdMb.Get();
-#else
   return false;
-#endif
 }
 
 void ForceInProcessNetworkService(bool is_forced) {
diff --git a/extensions/browser/browsertest_util.cc b/extensions/browser/browsertest_util.cc
index 107b6c0..c94d840b 100644
--- a/extensions/browser/browsertest_util.cc
+++ b/extensions/browser/browsertest_util.cc
@@ -4,6 +4,7 @@
 
 #include "extensions/browser/browsertest_util.h"
 
+#include "base/values.h"
 #include "content/public/browser/browser_context.h"
 #include "content/public/browser/service_worker_context.h"
 #include "content/public/browser/storage_partition.h"
@@ -28,7 +29,30 @@
 
 }  // namespace
 
-std::string ExecuteScriptInBackgroundPage(
+base::Value ExecuteScriptInBackgroundPage(
+    content::BrowserContext* context,
+    const std::string& extension_id,
+    const std::string& script,
+    ScriptUserActivation script_user_activation) {
+  BackgroundScriptExecutor script_executor(context);
+  base::Value value = script_executor.ExecuteScript(
+      extension_id, script,
+      BackgroundScriptExecutor::ResultCapture::kSendScriptResult,
+      script_user_activation);
+  if (value.is_none()) {
+    ADD_FAILURE() << "Bad return value. Script: " << GetScriptToLog(script);
+  }
+  return value;
+}
+
+bool ExecuteScriptInBackgroundPageNoWait(content::BrowserContext* context,
+                                         const std::string& extension_id,
+                                         const std::string& script) {
+  return BackgroundScriptExecutor::ExecuteScriptAsync(
+      context, extension_id, script, ScriptUserActivation::kActivate);
+}
+
+std::string ExecuteScriptInBackgroundPageDeprecated(
     content::BrowserContext* context,
     const std::string& extension_id,
     const std::string& script,
@@ -49,13 +73,6 @@
   return value.GetString();
 }
 
-bool ExecuteScriptInBackgroundPageNoWait(content::BrowserContext* context,
-                                         const std::string& extension_id,
-                                         const std::string& script) {
-  return BackgroundScriptExecutor::ExecuteScriptAsync(
-      context, extension_id, script, ScriptUserActivation::kActivate);
-}
-
 void StopServiceWorkerForExtensionGlobalScope(content::BrowserContext* context,
                                               const std::string& extension_id) {
   const Extension* extension =
diff --git a/extensions/browser/browsertest_util.h b/extensions/browser/browsertest_util.h
index c3ac2e1..edcb7b5b 100644
--- a/extensions/browser/browsertest_util.h
+++ b/extensions/browser/browsertest_util.h
@@ -9,6 +9,10 @@
 
 #include "content/public/test/browser_test_utils.h"
 
+namespace base {
+class Value;
+}  // namespace base
+
 namespace content {
 class BrowserContext;
 }  // namespace content
@@ -22,13 +26,13 @@
   kDontActivate,
 };
 
-// Waits until |script| calls "window.domAutomationController.send(result)",
-// where |result| is a string, and returns |result|. Fails the test and returns
-// an empty string if |extension_id| isn't installed in |context| or doesn't
-// have a background page, or if executing the script fails. The argument
-// |script_user_activation| determines if the script should be executed after a
-// user activation.
-std::string ExecuteScriptInBackgroundPage(
+// Waits until |script| calls "chrome.test.sendScriptResult(result)",
+// where |result| is a serializable value, and returns |result|. Fails
+// the test and returns an empty base::Value if |extension_id| isn't
+// installed in |context| or doesn't have a background page, or if
+// executing the script fails. The argument |script_user_activation|
+// determines if the script should be executed after a user activation.
+base::Value ExecuteScriptInBackgroundPage(
     content::BrowserContext* context,
     const std::string& extension_id,
     const std::string& script,
@@ -43,6 +47,19 @@
                                          const std::string& extension_id,
                                          const std::string& script);
 
+// Waits until |script| calls "window.domAutomationController.send(result)",
+// where |result| is a string, and returns |result|. Fails the test and returns
+// an empty string if |extension_id| isn't installed in |context| or doesn't
+// have a background page, or if executing the script fails. The argument
+// |script_user_activation| determines if the script should be executed after a
+// user activation.
+std::string ExecuteScriptInBackgroundPageDeprecated(
+    content::BrowserContext* context,
+    const std::string& extension_id,
+    const std::string& script,
+    ScriptUserActivation script_user_activation =
+        ScriptUserActivation::kActivate);
+
 // Synchronously stops the service worker registered by the extension with the
 // given `extension_id` at global scope. The extension must be installed and
 // enabled.
diff --git a/extensions/browser/browsertest_util_browsertest.cc b/extensions/browser/browsertest_util_browsertest.cc
index 98a9c3e8a..5e536bc9 100644
--- a/extensions/browser/browsertest_util_browsertest.cc
+++ b/extensions/browser/browsertest_util_browsertest.cc
@@ -54,22 +54,47 @@
   EXPECT_EQ(extension()->id(),
             ExecuteScriptInBackgroundPage(
                 browser_context(), extension()->id(),
-                "window.domAutomationController.send(chrome.runtime.id);"));
+                "chrome.test.sendScriptResult(chrome.runtime.id);"));
 
-  // Check that executing a script doesn't block the browser process.
-  EXPECT_EQ(std::string("/") + extensions::kGeneratedBackgroundPageFilename,
+  // Tests a successful test injection, including running nested tasks in the
+  // browser process (via an asynchronous extension API).
+  EXPECT_EQ("success",
             ExecuteScriptInBackgroundPage(
                 browser_context(), extension()->id(),
-                "chrome.runtime.getBackgroundPage(function(result) {\n"
-                "  let url = new URL(result.location.href);\n"
-                "  window.domAutomationController.send(url.pathname);\n"
-                "});"));
+                R"(chrome.runtime.setUninstallURL('http://example.com',
+                                                  function() {
+                     chrome.test.sendScriptResult('success');
+                   });)"));
+
+  // Return a non-string argument.
+  EXPECT_EQ(3,
+            ExecuteScriptInBackgroundPage(browser_context(), extension()->id(),
+                                          "chrome.test.sendScriptResult(3);")
+                .GetInt());
+}
+
+IN_PROC_BROWSER_TEST_F(ExtensionBrowsertestUtilTest,
+                       ExecuteScriptInBackgroundPageDeprecated) {
+  EXPECT_EQ(extension()->id(),
+            ExecuteScriptInBackgroundPageDeprecated(
+                browser_context(), extension()->id(),
+                "window.domAutomationController.send(chrome.runtime.id);"));
+
+  // Tests a successful test injection, including running nested tasks in the
+  // browser process (via an asynchronous extension API).
+  EXPECT_EQ(std::string("/") + extensions::kGeneratedBackgroundPageFilename,
+            ExecuteScriptInBackgroundPageDeprecated(
+                browser_context(), extension()->id(),
+                R"(chrome.runtime.getBackgroundPage(function(result) {
+                     let url = new URL(result.location.href);
+                     window.domAutomationController.send(url.pathname);
+                   });)"));
 
   // An argument that isn't a string should cause a failure, not a hang.
-  EXPECT_NONFATAL_FAILURE(
-      ExecuteScriptInBackgroundPage(browser_context(), extension()->id(),
-                                    "window.domAutomationController.send(3);"),
-      "send(3)");
+  EXPECT_NONFATAL_FAILURE(ExecuteScriptInBackgroundPageDeprecated(
+                              browser_context(), extension()->id(),
+                              "window.domAutomationController.send(3);"),
+                          "send(3)");
 }
 
 IN_PROC_BROWSER_TEST_F(ExtensionBrowsertestUtilTest,
diff --git a/extensions/browser/extension_event_histogram_value.h b/extensions/browser/extension_event_histogram_value.h
index b33c659c..62504ac 100644
--- a/extensions/browser/extension_event_histogram_value.h
+++ b/extensions/browser/extension_event_histogram_value.h
@@ -526,6 +526,7 @@
   PDF_VIEWER_PRIVATE_ON_PDF_OCR_PREF_CHANGED = 504,
   SMART_CARD_PROVIDER_PRIVATE_ON_CONNECT_REQUESTED = 505,
   SMART_CARD_PROVIDER_PRIVATE_ON_DISCONNECT_REQUESTED = 506,
+  SMART_CARD_PROVIDER_PRIVATE_ON_CANCEL_REQUESTED = 507,
   // Last entry: Add new entries above, then run:
   // tools/metrics/histograms/update_extension_histograms.py
   ENUM_BOUNDARY
diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h
index 96ae103..a455a73 100644
--- a/extensions/browser/extension_function_histogram_value.h
+++ b/extensions/browser/extension_function_histogram_value.h
@@ -1836,6 +1836,7 @@
   POWER_REPORTACTIVITY = 1773,
   PASSWORDSPRIVATE_CONTINUEIMPORT = 1774,
   PASSWORDSPRIVATE_RESETIMPORTER = 1775,
+  SMARTCARDPROVIDERPRIVATE_REPORTCANCELRESULT = 1776,
   // Last entry: Add new entries above, then run:
   // tools/metrics/histograms/update_extension_histograms.py
   ENUM_BOUNDARY
diff --git a/extensions/common/mojom/api_permission_id.mojom b/extensions/common/mojom/api_permission_id.mojom
index 80da98e..59a9524d 100644
--- a/extensions/common/mojom/api_permission_id.mojom
+++ b/extensions/common/mojom/api_permission_id.mojom
@@ -272,6 +272,7 @@
   kPdfViewerPrivate = 245,
   kSystemLog = 246,
   kSmartCardProviderPrivate = 247,
+  kChromeOSEvents = 248,
 
   // Add new entries at the end of the enum and be sure to update the
   // "ExtensionPermission3" enum in tools/metrics/histograms/enums.xml
diff --git a/ios/chrome/browser/autofill/BUILD.gn b/ios/chrome/browser/autofill/BUILD.gn
index d91635ca2..70bd286 100644
--- a/ios/chrome/browser/autofill/BUILD.gn
+++ b/ios/chrome/browser/autofill/BUILD.gn
@@ -58,6 +58,7 @@
     "//ios/chrome/browser/paths",
     "//ios/chrome/browser/shared/ui/util:util_swift",
     "//ios/chrome/browser/signin",
+    "//ios/chrome/browser/sync",
     "//ios/chrome/browser/ui/image_util",
     "//ios/chrome/browser/webdata_services",
     "//ios/web/common",
diff --git a/ios/chrome/browser/autofill/autofill_controller_unittest.mm b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
index fcd4ef84..535f4b1b 100644
--- a/ios/chrome/browser/autofill/autofill_controller_unittest.mm
+++ b/ios/chrome/browser/autofill/autofill_controller_unittest.mm
@@ -574,7 +574,7 @@
   PersonalDataManager* personal_data_manager =
       PersonalDataManagerFactory::GetForBrowserState(
           ChromeBrowserState::FromBrowserState(browser_state_.get()));
-  personal_data_manager->OnSyncServiceInitialized(nullptr);
+  personal_data_manager->SetSyncServiceForTest(nullptr);
   PersonalDataManagerFinishedProfileTasksWaiter waiter(personal_data_manager);
 
   AutofillProfile profile(base::GenerateGUID(), "https://www.example.com/");
@@ -768,7 +768,7 @@
   PersonalDataManager* personal_data_manager =
       PersonalDataManagerFactory::GetForBrowserState(
           ChromeBrowserState::FromBrowserState(browser_state_.get()));
-  personal_data_manager->OnSyncServiceInitialized(nullptr);
+  personal_data_manager->SetSyncServiceForTest(nullptr);
 
   // Check there are no registered profiles already.
   EXPECT_EQ(0U, personal_data_manager->GetCreditCards().size());
diff --git a/ios/chrome/browser/autofill/personal_data_manager_factory.mm b/ios/chrome/browser/autofill/personal_data_manager_factory.mm
index 819075f..b139c05 100644
--- a/ios/chrome/browser/autofill/personal_data_manager_factory.mm
+++ b/ios/chrome/browser/autofill/personal_data_manager_factory.mm
@@ -20,6 +20,7 @@
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/history/history_service_factory.h"
 #import "ios/chrome/browser/signin/identity_manager_factory.h"
+#import "ios/chrome/browser/sync/sync_service_factory.h"
 #import "ios/chrome/browser/webdata_services/web_data_service_factory.h"
 
 #if !defined(__has_feature) || !__has_feature(objc_arc)
@@ -62,6 +63,7 @@
   DependsOn(IdentityManagerFactory::GetInstance());
   DependsOn(ios::HistoryServiceFactory::GetInstance());
   DependsOn(ios::WebDataServiceFactory::GetInstance());
+  DependsOn(SyncServiceFactory::GetInstance());
 }
 
 PersonalDataManagerFactory::~PersonalDataManagerFactory() = default;
@@ -84,16 +86,15 @@
       chrome_browser_state, ServiceAccessType::EXPLICIT_ACCESS);
   auto* strike_database =
       StrikeDatabaseFactory::GetForBrowserState(chrome_browser_state);
+  auto* sync_service =
+      SyncServiceFactory::GetForBrowserState(chrome_browser_state);
 
   service->Init(
       local_storage, account_storage, chrome_browser_state->GetPrefs(),
       GetApplicationContext()->GetLocalState(),
       IdentityManagerFactory::GetForBrowserState(chrome_browser_state),
-      history_service, strike_database, /*image_fetcher=*/nullptr,
-      chrome_browser_state->IsOffTheRecord());
-
-  if (!syncer::IsSyncAllowedByFlag())
-    service->OnSyncServiceInitialized(nullptr);
+      history_service, sync_service, strike_database,
+      /*image_fetcher=*/nullptr, chrome_browser_state->IsOffTheRecord());
 
   return service;
 }
diff --git a/ios/chrome/browser/shared/coordinator/alert/BUILD.gn b/ios/chrome/browser/shared/coordinator/alert/BUILD.gn
new file mode 100644
index 0000000..82c0e60
--- /dev/null
+++ b/ios/chrome/browser/shared/coordinator/alert/BUILD.gn
@@ -0,0 +1,9 @@
+# Copyright 2016 The Chromium Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+source_set("alert") {
+  configs += [ "//build/config/compiler:enable_arc" ]
+  sources = [ "alert_coordinator.h" ]
+  deps = [ "//ios/chrome/browser/ui/alert_coordinator" ]
+}
diff --git a/ios/chrome/browser/shared/coordinator/alert/alert_coordinator.h b/ios/chrome/browser/shared/coordinator/alert/alert_coordinator.h
new file mode 100644
index 0000000..225e884
--- /dev/null
+++ b/ios/chrome/browser/shared/coordinator/alert/alert_coordinator.h
@@ -0,0 +1,11 @@
+// Copyright 2016 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_CHROME_BROWSER_SHARED_COORDINATOR_ALERT_ALERT_COORDINATOR_H_
+#define IOS_CHROME_BROWSER_SHARED_COORDINATOR_ALERT_ALERT_COORDINATOR_H_
+
+// Temporary include.
+#import "ios/chrome/browser/ui/alert_coordinator/alert_coordinator.h"
+
+#endif  // IOS_CHROME_BROWSER_SHARED_COORDINATOR_ALERT_ALERT_COORDINATOR_H_
diff --git a/ios/chrome/browser/signin/constants.h b/ios/chrome/browser/signin/constants.h
index 765044a..0df2ffb 100644
--- a/ios/chrome/browser/signin/constants.h
+++ b/ios/chrome/browser/signin/constants.h
@@ -34,6 +34,8 @@
 enum class PostSignInAction {
   // No post action after sign-in.
   kNone,
+  // Enables bookmark and reading list account storage.
+  kEnableBookmarkReadingListAccountStorage,
   // Starts sign-in flow for a sync consent.
   // The owner of `AuthenticationFlow` still needs to:
   //  * Record the sync dialog strings.
diff --git a/ios/chrome/browser/sync/BUILD.gn b/ios/chrome/browser/sync/BUILD.gn
index 8392c28..95a291b 100644
--- a/ios/chrome/browser/sync/BUILD.gn
+++ b/ios/chrome/browser/sync/BUILD.gn
@@ -60,7 +60,6 @@
     "//components/version_info",
     "//google_apis",
     "//ios/chrome/browser/application_context",
-    "//ios/chrome/browser/autofill",
     "//ios/chrome/browser/bookmarks",
     "//ios/chrome/browser/browser_state",
     "//ios/chrome/browser/complex_tasks",
diff --git a/ios/chrome/browser/sync/sync_service_factory.mm b/ios/chrome/browser/sync/sync_service_factory.mm
index c160bc7..5232b13b 100644
--- a/ios/chrome/browser/sync/sync_service_factory.mm
+++ b/ios/chrome/browser/sync/sync_service_factory.mm
@@ -17,7 +17,6 @@
 #import "components/sync/driver/sync_service.h"
 #import "components/sync/driver/sync_service_impl.h"
 #import "ios/chrome/browser/application_context/application_context.h"
-#import "ios/chrome/browser/autofill/personal_data_manager_factory.h"
 #import "ios/chrome/browser/bookmarks/account_bookmark_model_factory.h"
 #import "ios/chrome/browser/bookmarks/account_bookmark_sync_service_factory.h"
 #import "ios/chrome/browser/bookmarks/local_or_syncable_bookmark_model_factory.h"
@@ -94,7 +93,6 @@
   // The SyncService depends on various SyncableServices being around
   // when it is shut down.  Specify those dependencies here to build the proper
   // destruction order.
-  DependsOn(autofill::PersonalDataManagerFactory::GetInstance());
   DependsOn(ChromeAccountManagerServiceFactory::GetInstance());
   DependsOn(ConsentAuditorFactory::GetInstance());
   DependsOn(DeviceInfoSyncServiceFactory::GetInstance());
@@ -157,10 +155,5 @@
       std::make_unique<syncer::SyncServiceImpl>(std::move(init_params));
   sync_service->Initialize();
 
-  // Hook `sync_service` into PersonalDataManager (a circular dependency).
-  autofill::PersonalDataManager* pdm =
-      autofill::PersonalDataManagerFactory::GetForBrowserState(browser_state);
-  pdm->OnSyncServiceInitialized(sync_service.get());
-
   return sync_service;
 }
diff --git a/ios/chrome/browser/ui/authentication/BUILD.gn b/ios/chrome/browser/ui/authentication/BUILD.gn
index ba923c7..20c9aa1 100644
--- a/ios/chrome/browser/ui/authentication/BUILD.gn
+++ b/ios/chrome/browser/ui/authentication/BUILD.gn
@@ -29,6 +29,7 @@
     "resources:signin_confirmation_more",
     "resources:signin_promo_close_gray",
     "unified_consent",
+    "//components/bookmarks/common",
     "//components/consent_auditor",
     "//components/infobars/core",
     "//components/policy/core/common",
diff --git a/ios/chrome/browser/ui/authentication/authentication_flow.mm b/ios/chrome/browser/ui/authentication/authentication_flow.mm
index 69e39b0b..760d4552 100644
--- a/ios/chrome/browser/ui/authentication/authentication_flow.mm
+++ b/ios/chrome/browser/ui/authentication/authentication_flow.mm
@@ -8,6 +8,7 @@
 #import "base/check_op.h"
 #import "base/ios/block_types.h"
 #import "base/notreached.h"
+#import "components/bookmarks/common/bookmark_features.h"
 #import "ios/chrome/browser/application_context/application_context.h"
 #import "ios/chrome/browser/browser_state/chrome_browser_state.h"
 #import "ios/chrome/browser/main/browser.h"
@@ -44,6 +45,7 @@
   CLEAR_DATA,
   SIGN_IN,
   COMMIT_SYNC,
+  ENABLE_BOOKMARK_READING_LIST_ACCOUNT_STORAGE,
   REGISTER_FOR_USER_POLICY,
   FETCH_USER_POLICY,
   COMPLETE_WITH_SUCCESS,
@@ -192,6 +194,7 @@
     case CLEAR_DATA:
     case SIGN_IN:
     case COMMIT_SYNC:
+    case ENABLE_BOOKMARK_READING_LIST_ACCOUNT_STORAGE:
     case REGISTER_FOR_USER_POLICY:
     case FETCH_USER_POLICY:
       return COMPLETE_WITH_FAILURE;
@@ -247,6 +250,8 @@
       switch (self.postSignInAction) {
         case PostSignInAction::kCommitSync:
           return COMMIT_SYNC;
+        case PostSignInAction::kEnableBookmarkReadingListAccountStorage:
+          return ENABLE_BOOKMARK_READING_LIST_ACCOUNT_STORAGE;
         case PostSignInAction::kNone:
           return COMPLETE_WITH_SUCCESS;
       }
@@ -254,6 +259,8 @@
       if (policy::IsUserPolicyEnabled() && _shouldFetchUserPolicy)
         return REGISTER_FOR_USER_POLICY;
       return COMPLETE_WITH_SUCCESS;
+    case ENABLE_BOOKMARK_READING_LIST_ACCOUNT_STORAGE:
+      return COMPLETE_WITH_SUCCESS;
     case REGISTER_FOR_USER_POLICY:
       if (!_dmToken.length || !_clientID.length) {
         // Skip fetching user policies when registration failed.
@@ -332,6 +339,10 @@
       [self continueSignin];
       return;
 
+    case ENABLE_BOOKMARK_READING_LIST_ACCOUNT_STORAGE:
+      [self optInBookmarkReadingListAccountStorage];
+      return;
+
     case REGISTER_FOR_USER_POLICY:
       [_performer registerUserPolicy:browserState
                          forIdentity:_identityToSignIn];
@@ -383,6 +394,7 @@
     case PostSignInAction::kCommitSync:
       [self checkMergeCaseForUnsupervisedAccounts];
       break;
+    case PostSignInAction::kEnableBookmarkReadingListAccountStorage:
     case PostSignInAction::kNone:
       [self continueSignin];
       break;
@@ -503,6 +515,16 @@
                               browser:_browser];
 }
 
+// Opts in the bookmark and reading list account storage and continues the
+// sign-in flow.
+- (void)optInBookmarkReadingListAccountStorage {
+  DCHECK(
+      base::FeatureList::IsEnabled(bookmarks::kEnableBookmarksAccountStorage));
+  // TODO(crbug.com/1427044): Need to call the right APIs to opt in, as soon as
+  // those APIs will be implemented.
+  [self continueSignin];
+}
+
 #pragma mark AuthenticationFlowPerformerDelegate
 
 - (void)didSignOut {
diff --git a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm
index 4a2bd92..000ad15 100644
--- a/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm
+++ b/ios/chrome/browser/ui/authentication/signin/consistency_promo_signin/consistency_default_account/consistency_default_account_view_controller.mm
@@ -42,7 +42,7 @@
 @property(nonatomic, strong) IdentityButtonControl* identityButtonControl;
 // Button to
 // 1. confirm the default identity and sign-in when an account is available, or
-// 2. add an account when no account is available on the device
+// 2. add an account when no account is available on the device.
 @property(nonatomic, strong) UIButton* primaryButton;
 // Title for `self.primaryButton` when it needs to show the text "Continue as…".
 // This property is needed to hide the title the activity indicator is shown.
@@ -84,6 +84,8 @@
   DCHECK(self.activityIndicatorView);
   [self.activityIndicatorView removeFromSuperview];
   self.activityIndicatorView = nil;
+  // Show the IdentityButtonControl, since it may be hidden.
+  self.identityButtonControl.hidden = NO;
   // Enable buttons.
   self.identityButtonControl.enabled = YES;
   self.primaryButton.enabled = YES;
@@ -203,7 +205,7 @@
     [self.identityButtonControl.widthAnchor
         constraintEqualToAnchor:self.contentView.widthAnchor]
   ]];
-  // Add the primary button (the "Continue as"/"Sign in" button)
+  // Add the primary button (the "Continue as"/"Sign in" button).
   self.primaryButton =
       PrimaryActionButton(/* pointer_interaction_enabled */ YES);
   self.primaryButton.accessibilityIdentifier =
@@ -242,7 +244,8 @@
 
 - (void)primaryButtonAction:
     (ConsistencyDefaultAccountViewController*)viewController {
-  // if the IBC is hidden, then there is no account avaiable on the device
+  // If the IdentityButtonControl is hidden, there is no account avaiable on the
+  // device.
   if (!self.identityButtonControl.hidden) {
     [self.actionDelegate
         consistencyDefaultAccountViewControllerContinueWithSelectedIdentity:
@@ -291,12 +294,16 @@
   }
   self.continueAsTitle = l10n_util::GetNSStringF(
       IDS_IOS_SIGNIN_PROMO_CONTINUE_AS, base::SysNSStringToUTF16(givenName));
-  [self.primaryButton setTitle:self.continueAsTitle
-                      forState:UIControlStateNormal];
+
   [self.identityButtonControl setIdentityName:fullName email:email];
   [self.identityButtonControl setIdentityAvatar:avatar];
 
-  self.identityButtonControl.hidden = NO;
+  // If spinner is active, delay UI updates until stopSpinner() is called.
+  if (!self.activityIndicatorView) {
+    [self.primaryButton setTitle:self.continueAsTitle
+                        forState:UIControlStateNormal];
+    self.identityButtonControl.hidden = NO;
+  }
 }
 
 - (void)hideDefaultAccount {
@@ -304,8 +311,8 @@
     [self view];
   }
 
-  // hide the IdentityButtonControl, and update the primary button to serve as
-  // a "Sign in…" button
+  // Hide the IdentityButtonControl, and update the primary button to serve as
+  // a "Sign in…" button.
   self.identityButtonControl.hidden = YES;
   [self.primaryButton
       setTitle:l10n_util::GetNSString(IDS_IOS_CONSISTENCY_PROMO_SIGN_IN)
diff --git a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
index 197dacbb7..1561026 100644
--- a/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
+++ b/ios/chrome/browser/ui/authentication/signin_promo_view_mediator.mm
@@ -875,11 +875,12 @@
 // Starts the sign-in only flow.
 - (void)startSignInOnlyFlow {
   signin_metrics::RecordSigninUserActionForAccessPoint(self.accessPoint);
-  _authenticationFlow =
-      [[AuthenticationFlow alloc] initWithBrowser:_browser
-                                         identity:self.identity
-                                 postSignInAction:PostSignInAction::kNone
-                         presentingViewController:_baseViewController];
+  _authenticationFlow = [[AuthenticationFlow alloc]
+               initWithBrowser:_browser
+                      identity:self.identity
+              postSignInAction:PostSignInAction::
+                                   kEnableBookmarkReadingListAccountStorage
+      presentingViewController:_baseViewController];
   __weak id<SigninPromoViewConsumer> weakConsumer = self.consumer;
   [_authenticationFlow startSignInWithCompletion:^(BOOL success) {
     if ([weakConsumer respondsToSelector:@selector(signinDidFinish)]) {
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 29cdf13..b8e6f37d 100644
--- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
+++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -2613,35 +2613,23 @@
 }
 
 #pragma mark - OverscrollActionsControllerDelegate methods.
-// TODO(crbug.com/1272486) : Separate action handling for overscroll from UI
-// management.
 
-- (void)overscrollActionsController:(OverscrollActionsController*)controller
-                   didTriggerAction:(OverscrollAction)action {
-  switch (action) {
-    case OverscrollAction::NEW_TAB:
-      base::RecordAction(base::UserMetricsAction("MobilePullGestureNewTab"));
-      [self.applicationCommandsHandler
-          openURLInNewTab:[OpenNewTabCommand
-                              commandWithIncognito:_isOffTheRecord]];
-      break;
-    case OverscrollAction::CLOSE_TAB:
-      base::RecordAction(base::UserMetricsAction("MobilePullGestureCloseTab"));
-      [self.browserCoordinatorCommandsHandler closeCurrentTab];
-      break;
-    case OverscrollAction::REFRESH:
-      base::RecordAction(base::UserMetricsAction("MobilePullGestureReload"));
-      // Instruct the SnapshotTabHelper to ignore the next load event.
-      // Attempting to snapshot while the overscroll "bounce back" animation is
-      // occurring will cut the animation short.
-      DCHECK(self.currentWebState);
-      SnapshotTabHelper::FromWebState(self.currentWebState)->IgnoreNextLoad();
-      _webNavigationBrowserAgent->Reload();
-      break;
-    case OverscrollAction::NONE:
-      NOTREACHED();
-      break;
-  }
+- (void)overscrollActionNewTab:(OverscrollActionsController*)controller {
+  [self.applicationCommandsHandler
+      openURLInNewTab:[OpenNewTabCommand commandWithIncognito:_isOffTheRecord]];
+}
+
+- (void)overscrollActionCloseTab:(OverscrollActionsController*)controller {
+  [self.browserCoordinatorCommandsHandler closeCurrentTab];
+}
+
+- (void)overscrollActionRefresh:(OverscrollActionsController*)controller {
+  // Instruct the SnapshotTabHelper to ignore the next load event.
+  // Attempting to snapshot while the overscroll "bounce back" animation is
+  // occurring will cut the animation short.
+  DCHECK(self.currentWebState);
+  SnapshotTabHelper::FromWebState(self.currentWebState)->IgnoreNextLoad();
+  _webNavigationBrowserAgent->Reload();
 }
 
 - (BOOL)shouldAllowOverscrollActionsForOverscrollActionsController:
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
index 2572ccd6..e132629 100644
--- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
+++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator.mm
@@ -1218,29 +1218,21 @@
 
 #pragma mark - OverscrollActionsControllerDelegate
 
-- (void)overscrollActionsController:(OverscrollActionsController*)controller
-                   didTriggerAction:(OverscrollAction)action {
+- (void)overscrollActionNewTab:(OverscrollActionsController*)controller {
   id<ApplicationCommands> applicationCommandsHandler = HandlerForProtocol(
       self.browser->GetCommandDispatcher(), ApplicationCommands);
+  [applicationCommandsHandler openURLInNewTab:[OpenNewTabCommand command]];
+}
+
+- (void)overscrollActionCloseTab:(OverscrollActionsController*)controller {
   id<BrowserCoordinatorCommands> browserCoordinatorCommandsHandler =
       HandlerForProtocol(self.browser->GetCommandDispatcher(),
                          BrowserCoordinatorCommands);
+  [browserCoordinatorCommandsHandler closeCurrentTab];
+}
 
-  switch (action) {
-    case OverscrollAction::NEW_TAB: {
-      [applicationCommandsHandler openURLInNewTab:[OpenNewTabCommand command]];
-    } break;
-    case OverscrollAction::CLOSE_TAB: {
-      [browserCoordinatorCommandsHandler closeCurrentTab];
-      base::RecordAction(base::UserMetricsAction("OverscrollActionCloseTab"));
-    } break;
-    case OverscrollAction::REFRESH:
-      [self reload];
-      break;
-    case OverscrollAction::NONE:
-      NOTREACHED();
-      break;
-  }
+- (void)overscrollActionRefresh:(OverscrollActionsController*)controller {
+  [self reload];
 }
 
 - (BOOL)shouldAllowOverscrollActionsForOverscrollActionsController:
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h
index b916ae96..23afbf9 100644
--- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h
+++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.h
@@ -37,13 +37,12 @@
 // Finally the overscrollActionsController:didTriggerActionAtIndex: method is
 // called when an action has been triggered.
 @protocol OverscrollActionsControllerDelegate<NSObject>
-// Called when an action has been triggered.
-// The action index holds the current triggered action which are numbered left
-// to right.
-// TODO(crbug.com/1272486) : Separate action handling for overscroll from UI
-// management.
-- (void)overscrollActionsController:(OverscrollActionsController*)controller
-                   didTriggerAction:(OverscrollAction)action;
+// Called when a New Tab action has been triggered.
+- (void)overscrollActionNewTab:(OverscrollActionsController*)controller;
+// Called when a Close Tab action has been triggered.
+- (void)overscrollActionCloseTab:(OverscrollActionsController*)controller;
+// Called when a Refresh action has been triggered.
+- (void)overscrollActionRefresh:(OverscrollActionsController*)controller;
 // Should return true when the delegate wants to enable the overscroll actions.
 - (BOOL)shouldAllowOverscrollActionsForOverscrollActionsController:
     (OverscrollActionsController*)controller;
diff --git a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
index bc963caf..43714d7 100644
--- a/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
+++ b/ios/chrome/browser/ui/overscroll_actions/overscroll_actions_controller.mm
@@ -11,6 +11,9 @@
 
 #import "base/check_op.h"
 #import "base/metrics/histogram_macros.h"
+#import "base/metrics/user_metrics.h"
+#import "base/metrics/user_metrics_action.h"
+#import "base/notreached.h"
 #import "base/time/time.h"
 #import "ios/chrome/browser/shared/ui/util/rtl_geometry.h"
 #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h"
@@ -579,6 +582,28 @@
 
 #pragma mark - Private
 
+- (void)handleAction:(OverscrollAction)action {
+  // The action index holds the current triggered action which are numbered left
+  // to right.
+  switch (action) {
+    case OverscrollAction::NEW_TAB:
+      base::RecordAction(base::UserMetricsAction("MobilePullGestureNewTab"));
+      [self.delegate overscrollActionNewTab:self];
+      break;
+    case OverscrollAction::CLOSE_TAB:
+      base::RecordAction(base::UserMetricsAction("MobilePullGestureCloseTab"));
+      [self.delegate overscrollActionCloseTab:self];
+      break;
+    case OverscrollAction::REFRESH:
+      base::RecordAction(base::UserMetricsAction("MobilePullGestureReload"));
+      [self.delegate overscrollActionRefresh:self];
+      break;
+    case OverscrollAction::NONE:
+      NOTREACHED();
+      break;
+  }
+}
+
 - (BOOL)viewportAdjustsContentInset {
   if (_webViewProxy.shouldUseViewContentInset)
     return YES;
@@ -749,8 +774,7 @@
         dispatch_async(dispatch_get_main_queue(), ^{
           [self recordMetricForTriggeredAction:selectedAction];
           TriggerHapticFeedbackForImpact(UIImpactFeedbackStyleMedium);
-          [self.delegate overscrollActionsController:self
-                                    didTriggerAction:selectedAction];
+          [self handleAction:selectedAction];
         });
       }
     }
@@ -1008,9 +1032,7 @@
   [self startBounceWithInitialVelocity:CGPointZero];
 
   TriggerHapticFeedbackForImpact(UIImpactFeedbackStyleMedium);
-  [self.delegate
-      overscrollActionsController:self
-                 didTriggerAction:self.overscrollActionView.selectedAction];
+  [self handleAction:self.overscrollActionView.selectedAction];
 }
 
 - (void)overscrollActionsView:(OverscrollActionsView*)view
diff --git a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
index c1e5d65f..e6a2d43 100644
--- a/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
+++ b/ios/chrome/browser/ui/popup_menu/overflow_menu/overflow_menu_mediator.mm
@@ -607,8 +607,8 @@
   self.siteInfoDestination =
       [self createOverflowMenuDestination:IDS_IOS_TOOLS_MENU_SITE_INFORMATION
                               destination:overflow_menu::Destination::SiteInfo
-                               symbolName:kToolsMenuSiteInformation
-                             systemSymbol:YES
+                               symbolName:kTunerSymbol
+                             systemSymbol:NO
                           accessibilityID:kToolsMenuSiteInformation
                                   handler:^{
                                     [weakSelf openSiteInformation];
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator_unittest.mm b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator_unittest.mm
index 0373f17..a707025 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_add_credit_card_mediator_unittest.mm
@@ -37,7 +37,7 @@
     personal_data_manager_ =
         autofill::PersonalDataManagerFactory::GetForBrowserState(
             chrome_browser_state_.get());
-    personal_data_manager_->OnSyncServiceInitialized(nullptr);
+    personal_data_manager_->SetSyncServiceForTest(nullptr);
 
     if (base::FeatureList::IsEnabled(
             autofill::features::kAutofillUseAlternativeStateNameMap)) {
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller_unittest.mm
index 9cd2819..6827d5f3 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_credit_card_table_view_controller_unittest.mm
@@ -44,7 +44,7 @@
     // Set circular SyncService dependency to null.
     autofill::PersonalDataManagerFactory::GetForBrowserState(
         chrome_browser_state_.get())
-        ->OnSyncServiceInitialized(nullptr);
+        ->SetSyncServiceForTest(nullptr);
   }
 
   ChromeTableViewController* InstantiateController() override {
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_mediator_unittest.mm b/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_mediator_unittest.mm
index 72c78ea4c..32efe62 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_mediator_unittest.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_profile_edit_mediator_unittest.mm
@@ -84,7 +84,7 @@
     personal_data_manager_ =
         autofill::PersonalDataManagerFactory::GetForBrowserState(
             chrome_browser_state_.get());
-    personal_data_manager_->OnSyncServiceInitialized(nullptr);
+    personal_data_manager_->SetSyncServiceForTest(nullptr);
 
     if (base::FeatureList::IsEnabled(
             autofill::features::kAutofillUseAlternativeStateNameMap)) {
diff --git a/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller_unittest.mm
index 36a7d98..5148913 100644
--- a/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller_unittest.mm
+++ b/ios/chrome/browser/ui/settings/autofill/autofill_profile_table_view_controller_unittest.mm
@@ -58,7 +58,7 @@
     // Set circular SyncService dependency to null.
     autofill::PersonalDataManagerFactory::GetForBrowserState(
         chrome_browser_state_.get())
-        ->OnSyncServiceInitialized(nullptr);
+        ->SetSyncServiceForTest(nullptr);
   }
 
   ChromeTableViewController* InstantiateController() override {
@@ -84,7 +84,7 @@
           ->alternative_state_name_map_updater_for_testing()
           ->set_local_state_for_testing(local_state_.Get());
     }
-    personal_data_manager->OnSyncServiceInitialized(nullptr);
+    personal_data_manager->SetSyncServiceForTest(nullptr);
     PersonalDataManagerFinishedProfileTasksWaiter waiter(personal_data_manager);
 
     autofill::AutofillProfile autofill_profile(base::GenerateGUID(), origin);
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
index 4da435e..135e65c 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
@@ -407,8 +407,9 @@
                                 animated:NO
                           scrollPosition:UICollectionViewScrollPositionNone];
     [self updateFractionVisibleOfLastItem];
+
+    self.searchText = nil;
   }
-  self.searchText = nil;
 }
 
 - (void)setSearchText:(NSString*)searchText {
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.mm
index 12b7838f..974f32e 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/pinned_tabs_view_controller.mm
@@ -716,7 +716,10 @@
 
   UILabel* label = [[UILabel alloc] init];
   label.numberOfLines = 0;
+  label.textAlignment = NSTextAlignmentCenter;
   label.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
+  label.adjustsFontForContentSizeCategory = YES;
+  label.adjustsFontSizeToFitWidth = YES;
   label.textColor = [UIColor colorNamed:kTextPrimaryColor];
   label.text = l10n_util::GetNSString(IDS_IOS_PINNED_TABS_DRAG_TO_PIN_LABEL);
   label.translatesAutoresizingMaskIntoConstraints = NO;
@@ -728,6 +731,14 @@
         constraintEqualToAnchor:_dropOverlayView.centerYAnchor],
     [label.centerXAnchor
         constraintEqualToAnchor:_dropOverlayView.centerXAnchor],
+    [label.leadingAnchor
+        constraintGreaterThanOrEqualToAnchor:_dropOverlayView.leadingAnchor
+                                    constant:kPinnedViewHorizontalPadding],
+    [label.trailingAnchor
+        constraintLessThanOrEqualToAnchor:_dropOverlayView.trailingAnchor
+                                 constant:-kPinnedViewHorizontalPadding],
+    [label.bottomAnchor constraintEqualToAnchor:_dropOverlayView.bottomAnchor],
+    [label.topAnchor constraintEqualToAnchor:_dropOverlayView.topAnchor],
   ]];
 
   [self updateDropOverlayViewVisibility];
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/grid_transition_animation.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/grid_transition_animation.mm
index 01e8fb2a..becbfc0 100644
--- a/ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/grid_transition_animation.mm
+++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/transitions/grid_transition_animation.mm
@@ -473,7 +473,7 @@
   [cell positionCellViews];
 }
 
-// Prepares all of the items for an expansion anumation.
+// Prepares all of the items for an expansion animation.
 - (void)prepareAllItemsForExpansion {
   for (GridTransitionItem* item in self.layout.inactiveItems) {
     [self positionItemInGrid:item];
diff --git a/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.mm b/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.mm
index b3ffa61e..6bbc221 100644
--- a/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.mm
+++ b/ios/chrome/test/fakes/fake_overscroll_actions_controller_delegate.mm
@@ -18,9 +18,16 @@
   return self;
 }
 
-- (void)overscrollActionsController:(OverscrollActionsController*)controller
-                   didTriggerAction:(OverscrollAction)action {
-  _selectedAction = action;
+- (void)overscrollActionNewTab:(OverscrollActionsController*)controller {
+  _selectedAction = OverscrollAction::NEW_TAB;
+}
+
+- (void)overscrollActionCloseTab:(OverscrollActionsController*)controller {
+  _selectedAction = OverscrollAction::CLOSE_TAB;
+}
+
+- (void)overscrollActionRefresh:(OverscrollActionsController*)controller {
+  _selectedAction = OverscrollAction::REFRESH;
 }
 
 - (BOOL)shouldAllowOverscrollActionsForOverscrollActionsController:
diff --git a/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.mm b/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.mm
index 0fe61823..1c4841f 100644
--- a/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.mm
+++ b/ios/web_view/internal/autofill/web_view_personal_data_manager_factory.mm
@@ -13,6 +13,7 @@
 #include "components/keyed_service/ios/browser_state_dependency_manager.h"
 #include "ios/web_view/internal/app/application_context.h"
 #include "ios/web_view/internal/signin/web_view_identity_manager_factory.h"
+#import "ios/web_view/internal/sync/web_view_sync_service_factory.h"
 #include "ios/web_view/internal/web_view_browser_state.h"
 #include "ios/web_view/internal/webdata_services/web_view_web_data_service_wrapper_factory.h"
 
@@ -43,6 +44,7 @@
           BrowserStateDependencyManager::GetInstance()) {
   DependsOn(WebViewIdentityManagerFactory::GetInstance());
   DependsOn(WebViewWebDataServiceWrapperFactory::GetInstance());
+  DependsOn(WebViewSyncServiceFactory::GetInstance());
 }
 
 WebViewPersonalDataManagerFactory::~WebViewPersonalDataManagerFactory() {}
@@ -61,11 +63,13 @@
   auto account_db =
       WebViewWebDataServiceWrapperFactory::GetAutofillWebDataForAccount(
           browser_state, ServiceAccessType::EXPLICIT_ACCESS);
+  auto* sync_service =
+      WebViewSyncServiceFactory::GetForBrowserState(browser_state);
   service->Init(
       profile_db, account_db, browser_state->GetPrefs(),
       ApplicationContext::GetInstance()->GetLocalState(),
       WebViewIdentityManagerFactory::GetForBrowserState(browser_state),
-      /*history_service=*/nullptr, /*strike_database=*/nullptr,
+      /*history_service=*/nullptr, sync_service, /*strike_database=*/nullptr,
       /*image_fetcher=*/nullptr, browser_state->IsOffTheRecord());
   return service;
 }
diff --git a/ios/web_view/internal/sync/web_view_sync_service_factory.mm b/ios/web_view/internal/sync/web_view_sync_service_factory.mm
index ea436ac..3cfabfc 100644
--- a/ios/web_view/internal/sync/web_view_sync_service_factory.mm
+++ b/ios/web_view/internal/sync/web_view_sync_service_factory.mm
@@ -18,7 +18,6 @@
 #include "components/sync/driver/sync_service_impl.h"
 #include "ios/web/public/thread/web_thread.h"
 #include "ios/web_view/internal/app/application_context.h"
-#include "ios/web_view/internal/autofill/web_view_personal_data_manager_factory.h"
 #import "ios/web_view/internal/passwords/web_view_account_password_store_factory.h"
 #include "ios/web_view/internal/passwords/web_view_password_store_factory.h"
 #include "ios/web_view/internal/signin/web_view_identity_manager_factory.h"
@@ -60,7 +59,6 @@
   // destruction order.
   DependsOn(WebViewDeviceInfoSyncServiceFactory::GetInstance());
   DependsOn(WebViewIdentityManagerFactory::GetInstance());
-  DependsOn(WebViewPersonalDataManagerFactory::GetInstance());
   DependsOn(WebViewWebDataServiceWrapperFactory::GetInstance());
   DependsOn(WebViewAccountPasswordStoreFactory::GetInstance());
   DependsOn(WebViewPasswordStoreFactory::GetInstance());
@@ -94,11 +92,6 @@
       std::make_unique<syncer::SyncServiceImpl>(std::move(init_params));
   sync_service->Initialize();
 
-  // Hook PSS into PersonalDataManager (a circular dependency).
-  autofill::PersonalDataManager* pdm =
-      WebViewPersonalDataManagerFactory::GetForBrowserState(browser_state);
-  pdm->OnSyncServiceInitialized(sync_service.get());
-
   return sync_service;
 }
 
diff --git a/media/capture/video/chromeos/mojom/camera3.mojom b/media/capture/video/chromeos/mojom/camera3.mojom
index f8957e8..40b9c4a9 100644
--- a/media/capture/video/chromeos/mojom/camera3.mojom
+++ b/media/capture/video/chromeos/mojom/camera3.mojom
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-// Next min version: 5
+// Next min version: 6
 
 module cros.mojom;
 
@@ -114,6 +114,8 @@
   array<uint32> strides;
   array<uint32> offsets;
   [MinVersion=3] array<uint32>? sizes;
+  [MinVersion=5] bool has_modifier;
+  [MinVersion=5] uint64 modifier;
 };
 
 struct Camera3StreamBuffer {
diff --git a/media/capture/video/chromeos/request_builder.cc b/media/capture/video/chromeos/request_builder.cc
index 226fbd9..4d5be539 100644
--- a/media/capture/video/chromeos/request_builder.cc
+++ b/media/capture/video/chromeos/request_builder.cc
@@ -61,6 +61,8 @@
   buffer_handle->buffer_id = buffer_info.ipc_id;
   buffer_handle->drm_format = buffer_info.drm_format;
   buffer_handle->hal_pixel_format = buffer_info.hal_pixel_format;
+  buffer_handle->has_modifier = true;
+  buffer_handle->modifier = buffer_info.modifier;
   buffer_handle->width = buffer_info.dimension.width();
   buffer_handle->height = buffer_info.dimension.height();
 
diff --git a/media/capture/video/chromeos/request_builder.h b/media/capture/video/chromeos/request_builder.h
index 007d7c39..72253ec 100644
--- a/media/capture/video/chromeos/request_builder.h
+++ b/media/capture/video/chromeos/request_builder.h
@@ -26,6 +26,7 @@
   gfx::GpuMemoryBufferHandle gpu_memory_buffer_handle;
   uint32_t drm_format;
   cros::mojom::HalPixelFormat hal_pixel_format;
+  uint64_t modifier;
 };
 
 // RequestBuilder is used to build capture request that will be sent to camera
diff --git a/media/capture/video/chromeos/stream_buffer_manager.cc b/media/capture/video/chromeos/stream_buffer_manager.cc
index 5cef5d4..0c9f1db 100644
--- a/media/capture/video/chromeos/stream_buffer_manager.cc
+++ b/media/capture/video/chromeos/stream_buffer_manager.cc
@@ -359,6 +359,8 @@
   }
   buffer_info.drm_format = drm_format;
   buffer_info.hal_pixel_format = stream_context_[stream_type]->stream->format;
+  buffer_info.modifier =
+      buffer_info.gpu_memory_buffer_handle.native_pixmap_handle.modifier;
   return buffer_info;
 }
 
diff --git a/media/gpu/vaapi/vaapi_wrapper.cc b/media/gpu/vaapi/vaapi_wrapper.cc
index 7028f93..dfe7f264 100644
--- a/media/gpu/vaapi/vaapi_wrapper.cc
+++ b/media/gpu/vaapi/vaapi_wrapper.cc
@@ -1939,13 +1939,6 @@
   if (!IsDecodingSupportedForInternalFormat(VAProfileJPEGBaseline, rt_format))
     return false;
 
-  // Workaround: for Mesa VAAPI driver, VPP only supports internal surface
-  // format for 4:2:0 JPEG image.
-  DCHECK_NE(VAImplementation::kInvalid, GetImplementationType());
-  if (GetImplementationType() == VAImplementation::kMesaGallium &&
-      rt_format != VA_RT_FORMAT_YUV420) {
-    return false;
-  }
 
   return IsVppFormatSupported(fourcc);
 }
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc
index 5f115ac..94f3d74 100644
--- a/media/renderers/video_resource_updater.cc
+++ b/media/renderers/video_resource_updater.cc
@@ -447,7 +447,7 @@
     // Allocate SharedMemory and notify display compositor of the allocation.
     base::MappedReadOnlyRegion shm =
         viz::bitmap_allocation::AllocateSharedBitmap(
-            resource_size(), viz::ResourceFormat::RGBA_8888);
+            resource_size(), viz::SinglePlaneFormat::kRGBA_8888);
     shared_mapping_ = std::move(shm.mapping);
     shared_bitmap_reporter_->DidAllocateSharedBitmap(std::move(shm.region),
                                                      shared_bitmap_id_);
diff --git a/services/device/public/mojom/smart_card.mojom b/services/device/public/mojom/smart_card.mojom
index 676c88b..8c46b6d 100644
--- a/services/device/public/mojom/smart_card.mojom
+++ b/services/device/public/mojom/smart_card.mojom
@@ -194,6 +194,10 @@
                   array<SmartCardReaderStateIn> reader_states)
     => (SmartCardStatusChangeResult result);
 
+  // Terminates an outstanding GetStatusChange() call with
+  // SmartCardError::kCancelled.
+  Cancel() => (SmartCardResult result);
+
   // Establishes a connection to the specified reader.
   Connect(string reader, SmartCardShareMode share_mode,
           SmartCardProtocols preferred_protocols) =>
diff --git a/services/network/network_context_unittest.cc b/services/network/network_context_unittest.cc
index 9ba0766..9f034a4 100644
--- a/services/network/network_context_unittest.cc
+++ b/services/network/network_context_unittest.cc
@@ -3330,9 +3330,9 @@
         CreateTestMessage(static_cast<uint8_t>(j), kDatagramSize));
     {
       base::test::TestFuture<int32_t> send_future;
-      server_socket->SendTo(test_msg,
-                            net::HostPortPair::FromIPEndPoint(client_addr),
-                            send_future.GetCallback());
+      server_socket->SendTo(
+          test_msg, net::HostPortPair::FromIPEndPoint(client_addr),
+          net::DnsQueryType::UNSPECIFIED, send_future.GetCallback());
       ASSERT_EQ(send_future.Get(), net::OK);
     }
   }
diff --git a/services/network/public/mojom/restricted_udp_socket.mojom b/services/network/public/mojom/restricted_udp_socket.mojom
index be18dcb..d1d6d8a 100644
--- a/services/network/public/mojom/restricted_udp_socket.mojom
+++ b/services/network/public/mojom/restricted_udp_socket.mojom
@@ -5,6 +5,7 @@
 module network.mojom;
 
 import "mojo/public/mojom/base/read_only_buffer.mojom";
+import "services/network/public/mojom/host_resolver.mojom";
 import "services/network/public/mojom/network_param.mojom";
 import "services/network/public/mojom/udp_socket.mojom";
 
@@ -54,12 +55,16 @@
       => (int32 result);
 
   // Sends a UDP datagram to a particular destination |dest_addr|.
-  // Possible hosts are currently limited to raw IPv4/IPv6 addresses, i.e.
-  // no DNS resolution takes place on the receiving side.
+  // DNS resolution hints can be provided by supplying |dns_query_type|.
   // Upon successfully handing the data to the OS, |result| is net::OK.
   // On failure, |result| is a network error code.
   // Note that this call is only valid in BOUND mode, otherwise it will
   // immediately fail with an error.
-  SendTo(mojo_base.mojom.ReadOnlyBuffer data, HostPortPair dest_addr)
+  // TODO(crbug.com/657632): Make |dns_query_type| optional once Java support
+  // lands.
+  SendTo(
+      mojo_base.mojom.ReadOnlyBuffer data,
+      HostPortPair dest_addr,
+      network.mojom.DnsQueryType dns_query_type)
       => (int32 result);
 };
diff --git a/services/network/restricted_udp_socket.cc b/services/network/restricted_udp_socket.cc
index c7f9172..6d95e20a 100644
--- a/services/network/restricted_udp_socket.cc
+++ b/services/network/restricted_udp_socket.cc
@@ -10,6 +10,7 @@
 #include "net/base/net_errors.h"
 #include "net/base/network_anonymization_key.h"
 #include "services/network/public/cpp/simple_host_resolver.h"
+#include "services/network/public/mojom/host_resolver.mojom.h"
 #include "services/network/udp_socket.h"
 
 namespace network {
@@ -35,6 +36,7 @@
 
 void RestrictedUDPSocket::SendTo(base::span<const uint8_t> data,
                                  const net::HostPortPair& dest_addr,
+                                 net::DnsQueryType dns_query_type,
                                  SendToCallback callback) {
   // If a raw IP address is supplied, call SendTo() immediately.
   if (net::IPAddress address; address.AssignFromIPLiteral(dest_addr.host())) {
@@ -43,10 +45,12 @@
     return;
   }
 
+  auto params = mojom::ResolveHostParameters::New();
+  params->dns_query_type = dns_query_type;
+
   resolver_->ResolveHost(
       mojom::HostResolverHost::NewHostPortPair(dest_addr),
-      net::NetworkAnonymizationKey::CreateTransient(),
-      /*optional_parameters=*/nullptr,
+      net::NetworkAnonymizationKey::CreateTransient(), std::move(params),
       base::BindOnce(&RestrictedUDPSocket::OnResolveCompleteForSendTo,
                      base::Unretained(this),
                      /*data=*/std::vector<uint8_t>(data.begin(), data.end()),
diff --git a/services/network/restricted_udp_socket.h b/services/network/restricted_udp_socket.h
index 9e0f8af..eeb7043b 100644
--- a/services/network/restricted_udp_socket.h
+++ b/services/network/restricted_udp_socket.h
@@ -37,6 +37,7 @@
   void Send(base::span<const uint8_t> data, SendCallback callback) override;
   void SendTo(base::span<const uint8_t> data,
               const net::HostPortPair& dest_addr,
+              net::DnsQueryType dns_query_type,
               SendToCallback callback) override;
 
 #if BUILDFLAG(IS_CHROMEOS)
diff --git a/services/network/test/test_restricted_udp_socket.cc b/services/network/test/test_restricted_udp_socket.cc
index f3761ff..c4b089d 100644
--- a/services/network/test/test_restricted_udp_socket.cc
+++ b/services/network/test/test_restricted_udp_socket.cc
@@ -32,6 +32,7 @@
 
 void TestRestrictedUDPSocket::SendTo(base::span<const uint8_t> data,
                                      const net::HostPortPair& dest_addr,
+                                     net::DnsQueryType dns_query_type,
                                      SendToCallback callback) {
   if (net::IPAddress address; address.AssignFromIPLiteral(dest_addr.host())) {
     udp_socket_->SendTo(
diff --git a/services/network/test/test_restricted_udp_socket.h b/services/network/test/test_restricted_udp_socket.h
index fd8387d..519dc21 100644
--- a/services/network/test/test_restricted_udp_socket.h
+++ b/services/network/test/test_restricted_udp_socket.h
@@ -24,6 +24,7 @@
   void Send(base::span<const uint8_t> data, SendCallback callback) override;
   void SendTo(base::span<const uint8_t> data,
               const net::HostPortPair& dest_addr,
+              net::DnsQueryType dns_query_type,
               SendToCallback callback) override;
 
   TestUDPSocket* udp_socket() const { return udp_socket_.get(); }
diff --git a/sql/database.cc b/sql/database.cc
index c01ae69e..4c8c02d 100644
--- a/sql/database.cc
+++ b/sql/database.cc
@@ -1092,6 +1092,10 @@
   return CheckpointDatabase();
 }
 
+bool Database::RazeAndPoison() {
+  return RazeAndClose();
+}
+
 bool Database::RazeAndClose() {
   TRACE_EVENT0("sql", "Database::RazeAndClose");
 
diff --git a/sql/database.h b/sql/database.h
index 3bddea0c..f1e2f85e 100644
--- a/sql/database.h
+++ b/sql/database.h
@@ -447,11 +447,14 @@
   // Close() should still be called at some point.
   void Poison();
 
-  // Raze() the database and Poison() the handle.  Returns the return
-  // value from Raze().
-  // TODO(shess): Rename to RazeAndPoison().
+  // Deprecated: Renamed to `RazeAndPoison()`.
+  // TODO(apaseltiner): Remove this once all callers have been migrated.
   bool RazeAndClose();
 
+  // `Raze()` the database and `Poison()` the handle. Returns the return
+  // value from `Raze()`.
+  bool RazeAndPoison();
+
   // Delete the underlying database files associated with |path|. This should be
   // used on a database which is not opened by any Database instance. Open
   // Database instances pointing to the database can cause odd results or
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json
index 93482e43..3ddb4da 100644
--- a/testing/buildbot/chromium.chromiumos.json
+++ b/testing/buildbot/chromium.chromiumos.json
@@ -3706,7 +3706,7 @@
         "args": [
           "--browser-ui-tests-verify-pixels",
           "--enable-pixel-output-in-tests",
-          "--gtest_filter=KioskPixelTest.*",
+          "--test-launcher-filter-file=../../testing/buildbot/filters/linux-chromeos.browser_tests.pixel_tests.filter",
           "--git-revision=${got_revision}"
         ],
         "experiment_percentage": 100,
@@ -5886,9 +5886,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_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -5900,8 +5900,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -6057,9 +6057,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -6071,8 +6071,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -6209,9 +6209,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -6223,8 +6223,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json
index 8b776cf..1743bad9a 100644
--- a/testing/buildbot/chromium.coverage.json
+++ b/testing/buildbot/chromium.coverage.json
@@ -25631,9 +25631,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_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -25645,8 +25645,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -25802,9 +25802,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -25816,8 +25816,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -25954,9 +25954,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -25968,8 +25968,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json
index 5202014..22268f8 100644
--- a/testing/buildbot/chromium.fyi.json
+++ b/testing/buildbot/chromium.fyi.json
@@ -50174,9 +50174,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_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -50187,8 +50187,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -50345,9 +50345,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -50358,8 +50358,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -50497,9 +50497,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -50510,8 +50510,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -52017,9 +52017,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_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -52030,8 +52030,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -52188,9 +52188,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -52201,8 +52201,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -52340,9 +52340,9 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -52353,8 +52353,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -53108,9 +53108,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_v114.0.5676.0/test_ash_chrome"
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "merge": {
           "args": [],
           "script": "//testing/merge_scripts/standard_gtest_merge.py"
@@ -53121,8 +53121,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json
index ad18d40..7463e1d 100644
--- a/testing/buildbot/chromium.memory.json
+++ b/testing/buildbot/chromium.memory.json
@@ -18414,12 +18414,12 @@
       {
         "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_v114.0.5676.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18431,8 +18431,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -18605,12 +18605,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18622,8 +18622,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
@@ -18772,12 +18772,12 @@
       {
         "args": [
           "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter",
-          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5676.0/test_ash_chrome",
+          "--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome",
           "--test-launcher-print-test-stdio=always",
           "--combine-ash-logs-on-bots",
           "--asan-symbolize-output"
         ],
-        "description": "Run with ash-chrome version 114.0.5676.0",
+        "description": "Run with ash-chrome version 114.0.5677.0",
         "isolate_profile_data": true,
         "merge": {
           "args": [],
@@ -18789,8 +18789,8 @@
           "cipd_packages": [
             {
               "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip",
-              "location": "lacros_version_skew_tests_v114.0.5676.0",
-              "revision": "version:114.0.5676.0"
+              "location": "lacros_version_skew_tests_v114.0.5677.0",
+              "revision": "version:114.0.5677.0"
             }
           ],
           "dimension_sets": [
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn
index edc67cc..7916ecb 100644
--- a/testing/buildbot/filters/BUILD.gn
+++ b/testing/buildbot/filters/BUILD.gn
@@ -58,6 +58,7 @@
     "//testing/buildbot/filters/chromeos.msan.browser_tests.oobe_positive.filter",
     "//testing/buildbot/filters/code_coverage.browser_tests.filter",
     "//testing/buildbot/filters/fuchsia.browser_tests.filter",
+    "//testing/buildbot/filters/linux-chromeos.browser_tests.pixel_tests.filter",
     "//testing/buildbot/filters/linux-chromeos.browser_tests.require_lacros.filter",
     "//testing/buildbot/filters/linux-lacros.browser_tests.filter",
     "//testing/buildbot/filters/linux.linux-rel-cft.browser_tests.filter",
diff --git a/testing/buildbot/filters/linux-chromeos.browser_tests.pixel_tests.filter b/testing/buildbot/filters/linux-chromeos.browser_tests.pixel_tests.filter
new file mode 100644
index 0000000..fc16e50
--- /dev/null
+++ b/testing/buildbot/filters/linux-chromeos.browser_tests.pixel_tests.filter
@@ -0,0 +1,5 @@
+# This is the filter for browser_tests that support pixel tests on ChromeOS.
+# In order for pixel tests to work, you *must* include your test here.
+
+KioskPixelTest.*
+
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl
index 0e3e6752..b9101f00 100644
--- a/testing/buildbot/test_suites.pyl
+++ b/testing/buildbot/test_suites.pyl
@@ -4855,7 +4855,7 @@
         'args': [
           '--browser-ui-tests-verify-pixels',
           '--enable-pixel-output-in-tests',
-          '--gtest_filter=KioskPixelTest.*',
+          '--test-launcher-filter-file=../../testing/buildbot/filters/linux-chromeos.browser_tests.pixel_tests.filter',
         ],
         'experiment_percentage': 100,
         'test': 'browser_tests',
@@ -5477,7 +5477,8 @@
           '--num-retries=3',
           '-t',
           'Release',
-          'external/wpt/webrtc'
+          'external/wpt/webrtc',
+          'external/wpt/webrtc-svc',
         ],
         'isolate_name': 'blink_wpt_tests',
         'merge': {
diff --git a/testing/buildbot/tryserver.webrtc.json b/testing/buildbot/tryserver.webrtc.json
index dd5e746..3f10b63 100644
--- a/testing/buildbot/tryserver.webrtc.json
+++ b/testing/buildbot/tryserver.webrtc.json
@@ -56,6 +56,7 @@
           "-t",
           "Release",
           "external/wpt/webrtc",
+          "external/wpt/webrtc-svc",
           "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json",
           "--git-revision=${got_revision}"
         ],
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl
index 11dc38f..5bc11ac 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_v114.0.5676.0/test_ash_chrome',
+      '--ash-chrome-path-override=../../lacros_version_skew_tests_v114.0.5677.0/test_ash_chrome',
     ],
-    'description': 'Run with ash-chrome version 114.0.5676.0',
+    'description': 'Run with ash-chrome version 114.0.5677.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_v114.0.5676.0',
-          'revision': 'version:114.0.5676.0',
+          'location': 'lacros_version_skew_tests_v114.0.5677.0',
+          'revision': 'version:114.0.5677.0',
         },
       ],
     },
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json
index 33d6981..2c924e81 100644
--- a/testing/variations/fieldtrial_testing_config.json
+++ b/testing/variations/fieldtrial_testing_config.json
@@ -8987,26 +8987,6 @@
             ]
         }
     ],
-    "PageInfoAboutThisSiteMoreInfoDesktop": [
-        {
-            "platforms": [
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled_230303",
-                    "enable_features": [
-                        "PageInfoAboutThisSiteMoreInfo",
-                        "PageInfoAboutThisSiteNonEn"
-                    ]
-                }
-            ]
-        }
-    ],
     "PageInfoAboutThisSiteNewIcon": [
         {
             "platforms": [
@@ -11364,26 +11344,6 @@
             ]
         }
     ],
-    "SequentialPrerendering": [
-        {
-            "platforms": [
-                "android",
-                "chromeos",
-                "chromeos_lacros",
-                "linux",
-                "mac",
-                "windows"
-            ],
-            "experiments": [
-                {
-                    "name": "Enabled",
-                    "enable_features": [
-                        "Prerender2SequentialPrerendering"
-                    ]
-                }
-            ]
-        }
-    ],
     "ServerBasedTranscriptionForScreencast": [
         {
             "platforms": [
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
index c8d0e1d..893ef58 100644
--- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl
+++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -1669,6 +1669,24 @@
       # Available variation settings (a.k.a. "axes").
       optional array of FontVariationAxis fontVariationAxes
 
+  # CSS try rule representation.
+  type CSSTryRule extends object
+    properties
+      # The css style sheet identifier (absent for user agent stylesheet and user-specified
+      # stylesheet rules) this rule came from.
+      optional StyleSheetId styleSheetId
+      # Parent stylesheet's origin.
+      StyleSheetOrigin origin
+      # Associated style declaration.
+      optional CSSStyle style
+
+  # CSS position-fallback rule representation.
+  type CSSPositionFallbackRule extends object
+    properties
+      Value name
+      # List of keyframes.
+      array of CSSTryRule tryRules
+
   # CSS keyframes rule representation.
   type CSSKeyframesRule extends object
     properties
@@ -1802,6 +1820,8 @@
       optional array of InheritedPseudoElementMatches inheritedPseudoElements
       # A list of CSS keyframed animations matching this node.
       optional array of CSSKeyframesRule cssKeyframesRules
+      # A list of CSS position fallbacks matching this node.
+      optional array of CSSPositionFallbackRule cssPositionFallbackRules
       # Id of the first parent element that does not have display: contents.
       experimental optional DOM.NodeId parentLayoutNodeId
 
diff --git a/third_party/blink/renderer/core/css/css_position_fallback_rule.h b/third_party/blink/renderer/core/css/css_position_fallback_rule.h
index 84dd2a5..095301b 100644
--- a/third_party/blink/renderer/core/css/css_position_fallback_rule.h
+++ b/third_party/blink/renderer/core/css/css_position_fallback_rule.h
@@ -56,6 +56,10 @@
   CSSPositionFallbackRule(StyleRulePositionFallback*, CSSStyleSheet* parent);
   ~CSSPositionFallbackRule() final;
 
+  StyleRulePositionFallback* PositionFallback() {
+    return position_fallback_rule_.Get();
+  }
+
   String name() const { return position_fallback_rule_->Name(); }
 
   Type GetType() const final { return kPositionFallbackRule; }
diff --git a/third_party/blink/renderer/core/css/css_properties.json5 b/third_party/blink/renderer/core/css/css_properties.json5
index 19ceafe..bd9ff4b2 100644
--- a/third_party/blink/renderer/core/css/css_properties.json5
+++ b/third_party/blink/renderer/core/css/css_properties.json5
@@ -891,7 +891,7 @@
     },
     {
       name: "animation-range-start",
-      property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"],
       style_builder_template: "animation",
       style_builder_template_args: {
         attribute: "RangeStart",
@@ -904,7 +904,7 @@
     },
     {
       name: "animation-range-end",
-      property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal"],
+      property_methods: ["ParseSingleValue", "CSSValueFromComputedStyleInternal", "InitialValue"],
       style_builder_template: "animation",
       style_builder_template_args: {
         attribute: "RangeEnd",
@@ -6611,14 +6611,14 @@
     },
     {
       // Variant of the "animation" shorthand which includes the
-      // animation-timeline longhand.
+      // animation-timeline and animation-range-* longhands.
       name: "-alternative-animation-with-timeline",
       alternative_of: "animation",
       longhands: [
         "animation-duration", "animation-timing-function",
         "animation-delay", "animation-iteration-count", "animation-direction",
         "animation-fill-mode", "animation-play-state", "animation-name",
-        "animation-timeline"
+        "animation-timeline", "animation-range-start", "animation-range-end"
       ],
       property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
       valid_for_keyframe: false,
@@ -6634,7 +6634,7 @@
         "animation-delay-start", "animation-delay-end",
         "animation-iteration-count", "animation-direction",
         "animation-fill-mode", "animation-play-state", "animation-name",
-        "animation-timeline"
+        "animation-timeline", "animation-range-start", "animation-range-end"
       ],
       property_methods: ["ParseShorthand", "CSSValueFromComputedStyleInternal"],
       valid_for_keyframe: false,
diff --git a/third_party/blink/renderer/core/css/css_property_source_data.h b/third_party/blink/renderer/core/css/css_property_source_data.h
index abc4b32f..5b0b23d 100644
--- a/third_party/blink/renderer/core/css/css_property_source_data.h
+++ b/third_party/blink/renderer/core/css/css_property_source_data.h
@@ -90,7 +90,8 @@
 
   bool HasProperties() const {
     return type == StyleRule::kStyle || type == StyleRule::kFontFace ||
-           type == StyleRule::kPage || type == StyleRule::kKeyframe;
+           type == StyleRule::kPage || type == StyleRule::kKeyframe ||
+           type == StyleRule::kTry;
   }
 
   bool HasMedia() const {
diff --git a/third_party/blink/renderer/core/css/css_try_rule.cc b/third_party/blink/renderer/core/css/css_try_rule.cc
index ab4791d9..b874f1bc 100644
--- a/third_party/blink/renderer/core/css/css_try_rule.cc
+++ b/third_party/blink/renderer/core/css/css_try_rule.cc
@@ -6,6 +6,7 @@
 
 #include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
 #include "third_party/blink/renderer/core/css/css_property_value_set.h"
+#include "third_party/blink/renderer/core/css/style_rule_css_style_declaration.h"
 #include "third_party/blink/renderer/platform/wtf/text/string_builder.h"
 
 namespace blink {
@@ -38,6 +39,22 @@
   return result.ReleaseString();
 }
 
+MutableCSSPropertyValueSet& StyleRuleTry::MutableProperties() {
+  if (!properties_->IsMutable()) {
+    properties_ = properties_->MutableCopy();
+  }
+  return *To<MutableCSSPropertyValueSet>(properties_.Get());
+}
+
+CSSStyleDeclaration* CSSTryRule::style() const {
+  if (!properties_cssom_wrapper_) {
+    properties_cssom_wrapper_ =
+        MakeGarbageCollected<StyleRuleCSSStyleDeclaration>(
+            try_rule_->MutableProperties(), const_cast<CSSTryRule*>(this));
+  }
+  return properties_cssom_wrapper_.Get();
+}
+
 void CSSTryRule::Reattach(StyleRuleBase* rule) {
   DCHECK(rule);
   try_rule_ = To<StyleRuleTry>(rule);
@@ -45,6 +62,7 @@
 
 void CSSTryRule::Trace(Visitor* visitor) const {
   visitor->Trace(try_rule_);
+  visitor->Trace(properties_cssom_wrapper_);
   CSSRule::Trace(visitor);
 }
 
diff --git a/third_party/blink/renderer/core/css/css_try_rule.h b/third_party/blink/renderer/core/css/css_try_rule.h
index 9a02743..792e7a8e 100644
--- a/third_party/blink/renderer/core/css/css_try_rule.h
+++ b/third_party/blink/renderer/core/css/css_try_rule.h
@@ -11,6 +11,7 @@
 namespace blink {
 
 class CSSPositionFallbackRule;
+class StyleRuleCSSStyleDeclaration;
 
 class StyleRuleTry final : public StyleRuleBase {
  public:
@@ -18,6 +19,7 @@
   ~StyleRuleTry();
 
   const CSSPropertyValueSet& Properties() const { return *properties_; }
+  MutableCSSPropertyValueSet& MutableProperties();
 
   void TraceAfterDispatch(Visitor*) const;
 
@@ -37,6 +39,7 @@
   CSSTryRule(StyleRuleTry*, CSSPositionFallbackRule* parent);
   ~CSSTryRule() final;
 
+  CSSStyleDeclaration* style() const;
   Type GetType() const final { return kTryRule; }
 
   String cssText() const final;
@@ -46,6 +49,7 @@
 
  private:
   Member<StyleRuleTry> try_rule_;
+  mutable Member<StyleRuleCSSStyleDeclaration> properties_cssom_wrapper_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
index a19e780..ec7ccbe 100644
--- a/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
+++ b/third_party/blink/renderer/core/css/parser/css_parser_impl.cc
@@ -2199,7 +2199,8 @@
   }
 
   if (observer_ &&
-      (rule_type == StyleRule::kStyle || rule_type == StyleRule::kKeyframe)) {
+      (rule_type == StyleRule::kStyle || rule_type == StyleRule::kKeyframe ||
+       rule_type == StyleRule::kTry)) {
     // The end offset is the offset of the terminating token, which is peeked
     // but not yet consumed.
     observer_->ObserveProperty(decl_offset_start, stream.LookAheadOffset(),
diff --git a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
index 1ea1c9dd..0bea3752 100644
--- a/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
+++ b/third_party/blink/renderer/core/css/properties/css_parsing_utils.h
@@ -68,7 +68,7 @@
                                                 bool use_legacy_parsing);
 using IsPositionKeyword = bool (*)(CSSValueID);
 
-constexpr size_t kMaxNumAnimationLonghands = 10;
+constexpr size_t kMaxNumAnimationLonghands = 12;
 
 void Complete4Sides(CSSValue* side[4]);
 
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
index bacf892d..8024982 100644
--- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -481,6 +481,10 @@
                                                              style);
 }
 
+const CSSValue* AnimationRangeStart::InitialValue() const {
+  return CSSIdentifierValue::Create(CSSValueID::kNormal);
+}
+
 const CSSValue* AnimationRangeEnd::ParseSingleValue(
     CSSParserTokenRange& range,
     const CSSParserContext& context,
@@ -499,6 +503,10 @@
                                                            style);
 }
 
+const CSSValue* AnimationRangeEnd::InitialValue() const {
+  return CSSIdentifierValue::Create(CSSValueID::kNormal);
+}
+
 const CSSValue* AnimationTimeline::ParseSingleValue(
     CSSParserTokenRange& range,
     const CSSParserContext& context,
diff --git a/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc b/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc
index 5225eaf..dbb175a 100644
--- a/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc
+++ b/third_party/blink/renderer/core/css/properties/shorthands/shorthands_custom.cc
@@ -81,6 +81,8 @@
     case CSSPropertyID::kAnimationTimingFunction:
       return css_parsing_utils::ConsumeAnimationTimingFunction(range, context);
     case CSSPropertyID::kAnimationTimeline:
+    case CSSPropertyID::kAnimationRangeStart:
+    case CSSPropertyID::kAnimationRangeEnd:
       // New animation-* properties are  "reset only", see kAnimationDelayEnd.
       DCHECK(RuntimeEnabledFeatures::CSSScrollTimelineEnabled());
       return nullptr;
@@ -149,6 +151,14 @@
           CSSTimingData::GetRepeated(animation_data->DelayEndList(), i)) {
         return nullptr;
       }
+      if (CSSAnimationData::InitialRangeStart() !=
+          CSSTimingData::GetRepeated(animation_data->RangeStartList(), i)) {
+        return nullptr;
+      }
+      if (CSSAnimationData::InitialRangeEnd() !=
+          CSSTimingData::GetRepeated(animation_data->RangeEndList(), i)) {
+        return nullptr;
+      }
       animations_list->Append(*list);
     }
     return animations_list;
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 7b13465b..64a109b 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.cc
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.cc
@@ -47,6 +47,7 @@
 #include "third_party/blink/renderer/core/css/css_initial_color_value.h"
 #include "third_party/blink/renderer/core/css/css_keyframe_rule.h"
 #include "third_party/blink/renderer/core/css/css_keyframes_rule.h"
+#include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
 #include "third_party/blink/renderer/core/css/css_rule_list.h"
 #include "third_party/blink/renderer/core/css/css_selector.h"
@@ -2869,6 +2870,39 @@
   return *formatted_text_element_;
 }
 
+StyleRulePositionFallback* StyleResolver::ResolvePositionFallbackRule(
+    const TreeScope* tree_scope,
+    AtomicString position_fallback_name) {
+  if (!tree_scope) {
+    tree_scope = &GetDocument();
+  }
+
+  StyleRulePositionFallback* position_fallback_rule = nullptr;
+  for (; tree_scope; tree_scope = tree_scope->ParentTreeScope()) {
+    if (ScopedStyleResolver* resolver = tree_scope->GetScopedStyleResolver()) {
+      position_fallback_rule =
+          resolver->PositionFallbackForName(position_fallback_name);
+      if (position_fallback_rule) {
+        break;
+      }
+    }
+  }
+
+  // Try UA rules if no author rule matches
+  if (!position_fallback_rule) {
+    for (const auto& rule : CSSDefaultStyleSheets::Instance()
+                                .DefaultHtmlStyle()
+                                ->PositionFallbackRules()) {
+      if (position_fallback_name == rule->Name()) {
+        position_fallback_rule = rule;
+        break;
+      }
+    }
+  }
+
+  return position_fallback_rule;
+}
+
 scoped_refptr<const ComputedStyle> StyleResolver::ResolvePositionFallbackStyle(
     Element& element,
     unsigned index) {
@@ -2881,28 +2915,8 @@
     tree_scope = &GetDocument();
   }
 
-  StyleRulePositionFallback* position_fallback_rule = nullptr;
-  for (; tree_scope; tree_scope = tree_scope->ParentTreeScope()) {
-    if (ScopedStyleResolver* resolver = tree_scope->GetScopedStyleResolver()) {
-      position_fallback_rule =
-          resolver->PositionFallbackForName(position_fallback->GetName());
-      if (position_fallback_rule) {
-        break;
-      }
-    }
-  }
-
-  // Try UA rules if no author rule matches
-  if (!position_fallback_rule) {
-    for (const auto& rule : CSSDefaultStyleSheets::Instance()
-                                .DefaultHtmlStyle()
-                                ->PositionFallbackRules()) {
-      if (position_fallback->GetName() == rule->Name()) {
-        position_fallback_rule = rule;
-        break;
-      }
-    }
-  }
+  StyleRulePositionFallback* position_fallback_rule =
+      ResolvePositionFallbackRule(tree_scope, position_fallback->GetName());
 
   if (!position_fallback_rule ||
       index >= position_fallback_rule->TryRules().size()) {
diff --git a/third_party/blink/renderer/core/css/resolver/style_resolver.h b/third_party/blink/renderer/core/css/resolver/style_resolver.h
index 83063bf6..6c4b7678e 100644
--- a/third_party/blink/renderer/core/css/resolver/style_resolver.h
+++ b/third_party/blink/renderer/core/css/resolver/style_resolver.h
@@ -29,6 +29,7 @@
 #include "third_party/blink/renderer/core/animation/property_handle.h"
 #include "third_party/blink/renderer/core/core_export.h"
 #include "third_party/blink/renderer/core/css/color_scheme_flags.h"
+#include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
 #include "third_party/blink/renderer/core/css/element_rule_collector.h"
 #include "third_party/blink/renderer/core/css/resolver/matched_properties_cache.h"
 #include "third_party/blink/renderer/core/css/resolver/style_builder.h"
@@ -213,7 +214,9 @@
       Element& element,
       const ComputedStyle& base_style,
       ActiveInterpolationsMap& transition_interpolations);
-
+  StyleRulePositionFallback* ResolvePositionFallbackRule(
+      const TreeScope* tree_scope,
+      AtomicString position_fallback_name);
   scoped_refptr<const ComputedStyle> ResolvePositionFallbackStyle(
       Element&,
       unsigned index);
diff --git a/third_party/blink/renderer/core/css/style_engine_test.cc b/third_party/blink/renderer/core/css/style_engine_test.cc
index 4a04f382c..e43f4cb 100644
--- a/third_party/blink/renderer/core/css/style_engine_test.cc
+++ b/third_party/blink/renderer/core/css/style_engine_test.cc
@@ -5980,7 +5980,7 @@
     const CSSPropertyValueSet* set =
         css_test_helpers::ParseDeclarationBlock(css);
     ASSERT_TRUE(set);
-    EXPECT_EQ(9u, set->PropertyCount());
+    EXPECT_EQ(11u, set->PropertyCount());
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationDuration));
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationTimingFunction));
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationDelay));
@@ -5990,6 +5990,8 @@
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationPlayState));
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationName));
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationTimeline));
+    EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationRangeStart));
+    EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationRangeEnd));
   }
   {
     ScopedCSSScrollTimelineForTest scroll_timeline_enabled(true);
@@ -5997,7 +5999,7 @@
     const CSSPropertyValueSet* set =
         css_test_helpers::ParseDeclarationBlock(css);
     ASSERT_TRUE(set);
-    EXPECT_EQ(10u, set->PropertyCount());
+    EXPECT_EQ(12u, set->PropertyCount());
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationDuration));
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationTimingFunction));
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationDelayStart));
@@ -6008,6 +6010,8 @@
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationPlayState));
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationName));
     EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationTimeline));
+    EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationRangeStart));
+    EXPECT_TRUE(set->HasProperty(CSSPropertyID::kAnimationRangeEnd));
   }
   // Note that the combination CSSScrollTimeline=false and
   // CSSAnimationDelayStartEnd=true is not supported, via 'depends_on'
diff --git a/third_party/blink/renderer/core/css/style_property_serializer.cc b/third_party/blink/renderer/core/css/style_property_serializer.cc
index abcd024..58845b7 100644
--- a/third_party/blink/renderer/core/css/style_property_serializer.cc
+++ b/third_party/blink/renderer/core/css/style_property_serializer.cc
@@ -1561,6 +1561,22 @@
         }
         is_initial_value = true;
       }
+      if (property->IDEquals(CSSPropertyID::kAnimationRangeStart)) {
+        auto* ident = DynamicTo<CSSIdentifierValue>(value);
+        if (!ident || (ident->GetValueID() != CSSValueID::kNormal)) {
+          DCHECK(RuntimeEnabledFeatures::CSSScrollTimelineEnabled());
+          return g_empty_string;
+        }
+        is_initial_value = true;
+      }
+      if (property->IDEquals(CSSPropertyID::kAnimationRangeEnd)) {
+        auto* ident = DynamicTo<CSSIdentifierValue>(value);
+        if (!ident || (ident->GetValueID() != CSSValueID::kNormal)) {
+          DCHECK(RuntimeEnabledFeatures::CSSScrollTimelineEnabled());
+          return g_empty_string;
+        }
+        is_initial_value = true;
+      }
 
       if (!is_initial_value) {
         if (property->IDEquals(CSSPropertyID::kBackgroundSize) ||
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
index b2aa227..ae1e7f6 100644
--- a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
+++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
@@ -1623,8 +1623,7 @@
   if (const Node* start_node = first_range.StartPosition().AnchorNode()) {
     if (start_node->GetComputedStyle() &&
         !start_node->GetComputedStyle()->IsHorizontalWritingMode()) {
-      if (RuntimeEnabledFeatures::ImeVerticalFlagEnabled())
-        info.flags |= kWebTextInputFlagVertical;
+      info.flags |= kWebTextInputFlagVertical;
     }
   }
 
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
index 4585526c..e807f6e3 100644
--- a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
+++ b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
@@ -3422,8 +3422,6 @@
 }
 
 TEST_F(InputMethodControllerTest, VerticalTextInputFlags) {
-  if (!RuntimeEnabledFeatures::ImeVerticalFlagEnabled())
-    return;
   Vector<std::pair<String, int>> element_html_and_expected_flags = {
       {"<div contenteditable='true'></div>", 0},
       {"<div contenteditable='true' style='writing-mode:vertical-rl;'></div>",
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
index 720bca4..668d14a 100644
--- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -44,6 +44,7 @@
 #include "third_party/blink/renderer/core/css/css_layer_block_rule.h"
 #include "third_party/blink/renderer/core/css/css_layer_statement_rule.h"
 #include "third_party/blink/renderer/core/css/css_media_rule.h"
+#include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
 #include "third_party/blink/renderer/core/css/css_property_name.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
 #include "third_party/blink/renderer/core/css/css_property_value_set.h"
@@ -987,6 +988,8 @@
         inherited_pseudo_id_matches,
     Maybe<protocol::Array<protocol::CSS::CSSKeyframesRule>>*
         css_keyframes_rules,
+    Maybe<protocol::Array<protocol::CSS::CSSPositionFallbackRule>>*
+        css_position_fallback_rules,
     Maybe<int>* parentLayoutNodeId) {
   Response response = AssertEnabled();
   if (!response.IsSuccess())
@@ -1103,6 +1106,7 @@
   }
 
   *css_keyframes_rules = AnimationsForNode(element, animating_element);
+  *css_position_fallback_rules = PositionFallbackRulesForNode(element);
 
   auto* parentLayoutNode = LayoutTreeBuilderTraversal::LayoutParent(*element);
   if (parentLayoutNode) {
@@ -1116,8 +1120,12 @@
 template <class CSSRuleCollection>
 static CSSKeyframesRule* FindKeyframesRule(CSSRuleCollection* css_rules,
                                            StyleRuleKeyframes* keyframes_rule) {
+  if (!css_rules) {
+    return nullptr;
+  }
+
   CSSKeyframesRule* result = nullptr;
-  for (unsigned j = 0; css_rules && j < css_rules->length() && !result; ++j) {
+  for (unsigned j = 0; j < css_rules->length() && !result; ++j) {
     CSSRule* css_rule = css_rules->item(j);
     if (auto* css_style_rule = DynamicTo<CSSKeyframesRule>(css_rule)) {
       if (css_style_rule->Keyframes() == keyframes_rule)
@@ -1131,6 +1139,105 @@
   return result;
 }
 
+template <class CSSRuleCollection>
+static CSSPositionFallbackRule* FindPositionFallbackRule(
+    CSSRuleCollection* css_rules,
+    StyleRulePositionFallback* position_fallback_rule) {
+  if (!css_rules) {
+    return nullptr;
+  }
+
+  CSSPositionFallbackRule* result = nullptr;
+  for (unsigned j = 0; j < css_rules->length() && !result; ++j) {
+    CSSRule* css_rule = css_rules->item(j);
+    if (auto* css_style_rule = DynamicTo<CSSPositionFallbackRule>(css_rule)) {
+      if (css_style_rule->PositionFallback() == position_fallback_rule) {
+        result = css_style_rule;
+      }
+    } else if (auto* css_import_rule = DynamicTo<CSSImportRule>(css_rule)) {
+      result = FindPositionFallbackRule(css_import_rule->styleSheet(),
+                                        position_fallback_rule);
+    } else {
+      result = FindPositionFallbackRule(css_rule->cssRules(),
+                                        position_fallback_rule);
+    }
+  }
+  return result;
+}
+
+std::unique_ptr<protocol::Array<protocol::CSS::CSSPositionFallbackRule>>
+InspectorCSSAgent::PositionFallbackRulesForNode(Element* element) {
+  auto css_position_fallback_rules = std::make_unique<
+      protocol::Array<protocol::CSS::CSSPositionFallbackRule>>();
+  Document& document = element->GetDocument();
+  DCHECK(!document.NeedsLayoutTreeUpdateForNode(*element));
+
+  const ComputedStyle* style = element->EnsureComputedStyle();
+  if (!style) {
+    return css_position_fallback_rules;
+  }
+
+  const ScopedCSSName* position_fallback = style->PositionFallback();
+  if (!position_fallback) {
+    return css_position_fallback_rules;
+  }
+
+  const TreeScope* tree_scope = position_fallback->GetTreeScope();
+  if (!tree_scope) {
+    tree_scope = &document;
+  }
+
+  StyleResolver& style_resolver = document.GetStyleResolver();
+  StyleRulePositionFallback* position_fallback_rule =
+      style_resolver.ResolvePositionFallbackRule(tree_scope,
+                                                 position_fallback->GetName());
+
+  // Find CSSOM wrapper from internal Style rule.
+  CSSPositionFallbackRule* css_position_fallback_rule = nullptr;
+  for (CSSStyleSheet* style_sheet :
+       *document_to_css_style_sheets_.at(&document)) {
+    css_position_fallback_rule =
+        FindPositionFallbackRule(style_sheet, position_fallback_rule);
+    if (css_position_fallback_rule) {
+      break;
+    }
+  }
+
+  if (!css_position_fallback_rule) {
+    return css_position_fallback_rules;
+  }
+
+  auto try_rules =
+      std::make_unique<protocol::Array<protocol::CSS::CSSTryRule>>();
+  for (unsigned j = 0; j < css_position_fallback_rule->length(); ++j) {
+    InspectorStyleSheet* inspector_style_sheet =
+        BindStyleSheet(css_position_fallback_rule->parentStyleSheet());
+    try_rules->emplace_back(inspector_style_sheet->BuildObjectForTryRule(
+        css_position_fallback_rule->Item(j)));
+  }
+
+  InspectorStyleSheet* inspector_style_sheet =
+      BindStyleSheet(css_position_fallback_rule->parentStyleSheet());
+  CSSRuleSourceData* source_data =
+      inspector_style_sheet->SourceDataForRule(css_position_fallback_rule);
+  std::unique_ptr<protocol::CSS::Value> name =
+      protocol::CSS::Value::create()
+          .setText(css_position_fallback_rule->name())
+          .build();
+  if (source_data) {
+    name->setRange(inspector_style_sheet->BuildSourceRangeObject(
+        source_data->rule_header_range));
+  }
+
+  css_position_fallback_rules->emplace_back(
+      protocol::CSS::CSSPositionFallbackRule::create()
+          .setName(std::move(name))
+          .setTryRules(std::move(try_rules))
+          .build());
+
+  return css_position_fallback_rules;
+}
+
 std::unique_ptr<protocol::Array<protocol::CSS::CSSKeyframesRule>>
 InspectorCSSAgent::AnimationsForNode(Element* element,
                                      Element* animating_element) {
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.h b/third_party/blink/renderer/core/inspector/inspector_css_agent.h
index 67708d0..70ad937 100644
--- a/third_party/blink/renderer/core/inspector/inspector_css_agent.h
+++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.h
@@ -159,6 +159,7 @@
       protocol::Maybe<
           protocol::Array<protocol::CSS::InheritedPseudoElementMatches>>*,
       protocol::Maybe<protocol::Array<protocol::CSS::CSSKeyframesRule>>*,
+      protocol::Maybe<protocol::Array<protocol::CSS::CSSPositionFallbackRule>>*,
       protocol::Maybe<int>*) override;
   protocol::Response getInlineStylesForNode(
       int node_id,
@@ -320,6 +321,9 @@
       std::unique_ptr<protocol::Array<protocol::CSS::StyleDeclarationEdit>>,
       HeapVector<Member<StyleSheetAction>>* actions);
 
+  std::unique_ptr<protocol::Array<protocol::CSS::CSSPositionFallbackRule>>
+  PositionFallbackRulesForNode(Element* element);
+
   // If the |animating_element| is a pseudo element, then |element| is a
   // reference to its originating DOM element.
   std::unique_ptr<protocol::Array<protocol::CSS::CSSKeyframesRule>>
diff --git a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
index 70ccac6..c5d8fb01 100644
--- a/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
+++ b/third_party/blink/renderer/core/inspector/inspector_style_sheet.cc
@@ -35,6 +35,7 @@
 #include "third_party/blink/renderer/core/css/css_keyframes_rule.h"
 #include "third_party/blink/renderer/core/css/css_layer_block_rule.h"
 #include "third_party/blink/renderer/core/css/css_media_rule.h"
+#include "third_party/blink/renderer/core/css/css_position_fallback_rule.h"
 #include "third_party/blink/renderer/core/css/css_property_names.h"
 #include "third_party/blink/renderer/core/css/css_property_value_set.h"
 #include "third_party/blink/renderer/core/css/css_rule_list.h"
@@ -43,6 +44,7 @@
 #include "third_party/blink/renderer/core/css/css_style_sheet.h"
 #include "third_party/blink/renderer/core/css/css_style_sheet_ids.h"
 #include "third_party/blink/renderer/core/css/css_supports_rule.h"
+#include "third_party/blink/renderer/core/css/css_try_rule.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser_local_context.h"
 #include "third_party/blink/renderer/core/css/parser/css_parser_observer.h"
@@ -615,6 +617,7 @@
       case StyleRule::kFontFace:
       case StyleRule::kKeyframe:
       case StyleRule::kFontFeature:
+      case StyleRule::kTry:
         result->push_back(data);
         break;
       case StyleRule::kStyle:
@@ -625,6 +628,7 @@
       case StyleRule::kContainer:
       case StyleRule::kLayerBlock:
       case StyleRule::kFontFeatureValues:
+      case StyleRule::kPositionFallback:
         result->push_back(data);
         FlattenSourceData(data->child_rules, result);
         break;
@@ -660,6 +664,10 @@
   if (auto* layer_rule = DynamicTo<CSSLayerBlockRule>(rule))
     return layer_rule->cssRules();
 
+  if (auto* position_fallback_rule = DynamicTo<CSSPositionFallbackRule>(rule)) {
+    return position_fallback_rule->cssRules();
+  }
+
   return nullptr;
 }
 
@@ -681,6 +689,7 @@
       case CSSRule::kViewportRule:
       case CSSRule::kKeyframeRule:
       case CSSRule::kFontFeatureRule:
+      case CSSRule::kTryRule:
         result->push_back(rule);
         break;
       case CSSRule::kStyleRule:
@@ -691,6 +700,7 @@
       case CSSRule::kContainerRule:
       case CSSRule::kLayerBlockRule:
       case CSSRule::kFontFeatureValuesRule:
+      case CSSRule::kPositionFallbackRule:
         result->push_back(rule);
         CollectFlatRules(AsCSSRuleList(rule), result);
         break;
@@ -1897,6 +1907,19 @@
   return result;
 }
 
+std::unique_ptr<protocol::CSS::CSSTryRule>
+InspectorStyleSheet::BuildObjectForTryRule(CSSTryRule* try_rule) {
+  std::unique_ptr<protocol::CSS::CSSTryRule> result =
+      protocol::CSS::CSSTryRule::create()
+          .setOrigin(origin_)
+          .setStyle(BuildObjectForStyle(try_rule->style()))
+          .build();
+  if (CanBind(origin_) && !Id().empty()) {
+    result->setStyleSheetId(Id());
+  }
+  return result;
+}
+
 std::unique_ptr<protocol::CSS::CSSKeyframeRule>
 InspectorStyleSheet::BuildObjectForKeyframeRule(
     CSSKeyframeRule* keyframe_rule) {
diff --git a/third_party/blink/renderer/core/inspector/inspector_style_sheet.h b/third_party/blink/renderer/core/inspector/inspector_style_sheet.h
index 4d5a21f..158fb56 100644
--- a/third_party/blink/renderer/core/inspector/inspector_style_sheet.h
+++ b/third_party/blink/renderer/core/inspector/inspector_style_sheet.h
@@ -41,6 +41,7 @@
 
 namespace blink {
 
+class CSSTryRule;
 class CSSKeyframeRule;
 class CSSMediaRule;
 class CSSContainerRule;
@@ -198,6 +199,7 @@
       CSSStyleRule*);
   std::unique_ptr<protocol::CSS::RuleUsage> BuildObjectForRuleUsage(CSSRule*,
                                                                     bool);
+  std::unique_ptr<protocol::CSS::CSSTryRule> BuildObjectForTryRule(CSSTryRule*);
   std::unique_ptr<protocol::CSS::CSSKeyframeRule> BuildObjectForKeyframeRule(
       CSSKeyframeRule*);
   std::unique_ptr<protocol::CSS::SelectorList> BuildObjectForSelectorList(
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc
index 8c8e4c4..fe203ff 100644
--- a/third_party/blink/renderer/core/layout/layout_box.cc
+++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -1273,23 +1273,6 @@
     Layer()->UpdateSizeAndScrollingAfterLayout();
   }
 
-  // When we've finished layout, if we aren't a LayoutNG object, we need to
-  // reset our cached layout result. LayoutNG inside of
-  // |NGBlockNode::RunOldLayout| will call |LayoutBox::SetCachedLayoutResult|
-  // with a new synthesized layout result, if we are still being laid out by an
-  // NG container.
-  //
-  // We also want to make sure that if our entrance point into layout changes,
-  // e.g. an OOF-positioned object is laid out by an NG containing block, then
-  // Legacy, then NG again, NG won't use a stale layout result.
-  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled() &&
-      !IsLayoutNGObject() &&
-      // When side effects are disabled, it's not possible to disable side
-      // effects completely for |RunLegacyLayout|, but at least keep the
-      // fragment tree unaffected.
-      !NGDisableSideEffectsScope::IsDisabled())
-    ClearLayoutResults();
-
   GetFrame()->GetInputMethodController().DidUpdateLayout(*this);
   if (IsPositioned())
     GetFrame()->GetInputMethodController().DidLayoutSubtree(*this);
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_content.cc b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
index 3e4d4e8..60647ba7 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_content.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_content.cc
@@ -316,8 +316,6 @@
 void LayoutEmbeddedContent::UpdateLayout() {
   NOT_DESTROYED();
   DCHECK(NeedsLayout());
-  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
-    UpdateAfterLayout();
   ClearNeedsLayout();
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_embedded_object.cc b/third_party/blink/renderer/core/layout/layout_embedded_object.cc
index ad66c56..dc00b93 100644
--- a/third_party/blink/renderer/core/layout/layout_embedded_object.cc
+++ b/third_party/blink/renderer/core/layout/layout_embedded_object.cc
@@ -102,9 +102,6 @@
 
   ClearLayoutOverflow();
 
-  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
-    UpdateAfterLayout();
-
   if (!GetEmbeddedContentView() && GetFrameView())
     GetFrameView()->AddPartToUpdate(*this);
 
diff --git a/third_party/blink/renderer/core/layout/layout_iframe.cc b/third_party/blink/renderer/core/layout/layout_iframe.cc
index bba4d10..2faf9e6 100644
--- a/third_party/blink/renderer/core/layout/layout_iframe.cc
+++ b/third_party/blink/renderer/core/layout/layout_iframe.cc
@@ -53,9 +53,6 @@
   }
 
   ClearLayoutOverflow();
-  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
-    UpdateAfterLayout();
-
   ClearNeedsLayout();
 }
 
diff --git a/third_party/blink/renderer/core/layout/layout_replaced.cc b/third_party/blink/renderer/core/layout/layout_replaced.cc
index 6640bb5..3ef94a99 100644
--- a/third_party/blink/renderer/core/layout/layout_replaced.cc
+++ b/third_party/blink/renderer/core/layout/layout_replaced.cc
@@ -135,9 +135,6 @@
   ClearSelfNeedsLayoutOverflowRecalc();
   ClearChildNeedsLayoutOverflowRecalc();
 
-  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
-    UpdateAfterLayout();
-
   ClearNeedsLayout();
 
   if (ReplacedContentRectFrom(SizeFromNG(), BorderPaddingFromNG()) !=
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
index 1da259f..37bde85 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.cc
@@ -233,8 +233,7 @@
 void NGInlineLayoutAlgorithm::CreateLine(
     const NGLineLayoutOpportunity& opportunity,
     NGLineInfo* line_info,
-    NGLogicalLineItems* line_box,
-    NGLineBreaker* line_breaker) {
+    NGLogicalLineItems* line_box) {
   // Needs MutableResults to move ShapeResult out of the NGLineInfo.
   NGInlineItemResults* line_items = line_info->MutableResults();
   // Clear the current line without releasing the buffer.
@@ -496,8 +495,7 @@
     // [1]
     // https://wpt.live/css/css-inline/initial-letter/initial-letter-floats-005.html
     PlaceFloatingObjects(*line_info, line_box_metrics, opportunity,
-                         line_info->ComputeBlockStartAdjustment(), line_box,
-                         line_breaker);
+                         line_info->ComputeBlockStartAdjustment(), line_box);
   }
 
   // Apply any relative positioned offsets to *items* which have relative
@@ -847,8 +845,7 @@
     const FontHeight& line_box_metrics,
     const NGLineLayoutOpportunity& opportunity,
     LayoutUnit ruby_block_start_adjust,
-    NGLogicalLineItems* line_box,
-    NGLineBreaker* line_breaker) {
+    NGLogicalLineItems* line_box) {
   DCHECK(line_info.IsEmptyLine() || !line_box_metrics.IsEmpty())
       << "Non-empty lines must have a valid set of linebox metrics.";
 
@@ -884,14 +881,14 @@
         NGBlockNode float_node(To<LayoutBox>(child.unpositioned_float.Get()));
         auto* break_before = NGBlockBreakToken::CreateBreakBefore(
             float_node, /* is_forced_break */ false);
-        line_breaker->PropagateBreakToken(break_before);
+        context_->PropagateBreakToken(break_before);
         continue;
       } else {
         // If the float broke inside, we need to propagate the break token to
         // the block container, so that we'll resume in the next fragmentainer.
         if (const NGBreakToken* token =
                 positioned_float.layout_result->PhysicalFragment().BreakToken())
-          line_breaker->PropagateBreakToken(To<NGBlockBreakToken>(token));
+          context_->PropagateBreakToken(To<NGBlockBreakToken>(token));
         child.layout_result = std::move(positioned_float.layout_result);
         child.bfc_offset = positioned_float.bfc_offset;
         child.unpositioned_float = nullptr;
@@ -1415,9 +1412,17 @@
       line_info.SetAvailableWidth(line_opportunity.AvailableInlineSize());
     }
 
+    // Propagate any break tokens for floats that we fragmented before or inside
+    // to the block container in 3 steps: 1) in `PositionLeadingFloats`, 2) from
+    // `NGLineInfo` here, 3) then `CreateLine` may propagate more.
+    for (const NGBlockBreakToken* float_break_token :
+         line_info.PropagatedBreakTokens()) {
+      context_->PropagateBreakToken(float_break_token);
+    }
+
     PrepareBoxStates(line_info, break_token);
 
-    CreateLine(line_opportunity, &line_info, line_box, &line_breaker);
+    CreateLine(line_opportunity, &line_info, line_box);
     is_line_created = true;
 
     // Adjust the line BFC block-offset if we have a ruby annotation, raise
@@ -1494,12 +1499,6 @@
     container_builder_.SetBreakToken(line_info.BreakToken());
     container_builder_.SetBaseDirection(line_info.BaseDirection());
 
-    // Propagate any break tokens for floats that we fragmented before or inside
-    // to the block container.
-    for (const NGBlockBreakToken* float_break_token :
-         line_breaker.PropagatedBreakTokens())
-      context_->PropagateBreakToken(float_break_token);
-
     if (line_info.IsEmptyLine()) {
       DCHECK_EQ(container_builder_.BlockSize(), LayoutUnit());
       DCHECK(!container_builder_.BfcBlockOffset());
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
index dc31b00..ae219e1e 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_inline_layout_algorithm.h
@@ -27,7 +27,6 @@
 class NGInlineNode;
 class NGInlineItem;
 class NGInlineLayoutStateStack;
-class NGLineBreaker;
 class NGLineInfo;
 struct NGInlineBoxState;
 struct NGInlineItemResult;
@@ -52,8 +51,7 @@
 
   void CreateLine(const NGLineLayoutOpportunity&,
                   NGLineInfo*,
-                  NGLogicalLineItems* line_box,
-                  NGLineBreaker*);
+                  NGLogicalLineItems* line_box);
 
   const NGLayoutResult* Layout() override;
 
@@ -119,8 +117,7 @@
                             const FontHeight&,
                             const NGLineLayoutOpportunity&,
                             LayoutUnit ruby_block_start_adjust,
-                            NGLogicalLineItems* line_box,
-                            NGLineBreaker*);
+                            NGLogicalLineItems* line_box);
   void PlaceRelativePositionedItems(NGLogicalLineItems* line_box);
   void PlaceListMarker(const NGInlineItem&,
                        NGInlineItemResult*,
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
index 26425351..690a808 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.cc
@@ -415,9 +415,7 @@
   SetCurrentStyle(*line_initial_style);
 }
 
-NGLineBreaker::~NGLineBreaker() {
-  propagated_break_tokens_.clear();
-}
+NGLineBreaker::~NGLineBreaker() = default;
 
 inline NGInlineItemResult* NGLineBreaker::AddItem(const NGInlineItem& item,
                                                   unsigned end_offset,
@@ -2380,7 +2378,7 @@
       // algorithm. The float will start in the next fragmentainer.
       auto* break_before = NGBlockBreakToken::CreateBreakBefore(
           unpositioned_float.node, /* is_forced_break */ false);
-      PropagateBreakToken(break_before);
+      line_info->PropagateBreakToken(break_before);
       return;
     }
     // If we broke inside the float, we also need to propagate a break token to
@@ -2389,7 +2387,7 @@
     const NGPhysicalFragment& fragment =
         item_result->positioned_float->layout_result->PhysicalFragment();
     if (const NGBreakToken* token = fragment.BreakToken())
-      PropagateBreakToken(To<NGBlockBreakToken>(token));
+      line_info->PropagateBreakToken(To<NGBlockBreakToken>(token));
   }
 
   NGLayoutOpportunity opportunity = exclusion_space_->FindLayoutOpportunity(
@@ -3111,8 +3109,4 @@
                                     offset_, flags, sub_break_token);
 }
 
-void NGLineBreaker::PropagateBreakToken(const NGBlockBreakToken* token) {
-  propagated_break_tokens_.push_back(token);
-}
-
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
index 9b7e2b0e..44340ee 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_breaker.h
@@ -19,7 +19,6 @@
 namespace blink {
 
 class Hyphenation;
-class NGBlockBreakToken;
 class NGColumnSpannerPath;
 class NGInlineBreakToken;
 class NGInlineItem;
@@ -60,11 +59,6 @@
 
   bool IsFinished() const { return item_index_ >= Items().size(); }
 
-  void PropagateBreakToken(const NGBlockBreakToken*);
-  HeapVector<Member<const NGBlockBreakToken>>& PropagatedBreakTokens() {
-    return propagated_break_tokens_;
-  }
-
   // Computing |NGLineBreakerMode::kMinContent| with |MaxSizeCache| caches
   // information that can help computing |kMaxContent|. It is recommended to set
   // this when computing both |kMinContent| and |kMaxContent|.
@@ -368,8 +362,6 @@
   // if 'unicode-bidi: plaintext'.
   TextDirection base_direction_;
 
-  HeapVector<Member<const NGBlockBreakToken>> propagated_break_tokens_;
-
   // Fields for `box-decoration-break: clone`.
   unsigned cloned_box_decorations_count_ = 0;
   LayoutUnit cloned_box_decorations_initial_size_;
diff --git a/third_party/blink/renderer/core/layout/ng/inline/ng_line_info.h b/third_party/blink/renderer/core/layout/ng/inline/ng_line_info.h
index 0a065140..071f8443 100644
--- a/third_party/blink/renderer/core/layout/ng/inline/ng_line_info.h
+++ b/third_party/blink/renderer/core/layout/ng/inline/ng_line_info.h
@@ -91,6 +91,12 @@
   void SetBreakToken(const NGInlineBreakToken* break_token) {
     break_token_ = break_token;
   }
+  HeapVector<Member<const NGBlockBreakToken>>& PropagatedBreakTokens() {
+    return propagated_break_tokens_;
+  }
+  void PropagateBreakToken(const NGBlockBreakToken* token) {
+    propagated_break_tokens_.push_back(token);
+  }
 
   void SetTextIndent(LayoutUnit indent) { text_indent_ = indent; }
   LayoutUnit TextIndent() const { return text_indent_; }
@@ -235,6 +241,7 @@
   NGBfcOffset bfc_offset_;
 
   const NGInlineBreakToken* break_token_ = nullptr;
+  HeapVector<Member<const NGBlockBreakToken>> propagated_break_tokens_;
 
   const NGLayoutResult* block_in_inline_layout_result_ = nullptr;
 
diff --git a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
index 584429e..ee078f28 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_block_node.cc
@@ -1377,11 +1377,7 @@
     block->SetLayoutOverflowFromLayoutResults();
   }
 
-  // Replaced elements already have |LayoutBox::UpdateAfterLayout| called when
-  // we force a layout for them inside |NGBlockNode::FinishLayout|.
-  if (RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled() ||
-      !box_->IsLayoutReplaced())
-    box_->UpdateAfterLayout();
+  box_->UpdateAfterLayout();
 
   if (needs_full_invalidation)
     box_->ClearNeedsLayoutWithFullPaintInvalidation();
diff --git a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
index 548e6d0..b20b2da 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_column_layout_algorithm.cc
@@ -767,10 +767,10 @@
 
     do {
       // Lay out one column. Each column will become a fragment.
-      NGConstraintSpace child_space = CreateConstraintSpaceForColumns(
-          ConstraintSpace(), column_size, ColumnPercentageResolutionSize(),
-          allow_discard_start_margin, balance_columns,
-          min_break_appeal.value_or(kBreakAppealLastResort));
+      NGConstraintSpace child_space = CreateConstraintSpaceForFragmentainer(
+          ConstraintSpace(), kFragmentColumn, column_size,
+          ColumnPercentageResolutionSize(), allow_discard_start_margin,
+          balance_columns, min_break_appeal.value_or(kBreakAppealLastResort));
 
       NGFragmentGeometry fragment_geometry =
           CalculateInitialFragmentGeometry(child_space, Node(), BreakToken());
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
index 34007ffa..8d7bfb5a 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.cc
@@ -1163,25 +1163,30 @@
   return early_break.IsBreakBefore() && early_break.BlockNode() == child;
 }
 
-NGConstraintSpace CreateConstraintSpaceForColumns(
+NGConstraintSpace CreateConstraintSpaceForFragmentainer(
     const NGConstraintSpace& parent_space,
-    LogicalSize column_size,
+    NGFragmentationType fragmentation_type,
+    LogicalSize fragmentainer_size,
     LogicalSize percentage_resolution_size,
     bool allow_discard_start_margin,
     bool balance_columns,
     NGBreakAppeal min_break_appeal) {
   NGConstraintSpaceBuilder space_builder(
       parent_space, parent_space.GetWritingDirection(), /* is_new_fc */ true);
-  space_builder.SetAvailableSize(column_size);
+  space_builder.SetAvailableSize(fragmentainer_size);
   space_builder.SetPercentageResolutionSize(percentage_resolution_size);
   space_builder.SetInlineAutoBehavior(NGAutoBehavior::kStretchImplicit);
-  space_builder.SetFragmentationType(kFragmentColumn);
+  space_builder.SetFragmentationType(fragmentation_type);
   space_builder.SetShouldPropagateChildBreakValues();
-  space_builder.SetFragmentainerBlockSize(column_size.block_size);
+  space_builder.SetFragmentainerBlockSize(fragmentainer_size.block_size);
   space_builder.SetIsAnonymous(true);
-  space_builder.SetIsInColumnBfc();
-  if (balance_columns)
+  if (fragmentation_type == kFragmentColumn) {
+    space_builder.SetIsInColumnBfc();
+  }
+  if (balance_columns) {
+    DCHECK_EQ(fragmentation_type, kFragmentColumn);
     space_builder.SetIsInsideBalancedColumns();
+  }
   space_builder.SetMinBreakAppeal(min_break_appeal);
   if (allow_discard_start_margin) {
     // Unless it's the first column in the multicol container, or the first
diff --git a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
index afd33a5..d13a759 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
+++ b/third_party/blink/renderer/core/layout/ng/ng_fragmentation_utils.h
@@ -454,10 +454,12 @@
   return nullptr;
 }
 
-// Calculate the constraint space for columns of a multi-column layout.
-NGConstraintSpace CreateConstraintSpaceForColumns(
+// Set up a constraint space for columns in multi-column layout, or for pages
+// when printing; as specified by fragmentation_type.
+NGConstraintSpace CreateConstraintSpaceForFragmentainer(
     const NGConstraintSpace& parent_space,
-    LogicalSize column_size,
+    NGFragmentationType fragmentation_type,
+    LogicalSize fragmentainer_size,
     LogicalSize percentage_resolution_size,
     bool allow_discard_start_margin,
     bool balance_columns,
diff --git a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
index dcf657f4..693a2e1b 100644
--- a/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
+++ b/third_party/blink/renderer/core/layout/ng/ng_out_of_flow_layout_part.cc
@@ -2464,12 +2464,10 @@
   // rather than moving to the next one).
   NGBreakAppeal min_break_appeal = kBreakAppealLastResort;
 
-  // TODO(bebeaudr): Need to handle different fragmentation types. It won't
-  // always be multi-column.
-  return CreateConstraintSpaceForColumns(
-      ConstraintSpace(), column_size, percentage_resolution_size,
-      allow_discard_start_margin, /* balance_columns */ false,
-      min_break_appeal);
+  return CreateConstraintSpaceForFragmentainer(
+      ConstraintSpace(), GetFragmentainerType(), column_size,
+      percentage_resolution_size, allow_discard_start_margin,
+      /* balance_columns */ false, min_break_appeal);
 }
 
 // Compute in which fragmentainer the OOF element will start its layout and
diff --git a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
index 31563ce..726bbbd 100644
--- a/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
+++ b/third_party/blink/renderer/core/layout/svg/layout_svg_root.cc
@@ -275,8 +275,6 @@
       Layer()->SetNeedsCompositingInputsUpdate();
   }
 
-  if (!RuntimeEnabledFeatures::LayoutNGUnifyUpdateAfterLayoutEnabled())
-    UpdateAfterLayout();
   ClearNeedsLayout();
 }
 
diff --git a/third_party/blink/renderer/core/layout/svg/svg_content_container.cc b/third_party/blink/renderer/core/layout/svg/svg_content_container.cc
index 34a314a8..40c946b 100644
--- a/third_party/blink/renderer/core/layout/svg/svg_content_container.cc
+++ b/third_party/blink/renderer/core/layout/svg/svg_content_container.cc
@@ -45,11 +45,7 @@
   // The above IsSVG() check is not enough for a <svg> in a foreign element
   // with `display: contents` because SVGSVGElement::LayoutObjectIsNeeded()
   // doesn't check HasSVGParent().
-  if (RuntimeEnabledFeatures::
-          SvgContainersRejectSvgInDisplayContentsEnabled()) {
-    return !child.IsSVGRoot();
-  }
-  return true;
+  return !child.IsSVGRoot();
 }
 
 void SVGContentContainer::Layout(const SVGContainerLayoutInfo& layout_info) {
diff --git a/third_party/blink/renderer/modules/csspaint/DIR_METADATA b/third_party/blink/renderer/modules/csspaint/DIR_METADATA
index 660b8317..0474e9a 100644
--- a/third_party/blink/renderer/modules/csspaint/DIR_METADATA
+++ b/third_party/blink/renderer/modules/csspaint/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
-  component: "Blink>CSS"
+  component: "Blink>Canvas"
 }
-team_email: "layout-dev@chromium.org"
\ No newline at end of file
+team_email: "canvas-dev@chromium.org"
\ No newline at end of file
diff --git a/third_party/blink/renderer/modules/direct_sockets/udp_message.idl b/third_party/blink/renderer/modules/direct_sockets/udp_message.idl
index 69e0faa..c08fe46 100644
--- a/third_party/blink/renderer/modules/direct_sockets/udp_message.idl
+++ b/third_party/blink/renderer/modules/direct_sockets/udp_message.idl
@@ -8,4 +8,5 @@
   BufferSource   data;
   DOMString      remoteAddress;
   unsigned short remotePort;
+  SocketDnsQueryType dnsQueryType;
 };
diff --git a/third_party/blink/renderer/modules/direct_sockets/udp_readable_stream_wrapper_unittest.cc b/third_party/blink/renderer/modules/direct_sockets/udp_readable_stream_wrapper_unittest.cc
index 1a0ca15..5bc0be24 100644
--- a/third_party/blink/renderer/modules/direct_sockets/udp_readable_stream_wrapper_unittest.cc
+++ b/third_party/blink/renderer/modules/direct_sockets/udp_readable_stream_wrapper_unittest.cc
@@ -43,6 +43,7 @@
 
   void SendTo(base::span<const uint8_t> data,
               const net::HostPortPair& dest_addr,
+              net::DnsQueryType dns_query_type,
               SendToCallback callback) override {
     NOTREACHED();
   }
diff --git a/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper.cc b/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper.cc
index e34d2fe8..f132f56 100644
--- a/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper.cc
+++ b/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper.cc
@@ -12,6 +12,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_typedefs.h"
 #include "third_party/blink/renderer/bindings/core/v8/v8_union_arraybuffer_arraybufferview.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_socket_dns_query_type.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_udp_message.h"
 #include "third_party/blink/renderer/core/dom/abort_signal.h"
 #include "third_party/blink/renderer/core/dom/dom_exception.h"
@@ -107,6 +108,24 @@
     return ScriptPromise();
   }
 
+  auto dns_query_type = net::DnsQueryType::UNSPECIFIED;
+  if (message->hasDnsQueryType()) {
+    if (mode_ == network::mojom::RestrictedUDPSocketMode::CONNECTED) {
+      exception_state.ThrowTypeError(
+          "UDPMessage: 'dnsQueryType' must not be specified "
+          "in 'connected' mode.");
+      return ScriptPromise();
+    }
+    switch (message->dnsQueryType().AsEnum()) {
+      case V8SocketDnsQueryType::Enum::kIpv4:
+        dns_query_type = net::DnsQueryType::A;
+        break;
+      case V8SocketDnsQueryType::Enum::kIpv6:
+        dns_query_type = net::DnsQueryType::AAAA;
+        break;
+    }
+  }
+
   DOMArrayPiece array_piece(message->data());
   base::span<const uint8_t> data{array_piece.Bytes(), array_piece.ByteLength()};
 
@@ -117,7 +136,8 @@
   auto callback = WTF::BindOnce(&UDPWritableStreamWrapper::OnSend,
                                 WrapWeakPersistent(this));
   if (dest_addr) {
-    udp_socket_->get()->SendTo(data, *dest_addr, std::move(callback));
+    udp_socket_->get()->SendTo(data, *dest_addr, dns_query_type,
+                               std::move(callback));
   } else {
     udp_socket_->get()->Send(data, std::move(callback));
   }
diff --git a/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper_unittest.cc b/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper_unittest.cc
index 9e8e5caf..c5e7afd 100644
--- a/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper_unittest.cc
+++ b/third_party/blink/renderer/modules/direct_sockets/udp_writable_stream_wrapper_unittest.cc
@@ -45,6 +45,7 @@
 
   void SendTo(base::span<const uint8_t> data,
               const net::HostPortPair& dest_addr,
+              net::DnsQueryType dns_query_type,
               SendToCallback callback) override {
     NOTREACHED();
   }
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
index b7819ad4..d50a5b0 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
@@ -7,6 +7,7 @@
 #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_testing.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_clamp_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ml_leaky_relu_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_transpose_options.h"
 #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h"
@@ -267,6 +268,61 @@
 }
 
 template <typename T>
+struct LeakyReluTester {
+  OperandInfo<T> input;
+  Vector<T> expected;
+
+  void Test(MLGraphTest& helper,
+            V8TestingScope& scope,
+            MLLeakyReluOptions* options = MLLeakyReluOptions::Create()) {
+    // Build the graph.
+    auto* builder = CreateMLGraphBuilder(scope.GetExecutionContext());
+    auto* input_operand = BuildInput(builder, "input", input.dimensions,
+                                     input.type, scope.GetExceptionState());
+    auto* output_operand =
+        BuildLeakyRelu(scope, builder, input_operand, options);
+    auto [graph, build_exception] =
+        helper.BuildGraph(scope, builder, {{"output", output_operand}});
+    EXPECT_NE(graph, nullptr);
+
+    // Compute the graph.
+    MLNamedArrayBufferViews inputs(
+        {{"input",
+          CreateArrayBufferViewForOperand(input_operand, input.values)}});
+    MLNamedArrayBufferViews outputs(
+        {{"output", CreateArrayBufferViewForOperand(output_operand)}});
+    auto* compute_exception =
+        helper.ComputeGraph(scope, graph, inputs, outputs);
+    EXPECT_EQ(compute_exception, nullptr);
+    auto results = GetArrayBufferViewValues<T>(outputs[0].second);
+    EXPECT_EQ(results, expected);
+  }
+};
+
+TEST_P(MLGraphTest, LeakyReluTest) {
+  V8TestingScope scope;
+  {
+    // Test leakyRelu operator with default options.
+    auto* options = MLLeakyReluOptions::Create();
+    LeakyReluTester<float>{.input = {.type = V8MLOperandType::Enum::kFloat32,
+                                     .dimensions = {1, 2, 2, 1},
+                                     .values = {10, 5, -100, 0}},
+                           .expected = {10, 5, -1, 0}}
+        .Test(*this, scope, options);
+  }
+  {
+    // Test leakyRelu operator with alpha = 0.2.
+    auto* options = MLLeakyReluOptions::Create();
+    options->setAlpha(0.2);
+    LeakyReluTester<float>{.input = {.type = V8MLOperandType::Enum::kFloat32,
+                                     .dimensions = {1, 2, 2, 1},
+                                     .values = {10, 5, -100, 0}},
+                           .expected = {10, 5, -20, 0}}
+        .Test(*this, scope, options);
+  }
+}
+
+template <typename T>
 struct Resample2dTester {
   OperandInfo<T> input;
   Vector<T> expected;
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc
index 856fa5f..2df6da5 100644
--- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc
+++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc
@@ -19,6 +19,7 @@
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_compute_result.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_conv_2d_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_gemm_options.h"
+#include "third_party/blink/renderer/bindings/modules/v8/v8_ml_leaky_relu_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_resample_2d_options.h"
 #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_transpose_options.h"
@@ -732,6 +733,25 @@
   return xnn_status_success;
 }
 
+xnn_status DefineXnnNodeForLeakyRelu(
+    xnn_subgraph_t subgraph,
+    const MLOperator* leaky_relu,
+    const OperandValueIdMap& operand_value_id_map,
+    String& error_message) {
+  const uint32_t input_id =
+      GetOperatorInputValueId(leaky_relu, operand_value_id_map);
+  const uint32_t output_id =
+      GetOperatorOutputValueId(leaky_relu, operand_value_id_map);
+  const MLLeakyReluOptions* options =
+      static_cast<const MLLeakyReluOptions*>(leaky_relu->Options());
+  CHECK(options);
+  const float negative_slope = options->alpha();
+  const uint32_t flags = 0;
+  XNN_CHECK_STATUS_AND_SET_ERROR_MESSAGE(xnn_define_leaky_relu(
+      subgraph, negative_slope, input_id, output_id, flags));
+  return xnn_status_success;
+}
+
 xnn_status DefineXnnNodeForPool2d(xnn_subgraph_t subgraph,
                                   const MLOperator* pool2d,
                                   const OperandValueIdMap& operand_value_id_map,
@@ -1095,6 +1115,10 @@
           subgraph, ml_operator, operand_value_id_map, error_message));
       break;
     }
+    case MLOperator::OperatorKind::kLeakyRelu:
+      XNN_CHECK_STATUS(DefineXnnNodeForLeakyRelu(
+          subgraph, ml_operator, operand_value_id_map, error_message));
+      break;
     case MLOperator::OperatorKind::kRelu:
       XNN_CHECK_STATUS(DefineXnnNodeForRelu(
           subgraph, ml_operator, operand_value_id_map, error_message));
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5
index e8b4d85..9f0ae46 100644
--- a/third_party/blink/renderer/platform/runtime_enabled_features.json5
+++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1887,10 +1887,6 @@
       public: true,
     },
     {
-      name: "ImeVerticalFlag",
-      status: "stable",
-    },
-    {
       name: "ImplicitRootScroller",
       public: true,
       settable_from_internals: true,
@@ -1990,12 +1986,6 @@
       base_feature: "none",
     },
     {
-      // Merge UpdateAfterLayout() calls for LayoutReplaced into one in
-      // CopyFragmentDataToLayoutBox(). crbug.com/1353190
-      name: "LayoutNGUnifyUpdateAfterLayout",
-      status: "stable",
-    },
-    {
       name: "LazyFrameLoading",
       public: true,
       status: "stable",
@@ -3251,11 +3241,6 @@
       base_feature: "none",
     },
     {
-      // crbug.com/1393223
-      name: "SvgContainersRejectSvgInDisplayContents",
-      status: "stable",
-    },
-    {
       name: "SvgRasterOptimizations",
       status: "experimental",
     },
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations
index da13085..edc1d88 100644
--- a/third_party/blink/web_tests/TestExpectations
+++ b/third_party/blink/web_tests/TestExpectations
@@ -4171,7 +4171,9 @@
 # Sheriff 2019-08-22
 crbug.com/994008 [ Linux ] http/tests/devtools/elements/styles-3/styles-computed-trace.js [ Failure Pass Timeout ]
 crbug.com/994008 [ Win ] http/tests/devtools/elements/styles-3/styles-computed-trace.js [ Failure Pass Timeout ]
-crbug.com/994034 [ Linux ] http/tests/devtools/elements/styles-3/styles-add-new-rule-colon.js [ Failure Pass Timeout ]
+
+# Temporarily disable test to land "Roll devtools-internal"
+crbug.com/1427916 http/tests/devtools/elements/styles-3/styles-add-new-rule-colon.js [ Failure Pass Timeout ]
 
 crbug.com/995669 [ Win ] http/tests/media/video-throttled-load-metadata.html [ Crash Failure Pass ]
 
@@ -6671,10 +6673,6 @@
 # Temporarily disabled for a v8 change
 crbug.com/1418938 http/tests/devtools/sources/debugger-step/debugger-step-into-event-listener.js [ Failure Skip ]
 
-# Flaky loaf tests, still working on deflaking.
-crbug.com/1422630 external/wpt/long-animation-frame/tentative/loaf-desired-exec-time.html [ Failure Pass Timeout ]
-crbug.com/1422630 external/wpt/long-animation-frame/tentative/loaf-script-block.html [ Failure Pass Timeout ]
-
 # Sheriff 2023-03-23
 crbug.com/952717 [ Win10.20h2 ] http/tests/xmlhttprequest/redirect-cross-origin-post.html [ Failure Pass ]
 
@@ -6691,4 +6689,4 @@
 crbug.com/1427397 http/tests/devtools/persistence/persistence-navigator-unique-names.js [ Failure Pass ]
 
 # Sheriff 2023-03-27
-crbug.com/1427936 external/wpt/js-self-profiling/function-expression-names.https.html [ Failure Pass ]
\ No newline at end of file
+crbug.com/1427936 external/wpt/js-self-profiling/function-expression-names.https.html [ Failure Pass ]
diff --git a/third_party/blink/web_tests/css-parser/DIR_METADATA b/third_party/blink/web_tests/css-parser/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css-parser/DIR_METADATA
+++ b/third_party/blink/web_tests/css-parser/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css1/basic/DIR_METADATA b/third_party/blink/web_tests/css1/basic/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css1/basic/DIR_METADATA
+++ b/third_party/blink/web_tests/css1/basic/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css1/box_properties/DIR_METADATA b/third_party/blink/web_tests/css1/box_properties/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css1/box_properties/DIR_METADATA
+++ b/third_party/blink/web_tests/css1/box_properties/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css1/cascade/DIR_METADATA b/third_party/blink/web_tests/css1/cascade/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css1/cascade/DIR_METADATA
+++ b/third_party/blink/web_tests/css1/cascade/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css1/classification/DIR_METADATA b/third_party/blink/web_tests/css1/classification/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css1/classification/DIR_METADATA
+++ b/third_party/blink/web_tests/css1/classification/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css1/color_and_background/DIR_METADATA b/third_party/blink/web_tests/css1/color_and_background/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css1/color_and_background/DIR_METADATA
+++ b/third_party/blink/web_tests/css1/color_and_background/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css1/conformance/DIR_METADATA b/third_party/blink/web_tests/css1/conformance/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css1/conformance/DIR_METADATA
+++ b/third_party/blink/web_tests/css1/conformance/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css1/pseudo/DIR_METADATA b/third_party/blink/web_tests/css1/pseudo/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css1/pseudo/DIR_METADATA
+++ b/third_party/blink/web_tests/css1/pseudo/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css1/units/DIR_METADATA b/third_party/blink/web_tests/css1/units/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css1/units/DIR_METADATA
+++ b/third_party/blink/web_tests/css1/units/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css2.1/DIR_METADATA b/third_party/blink/web_tests/css2.1/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css2.1/DIR_METADATA
+++ b/third_party/blink/web_tests/css2.1/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/css3/DIR_METADATA b/third_party/blink/web_tests/css3/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/css3/DIR_METADATA
+++ b/third_party/blink/web_tests/css3/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/cssom/DIR_METADATA b/third_party/blink/web_tests/cssom/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/cssom/DIR_METADATA
+++ b/third_party/blink/web_tests/cssom/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
diff --git a/third_party/blink/web_tests/custom-properties/DIR_METADATA b/third_party/blink/web_tests/custom-properties/DIR_METADATA
index a1cb39c..4f1274e9 100644
--- a/third_party/blink/web_tests/custom-properties/DIR_METADATA
+++ b/third_party/blink/web_tests/custom-properties/DIR_METADATA
@@ -1,4 +1,4 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
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 ffdc59cf..3f4a39a 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
@@ -182619,6 +182619,19 @@
         {}
        ]
       ],
+      "text-align-last-015.html": [
+       "a0d8fa4df92c4b5a1cb1e37cfb1177bcaa71e3f7",
+       [
+        null,
+        [
+         [
+          "/css/css-text/text-align/text-align-last-015-ref.html",
+          "=="
+         ]
+        ],
+        {}
+       ]
+      ],
       "text-align-last-center.html": [
        "639156062d23e61d07130b48b573fc521f115382",
        [
@@ -267443,16 +267456,6 @@
    }
   },
   "support": {
-   ".cache": {
-    "gitignore2.json": [
-     "d14ad630c03e8d0619ad95b56ef3007a441a3490",
-     []
-    ],
-    "mtime.json": [
-     "e925d358f44bfb292ee7b55a8784315f4b809692",
-     []
-    ]
-   },
    ".gitignore": [
     "d93e645d547894b50149d3726de2654957b6e06f",
     []
@@ -282397,7 +282400,7 @@
      }
     },
     "DIR_METADATA": [
-     "275a4301518da45ba222e6ce4e6a69c6dc2b415d",
+     "c41ee089b8e083540febdab0fb23c1c8bafbbfc5",
      []
     ],
     "README.md": [
@@ -317060,6 +317063,10 @@
        "2f26b42723d0e736ef8d01ddc72ec3cc5e69d088",
        []
       ],
+      "text-align-last-015-ref.html": [
+       "75fc7d22c66b1e3180d08de2208e5b3eff6dec19",
+       []
+      ],
       "text-align-last-center-ref.html": [
        "6ad0e6396d18f437d18d4ac87594260ffac9ae4c",
        []
@@ -365939,18 +365946,10 @@
      []
     ],
     "tentative": {
-     "loaf-desired-exec-time.html.ini": [
-      "6462928c3a3e0a9d2efdfe48cd031a4296a512c7",
-      []
-     ],
      "loaf-first-ui-event.html.ini": [
       "a3d3fb4e0bd5cacd8cb627501073eaf076b90af7",
       []
      ],
-     "loaf-script-block.html.ini": [
-      "8b5c9fa63607cc2d18d9eba06219092c42f39447",
-      []
-     ],
      "loaf-visibility.html.ini": [
       "60ce4deae28d3344ecd0b184d4220b1a3b198108",
       []
@@ -365961,7 +365960,7 @@
        []
       ],
       "utils.js": [
-       "394d81706cc8ec7f11e566b91d272e6edd3cc1fa",
+       "f956ed410186a6ea5ca0cc698fb5966974d1d90d",
        []
       ]
      }
@@ -372209,7 +372208,7 @@
    },
    "quirks": {
     "DIR_METADATA": [
-     "275a4301518da45ba222e6ce4e6a69c6dc2b415d",
+     "c41ee089b8e083540febdab0fb23c1c8bafbbfc5",
      []
     ],
     "META.yml": [
@@ -430374,14 +430373,14 @@
        ]
       ],
       "animation-shorthand.html": [
-       "b981ad3ad6893c3305183c965be973eb369331c5",
+       "464e42460b169f52b4558d0b2778c04c82eeaf36",
        [
         null,
         {}
        ]
       ],
       "animation-shorthand.tentative.html": [
-       "ac3613cf825c0e739c3ed5a27db248aeeaa2aabc",
+       "04d06080e5efd7b9a00bfc6d5e191902c0396cde",
        [
         null,
         {}
@@ -558446,7 +558445,7 @@
       ]
      ],
      "loaf-first-ui-event.html": [
-      "b30b645d2fab262e77b922c0d0d075b23d1f844d",
+      "47a3a51de215e47add78b96047d431b13eb89257",
       [
        null,
        {
@@ -558483,7 +558482,7 @@
       ]
      ],
      "loaf-script-block.html": [
-      "f896a737ce7cc14af380a772a06146b874a6c74e",
+      "866eea09e0907622ad62c53c8b5f020566ba559f",
       [
        null,
        {
@@ -589054,7 +589053,7 @@
       ]
      ],
      "animation-shorthand.html": [
-      "87e66d0f532bf85de5e19e90235e8fc71e7cb11a",
+      "7bd17b9919070006824fee9e77ec5b20e464315b",
       [
        null,
        {}
@@ -589313,7 +589312,7 @@
       ]
      ],
      "view-timeline-animation-range-update.tentative.html": [
-      "41386bd7c55baff1062e3d0caa7f663cf80c0637",
+      "6c2a792aeec0c0baf4998423a9e4750a1de2af4e",
       [
        null,
        {}
diff --git a/third_party/blink/web_tests/external/wpt/css/DIR_METADATA b/third_party/blink/web_tests/external/wpt/css/DIR_METADATA
index 275a430..c41ee089 100644
--- a/third_party/blink/web_tests/external/wpt/css/DIR_METADATA
+++ b/third_party/blink/web_tests/external/wpt/css/DIR_METADATA
@@ -1,7 +1,7 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
 wpt {
   notify: YES
 }
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.html
index b981ad3a..464e424 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.html
@@ -20,7 +20,9 @@
   'animation-fill-mode': 'both',
   'animation-play-state': 'paused',
   'animation-name': 'anim',
-  'animation-timeline': 'auto'
+  'animation-timeline': 'auto',
+  'animation-range-start': 'normal',
+  'animation-range-end': 'normal',
 });
 
 test_shorthand_value('animation', 'anim paused both reverse, 4 1s -3s cubic-bezier(0, -2, 1, 3)', {
@@ -32,7 +34,9 @@
   'animation-fill-mode': 'both, none',
   'animation-play-state': 'paused, running',
   'animation-name': 'anim, none',
-  'animation-timeline': 'auto, auto'
+  'animation-timeline': 'auto, auto',
+  'animation-range-start': 'normal, normal',
+  'animation-range-end': 'normal, normal',
 });
 
 test_shorthand_value('animation', '4 1s -3s cubic-bezier(0, -2, 1, 3), anim paused both reverse', {
@@ -44,7 +48,9 @@
   'animation-fill-mode': 'none, both',
   'animation-play-state': 'running, paused',
   'animation-name': 'none, anim',
-  'animation-timeline': 'auto, auto'
+  'animation-timeline': 'auto, auto',
+  'animation-range-start': 'normal, normal',
+  'animation-range-end': 'normal, normal',
 });
 </script>
 </body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.tentative.html
index ac3613c..04d0608 100644
--- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-shorthand.tentative.html
@@ -18,6 +18,8 @@
   'animation-fill-mode': 'both',
   'animation-play-state': 'paused',
   'animation-name': 'anim',
-  'animation-timeline': 'auto'
+  'animation-timeline': 'auto',
+  'animation-range-start': 'normal',
+  'animation-range-end': 'normal',
 });
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-015-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-015-ref.html
new file mode 100644
index 0000000..75fc7d22
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-015-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Reference: text-align-last applied to last line in the second column</title>
+<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+
+<style>
+:root {
+  font: 25px/1 Ahem;
+}
+.multicol {
+  width: 200px;
+  border: 5px solid orange;
+}
+</style>
+
+<div class="multicol">
+  <div>ab&nbsp;&nbsp;ab</div>
+  <div>ab&nbsp;&nbsp;&nbsp;&nbsp;ab</div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-015.html b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-015.html
new file mode 100644
index 0000000..a0d8fa4
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/css-text/text-align/text-align-last-015.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Text Test: text-align-last applied to last line in the second column</title>
+<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#text-align-last-property">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1817235">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<link rel="match" href="text-align-last-015-ref.html">
+
+<style>
+:root {
+  font: 25px/1 Ahem;
+}
+.multicol {
+  width: 200px;
+  column-count: 2;
+  column-gap: 0;
+  border: 5px solid orange;
+}
+.multicol > div {
+  text-align: start;
+  text-align-last: end;
+}
+</style>
+
+<div class="multicol">
+  <div>ab ab ab ab</div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/printing/page-name-003-print-ref.html b/third_party/blink/web_tests/external/wpt/css/printing/page-name-003-print-ref.html
new file mode 100644
index 0000000..52ea6bff
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/printing/page-name-003-print-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+1st page
+<div style="break-before:page;">
+  2nd page
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/css/printing/page-name-003-print.html b/third_party/blink/web_tests/external/wpt/css/printing/page-name-003-print.html
new file mode 100644
index 0000000..9ef4db8c75
--- /dev/null
+++ b/third_party/blink/web_tests/external/wpt/css/printing/page-name-003-print.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-page-3/#using-named-pages">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1428011">
+<link rel="match" href="page-name-003-print-ref.html">
+<div style="position:absolute;">
+  <div style="page:a;">1st page</div>
+  <div style="page:b;">2nd page</div>
+</div>
diff --git a/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-desired-exec-time.html.ini b/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-desired-exec-time.html.ini
deleted file mode 100644
index 6462928c..0000000
--- a/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-desired-exec-time.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[loaf-desired-exec-time.html]
-  [event-listener entries desiredExecutionStart is the eventTimestamp]
-    expected:
-      if product == "chrome": FAIL
diff --git a/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-script-block.html b/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-script-block.html
index f896a737..866eea09 100644
--- a/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-script-block.html
+++ b/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-script-block.html
@@ -4,6 +4,7 @@
 <meta name="timeout" content="long">
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
 <script src="resources/utils.js"></script>
 
 <body>
@@ -30,16 +31,18 @@
 }, new URL("resources/busy.js", location.href).href, "classic-script");
 
 test_self_script_block(t => {
+    const uid = token();
     const script = document.createElement("script");
-    script.src = "resources/busy.js";
+    script.src = `resources/busy.js?token=${uid}`;
     script.type = "module";
     document.body.appendChild(script);
 }, new URL("resources/busy.js", location.href).href, "module-script");
 
 test_self_script_block(t => {
+    const uid = token();
     const script = document.createElement("script");
     script.type = "module";
-    script.innerHTML = `import("./resources/busy.js?import");`;
+    script.innerHTML = `import("./resources/busy.js?import=${uid}");`;
     document.body.appendChild(script);
 }, new URL("resources/busy.js?import", location.href).href, "execute-script");
 
diff --git a/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-script-block.html.ini b/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-script-block.html.ini
deleted file mode 100644
index 8b5c9fa6..0000000
--- a/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/loaf-script-block.html.ini
+++ /dev/null
@@ -1,5 +0,0 @@
-[loaf-script-block.html]
-  [LoAF script: http://web-platform.test:8001/long-animation-frame/tentative/resources/busy.js?import execute-script,]
-    expected:
-      if (product == "content_shell") and (os == "mac"): FAIL
-      if (product == "content_shell") and (os == "linux"): FAIL
diff --git a/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/resources/utils.js b/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/resources/utils.js
index 394d817..f956ed41 100644
--- a/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/resources/utils.js
+++ b/third_party/blink/web_tests/external/wpt/long-animation-frame/tentative/resources/utils.js
@@ -97,10 +97,12 @@
   promise_test(async t => {
     let [entry, script] = [];
     [entry, script] = await expect_long_frame_with_script(cb,
-      script => (script.type === type && script.duration >= very_long_frame_duration), t);
+      script => (
+        script.type === type &&
+        script.name.startsWith(name) &&
+        script.duration >= very_long_frame_duration), t);
 
     assert_true(!!entry, "Entry detected");
-    assert_equals(script.name, name);
     assert_greater_than_equal(script.duration, very_long_frame_duration);
     assert_greater_than_equal(entry.duration, script.duration);
     assert_greater_than_equal(script.executionStart, script.startTime);
diff --git a/third_party/blink/web_tests/external/wpt/quirks/DIR_METADATA b/third_party/blink/web_tests/external/wpt/quirks/DIR_METADATA
index 275a430..c41ee089 100644
--- a/third_party/blink/web_tests/external/wpt/quirks/DIR_METADATA
+++ b/third_party/blink/web_tests/external/wpt/quirks/DIR_METADATA
@@ -1,7 +1,7 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
 wpt {
   notify: YES
 }
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-shorthand.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-shorthand.html
index 87e66d0..7bd17b9 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-shorthand.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/animation-shorthand.html
@@ -38,7 +38,9 @@
   'animation-fill-mode': 'forwards, forwards, forwards',
   'animation-play-state': 'paused, paused, paused',
   'animation-name': 'anim1, anim2, anim3',
-  'animation-timeline': 'auto, auto, auto'
+  'animation-timeline': 'auto, auto, auto',
+  'animation-range-start': 'normal, normal, normal',
+  'animation-range-end': 'normal, normal, normal',
 });
 
 test((t) => {
@@ -89,4 +91,52 @@
   assert_equals(getComputedStyle(target).animationDuration, '1s');
 }, 'Animation shorthand can not represent non-initial animation-delay-end (computed)');
 
+test((t) => {
+  t.add_cleanup(() => {
+    target.style = '';
+  });
+
+  target.style.animation = 'anim 1s';
+  target.style.animationRangeStart = 'entry';
+  assert_equals(target.style.animation, '');
+  assert_equals(target.style.animationName, 'anim');
+  assert_equals(target.style.animationDuration, '1s');
+}, 'Animation shorthand can not represent non-initial animation-range-start (specified)');
+
+test((t) => {
+  t.add_cleanup(() => {
+    target.style = '';
+  });
+
+  target.style.animation = 'anim 1s';
+  target.style.animationRangeStart = 'entry';
+  assert_equals(getComputedStyle(target).animation, '');
+  assert_equals(getComputedStyle(target).animationName, 'anim');
+  assert_equals(getComputedStyle(target).animationDuration, '1s');
+}, 'Animation shorthand can not represent non-initial animation-range-start (computed)');
+
+test((t) => {
+  t.add_cleanup(() => {
+    target.style = '';
+  });
+
+  target.style.animation = 'anim 1s';
+  target.style.animationRangeEnd = 'entry';
+  assert_equals(target.style.animation, '');
+  assert_equals(target.style.animationName, 'anim');
+  assert_equals(target.style.animationDuration, '1s');
+}, 'Animation shorthand can not represent non-initial animation-range-end (specified)');
+
+test((t) => {
+  t.add_cleanup(() => {
+    target.style = '';
+  });
+
+  target.style.animation = 'anim 1s';
+  target.style.animationRangeEnd = 'entry';
+  assert_equals(getComputedStyle(target).animation, '');
+  assert_equals(getComputedStyle(target).animationName, 'anim');
+  assert_equals(getComputedStyle(target).animationDuration, '1s');
+}, 'Animation shorthand can not represent non-initial animation-range-end (computed)');
+
 </script>
diff --git a/third_party/blink/web_tests/external/wpt/scroll-animations/css/view-timeline-animation-range-update.tentative.html b/third_party/blink/web_tests/external/wpt/scroll-animations/css/view-timeline-animation-range-update.tentative.html
index 41386bd..6c2a792ae 100644
--- a/third_party/blink/web_tests/external/wpt/scroll-animations/css/view-timeline-animation-range-update.tentative.html
+++ b/third_party/blink/web_tests/external/wpt/scroll-animations/css/view-timeline-animation-range-update.tentative.html
@@ -19,7 +19,8 @@
     width: 200px;
     height: 200px;
   }
-  #target {
+  /* Reset specificity to allow animation-range-* from .restrict-range to win. */
+  :where(#target) {
     margin: 800px 0px;
     width: 100px;
     height: 100px;
diff --git a/third_party/blink/web_tests/fast/css-generated-content/DIR_METADATA b/third_party/blink/web_tests/fast/css-generated-content/DIR_METADATA
index 7bdd904..adc82906 100644
--- a/third_party/blink/web_tests/fast/css-generated-content/DIR_METADATA
+++ b/third_party/blink/web_tests/fast/css-generated-content/DIR_METADATA
@@ -1,5 +1,5 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
 
diff --git a/third_party/blink/web_tests/fast/css/DIR_METADATA b/third_party/blink/web_tests/fast/css/DIR_METADATA
index 7bdd904..adc82906 100644
--- a/third_party/blink/web_tests/fast/css/DIR_METADATA
+++ b/third_party/blink/web_tests/fast/css/DIR_METADATA
@@ -1,5 +1,5 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
 
diff --git a/third_party/blink/web_tests/fast/dom/CSSStyleDeclaration/DIR_METADATA b/third_party/blink/web_tests/fast/dom/CSSStyleDeclaration/DIR_METADATA
index 7bdd904..adc82906 100644
--- a/third_party/blink/web_tests/fast/dom/CSSStyleDeclaration/DIR_METADATA
+++ b/third_party/blink/web_tests/fast/dom/CSSStyleDeclaration/DIR_METADATA
@@ -1,5 +1,5 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-keyframes-display-none-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-keyframes-display-none-expected.txt
index 82cc766..fbde0ea 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-keyframes-display-none-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-keyframes-display-none-expected.txt
@@ -46,6 +46,8 @@
         animation-play-state: running;
         animation-name: animName;
         animation-timeline: auto;
+        animation-range-start: normal;
+        animation-range-end: normal;
     display: none;
 
 [expanded] 
diff --git a/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-keyframes-expected.txt b/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-keyframes-expected.txt
index 3763baeb..12864ac 100644
--- a/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-keyframes-expected.txt
+++ b/third_party/blink/web_tests/http/tests/devtools/elements/styles-4/styles-keyframes-expected.txt
@@ -17,6 +17,8 @@
         animation-play-state: running, running, running, running;
         animation-name: animName, mediaAnim, doesNotExist, styleSheetAnim;
         animation-timeline: auto, auto, auto, auto;
+        animation-range-start: normal, normal, normal, normal;
+        animation-range-end: normal, normal, normal, normal;
 
 [expanded] 
 div { (user agent stylesheet)
@@ -71,6 +73,8 @@
         animation-play-state: running, running, running, running;
         animation-name: animName, mediaAnim, doesNotExist, styleSheetAnim;
         animation-timeline: auto, auto, auto, auto;
+        animation-range-start: normal, normal, normal, normal;
+        animation-range-end: normal, normal, normal, normal;
 
 [expanded] 
 div { (user agent stylesheet)
@@ -125,6 +129,8 @@
         animation-play-state: running, running, running, running;
         animation-name: animName, mediaAnim, doesNotExist, styleSheetAnim;
         animation-timeline: auto, auto, auto, auto;
+        animation-range-start: normal, normal, normal, normal;
+        animation-range-end: normal, normal, normal, normal;
 
 [expanded] 
 div { (user agent stylesheet)
@@ -179,6 +185,8 @@
         animation-play-state: running, running, running, running;
         animation-name: animName, mediaAnim, doesNotExist, styleSheetAnim;
         animation-timeline: auto, auto, auto, auto;
+        animation-range-start: normal, normal, normal, normal;
+        animation-range-end: normal, normal, normal, normal;
 
 [expanded] 
 div { (user agent stylesheet)
@@ -233,6 +241,8 @@
         animation-play-state: running, running, running, running;
         animation-name: animName, mediaAnim, doesNotExist, styleSheetAnim;
         animation-timeline: auto, auto, auto, auto;
+        animation-range-start: normal, normal, normal, normal;
+        animation-range-end: normal, normal, normal, normal;
 
 [expanded] 
 div { (user agent stylesheet)
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/remove-breakpoint-regex-close-expected.txt b/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/remove-breakpoint-regex-close-expected.txt
deleted file mode 100644
index 39934779..0000000
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/remove-breakpoint-regex-close-expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Tests debugger disconnect while removing a regexp breakpoint.
-Called setBreakpointByUrl (with regex)
-Called removeBreakpoint (with regex)
-Disconnected
-
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/remove-breakpoint-regex-close.js b/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/remove-breakpoint-regex-close.js
deleted file mode 100644
index 883e33b..0000000
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/remove-breakpoint-regex-close.js
+++ /dev/null
@@ -1,32 +0,0 @@
-(async function(testRunner) {
-  const {session, dp, page} = await testRunner.startBlank(
-      `Tests debugger disconnect while removing a regexp breakpoint.`);
-
-  await dp.Target.setDiscoverTargets({discover: true});
-  await dp.Debugger.enable();
-
-  const name = '0'.repeat(20);
-  for (let i = 0; i < 10; i++) {
-    await session.evaluateAsync(`//# sourceURL=${name}${i}.js`);
-  }
-
-  const {result: {breakpointId}} = await dp.Debugger.setBreakpointByUrl(
-      {lineNumber: 5, columnNumber: 0, urlRegex: '^(0+)*x$'});
-  testRunner.log('Called setBreakpointByUrl (with regex)');
-
-  // [crbug.com/1426163] Disconnecting the debugger while
-  // in removeBreakpoint should not crash. Note that removeBreakpoint
-  // with regexp can be interrupted in v8; let us try to disconnect
-  // during that interrupt.
-  dp.Debugger.removeBreakpoint({breakpointId});
-  testRunner.log('Called removeBreakpoint (with regex)');
-
-  await session.disconnect();
-  testRunner.log('Disconnected');
-
-  // Let's try to connect to the page to make sure it is still alive.
-  const session2 = await page.createSession();
-  await session2.protocol.Debugger.enable();
-
-  testRunner.completeTest();
-})
diff --git a/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/set-breakpoint-regex-close.js b/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/set-breakpoint-regex-close.js
index 6488fd64..f21cfcb 100644
--- a/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/set-breakpoint-regex-close.js
+++ b/third_party/blink/web_tests/http/tests/inspector-protocol/debugger/set-breakpoint-regex-close.js
@@ -1,5 +1,5 @@
 (async function(testRunner) {
-  const {session, dp, page} = await testRunner.startBlank(
+  const {session, dp} = await testRunner.startBlank(
       `Tests setting a regexp breakpoint and disconnect.`);
 
   await dp.Target.setDiscoverTargets({discover: true});
@@ -21,9 +21,5 @@
   session.disconnect();
   testRunner.log('Disconnected');
 
-  // Let's try to connect to the page to make sure it is still alive.
-  const session2 = await page.createSession();
-  await session2.protocol.Debugger.enable();
-
   testRunner.completeTest();
-})
+})
\ No newline at end of file
diff --git a/third_party/blink/web_tests/inspector-protocol/css/css-get-position-fallbacks-expected.txt b/third_party/blink/web_tests/inspector-protocol/css/css-get-position-fallbacks-expected.txt
new file mode 100644
index 0000000..054f0b7b
--- /dev/null
+++ b/third_party/blink/web_tests/inspector-protocol/css/css-get-position-fallbacks-expected.txt
@@ -0,0 +1,13 @@
+Test that position-fallback rules are reported.
+Dumping CSS position-fallback rules: 
+@position-fallback --top-first {
+    @try {
+        top: anchor(--anchor top); @[14:8-14:34]
+        top: anchor(--anchor top); @[undefined-undefined]
+    }
+    @try {
+        top: anchor(--anchor bottom); @[18:8-18:37]
+        top: anchor(--anchor bottom); @[undefined-undefined]
+    }
+}
+
diff --git a/third_party/blink/web_tests/inspector-protocol/css/css-get-position-fallbacks.js b/third_party/blink/web_tests/inspector-protocol/css/css-get-position-fallbacks.js
new file mode 100644
index 0000000..c0efae6
--- /dev/null
+++ b/third_party/blink/web_tests/inspector-protocol/css/css-get-position-fallbacks.js
@@ -0,0 +1,41 @@
+(async function(testRunner) {
+  var {page, session, dp} = await testRunner.startHTML(`
+<style>
+
+#anchor {
+    position: relative;
+    anchor-name: --anchor;
+}
+
+#anchored-element {
+    position: absolute;
+    position-fallback: --top-first;
+}
+
+@position-fallback --top-first {
+    @try {
+        top: anchor(--anchor top);
+    }
+
+    @try {
+        top: anchor(--anchor bottom);
+    }
+}
+
+</style>
+<div id='anchor'>
+    <div id='anchored-element'></div>
+</div>
+`, 'Test that position-fallback rules are reported.');
+
+  var CSSHelper = await testRunner.loadScript('../resources/css-helper.js');
+  var cssHelper = new CSSHelper(testRunner, dp);
+
+  await dp.DOM.enable();
+  await dp.CSS.enable();
+
+  var documentNodeId = await cssHelper.requestDocumentNodeId();
+  var nodeId = await cssHelper.requestNodeId(documentNodeId, '#anchored-element');
+  await cssHelper.loadAndDumpCSSPositionFallbacksForNode(nodeId);
+  testRunner.completeTest();
+});
diff --git a/third_party/blink/web_tests/inspector-protocol/resources/css-helper.js b/third_party/blink/web_tests/inspector-protocol/resources/css-helper.js
index 19340a3..7fee79c6 100644
--- a/third_party/blink/web_tests/inspector-protocol/resources/css-helper.js
+++ b/third_party/blink/web_tests/inspector-protocol/resources/css-helper.js
@@ -186,6 +186,22 @@
     }
   }
 
+  async loadAndDumpCSSPositionFallbacksForNode(nodeId) {
+    var {result} =
+        await this._dp.CSS.getMatchedStylesForNode({'nodeId': nodeId});
+    this._testRunner.log('Dumping CSS position-fallback rules: ');
+    for (var cssPositionFallbackRule of result.cssPositionFallbackRules) {
+      this._testRunner.log(
+          '@position-fallback ' + cssPositionFallbackRule.name.text + ' {');
+      for (var tryRule of cssPositionFallbackRule.tryRules) {
+        this._indentLog(4, '@try {');
+        this.dumpStyle(tryRule.style, 4);
+        this._indentLog(4, '}');
+      }
+      this._testRunner.log('}');
+    }
+  }
+
   async loadAndDumpCSSAnimationsForNode(nodeId) {
     var {result} =
         await this._dp.CSS.getMatchedStylesForNode({'nodeId': nodeId});
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/leaky_relu.https.any-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/leaky_relu.https.any-expected.txt
deleted file mode 100644
index 754ecc8..0000000
--- a/third_party/blink/web_tests/platform/win/external/wpt/webnn/leaky_relu.https.any-expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-This is a testharness.js-based test.
-FAIL leakyRelu float32 1D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 2D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 3D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 4D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 5D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 1D tensor negative options.alpha / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 2D tensor positive options.alpha / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 5D tensor options.alpha=0.0 / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/leaky_relu.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/leaky_relu.https.any.worker-expected.txt
deleted file mode 100644
index f978ca4..0000000
--- a/third_party/blink/web_tests/platform/win/external/wpt/webnn/leaky_relu.https.any.worker-expected.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-This is a testharness.js-based test.
-FAIL leakyRelu float32 1D tensor default options / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (leakyRelu) is not supported.
-FAIL leakyRelu float32 2D tensor default options / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (leakyRelu) is not supported.
-FAIL leakyRelu float32 3D tensor default options / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (leakyRelu) is not supported.
-FAIL leakyRelu float32 4D tensor default options / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (leakyRelu) is not supported.
-FAIL leakyRelu float32 5D tensor default options / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (leakyRelu) is not supported.
-FAIL leakyRelu float32 1D tensor negative options.alpha / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (leakyRelu) is not supported.
-FAIL leakyRelu float32 2D tensor positive options.alpha / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (leakyRelu) is not supported.
-FAIL leakyRelu float32 5D tensor options.alpha=0.0 / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (leakyRelu) is not supported.
-FAIL leakyRelu float32 1D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 2D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 3D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 4D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 5D tensor default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 1D tensor negative options.alpha / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 2D tensor positive options.alpha / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-FAIL leakyRelu float32 5D tensor options.alpha=0.0 / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (leakyRelu) is not supported."
-Harness: the test ran to completion.
-
diff --git a/third_party/blink/web_tests/typedcssom/DIR_METADATA b/third_party/blink/web_tests/typedcssom/DIR_METADATA
index 7bdd904..adc82906 100644
--- a/third_party/blink/web_tests/typedcssom/DIR_METADATA
+++ b/third_party/blink/web_tests/typedcssom/DIR_METADATA
@@ -1,5 +1,5 @@
 monorail {
   component: "Blink>CSS"
 }
-team_email: "layout-dev@chromium.org"
+team_email: "style-dev@chromium.org"
 
diff --git a/third_party/blink/web_tests/virtual/view-transition-wide-gamut/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt b/third_party/blink/web_tests/virtual/view-transition-wide-gamut/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt
index 2f074e16..3500ad7 100644
--- a/third_party/blink/web_tests/virtual/view-transition-wide-gamut/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt
+++ b/third_party/blink/web_tests/virtual/view-transition-wide-gamut/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt
@@ -4,6 +4,8 @@
     result : {
         cssKeyframesRules : [
         ]
+        cssPositionFallbackRules : [
+        ]
         inherited : [
         ]
         inheritedPseudoElements : [
diff --git a/third_party/blink/web_tests/virtual/view-transition/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt b/third_party/blink/web_tests/virtual/view-transition/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt
index 2f074e16..3500ad7 100644
--- a/third_party/blink/web_tests/virtual/view-transition/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt
+++ b/third_party/blink/web_tests/virtual/view-transition/inspector-protocol/css/css-get-styles-for-view-transition-expected.txt
@@ -4,6 +4,8 @@
     result : {
         cssKeyframesRules : [
         ]
+        cssPositionFallbackRules : [
+        ]
         inherited : [
         ]
         inheritedPseudoElements : [
diff --git a/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt b/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
index c5a65ee..581f334 100644
--- a/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
+++ b/third_party/blink/web_tests/webexposed/css-property-listing-expected.txt
@@ -462,6 +462,8 @@
         animation-iteration-count
         animation-name
         animation-play-state
+        animation-range-end
+        animation-range-start
         animation-timeline
         animation-timing-function
     animation-delay
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl
index 6c6f602..31ab7012 100644
--- a/tools/mb/mb_config.pyl
+++ b/tools/mb/mb_config.pyl
@@ -1461,7 +1461,7 @@
       'linux_chromium_compile': 'release_trybot_reclient',
       'linux_chromium_compile_dbg': 'debug_bot_reclient',
       'mac_chromium_compile': 'gpu_tests_release_trybot_reclient',
-      'webrtc_linux_chromium': 'release_trybot_reclient',
+      'webrtc_linux_chromium': 'release_trybot_blink_reclient',
       'win_chromium_compile': 'gpu_tests_release_trybot_resource_allowlisting_reclient',
       'win_chromium_compile_dbg': 'gpu_tests_debug_bot_x86_no_symbols_reclient',
     },
diff --git a/tools/mb/mb_config_expectations/tryserver.webrtc.json b/tools/mb/mb_config_expectations/tryserver.webrtc.json
index 6f730d08..30bb4a0a 100644
--- a/tools/mb/mb_config_expectations/tryserver.webrtc.json
+++ b/tools/mb/mb_config_expectations/tryserver.webrtc.json
@@ -44,9 +44,11 @@
   "webrtc_linux_chromium": {
     "gn_args": {
       "dcheck_always_on": true,
+      "ffmpeg_branding": "Chrome",
       "is_component_build": false,
       "is_debug": false,
-      "symbol_level": 0,
+      "proprietary_codecs": true,
+      "symbol_level": 1,
       "use_remoteexec": true
     }
   },
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 7701747..868b8ef 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -33767,6 +33767,7 @@
   <int value="504" label="PDF_VIEWER_PRIVATE_ON_PDF_OCR_PREF_CHANGED"/>
   <int value="505" label="SMART_CARD_PROVIDER_PRIVATE_ON_CONNECT_REQUESTED"/>
   <int value="506" label="SMART_CARD_PROVIDER_PRIVATE_ON_DISCONNECT_REQUESTED"/>
+  <int value="507" label="SMART_CARD_PROVIDER_PRIVATE_ON_CANCEL_REQUESTED"/>
 </enum>
 
 <enum name="ExtensionFileWriteResult">
@@ -35633,6 +35634,7 @@
   <int value="1773" label="POWER_REPORTACTIVITY"/>
   <int value="1774" label="PASSWORDSPRIVATE_CONTINUEIMPORT"/>
   <int value="1775" label="PASSWORDSPRIVATE_RESETIMPORTER"/>
+  <int value="1776" label="SMARTCARDPROVIDERPRIVATE_REPORTCANCELRESULT"/>
 </enum>
 
 <enum name="ExtensionIconState">
@@ -36270,6 +36272,7 @@
   <int value="245" label="kPdfViewerPrivate"/>
   <int value="246" label="kSystemLog"/>
   <int value="247" label="kSmartCardProviderPrivate"/>
+  <int value="248" label="kChromeOSEvents"/>
 </enum>
 
 <enum name="ExtensionPointEnableState">
diff --git a/tools/metrics/histograms/metadata/chromeos_hps/OWNERS b/tools/metrics/histograms/metadata/chromeos_hps/OWNERS
index 5a4c244..25a2fea 100644
--- a/tools/metrics/histograms/metadata/chromeos_hps/OWNERS
+++ b/tools/metrics/histograms/metadata/chromeos_hps/OWNERS
@@ -2,7 +2,6 @@
 
 # Prefer sending CLs to the owners listed below.
 # Use chromium-metrics-reviews@google.com as a backup.
-azeemarshad@chromium.org
 chadduffin@chromium.org
 crisrael@google.com
 jorgelo@chromium.org
diff --git a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
index c5284714..8f75229 100644
--- a/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
+++ b/tools/metrics/histograms/metadata/histogram_suffixes_list.xml
@@ -5769,8 +5769,6 @@
   <affected-histogram name="Startup.FirstWebContents.MainNavigationFinished"/>
   <affected-histogram name="Startup.FirstWebContents.MainNavigationStart"/>
   <affected-histogram name="Startup.FirstWebContents.NonEmptyPaint3"/>
-  <affected-histogram
-      name="Startup.FirstWebContents.RenderProcessHostInit.ToNonEmptyPaint"/>
   <affected-histogram name="Startup.LoadTime.ApplicationStartToChromeMain"/>
   <affected-histogram name="Startup.LoadTime.ProcessCreateToApplicationStart"/>
 </histogram_suffixes>
diff --git a/tools/metrics/histograms/metadata/password/histograms.xml b/tools/metrics/histograms/metadata/password/histograms.xml
index a454cd23..163868d 100644
--- a/tools/metrics/histograms/metadata/password/histograms.xml
+++ b/tools/metrics/histograms/metadata/password/histograms.xml
@@ -3761,11 +3761,13 @@
 </histogram>
 
 <histogram name="PasswordManager.{Location}.AuthenticationTime" units="ms"
-    expires_after="M115">
+    expires_after="M120">
   <owner>vsemeniuk@google.com</owner>
   <owner>vasilii@chromium.org</owner>
   <summary>Records the time it takes user to authenticate {Location}.</summary>
   <token key="Location">
+    <variant name="ManagementBubble"
+        summary="in management bubble when navigating to details view"/>
     <variant name="PasswordFilling"
         summary="on webpage after selecting a suggestion to fill"/>
     <variant name="Settings"
diff --git a/tools/metrics/histograms/metadata/startup/histograms.xml b/tools/metrics/histograms/metadata/startup/histograms.xml
index 253e24fd..778c03d 100644
--- a/tools/metrics/histograms/metadata/startup/histograms.xml
+++ b/tools/metrics/histograms/metadata/startup/histograms.xml
@@ -670,16 +670,6 @@
   </summary>
 </histogram>
 
-<histogram
-    name="Startup.FirstWebContents.RenderProcessHostInit.ToNonEmptyPaint"
-    units="ms" expires_after="M78">
-  <owner>hans@chromium.org</owner>
-  <summary>
-    Time between RenderFrameHostImpl::Init and
-    Startup.FirstWebContents.NonEmptyPaint2.
-  </summary>
-</histogram>
-
 <histogram name="Startup.IncognitoForcedStart" enum="IncognitoForcedStart"
     expires_after="M111">
   <owner>arabm@google.com</owner>
diff --git a/weblayer/shell/android/BUILD.gn b/weblayer/shell/android/BUILD.gn
index 6c35222..ec9637b 100644
--- a/weblayer/shell/android/BUILD.gn
+++ b/weblayer/shell/android/BUILD.gn
@@ -150,8 +150,7 @@
     "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineNavigationTestActivity.java",
     "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java",
     "webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineStateTestActivity.java",
-    "webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBar.java",
-    "webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBarImpl.java",
+    "webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsObserver.java",
     "webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBarObservers.java",
   ]
 
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java
index ca23b7f..2c46db82 100644
--- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java
+++ b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/WebEngineShellActivity.java
@@ -7,9 +7,14 @@
 import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
 import android.os.Bundle;
+import android.util.Patterns;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
@@ -39,7 +44,7 @@
 import org.chromium.webengine.WebEngine;
 import org.chromium.webengine.WebFragment;
 import org.chromium.webengine.WebSandbox;
-import org.chromium.webengine.shell.topbar.TopBarImpl;
+import org.chromium.webengine.shell.topbar.TabEventsObserver;
 import org.chromium.webengine.shell.topbar.TopBarObservers;
 
 import java.util.Arrays;
@@ -53,7 +58,8 @@
  *  - Move cookie test to manual-test activity
  *  - Move registerWebMessageCallback to manual-test activity
  */
-public class WebEngineShellActivity extends AppCompatActivity implements FullscreenCallback {
+public class WebEngineShellActivity
+        extends AppCompatActivity implements FullscreenCallback, TabEventsObserver {
     private static final String TAG = "WebEngineShell";
 
     private static final String WEB_FRAGMENT_TAG = "WEB_FRAGMENT_TAG";
@@ -63,6 +69,16 @@
     private WebSandbox mWebSandbox;
     private TabManager mTabManager;
 
+    private ProgressBar mProgressBar;
+    private EditText mUrlBar;
+    private Button mTabCountButton;
+    private Spinner mTabListSpinner;
+    private ArrayAdapter<TabWrapper> mTabListAdapter;
+
+    private ImageButton mReloadButton;
+    private Drawable mRefreshDrawable;
+    private Drawable mStopDrawable;
+
     private DefaultObservers mDefaultTabListObserver;
 
     private int mSystemVisibilityToRestore;
@@ -76,6 +92,57 @@
 
         setupActivitySpinner((Spinner) findViewById(R.id.activity_nav), this, 0);
 
+        mProgressBar = findViewById(R.id.progress_bar);
+        mUrlBar = findViewById(R.id.url_bar);
+        mTabCountButton = findViewById(R.id.tab_count);
+        mTabListSpinner = findViewById(R.id.tab_list);
+
+        mReloadButton = findViewById(R.id.reload_button);
+        mRefreshDrawable = getDrawable(R.drawable.ic_refresh);
+        mStopDrawable = getDrawable(R.drawable.ic_stop);
+
+        mUrlBar.setOnEditorActionListener(new TextView.OnEditorActionListener() {
+            @Override
+            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+                Uri query = Uri.parse(v.getText().toString());
+                if (query.isAbsolute()) {
+                    mTabManager.getActiveTab().getNavigationController().navigate(
+                            query.normalizeScheme().toString());
+                } else if (Patterns.DOMAIN_NAME.matcher(query.toString()).matches()) {
+                    mTabManager.getActiveTab().getNavigationController().navigate(
+                            "https://" + query);
+                } else {
+                    mTabManager.getActiveTab().getNavigationController().navigate(
+                            "https://www.google.com/search?q="
+                            + Uri.encode(v.getText().toString()));
+                }
+                // Hides keyboard on Enter key pressed
+                InputMethodManager imm = (InputMethodManager) mContext.getSystemService(
+                        Context.INPUT_METHOD_SERVICE);
+                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
+                return true;
+            }
+        });
+
+        mReloadButton.setOnClickListener(v -> {
+            if (mReloadButton.getDrawable().equals(mRefreshDrawable)) {
+                mTabManager.getActiveTab().getNavigationController().reload();
+            } else if (mReloadButton.getDrawable().equals(mStopDrawable)) {
+                mTabManager.getActiveTab().getNavigationController().stop();
+            }
+        });
+
+        mTabCountButton.setOnClickListener(v -> mTabListSpinner.performClick());
+
+        mTabListSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+                mTabListAdapter.getItem(pos).getTab().setActive();
+            }
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {}
+        });
+
         ListenableFuture<String> sandboxVersionFuture = WebSandbox.getVersion(mContext);
 
         Futures.addCallback(sandboxVersionFuture, new FutureCallback<String>() {
@@ -147,14 +214,17 @@
         CookieManager cookieManager = webEngine.getCookieManager();
 
         Tab activeTab = mTabManager.getActiveTab();
-        ProgressBar progressBar = findViewById(R.id.progress_bar);
-        EditText urlBar = findViewById(R.id.url_bar);
-        ImageButton reloadButton = findViewById(R.id.reload_button);
-        Button tabCountButton = findViewById(R.id.tab_count);
-        Spinner tabListSpinner = findViewById(R.id.tab_list);
-        new TopBarObservers(new TopBarImpl(this, mTabManager, urlBar, progressBar, reloadButton,
-                                    tabCountButton, tabListSpinner),
-                mTabManager);
+
+        mTabCountButton.setText(String.valueOf(getTabsCount()));
+
+        mTabListAdapter =
+                new ArrayAdapter<TabWrapper>(this, android.R.layout.simple_spinner_dropdown_item);
+        for (Tab t : mTabManager.getAllTabs()) {
+            mTabListAdapter.add(new TabWrapper(t));
+        }
+        mTabListSpinner.setAdapter(mTabListAdapter);
+
+        new TopBarObservers(this, mTabManager);
 
         activeTab.setFullscreenCallback(this);
         mTabManager.registerTabListObserver(new TabListObserver() {
@@ -326,4 +396,72 @@
             getWindow().setAttributes(attrs);
         }
     }
+
+    @Override
+    public void setUrlBar(String uri) {
+        mUrlBar.setText(uri);
+    }
+
+    @Override
+    public void setProgress(double progress) {
+        int progressValue = (int) Math.rint(progress * 100);
+        if (progressValue != mProgressBar.getMax()) {
+            mReloadButton.setImageDrawable(mStopDrawable);
+            mProgressBar.setVisibility(View.VISIBLE);
+        } else {
+            mReloadButton.setImageDrawable(mRefreshDrawable);
+            mProgressBar.setVisibility(View.INVISIBLE);
+        }
+        mProgressBar.setProgress(progressValue);
+    }
+
+    @Override
+    public void addTabToList(Tab tab) {
+        mTabCountButton.setText(String.valueOf(getTabsCount()));
+        mTabListAdapter.add(new TabWrapper(tab));
+    }
+
+    @Override
+    public void removeTabFromList(Tab tab) {
+        mTabCountButton.setText(String.valueOf(getTabsCount()));
+        for (int position = 0; position < mTabListAdapter.getCount(); ++position) {
+            TabWrapper tabAdapter = mTabListAdapter.getItem(position);
+            if (tabAdapter.getTab().equals(tab)) {
+                mTabListAdapter.remove(tabAdapter);
+                return;
+            }
+        }
+    }
+
+    @Override
+    public void setTabListSelection(Tab tab) {
+        for (int position = 0; position < mTabListAdapter.getCount(); ++position) {
+            TabWrapper tabWrapper = mTabListAdapter.getItem(position);
+            if (tabWrapper.getTab().equals(tab)) {
+                mTabListSpinner.setSelection(mTabListAdapter.getPosition(tabWrapper));
+                return;
+            }
+        }
+    }
+
+    public int getTabsCount() {
+        return mTabManager.getAllTabs().size();
+    }
+
+    static class TabWrapper {
+        final Tab mTab;
+        public TabWrapper(Tab tab) {
+            mTab = tab;
+        }
+
+        public Tab getTab() {
+            return mTab;
+        }
+
+        @NonNull
+        @Override
+        public String toString() {
+            return mTab.getDisplayUri().getAuthority() + mTab.getDisplayUri().getPath();
+        }
+    }
 }
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsObserver.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsObserver.java
new file mode 100644
index 0000000..2dfa8e2
--- /dev/null
+++ b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TabEventsObserver.java
@@ -0,0 +1,22 @@
+// Copyright 2023 The Chromium Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.webengine.shell.topbar;
+
+import org.chromium.webengine.Tab;
+
+/**
+ * An interface for setting values in the Top Bar.
+ */
+public interface TabEventsObserver {
+    void setUrlBar(String uri);
+
+    void setProgress(double progress);
+
+    void addTabToList(Tab tab);
+
+    void removeTabFromList(Tab tab);
+
+    void setTabListSelection(Tab tab);
+}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBar.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBar.java
deleted file mode 100644
index 0ad1e379..0000000
--- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBar.java
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.webengine.shell.topbar;
-
-import org.chromium.webengine.Tab;
-
-/**
- * An interface for setting the values in the Top Bar.
- */
-public abstract class TopBar {
-    public abstract void setUrlBar(String uri);
-
-    public abstract void setProgress(double progress);
-
-    public abstract void addTabToList(Tab tab);
-
-    public abstract void removeTabFromList(Tab tab);
-
-    public abstract void setTabListSelection(Tab tab);
-
-    public abstract boolean isTabActive(Tab tab);
-
-    public abstract int getTabsCount();
-}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBarImpl.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBarImpl.java
deleted file mode 100644
index b15265d5..0000000
--- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBarImpl.java
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2023 The Chromium Authors
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.webengine.shell.topbar;
-
-import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.net.Uri;
-import android.util.Patterns;
-import android.view.KeyEvent;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.EditText;
-import android.widget.ImageButton;
-import android.widget.ProgressBar;
-import android.widget.Spinner;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-
-import org.chromium.webengine.Tab;
-import org.chromium.webengine.TabManager;
-
-/**
- * Sets the values in the Top Bar Views.
- */
-public class TopBarImpl extends TopBar {
-    private final Context mContext;
-    private final TabManager mTabManager;
-    private final EditText mUrlBar;
-    private final ProgressBar mProgressBar;
-    private final ImageButton mReloadButton;
-    private final Drawable mRefreshDrawable;
-    private final Drawable mStopDrawable;
-    private final Button mTabCountButton;
-    private final Spinner mTabListSpinner;
-    private final ArrayAdapter<TabWrapper> mTabListAdapter;
-
-    public TopBarImpl(Context context, TabManager tabManager, EditText urlBar,
-            ProgressBar progressBar, ImageButton reloadButton, Button tabCountButton,
-            Spinner tabListSpinner) {
-        mContext = context;
-        mTabManager = tabManager;
-        mUrlBar = urlBar;
-        mProgressBar = progressBar;
-
-        mReloadButton = reloadButton;
-        mRefreshDrawable = mContext.getDrawable(org.chromium.webengine.shell.R.drawable.ic_refresh);
-        mStopDrawable = mContext.getDrawable(org.chromium.webengine.shell.R.drawable.ic_stop);
-
-        mTabCountButton = tabCountButton;
-        mTabCountButton.setText(String.valueOf(getTabsCount()));
-
-        mTabListAdapter = new ArrayAdapter<TabWrapper>(
-                context, android.R.layout.simple_spinner_dropdown_item);
-        for (Tab t : mTabManager.getAllTabs()) {
-            mTabListAdapter.add(new TabWrapper(t));
-        }
-        mTabListSpinner = tabListSpinner;
-        mTabListSpinner.setAdapter(mTabListAdapter);
-
-        urlBar.setOnEditorActionListener(new TextView.OnEditorActionListener() {
-            @Override
-            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-                Uri query = Uri.parse(v.getText().toString());
-                if (query.isAbsolute()) {
-                    mTabManager.getActiveTab().getNavigationController().navigate(
-                            query.normalizeScheme().toString());
-                } else if (Patterns.DOMAIN_NAME.matcher(query.toString()).matches()) {
-                    mTabManager.getActiveTab().getNavigationController().navigate(
-                            "https://" + query);
-                } else {
-                    mTabManager.getActiveTab().getNavigationController().navigate(
-                            "https://www.google.com/search?q="
-                            + Uri.encode(v.getText().toString()));
-                }
-                // Hides keyboard on Enter key pressed
-                InputMethodManager imm = (InputMethodManager) mContext.getSystemService(
-                        Context.INPUT_METHOD_SERVICE);
-                imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
-                return true;
-            }
-        });
-
-        mReloadButton.setOnClickListener(v -> {
-            if (mReloadButton.getDrawable().equals(mRefreshDrawable)) {
-                tabManager.getActiveTab().getNavigationController().reload();
-            } else if (mReloadButton.getDrawable().equals(mStopDrawable)) {
-                tabManager.getActiveTab().getNavigationController().stop();
-            }
-        });
-
-        mTabCountButton.setOnClickListener(v -> mTabListSpinner.performClick());
-
-        mTabListSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
-            @Override
-            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
-                mTabListAdapter.getItem(pos).getTab().setActive();
-            }
-            @Override
-            public void onNothingSelected(AdapterView<?> parent) {}
-        });
-    }
-
-    @Override
-    public void setUrlBar(String uri) {
-        mUrlBar.setText(uri);
-    }
-
-    @Override
-    public void setProgress(double progress) {
-        int progressValue = (int) Math.rint(progress * 100);
-        if (progressValue != mProgressBar.getMax()) {
-            mReloadButton.setImageDrawable(mStopDrawable);
-            mProgressBar.setVisibility(View.VISIBLE);
-        } else {
-            mReloadButton.setImageDrawable(mRefreshDrawable);
-            mProgressBar.setVisibility(View.INVISIBLE);
-        }
-        mProgressBar.setProgress(progressValue);
-    }
-
-    @Override
-    public void addTabToList(Tab tab) {
-        mTabCountButton.setText(String.valueOf(getTabsCount()));
-        mTabListAdapter.add(new TabWrapper(tab));
-    }
-
-    @Override
-    public void removeTabFromList(Tab tab) {
-        mTabCountButton.setText(String.valueOf(getTabsCount()));
-        for (int position = 0; position < mTabListAdapter.getCount(); ++position) {
-            TabWrapper tabAdapter = mTabListAdapter.getItem(position);
-            if (tabAdapter.getTab().equals(tab)) {
-                mTabListAdapter.remove(tabAdapter);
-                return;
-            }
-        }
-    }
-
-    @Override
-    public void setTabListSelection(Tab tab) {
-        for (int position = 0; position < mTabListAdapter.getCount(); ++position) {
-            TabWrapper tabWrapper = mTabListAdapter.getItem(position);
-            if (tabWrapper.getTab().equals(tab)) {
-                mTabListSpinner.setSelection(mTabListAdapter.getPosition(tabWrapper));
-                return;
-            }
-        }
-    }
-
-    @Override
-    public boolean isTabActive(Tab tab) {
-        return mTabManager.getActiveTab() != null && mTabManager.getActiveTab().equals(tab);
-    }
-
-    @Override
-    public int getTabsCount() {
-        return mTabManager.getAllTabs().size();
-    }
-
-    static class TabWrapper {
-        final Tab mTab;
-        public TabWrapper(Tab tab) {
-            mTab = tab;
-        }
-
-        public Tab getTab() {
-            return mTab;
-        }
-
-        @NonNull
-        @Override
-        public String toString() {
-            return mTab.getDisplayUri().getAuthority() + mTab.getDisplayUri().getPath();
-        }
-    }
-}
diff --git a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBarObservers.java b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBarObservers.java
index bd325f44..4529cdf 100644
--- a/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBarObservers.java
+++ b/weblayer/shell/android/webengine_shell_apk/src/org/chromium/webengine/shell/topbar/TopBarObservers.java
@@ -19,10 +19,10 @@
  * Top Bar observers for Test Activities.
  */
 public class TopBarObservers implements TabObserver, NavigationObserver, TabListObserver {
-    final TopBar mTopBar;
+    final TabEventsObserver mTabEventsObserver;
     final TabManager mTabManager;
-    public TopBarObservers(TopBar topBar, TabManager tabManager) {
-        mTopBar = topBar;
+    public TopBarObservers(TabEventsObserver tabEventObserver, TabManager tabManager) {
+        mTabEventsObserver = tabEventObserver;
         mTabManager = tabManager;
 
         mTabManager.registerTabListObserver(this);
@@ -34,10 +34,10 @@
 
     @Override
     public void onVisibleUriChanged(@NonNull Tab tab, @NonNull String uri) {
-        if (!mTopBar.isTabActive(tab)) {
+        if (!isTabActive(tab)) {
             return;
         }
-        mTopBar.setUrlBar(uri);
+        mTabEventsObserver.setUrlBar(uri);
     }
 
     @Override
@@ -53,13 +53,13 @@
         if (activeTab == null) {
             return;
         }
-        mTopBar.setUrlBar(activeTab.getDisplayUri().toString());
-        mTopBar.setTabListSelection(activeTab);
+        mTabEventsObserver.setUrlBar(activeTab.getDisplayUri().toString());
+        mTabEventsObserver.setTabListSelection(activeTab);
     }
 
     @Override
     public void onTabAdded(@NonNull WebEngine webEngine, @NonNull Tab tab) {
-        mTopBar.addTabToList(tab);
+        mTabEventsObserver.addTabToList(tab);
         // Recursively add tab and navigation observers to any new tab.
         tab.registerTabObserver(this);
         tab.getNavigationController().registerNavigationObserver(this);
@@ -67,7 +67,7 @@
 
     @Override
     public void onTabRemoved(@NonNull WebEngine webEngine, @NonNull Tab tab) {
-        mTopBar.removeTabFromList(tab);
+        mTabEventsObserver.removeTabFromList(tab);
     }
 
     @Override
@@ -88,9 +88,13 @@
 
     @Override
     public void onLoadProgressChanged(@NonNull Tab tab, double progress) {
-        if (!mTopBar.isTabActive(tab)) {
+        if (!isTabActive(tab)) {
             return;
         }
-        mTopBar.setProgress(progress);
+        mTabEventsObserver.setProgress(progress);
+    }
+
+    boolean isTabActive(Tab tab) {
+        return mTabManager.getActiveTab() != null && mTabManager.getActiveTab().equals(tab);
     }
 }